modify: auth 插件
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
from .login import login
|
||||
from .register import register
|
||||
from .me import me
|
||||
from .update_profile import update_profile
|
||||
from .change_password import change_password
|
||||
|
||||
|
||||
__all__ = ["login", "register", "me", "update_profile", "change_password"]
|
||||
@@ -0,0 +1,81 @@
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from chongming_worker import rpc_method
|
||||
from chongming_password import hash_password, verify_password
|
||||
|
||||
from ..models.pydantic import (
|
||||
ChangePasswordPostRequest,
|
||||
ChangePasswordPostResponse
|
||||
)
|
||||
from ..models.auth import Users
|
||||
|
||||
|
||||
@rpc_method(
|
||||
subject="auth.change_password",
|
||||
method="POST",
|
||||
summary="修改密码",
|
||||
response_model=ChangePasswordPostResponse,
|
||||
)
|
||||
async def change_password(change_password_post_request: ChangePasswordPostRequest) -> ChangePasswordPostResponse:
|
||||
from ..global_var import db
|
||||
|
||||
if db is None:
|
||||
raise RuntimeError("Database not initialized")
|
||||
|
||||
user_id = change_password_post_request.user_id
|
||||
old_password = change_password_post_request.old_password
|
||||
new_password = change_password_post_request.new_password
|
||||
|
||||
if not old_password:
|
||||
return ChangePasswordPostResponse(
|
||||
result="fail",
|
||||
message="旧密码不能为空",
|
||||
timestamp=time.time()
|
||||
)
|
||||
if not new_password:
|
||||
return ChangePasswordPostResponse(
|
||||
result="fail",
|
||||
message="新密码不能为空",
|
||||
timestamp=time.time()
|
||||
)
|
||||
if old_password == new_password:
|
||||
return ChangePasswordPostResponse(
|
||||
result="fail",
|
||||
message="新密码不能与旧密码相同",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
async with db.get_session() as session:
|
||||
stmt = select(Users).filter_by(id=user_id)
|
||||
result = await session.execute(stmt)
|
||||
user: Users | None = result.scalar_one_or_none()
|
||||
|
||||
if user is None:
|
||||
return ChangePasswordPostResponse(
|
||||
result="fail",
|
||||
message="用户不存在",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
# 验证旧密码
|
||||
if not verify_password(old_password, user.hashed_password):
|
||||
return ChangePasswordPostResponse(
|
||||
result="fail",
|
||||
message="旧密码错误",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
# 更新密码
|
||||
user.hashed_password = hash_password(new_password)
|
||||
user.updated_at = datetime.now()
|
||||
session.add(user)
|
||||
await session.commit()
|
||||
|
||||
return ChangePasswordPostResponse(
|
||||
result="success",
|
||||
message="密码修改成功",
|
||||
timestamp=time.time()
|
||||
)
|
||||
@@ -0,0 +1,85 @@
|
||||
import time
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from chongming_worker import rpc_method
|
||||
from chongming_password import verify_password
|
||||
|
||||
from ..models.pydantic import (
|
||||
LoginPostRequest,
|
||||
LoginPostResponse
|
||||
)
|
||||
from ..models.auth import Users
|
||||
|
||||
|
||||
@rpc_method(
|
||||
subject="auth.login",
|
||||
method="POST",
|
||||
summary="登录",
|
||||
response_model=LoginPostResponse,
|
||||
)
|
||||
async def login(login_post_request: LoginPostRequest) -> LoginPostResponse:
|
||||
from ..global_var import jwt, db
|
||||
|
||||
if db is None:
|
||||
raise RuntimeError("Database not initialized")
|
||||
async with db.get_session() as session:
|
||||
statement = select(Users).filter_by(
|
||||
username=login_post_request.username,
|
||||
)
|
||||
result = await session.execute(statement)
|
||||
user: Users | None = result.scalar_one_or_none()
|
||||
|
||||
if user is None:
|
||||
return LoginPostResponse(
|
||||
result="fail",
|
||||
message="用户名错误",
|
||||
token="",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
if not verify_password(login_post_request.password, user.hashed_password):
|
||||
return LoginPostResponse(
|
||||
result="fail",
|
||||
message="密码错误",
|
||||
token="",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
if not user.is_active:
|
||||
return LoginPostResponse(
|
||||
result="fail",
|
||||
message="用户已经注销或被禁用",
|
||||
token="",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
user.last_login_at = datetime.now()
|
||||
|
||||
payload = {
|
||||
"sub": user.id,
|
||||
"username": user.username,
|
||||
"email": user.email,
|
||||
"full_name": user.full_name,
|
||||
"avatar_url": user.avatar_url,
|
||||
"phone": user.phone,
|
||||
"is_verified": user.is_verified,
|
||||
"is_superuser": user.is_superuser,
|
||||
"created_at": user.created_at.isoformat(),
|
||||
"updated_at": user.updated_at.isoformat(),
|
||||
"last_login_at": user.last_login_at.isoformat()
|
||||
}
|
||||
|
||||
token = jwt.encode(
|
||||
json.dumps(payload),
|
||||
expires_in_seconds=10800 # 3小时有效期
|
||||
)
|
||||
|
||||
return LoginPostResponse(
|
||||
result="success",
|
||||
message="登录成功",
|
||||
token=token,
|
||||
timestamp=time.time()
|
||||
)
|
||||
@@ -0,0 +1,56 @@
|
||||
import time
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from chongming_worker import rpc_method
|
||||
|
||||
from ..models.pydantic import (
|
||||
MeGetRequest,
|
||||
MeGetResponse
|
||||
)
|
||||
from ..models.auth import Users
|
||||
|
||||
|
||||
@rpc_method(
|
||||
subject="auth.me",
|
||||
method="GET",
|
||||
summary="获取当前用户信息",
|
||||
response_model=MeGetResponse,
|
||||
)
|
||||
async def me(me_get_request: MeGetRequest) -> MeGetResponse:
|
||||
from ..global_var import db
|
||||
|
||||
if db is None:
|
||||
raise RuntimeError("Database not initialized")
|
||||
|
||||
async with db.get_session() as session:
|
||||
stmt = select(Users).filter_by(id=me_get_request.user_id)
|
||||
result = await session.execute(stmt)
|
||||
user: Users | None = result.scalar_one_or_none()
|
||||
|
||||
if user is None:
|
||||
return MeGetResponse(
|
||||
result="fail",
|
||||
id="",
|
||||
username="",
|
||||
email="",
|
||||
is_active=False,
|
||||
is_verified=False,
|
||||
is_superuser=False,
|
||||
)
|
||||
|
||||
return MeGetResponse(
|
||||
result="success",
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
email=user.email,
|
||||
full_name=user.full_name,
|
||||
avatar_url=user.avatar_url,
|
||||
phone=user.phone,
|
||||
is_active=user.is_active,
|
||||
is_verified=user.is_verified,
|
||||
is_superuser=user.is_superuser,
|
||||
created_at=user.created_at.isoformat() if user.created_at else None,
|
||||
updated_at=user.updated_at.isoformat() if user.updated_at else None,
|
||||
last_login_at=user.last_login_at.isoformat() if user.last_login_at else None,
|
||||
)
|
||||
@@ -0,0 +1,93 @@
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from chongming_worker import rpc_method
|
||||
from chongming_password import hash_password
|
||||
|
||||
from ..models.pydantic import (
|
||||
RegisterPostRequest,
|
||||
RegisterPostResponse
|
||||
)
|
||||
from ..models.auth import Users
|
||||
|
||||
|
||||
@rpc_method(
|
||||
subject="auth.register",
|
||||
method="POST",
|
||||
summary="用户注册",
|
||||
response_model=RegisterPostResponse,
|
||||
)
|
||||
async def register(register_post_request: RegisterPostRequest) -> RegisterPostResponse:
|
||||
from ..global_var import db
|
||||
|
||||
if db is None:
|
||||
raise RuntimeError("Database not initialized")
|
||||
|
||||
username = register_post_request.username.strip()
|
||||
email = register_post_request.email.strip()
|
||||
full_name = register_post_request.full_name.strip() or None
|
||||
phone = register_post_request.phone.strip() or None
|
||||
|
||||
# 校验必填字段
|
||||
if not username:
|
||||
return RegisterPostResponse(
|
||||
result="fail",
|
||||
message="用户名不能为空",
|
||||
timestamp=time.time()
|
||||
)
|
||||
if not email:
|
||||
return RegisterPostResponse(
|
||||
result="fail",
|
||||
message="邮箱不能为空",
|
||||
timestamp=time.time()
|
||||
)
|
||||
if not register_post_request.password:
|
||||
return RegisterPostResponse(
|
||||
result="fail",
|
||||
message="密码不能为空",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
async with db.get_session() as session:
|
||||
# 检查用户名是否已存在
|
||||
stmt = select(Users).filter_by(username=username)
|
||||
result = await session.execute(stmt)
|
||||
if result.scalar_one_or_none() is not None:
|
||||
return RegisterPostResponse(
|
||||
result="fail",
|
||||
message="用户名已存在",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
# 检查邮箱是否已存在
|
||||
stmt = select(Users).filter_by(email=email)
|
||||
result = await session.execute(stmt)
|
||||
if result.scalar_one_or_none() is not None:
|
||||
return RegisterPostResponse(
|
||||
result="fail",
|
||||
message="邮箱已被注册",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
# 创建新用户
|
||||
user = Users(
|
||||
username=username,
|
||||
hashed_password=hash_password(register_post_request.password),
|
||||
email=email,
|
||||
full_name=full_name,
|
||||
phone=phone,
|
||||
created_at=datetime.now(),
|
||||
updated_at=datetime.now(),
|
||||
)
|
||||
session.add(user)
|
||||
await session.commit()
|
||||
await session.refresh(user)
|
||||
|
||||
return RegisterPostResponse(
|
||||
result="success",
|
||||
message="注册成功",
|
||||
user_id=user.id,
|
||||
timestamp=time.time()
|
||||
)
|
||||
@@ -0,0 +1,74 @@
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from chongming_worker import rpc_method
|
||||
|
||||
from ..models.pydantic import (
|
||||
UpdateProfilePostRequest,
|
||||
UpdateProfilePostResponse
|
||||
)
|
||||
from ..models.auth import Users
|
||||
|
||||
|
||||
@rpc_method(
|
||||
subject="auth.update_profile",
|
||||
method="POST",
|
||||
summary="更新用户资料",
|
||||
response_model=UpdateProfilePostResponse,
|
||||
)
|
||||
async def update_profile(update_profile_post_request: UpdateProfilePostRequest) -> UpdateProfilePostResponse:
|
||||
from ..global_var import db
|
||||
|
||||
if db is None:
|
||||
raise RuntimeError("Database not initialized")
|
||||
|
||||
user_id = update_profile_post_request.user_id
|
||||
|
||||
async with db.get_session() as session:
|
||||
stmt = select(Users).filter_by(id=user_id)
|
||||
result = await session.execute(stmt)
|
||||
user: Users | None = result.scalar_one_or_none()
|
||||
|
||||
if user is None:
|
||||
return UpdateProfilePostResponse(
|
||||
result="fail",
|
||||
message="用户不存在",
|
||||
timestamp=time.time()
|
||||
)
|
||||
|
||||
# 更新字段(只更新非空值)
|
||||
full_name = update_profile_post_request.full_name.strip()
|
||||
email = update_profile_post_request.email.strip()
|
||||
avatar_url = update_profile_post_request.avatar_url.strip()
|
||||
phone = update_profile_post_request.phone.strip()
|
||||
|
||||
if full_name:
|
||||
user.full_name = full_name
|
||||
if email:
|
||||
# 检查邮箱是否被其他用户占用
|
||||
if email != user.email:
|
||||
check_stmt = select(Users).filter_by(email=email)
|
||||
check_result = await session.execute(check_stmt)
|
||||
if check_result.scalar_one_or_none() is not None:
|
||||
return UpdateProfilePostResponse(
|
||||
result="fail",
|
||||
message="邮箱已被其他用户使用",
|
||||
timestamp=time.time()
|
||||
)
|
||||
user.email = email
|
||||
if avatar_url:
|
||||
user.avatar_url = avatar_url
|
||||
if phone:
|
||||
user.phone = phone
|
||||
|
||||
user.updated_at = datetime.now()
|
||||
session.add(user)
|
||||
await session.commit()
|
||||
|
||||
return UpdateProfilePostResponse(
|
||||
result="success",
|
||||
message="资料更新成功",
|
||||
timestamp=time.time()
|
||||
)
|
||||
Reference in New Issue
Block a user