Initial commit: Office365 web management platform

This commit is contained in:
youbin
2026-03-21 21:11:01 +08:00
commit 8d715a3a15
21 changed files with 3828 additions and 0 deletions

250
README.md Normal file
View File

@@ -0,0 +1,250 @@
# Office 365 Web 管理平台
基于你指定的 [`eggyrooch-blip/office365-tools`](https://github.com/eggyrooch-blip/office365-tools) 思路重新封装,做成了一套可直接 Web 管理的 Office 365 / Microsoft 365 账号管理后台。当前项目只保留国际版 Microsoft 365 / Microsoft Graph 实现。
当前版本覆盖的核心能力:
- 单个账号增删改查
- 用户列表勾选后批量删除、批量启用、批量停用、批量重置密码
- 批量创建、批量更新、批量删除
- 单个与批量重置密码
- 批量模板 CSV 下载后上传执行
- 批量任务进度展示,详细处理过程写入日志文件
- 许可证 SKU 列表与剩余席位查看
- 基于 `.env` 的租户配置
- 可选的后台登录保护
## 项目结构
```text
.
├── app.py
├── office365_admin/
│ ├── __init__.py
│ ├── batch.py
│ ├── graph.py
│ ├── routes.py
│ ├── services.py
│ ├── settings.py
│ ├── static/
│ └── templates/
├── tests/
└── reference-office365-tools/ # 参考仓库,保留用于对照
```
## 启动方式
1. 创建虚拟环境并安装依赖
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
2. 复制配置文件
```bash
cp .env.example .env
```
3.`.env` 中填写你的租户配置
必填项:
- `CLIENT_ID`
- `TENANT_ID`
- `CLIENT_SECRET`
- `DEFAULT_PASSWORD`
常用项:
- `DEFAULT_DOMAIN`
- `DEFAULT_LICENSE_SKU`
- `ADMIN_USERNAME`
- `ADMIN_PASSWORD`
4. 启动服务
```bash
python3 app.py
```
默认访问地址:
- [http://127.0.0.1:8000](http://127.0.0.1:8000)
## 批量导入格式
### 批量创建 CSV
```csv
userPrincipalName,displayName,givenName,surname,department,jobTitle,usageLocation,skuPartNumber,password
alice,Alice Zhang,Alice,Zhang,Sales,Manager,US,ENTERPRISEPACK,Temp123!
bob@contoso.com,Bob Li,Bob,Li,IT,Engineer,US,ENTERPRISEPACK,
```
说明:
- `userPrincipalName` 可以只写用户名,系统会自动拼接 `DEFAULT_DOMAIN`
- `password` 为空时使用 `DEFAULT_PASSWORD`
- `skuPartNumber` 为空时使用 `DEFAULT_LICENSE_SKU`
### 批量更新 CSV
```csv
userPrincipalName,department,jobTitle,accountEnabled,skuPartNumber
alice@contoso.com,Operations,Lead,true,O365_BUSINESS
bob@contoso.com,Finance,Analyst,false,
```
说明:
- 至少要有一列账号标识
- 批量更新里的空白字段默认忽略,不会清空已有值
### 批量删除文本
```text
alice
bob@contoso.com
charlie@contoso.com
```
### 批量重置密码 CSV
```csv
userPrincipalName,password,forceChangePasswordNextSignIn
alice@contoso.com,Temp123!,true
bob@contoso.com,Another123!,true
```
也可以直接传纯文本账号列表,此时统一使用 `DEFAULT_PASSWORD`
## 配置说明
### `.env` 参数配置与获取方式
| 参数名 | 是否必填 | 说明 | 获取方式 / 示例 |
| --- | --- | --- | --- |
| `CLIENT_ID` | 是 | Entra 应用的客户端 ID | 在应用注册概览页复制“应用程序(客户端) ID” |
| `TENANT_ID` | 是 | 租户 ID | 在应用注册概览页复制“目录(租户) ID” |
| `CLIENT_SECRET` | 是 | 应用客户端密钥值 | 在“证书和密码”中新建客户端密码后复制 `Value` |
| `DEFAULT_PASSWORD` | 是 | 新建账号或重置密码时的默认密码 | 由你自行定义,建议使用高强度临时密码 |
| `DEFAULT_DOMAIN` | 建议 | 用户名自动补全时使用的默认域名 | 例如 `yourtenant.onmicrosoft.com` 或已验证自定义域名 |
| `DEFAULT_USAGE_LOCATION` | 建议 | 账号默认使用地区 | 国际版常见示例:`US``SG``JP` |
| `DEFAULT_LICENSE_SKU` | 可选 | 创建用户时默认分配的许可证 SKU | 例如 `ENTERPRISEPACK``M365_BUSINESS_PREMIUM` |
| `WEB_AUTH_ENABLED` | 可选 | 是否启用平台网页登录保护 | `true``false` |
| `ADMIN_USERNAME` | 建议 | 本平台网页登录用户名 | 例如 `admin` |
| `ADMIN_PASSWORD` | 建议 | 本平台网页登录密码 | 由你自行定义;这不是 Microsoft 365 账号密码 |
| `SESSION_SECRET` | 建议 | Flask 会话密钥 | 建议使用随机长字符串 |
| `HOST` | 可选 | Web 服务监听地址 | 默认 `0.0.0.0` |
| `PORT` | 可选 | Web 服务监听端口 | 默认 `8000` |
| `DEBUG` | 可选 | 是否启用调试模式 | 默认 `false` |
说明:
- `DEFAULT_LICENSE_SKU` 需要填写租户里实际存在的 SKU Part Number如果不确定可以先启动系统在“许可证概览”里查看。
- `ADMIN_USERNAME` / `ADMIN_PASSWORD` 是这个管理平台自己的登录账号,不是 Microsoft 365 管理员邮箱账号。
- 如果不填写 `DEFAULT_DOMAIN`,创建用户时必须填写完整邮箱格式的 `userPrincipalName`
### Entra ID 应用注册配置
在使用本工具之前,需要在 Microsoft Entra IDAzure AD中注册应用程序并配置权限。
#### 步骤 1创建应用注册
1. 登录 Microsoft Entra 管理中心
2. 导航到 `身份` -> `应用注册`
3. 点击 `+ 新建注册`
4. 填写应用信息:
- 名称:输入应用名称,例如 `Office 365 用户管理工具`
- 支持的帐户类型:选择“仅此组织目录中的帐户”
- 重定向 URI无需填写本项目使用客户端凭据流程
5. 点击 `注册`
#### 步骤 2获取应用信息
注册完成后,在应用概览页面可以获取:
- 应用程序(客户端) ID复制此值作为 `CLIENT_ID`
- 目录(租户) ID复制此值作为 `TENANT_ID`
#### 步骤 3创建客户端密钥
1. 在应用注册页面,导航到 `证书和密码`
2. 点击 `+ 新建客户端密码`
3. 填写描述和过期时间
4. 点击 `添加`
5. 重要:立即复制密钥值,它只会显示一次;将其填写为 `CLIENT_SECRET`
#### 步骤 4配置 API 权限
1. 在应用注册页面,导航到 `API 权限`
2. 点击 `+ 添加权限` -> `Microsoft Graph` -> `应用程序权限`
必需权限列表:
| 权限名称 | 说明 | 是否必需 |
| --- | --- | --- |
| `User.ReadWrite.All` | 读取和写入所有用户配置文件 | 必需,用于创建、更新、删除用户 |
| `User-PasswordProfile.ReadWrite.All` | 读取和写入所有用户的密码配置文件 | 必需,用于重置密码 |
| `LicenseAssignment.ReadWrite.All` | 读取和写入所有许可证分配 | 必需,用于分配许可证 |
| `Directory.ReadWrite.All` | 读取和写入目录数据 | 可选,更高权限,可替代部分用户写入权限 |
| `AuditLog.Read.All` | 读取审核日志数据 | 可选,用于后续扩展登录活动或审计场景 |
权限配置步骤:
1. 搜索并选择每个权限
2. 点击 `添加权限`
3. 添加完成后,点击 `为 [你的组织名称] 授予管理员同意`
4. 确认授予同意
重要提示:
- 所有应用程序权限都需要管理员同意才能生效。
- 确保你是该应用程序的 `所有者`
- 权限生效可能需要几分钟。
- 如果权限 Owner 发生变化,或者管理员重新授予了同意,建议重启本项目服务以重新获取访问令牌。
#### 步骤 5验证权限配置
`API 权限` 页面,确认所有需要的权限状态都显示为“已授予(管理员同意)”。
### Graph 端点
项目固定使用国际版端点:
- Graph API: `https://graph.microsoft.com/v1.0`
- Token Endpoint: `https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token`
- Scope: `https://graph.microsoft.com/.default`
### 平台登录
如果你希望平台访问前需要登录,请配置:
```env
WEB_AUTH_ENABLED=true
ADMIN_USERNAME=admin
ADMIN_PASSWORD=ChangeMe123!
SESSION_SECRET=random-long-secret
```
如果 `WEB_AUTH_ENABLED=true` 但没有设置用户名密码,系统会自动降级为无登录保护模式,并在页面状态区显示提醒。
## 测试
```bash
pytest
```
## 日志
服务运行后会把详细操作日志写入:
- [logs/office365_admin.log](/Users/youbin/Desktop/Office365UserManage/logs/office365_admin.log)
## 说明
- `reference-office365-tools` 是我拉下来的参考仓库,当前运行时不会直接引用它。
- Web 平台的 Graph 调用逻辑已经按后台服务方式重构,便于继续扩展审批流、组织架构、日志审计等能力。