Add email field to users, login accepts email or username
This commit is contained in:
+16
-7
@@ -61,7 +61,7 @@ def require_admin(session: Optional[str] = Cookie(None)) -> dict:
|
||||
# --- Schemas ---
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
username: str
|
||||
username: str # accepts username or email
|
||||
password: str
|
||||
|
||||
class InstanceCreate(BaseModel):
|
||||
@@ -84,12 +84,14 @@ class RunCreate(BaseModel):
|
||||
|
||||
class UserCreate(BaseModel):
|
||||
username: str
|
||||
email: str = ""
|
||||
password: str
|
||||
display_name: str = ""
|
||||
role: str = "user"
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
display_name: Optional[str] = None
|
||||
email: Optional[str] = None
|
||||
role: Optional[str] = None
|
||||
password: Optional[str] = None
|
||||
|
||||
@@ -114,12 +116,14 @@ class LLMProviderUpdate(BaseModel):
|
||||
|
||||
@app.post("/api/login")
|
||||
def login(creds: LoginRequest, response: Response, db: Session = Depends(get_db)):
|
||||
user = db.query(User).filter(User.username == creds.username).first()
|
||||
user = db.query(User).filter(
|
||||
(User.username == creds.username) | (User.email == creds.username)
|
||||
).first()
|
||||
if not user or not verify_password(creds.password, user.password_hash):
|
||||
raise HTTPException(status_code=401, detail="Invalid credentials")
|
||||
token = create_session(user)
|
||||
response.set_cookie("session", token, httponly=True, samesite="lax", max_age=86400 * 7)
|
||||
return {"status": "ok", "user": user.username, "role": user.role, "display_name": user.display_name}
|
||||
return {"status": "ok", "user": user.username, "email": user.email or "", "role": user.role, "display_name": user.display_name}
|
||||
|
||||
|
||||
@app.post("/api/logout")
|
||||
@@ -134,8 +138,9 @@ def logout(response: Response, session: Optional[str] = Cookie(None)):
|
||||
def me(user: dict = Depends(require_auth), db: Session = Depends(get_db)):
|
||||
u = db.query(User).filter(User.id == user["user_id"]).first()
|
||||
return {
|
||||
"id": u.id, "username": u.username, "display_name": u.display_name,
|
||||
"role": u.role, "created_at": u.created_at.isoformat() if u.created_at else None,
|
||||
"id": u.id, "username": u.username, "email": u.email or "",
|
||||
"display_name": u.display_name, "role": u.role,
|
||||
"created_at": u.created_at.isoformat() if u.created_at else None,
|
||||
}
|
||||
|
||||
|
||||
@@ -329,8 +334,9 @@ def list_runs(limit: int = 50, user: dict = Depends(require_auth), db: Session =
|
||||
def admin_list_users(admin: dict = Depends(require_admin), db: Session = Depends(get_db)):
|
||||
users = db.query(User).all()
|
||||
return [{
|
||||
"id": u.id, "username": u.username, "display_name": u.display_name,
|
||||
"role": u.role, "created_at": u.created_at.isoformat() if u.created_at else None,
|
||||
"id": u.id, "username": u.username, "email": u.email or "",
|
||||
"display_name": u.display_name, "role": u.role,
|
||||
"created_at": u.created_at.isoformat() if u.created_at else None,
|
||||
"instance_count": db.query(AgentInstance).filter(AgentInstance.user_id == u.id).count(),
|
||||
} for u in users]
|
||||
|
||||
@@ -341,6 +347,7 @@ def admin_create_user(data: UserCreate, admin: dict = Depends(require_admin), db
|
||||
raise HTTPException(status_code=409, detail="Username exists")
|
||||
user = User(
|
||||
username=data.username,
|
||||
email=data.email or None,
|
||||
password_hash=hash_password(data.password),
|
||||
display_name=data.display_name or data.username,
|
||||
role=data.role,
|
||||
@@ -357,6 +364,8 @@ def admin_update_user(user_id: int, update: UserUpdate, admin: dict = Depends(re
|
||||
raise HTTPException(status_code=404)
|
||||
if update.display_name is not None:
|
||||
user.display_name = update.display_name
|
||||
if update.email is not None:
|
||||
user.email = update.email or None
|
||||
if update.role is not None:
|
||||
user.role = update.role
|
||||
if update.password is not None:
|
||||
|
||||
Reference in New Issue
Block a user