feat: add password
This commit is contained in:
@@ -445,6 +445,45 @@ Base 前缀 `/api/v1/admin`。
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 6.1 `POST /api/v1/admin/employees`
|
||||||
|
|
||||||
|
创建员工账号。
|
||||||
|
|
||||||
|
- **请求体字段**:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 必填 | 限制 | 说明 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `username` | string | 是 | 2~64 字符 | 登录名,workspace 内唯一 |
|
||||||
|
| `display_name` | string | 是 | 1~100 字符 | 显示名称 |
|
||||||
|
| `email` | string | 否 | ≤255 字符 | 邮箱,全局唯一 |
|
||||||
|
| `role_code` | string | 否 | `admin` \| `developer` | 默认 `developer` |
|
||||||
|
| `password` | string | 是 | 8~72 字符 | 登录密码 |
|
||||||
|
|
||||||
|
- **密码说明**:
|
||||||
|
- 密码明文**不会**存入数据库,后端使用 bcrypt 哈希后保存到 `password_hash`。
|
||||||
|
- 请求体中 `password` 必填,长度必须在 8~72 字符之间,否则返回 `422`。
|
||||||
|
- 创建成功后的响应**不**包含 `password` 或 `password_hash`。
|
||||||
|
|
||||||
|
- **响应 201**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"request_id": "...",
|
||||||
|
"data": {
|
||||||
|
"user_id": "...",
|
||||||
|
"username": "...",
|
||||||
|
"display_name": "...",
|
||||||
|
"email": "...",
|
||||||
|
"status": "active",
|
||||||
|
"role_code": "developer",
|
||||||
|
"role_name": "...",
|
||||||
|
"created_at": "..."
|
||||||
|
},
|
||||||
|
"meta": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> `PATCH` / `DELETE` 员工接口**不**涉及密码字段,也不返回密码相关信息。
|
||||||
|
|
||||||
## 七、Jupyter 路由
|
## 七、Jupyter 路由
|
||||||
|
|
||||||
> **本节是 Nginx 行为,不是直接 HTTP 端点**。前端**不要**直接调用。
|
> **本节是 Nginx 行为,不是直接 HTTP 端点**。前端**不要**直接调用。
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
|
|
||||||
from common.db.models import Roles, Users, WorkspaceMembers
|
from common.db.models import Roles, Users, WorkspaceMembers
|
||||||
from common.ids import new_ulid
|
from common.ids import new_ulid
|
||||||
|
from common.auth.passwords import hash_password
|
||||||
from backend.dependencies import (
|
from backend.dependencies import (
|
||||||
RequestContext,
|
RequestContext,
|
||||||
database_session,
|
database_session,
|
||||||
@@ -26,6 +27,7 @@ class EmployeeCreate(BaseModel):
|
|||||||
display_name: str = Field(min_length=1, max_length=100)
|
display_name: str = Field(min_length=1, max_length=100)
|
||||||
email: str | None = Field(default=None, max_length=255)
|
email: str | None = Field(default=None, max_length=255)
|
||||||
role_code: Literal["admin", "developer"] = "developer"
|
role_code: Literal["admin", "developer"] = "developer"
|
||||||
|
password: str = Field(min_length=8, max_length=72)
|
||||||
|
|
||||||
|
|
||||||
class EmployeeUpdate(BaseModel):
|
class EmployeeUpdate(BaseModel):
|
||||||
@@ -133,7 +135,7 @@ async def create_employee(
|
|||||||
username=username,
|
username=username,
|
||||||
display_name=display_name,
|
display_name=display_name,
|
||||||
email=payload.email.strip() if payload.email else None,
|
email=payload.email.strip() if payload.email else None,
|
||||||
password_hash="demo-login-disabled",
|
password_hash=hash_password(payload.password),
|
||||||
status="active",
|
status="active",
|
||||||
)
|
)
|
||||||
session.add(user)
|
session.add(user)
|
||||||
|
|||||||
Reference in New Issue
Block a user