Files
office365-self-service/README.md

171 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Office 365 Self Service
基于 Microsoft Graph API 实现的 Office 365 账号自助开通系统。通过兑换码自助开通账号,每个兑换码只能开通一个账号。
## 功能特性
- **兑换码管理**:管理员后台批量生成兑换码
- **自助开通**:用户输入兑换码和用户名自助开通 Office 365 账号
- **自动授权**:账号开通时自动分配许可证
- **兑换记录**:后台记录兑换码与已开通账号的对应关系
- **审计日志**:后台分页查看生成、删除、兑换成功/失败等关键事件
## 项目结构
```
.
├── app.py # 应用入口
├── Dockerfile # Docker 镜像构建
├── docker-compose.yml # Docker Compose 部署
├── requirements.txt # Python 依赖
├── .env.example # 配置示例
├── office365_self_service/
│ ├── __init__.py # Flask 应用工厂
│ ├── settings.py # 配置加载
│ ├── routes.py # 路由定义
│ ├── models.py # 数据库模型
│ ├── services.py # Office 365 服务
│ ├── graph.py # Graph API 客户端
│ └── templates/ # 前端模板
│ ├── admin_login.html # 管理员登录
│ ├── admin_dashboard.html # 管理后台
│ └── user_redemption.html # 用户兑换页面
```
## 部署方式
### 本地运行
```bash
# 1. 创建虚拟环境并安装依赖
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# 2. 复制配置文件
cp .env.example .env
# 3. 在 .env 中填写配置(见下方参数说明)
# 4. 启动服务
python3 app.py
```
访问地址http://127.0.0.1:8000
### Docker Compose 部署
```bash
# 1. 复制配置文件并配置
cp .env.example .env
# 2. 构建并启动
docker compose up -d --build
# 3. 查看日志
docker compose logs -f
# 4. 停止服务
docker compose down
```
默认端口8000
### 环境变量参数说明
| 参数名 | 必填 | 说明 | 获取方式 |
|--------|------|------|----------|
| `CLIENT_ID` | 是 | Entra 应用客户端 ID | Azure AD 应用注册概览页 |
| `TENANT_ID` | 是 | 租户 ID | Azure AD 应用注册概览页 |
| `CLIENT_SECRET` | 是 | 应用客户端密钥 | Azure AD -> 证书和密码 |
| `DEFAULT_PASSWORD` | 是 | 新建账号默认密码 | 自定义高强度密码 |
| `DEFAULT_DOMAIN` | 建议 | 默认域名 | 例如 `yourtenant.onmicrosoft.com` |
| `DEFAULT_LICENSE_SKU` | 可选 | 默认许可证 SKU | 例如 `ENTERPRISEPACK``M365_BUSINESS_PREMIUM` |
| `LICENSE_ASSIGNMENT_REQUIRED` | 可选 | 许可证分配失败时是否回滚删除新账号 | 默认 `false` |
| `DEFAULT_USAGE_LOCATION` | 建议 | 默认使用地区 | 国际版常用:`US``SG``JP` |
| `WEB_AUTH_ENABLED` | 可选 | 后台登录保护 | `true``false` |
| `ADMIN_USERNAME` | 建议 | 后台登录用户名 | 自定义 |
| `ADMIN_PASSWORD` | 建议 | 后台登录密码 | 自定义 |
| `YAOHUO_VERIFICATION_ENABLED` | 可选 | 是否启用妖火论坛私信验证免兑换码开通 | `true``false` |
| `YAOHUO_COOKIE` | 妖火验证必填 | 后台已登录妖火账号的 Cookie | 浏览器复制完整 Cookie |
| `YAOHUO_MESSAGE_URL` | 可选 | 妖火发私信地址 | 默认 `https://www.yaohuo.me/bbs/messagelist_add.aspx` |
| `YAOHUO_VERIFICATION_CODE_TTL_SECONDS` | 可选 | 妖火验证码有效期(秒) | 默认 `600` |
| `SESSION_SECRET` | 建议 | Flask 会话密钥 | 随机长字符串 |
| `HOST` | 可选 | 服务监听地址 | 默认 `0.0.0.0` |
| `PORT` | 可选 | 服务监听端口 | 默认 `8000` |
| `DEBUG` | 可选 | 调试模式 | 默认 `false` |
提示:如果本地误用了容器内的 SQLite 路径(例如 `sqlite:////app/data/redemption.db`),项目现在会自动映射到当前仓库下的对应本地路径。
### Entra ID (Azure AD) 应用配置
1. **创建应用注册**
- 登录 Microsoft Entra 管理中心
- 导航到 `身份` -> `应用注册` -> `+ 新建注册`
- 填写名称(例如 `Office 365 Self Service`
- 选择「仅此组织目录中的帐户」
- 不需要填写重定向 URI
- 点击「注册」
2. **获取应用信息**
- 复制「应用程序(客户端) ID」→ `CLIENT_ID`
- 复制「目录(租户) ID」→ `TENANT_ID`
3. **创建客户端密钥**
- 导航到「证书和密码」
- 点击「+ 新建客户端密码」
- 设置描述和过期时间
- 点击「添加」后复制密钥值 → `CLIENT_SECRET`
4. **配置 API 权限**
- 导航到「API 权限」
- 点击「+ 添加权限」-> 「Microsoft Graph」-> 「应用程序权限」
- 添加以下权限:
- `User.ReadWrite.All` - 读取和写入用户
- `User-PasswordProfile.ReadWrite.All` - 密码配置
- `LicenseAssignment.ReadWrite.All` - 许可证分配
- 点击「为 xx 授予管理员同意」
## 使用说明
### 管理员后台
访问地址:`http://ip:port/admin/`
1. 使用设置的 admin 账号登录
2. 点击「生成兑换码」批量生成兑换码
3. 可以查看兑换码、兑换记录和审计日志
### 用户自助开通
访问地址:`http://ip:port/`
1. 输入管理员提供的兑换码
2. 输入想要的用户名(不需要加域名)
3. 点击「立即开通」
4. 系统返回临时密码,首次登录后需更改密码
### 妖火论坛验证开通
1.`.env` 中启用 `YAOHUO_VERIFICATION_ENABLED=true`
2. 配置可用的 `YAOHUO_COOKIE`
3. 用户在首页切换到「妖火验证开通」
4. 输入目标妖火 ID系统向该 ID 发送私信验证码
5. 对方提供验证码后完成验证
6. 验证通过后无需兑换码即可直接开通账号
## 技术栈
- Python 3.9+
- Flask + Flask-SQLAlchemy
- Microsoft Graph API
- SQLite数据持久化
- Docker
## 注意事项
- `DEFAULT_LICENSE_SKU` 必须是租户中实际存在的 SKU 名称
- 如果希望“建号和授权”保持强一致,可设置 `LICENSE_ASSIGNMENT_REQUIRED=true`
- 兑换码使用后立即失效,无法重复使用
- 生产环境建议使用 `DEBUG=false` 并配置反向代理