Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions backend/plugin/oauth2/api/v1/user_social.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from fastapi import APIRouter, Request

from backend.common.response.response_schema import ResponseModel, response_base
from backend.common.security.jwt import DependsJwtAuth
from backend.database.db import CurrentSessionTransaction
from backend.plugin.oauth2.enums import UserSocialType
from backend.plugin.oauth2.service.user_social import user_social_service

router = APIRouter()


@router.delete('/me', summary='解绑用户社交账号', dependencies=[DependsJwtAuth])
async def unbinding_user(db: CurrentSessionTransaction, request: Request, source: UserSocialType) -> ResponseModel:
await user_social_service.unbinding(db=db, user_id=request.user.id, source=source)
return response_base.success()
17 changes: 9 additions & 8 deletions backend/plugin/oauth2/crud/crud_user_social.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@
class CRUDUserSocial(CRUDPlus[UserSocial]):
"""用户社交账号数据库操作类"""

async def check_binding(self, db: AsyncSession, pk: int, source: str) -> UserSocial | None:
async def check_binding(self, db: AsyncSession, user_id: int, source: str) -> UserSocial | None:
"""
检查系统用户社交账号绑定

:param db: 数据库会话
:param pk: 用户 ID
:param user_id: 用户 ID
:param source: 社交账号类型
:return:
"""
return await self.select_model_by_column(db, user_id=pk, source=source)
return await self.select_model_by_column(db, user_id=user_id, source=source)

async def get_by_sid(self, db: AsyncSession, sid: str, source: str) -> UserSocial | None:
"""
通过 UUID 获取社交用户
通过 sid 获取社交用户

:param db: 数据库会话
:param sid: 第三方 UUID
:param sid: 第三方用户唯一编码
:param source: 社交账号类型
:return:
"""
Expand All @@ -40,15 +40,16 @@ async def create(self, db: AsyncSession, obj: CreateUserSocialParam) -> None:
"""
await self.create_model(db, obj)

async def delete(self, db: AsyncSession, social_id: int) -> int:
async def delete(self, db: AsyncSession, user_id: int, source: str) -> int:
"""
删除用户社交账号绑定

:param db: 数据库会话
:param social_id: 社交账号绑定 ID
:param user_id: 用户 ID
:param source: 社交账号类型
:return:
"""
return await self.delete_model(db, social_id)
return await self.delete_model_by_column(db, user_id=user_id, source=source)


user_social_dao: CRUDUserSocial = CRUDUserSocial(UserSocial)
2 changes: 1 addition & 1 deletion backend/plugin/oauth2/plugin.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[plugin]
summary = 'OAuth 2.0'
version = '0.0.7'
version = '0.0.8'
description = '通过 OAuth 2.0 的方式登录系统'
author = 'wu-clan'

Expand Down
25 changes: 25 additions & 0 deletions backend/plugin/oauth2/service/user_social.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from sqlalchemy.ext.asyncio import AsyncSession

from backend.common.exception import errors
from backend.plugin.oauth2.crud.crud_user_social import user_social_dao
from backend.plugin.oauth2.enums import UserSocialType


class UserSocialService:
@staticmethod
async def unbinding(*, db: AsyncSession, user_id: int, source: UserSocialType) -> int:
"""
解绑用户社交账号

:param db: 数据库会话
:param user_id: 用户 ID
:param source: 解绑源
:return:
"""
bind = user_social_dao.check_binding(db, user_id, source.value)
if not bind:
raise errors.NotFoundError(msg=f'用户未绑定 {source.value} 账号')
return await user_social_dao.delete(db, user_id, source.value)


user_social_service: UserSocialService = UserSocialService()