v0.0.30 | Google 계정 승인 대기 및 등급 변경 기능
All checks were successful
Build And Test / build-and-push (push) Successful in 2m48s

- Google 소셜 로그인 신규 가입 시 관리자 승인 대기 상태로 변경
- UserUpdateView에 등급(grade) 변경 기능 추가
- admin 등급 부여는 admin만 가능하도록 제한
- 자기 자신의 admin 등급 하향 방지

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-19 00:15:34 +09:00
parent 03f7ad94a9
commit d6bec2c883
2 changed files with 50 additions and 9 deletions

View File

@ -279,19 +279,49 @@ class UserUpdateView(generics.RetrieveUpdateDestroyAPIView):
instance = self.get_object()
target_email = instance.email
# is_active만 수정 가능
update_fields = []
actions = []
# is_active 수정
is_active = request.data.get('is_active')
if is_active is not None:
instance.is_active = is_active
instance.save(update_fields=['is_active'])
update_fields.append('is_active')
actions.append("activated" if is_active else "deactivated")
action = "activated" if is_active else "deactivated"
# grade 수정 (관리자만 admin 등급 부여 가능)
grade = request.data.get('grade')
if grade is not None:
valid_grades = ['admin', 'manager', 'user']
if grade not in valid_grades:
return Response(
{"error": f"유효하지 않은 등급입니다. 가능한 값: {valid_grades}"},
status=status.HTTP_400_BAD_REQUEST
)
# admin 등급 부여는 admin만 가능 (manager는 불가)
if grade == 'admin' and request.user.grade != 'admin':
return Response(
{"error": "admin 등급 부여는 admin만 가능합니다."},
status=status.HTTP_403_FORBIDDEN
)
# 자기 자신의 등급 하향 방지 (실수로 관리자 권한 잃는 것 방지)
if request.user.id == instance.id and instance.grade == 'admin' and grade != 'admin':
return Response(
{"error": "자신의 admin 등급을 변경할 수 없습니다."},
status=status.HTTP_400_BAD_REQUEST
)
instance.grade = grade
update_fields.append('grade')
actions.append(f"grade_changed_to_{grade}")
if update_fields:
instance.save(update_fields=update_fields)
logger.info(
f"[USER UPDATE] admin={admin_email} | target={target_email} | action={action} | IP={ip} | UA={ua}"
f"[USER UPDATE] admin={admin_email} | target={target_email} | actions={actions} | IP={ip} | UA={ua}"
)
span.add_event(
f"User {action}",
attributes={"admin": admin_email, "target": target_email}
"User updated",
attributes={"admin": admin_email, "target": target_email, "actions": str(actions)}
)
serializer = self.get_serializer(instance)
@ -1162,12 +1192,23 @@ class GoogleLoginView(APIView):
social_provider="google",
social_id=google_id,
profile_image=picture,
is_active=True, # 소셜 로그인은 이메일 인증 불필요
is_active=False, # 관리자 승인 필요
)
# 비밀번호 없이 사용 불가하게 설정
user.set_unusable_password()
user.save()
logger.info(f"[GOOGLE LOGIN] user={email} | status=new_user_created | IP={ip} | UA={ua}")
logger.info(f"[GOOGLE LOGIN] user={email} | status=new_user_created_pending | IP={ip} | UA={ua}")
# 승인 대기 응답 반환
span.add_event("Google login - pending approval", attributes={"email": email})
return Response(
{
"error": "회원가입이 완료되었습니다. 관리자 승인 후 로그인할 수 있습니다.",
"code": "PENDING_APPROVAL",
"message": "관리자 승인 대기 중입니다.",
},
status=status.HTTP_403_FORBIDDEN
)
# 사용자 활성 상태 확인
if not user.is_active: