320 lines
8.8 KiB
Python
320 lines
8.8 KiB
Python
import logging
|
|
|
|
from sqladmin import ModelView, action
|
|
from starlette.requests import Request
|
|
from starlette.responses import RedirectResponse
|
|
|
|
from app.backoffice.user_view_actions import (
|
|
handle_block_users,
|
|
handle_deduct_credits,
|
|
handle_grant_credits,
|
|
handle_set_role,
|
|
)
|
|
from app.user.models import RefreshToken, SocialAccount, User
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class UserAdmin(ModelView, model=User):
|
|
name = "사용자"
|
|
name_plural = "사용자 목록"
|
|
icon = "fa-solid fa-user"
|
|
category = "사용자 관리"
|
|
page_size = 20
|
|
|
|
column_list = [
|
|
"id",
|
|
"kakao_id",
|
|
"email",
|
|
"nickname",
|
|
"credits",
|
|
"role",
|
|
"is_active",
|
|
"is_deleted",
|
|
"created_at",
|
|
]
|
|
|
|
column_details_list = [
|
|
"id",
|
|
"kakao_id",
|
|
"email",
|
|
"nickname",
|
|
"profile_image_url",
|
|
"thumbnail_image_url",
|
|
"phone",
|
|
"name",
|
|
"birth_date",
|
|
"gender",
|
|
"credits",
|
|
"is_active",
|
|
"is_admin",
|
|
"role",
|
|
"is_deleted",
|
|
"deleted_at",
|
|
"last_login_at",
|
|
"created_at",
|
|
"updated_at",
|
|
"credit_requests",
|
|
"credit_transactions",
|
|
]
|
|
|
|
form_columns = [
|
|
"nickname",
|
|
"email",
|
|
"phone",
|
|
"name",
|
|
"birth_date",
|
|
"gender",
|
|
"credits",
|
|
"is_active",
|
|
"is_admin",
|
|
"role",
|
|
"is_deleted",
|
|
]
|
|
|
|
column_searchable_list = [
|
|
User.kakao_id,
|
|
User.email,
|
|
User.nickname,
|
|
User.phone,
|
|
User.name,
|
|
]
|
|
|
|
column_default_sort = (User.created_at, True)
|
|
|
|
column_sortable_list = [
|
|
User.id,
|
|
User.kakao_id,
|
|
User.email,
|
|
User.nickname,
|
|
User.credits,
|
|
User.role,
|
|
User.is_active,
|
|
User.is_deleted,
|
|
User.created_at,
|
|
]
|
|
|
|
column_labels = {
|
|
"id": "ID",
|
|
"kakao_id": "카카오 ID",
|
|
"email": "이메일",
|
|
"nickname": "닉네임",
|
|
"profile_image_url": "프로필 이미지",
|
|
"thumbnail_image_url": "썸네일 이미지",
|
|
"phone": "전화번호",
|
|
"name": "실명",
|
|
"birth_date": "생년월일",
|
|
"gender": "성별",
|
|
"credits": "크레딧",
|
|
"is_active": "활성화",
|
|
"is_admin": "관리자",
|
|
"role": "권한",
|
|
"is_deleted": "삭제됨",
|
|
"deleted_at": "삭제일시",
|
|
"last_login_at": "마지막 로그인",
|
|
"created_at": "생성일시",
|
|
"updated_at": "수정일시",
|
|
}
|
|
|
|
@action(
|
|
name="block_user",
|
|
label="계정 차단",
|
|
confirmation_message="선택한 사용자를 차단하시겠습니까? 로그인이 불가해집니다.",
|
|
add_in_list=True,
|
|
)
|
|
async def block_user_action(self, request: Request) -> RedirectResponse:
|
|
return await handle_block_users(request, self.identity, block=True)
|
|
|
|
@action(
|
|
name="unblock_user",
|
|
label="차단 해제",
|
|
confirmation_message="선택한 사용자의 차단을 해제하시겠습니까?",
|
|
add_in_list=True,
|
|
)
|
|
async def unblock_user_action(self, request: Request) -> RedirectResponse:
|
|
return await handle_block_users(request, self.identity, block=False)
|
|
|
|
@action(
|
|
name="set_role_admin",
|
|
label="권한: admin으로 변경",
|
|
confirmation_message="선택한 사용자를 admin으로 변경하시겠습니까?",
|
|
add_in_list=True,
|
|
)
|
|
async def set_role_admin_action(self, request: Request) -> RedirectResponse:
|
|
return await handle_set_role(request, self.identity, role="admin")
|
|
|
|
@action(
|
|
name="set_role_user",
|
|
label="권한: user로 변경",
|
|
confirmation_message="선택한 사용자를 일반 user로 변경하시겠습니까?",
|
|
add_in_list=True,
|
|
)
|
|
async def set_role_user_action(self, request: Request) -> RedirectResponse:
|
|
return await handle_set_role(request, self.identity, role="user")
|
|
|
|
@action(
|
|
name="grant_credits_1",
|
|
label="크레딧 +1 충전",
|
|
confirmation_message="선택한 사용자에게 크레딧 1개를 충전하시겠습니까?",
|
|
add_in_list=True,
|
|
)
|
|
async def grant_credits_1_action(self, request: Request) -> RedirectResponse:
|
|
admin_id = request.session.get("admin_id")
|
|
return await handle_grant_credits(request, self.identity, amount=1, admin_id=admin_id)
|
|
|
|
@action(
|
|
name="grant_credits_5",
|
|
label="크레딧 +5 충전",
|
|
confirmation_message="선택한 사용자에게 크레딧 5개를 충전하시겠습니까?",
|
|
add_in_list=True,
|
|
)
|
|
async def grant_credits_5_action(self, request: Request) -> RedirectResponse:
|
|
admin_id = request.session.get("admin_id")
|
|
return await handle_grant_credits(request, self.identity, amount=5, admin_id=admin_id)
|
|
|
|
@action(
|
|
name="grant_credits_10",
|
|
label="크레딧 +10 충전",
|
|
confirmation_message="선택한 사용자에게 크레딧 10개를 충전하시겠습니까?",
|
|
add_in_list=True,
|
|
)
|
|
async def grant_credits_10_action(self, request: Request) -> RedirectResponse:
|
|
admin_id = request.session.get("admin_id")
|
|
return await handle_grant_credits(request, self.identity, amount=10, admin_id=admin_id)
|
|
|
|
@action(
|
|
name="deduct_credits_1",
|
|
label="크레딧 -1 차감",
|
|
confirmation_message="선택한 사용자의 크레딧 1개를 차감하시겠습니까?",
|
|
add_in_list=True,
|
|
)
|
|
async def deduct_credits_1_action(self, request: Request) -> RedirectResponse:
|
|
admin_id = request.session.get("admin_id")
|
|
return await handle_deduct_credits(request, self.identity, amount=1, admin_id=admin_id)
|
|
|
|
|
|
class RefreshTokenAdmin(ModelView, model=RefreshToken):
|
|
name = "리프레시 토큰"
|
|
name_plural = "리프레시 토큰 목록"
|
|
icon = "fa-solid fa-key"
|
|
category = "사용자 관리"
|
|
page_size = 20
|
|
|
|
column_list = [
|
|
"id",
|
|
"user_id",
|
|
"is_revoked",
|
|
"expires_at",
|
|
"created_at",
|
|
]
|
|
|
|
column_details_list = [
|
|
"id",
|
|
"user_id",
|
|
"token_hash",
|
|
"expires_at",
|
|
"is_revoked",
|
|
"created_at",
|
|
"revoked_at",
|
|
"user_agent",
|
|
"ip_address",
|
|
]
|
|
|
|
form_excluded_columns = ["created_at", "user"]
|
|
|
|
column_searchable_list = [
|
|
RefreshToken.user_id,
|
|
RefreshToken.token_hash,
|
|
RefreshToken.ip_address,
|
|
]
|
|
|
|
column_default_sort = (RefreshToken.created_at, True)
|
|
|
|
column_sortable_list = [
|
|
RefreshToken.id,
|
|
RefreshToken.user_id,
|
|
RefreshToken.is_revoked,
|
|
RefreshToken.expires_at,
|
|
RefreshToken.created_at,
|
|
]
|
|
|
|
column_labels = {
|
|
"id": "ID",
|
|
"user_id": "사용자 ID",
|
|
"token_hash": "토큰 해시",
|
|
"expires_at": "만료일시",
|
|
"is_revoked": "폐기됨",
|
|
"created_at": "생성일시",
|
|
"revoked_at": "폐기일시",
|
|
"user_agent": "User Agent",
|
|
"ip_address": "IP 주소",
|
|
}
|
|
|
|
|
|
class SocialAccountAdmin(ModelView, model=SocialAccount):
|
|
name = "소셜 계정"
|
|
name_plural = "소셜 계정 목록"
|
|
icon = "fa-solid fa-share-nodes"
|
|
category = "사용자 관리"
|
|
page_size = 20
|
|
|
|
column_list = [
|
|
"id",
|
|
"user_uuid",
|
|
"platform",
|
|
"platform_username",
|
|
"is_active",
|
|
"is_deleted",
|
|
"created_at",
|
|
]
|
|
|
|
column_details_list = [
|
|
"id",
|
|
"user_uuid",
|
|
"platform",
|
|
"platform_user_id",
|
|
"platform_username",
|
|
"platform_data",
|
|
"scope",
|
|
"token_expires_at",
|
|
"is_active",
|
|
"is_deleted",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
|
|
form_excluded_columns = ["created_at", "updated_at", "user"]
|
|
|
|
column_searchable_list = [
|
|
SocialAccount.user_uuid,
|
|
SocialAccount.platform,
|
|
SocialAccount.platform_user_id,
|
|
SocialAccount.platform_username,
|
|
]
|
|
|
|
column_default_sort = (SocialAccount.created_at, True)
|
|
|
|
column_sortable_list = [
|
|
SocialAccount.id,
|
|
SocialAccount.user_uuid,
|
|
SocialAccount.platform,
|
|
SocialAccount.is_active,
|
|
SocialAccount.is_deleted,
|
|
SocialAccount.created_at,
|
|
]
|
|
|
|
column_labels = {
|
|
"id": "ID",
|
|
"user_uuid": "사용자 UUID",
|
|
"platform": "플랫폼",
|
|
"platform_user_id": "플랫폼 사용자 ID",
|
|
"platform_username": "플랫폼 사용자명",
|
|
"platform_data": "플랫폼 데이터",
|
|
"scope": "권한 범위",
|
|
"token_expires_at": "토큰 만료일시",
|
|
"is_active": "활성화",
|
|
"is_deleted": "삭제됨",
|
|
"created_at": "생성일시",
|
|
"updated_at": "수정일시",
|
|
}
|