133 lines
5.8 KiB
Python
133 lines
5.8 KiB
Python
from django.conf import settings
|
|
|
|
from django.shortcuts import get_object_or_404
|
|
|
|
from rest_framework.views import APIView
|
|
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenRefreshSerializer
|
|
from rest_framework_simplejwt.tokens import RefreshToken
|
|
from rest_framework_simplejwt.exceptions import TokenError, InvalidToken
|
|
|
|
from rest_framework import status
|
|
from rest_framework.response import Response
|
|
from rest_framework.permissions import AllowAny, IsAuthenticated
|
|
|
|
from django.contrib.auth import authenticate
|
|
from django.db.models import Case, When, Value, IntegerField, Q
|
|
|
|
from .models import *
|
|
from .serializers import *
|
|
|
|
|
|
class RefreshAPIView(APIView):
|
|
permission_classes = [AllowAny]
|
|
# access token 재발급
|
|
def post(self, request):
|
|
refresh = request.COOKIES.get("refresh")
|
|
if not refresh:
|
|
return Response({"message": "No refresh token"}, status=status.HTTP_400_BAD_REQUEST)
|
|
if request.data.get("user_id", None) != RefreshToken(refresh).payload.get("user_id", None):
|
|
return Response({"message": "Wrong userid"}, status=status.HTTP_400_BAD_REQUEST)
|
|
try:
|
|
serializer = TokenRefreshSerializer(data={'refresh': refresh})
|
|
if serializer.is_valid():
|
|
res = Response({"access": serializer.validated_data['access']}, status=status.HTTP_200_OK)
|
|
res.set_cookie("refresh", serializer.validated_data['refresh'], httponly=True, samesite=None, secure=not settings.DEBUG)
|
|
return res
|
|
except TokenError as e:
|
|
return Response({"message": f"Invalid token: {e}"}, status=status.HTTP_401_UNAUTHORIZED)
|
|
|
|
|
|
|
|
class JoinAPIView(APIView):
|
|
permission_classes = [AllowAny]
|
|
# 회원가입
|
|
def post(self, request):
|
|
serializer = JoinSerializer(data=request.data)
|
|
if serializer.is_valid():
|
|
serializer.save()
|
|
res = Response({"message": "회원가입이 완료되었습니다."}, status=status.HTTP_200_OK)
|
|
return res
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
class LoginAPIView(APIView):
|
|
permission_classes = [AllowAny]
|
|
# 로그인
|
|
def post(self, request):
|
|
email=request.data.get("email", None)
|
|
password=request.data.get("password", None)
|
|
# 로그인 전 쿠키에 있는 리프레시 토큰 무효화
|
|
try:
|
|
refresh = request.COOKIES.get('refresh')
|
|
if refresh:
|
|
refresh_token = RefreshToken(refresh)
|
|
refresh_token.blacklist()
|
|
except TokenError as e:
|
|
pass
|
|
|
|
if user := authenticate(email=email, password=password):
|
|
serializer = TokenObtainPairSerializer(data={'email': email, 'password': password})
|
|
# id, 비번 맞나 틀리나 검사
|
|
if serializer.is_valid():
|
|
res = Response(
|
|
{
|
|
"message": "login success",
|
|
"user_id": user.id,
|
|
"nickname": user.nickname,
|
|
"access": serializer.validated_data['access'],
|
|
"is_custom_url": user.is_custom_url
|
|
},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
res.set_cookie("refresh", serializer.validated_data['refresh'], httponly=True, samesite=None, secure=not settings.DEBUG)
|
|
return res
|
|
else:
|
|
return Response(serializer.errors)
|
|
else: # id, 비번 둘 중 하나가 틀렸을 때
|
|
return Response({"message": "아이디 혹은 비밀번호가 맞지 않습니다."}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
class NicknameAPIView(APIView):
|
|
permission_classes = [AllowAny]
|
|
# 닉네임 중복 체크
|
|
def get(self, request):
|
|
nickname = request.GET.get('nickname', None)
|
|
if not nickname:
|
|
return Response({"message": "닉네임을 입력하세요."}, status=status.HTTP_400_BAD_REQUEST)
|
|
try:
|
|
get_object_or_404(User, nickname=nickname)
|
|
return Response({"message": "해당 닉네임은 사용할 수 없습니다."}, status=status.HTTP_400_BAD_REQUEST)
|
|
except:
|
|
return Response({"message": "사용할 수 있는 닉네임입니다."}, status=status.HTTP_200_OK)
|
|
|
|
class TagUserAPIView(APIView):
|
|
def get(self, request):
|
|
nickname = request.query_params.get('nickname')
|
|
users = User.objects.filter(nickname__icontains=nickname).annotate(
|
|
priority=Case(
|
|
When(nickname__iexact=nickname, then=Value(0)),
|
|
default=Value(1),
|
|
output_field=IntegerField()
|
|
)
|
|
).order_by('priority').values('profile_image', 'nickname')[:5]
|
|
serializer = TagUserSerializer(users, many=True)
|
|
return Response({'users': serializer.data})
|
|
|
|
|
|
class SetPortofolioRequiredInfoAPIView(APIView):
|
|
def get(self, request):
|
|
custom_url = request.GET.get('custom_url', None)
|
|
if not custom_url:
|
|
return Response({"message": "no url"}, status=status.HTTP_400_BAD_REQUEST)
|
|
if User.objects.filter(custom_url=custom_url).exists():
|
|
return Response({"message": "already used url"}, status=status.HTTP_400_BAD_REQUEST)
|
|
else:
|
|
return Response({"message": "can use this url"}, status=status.HTTP_200_OK)
|
|
|
|
def patch(self, request):
|
|
user = request.user
|
|
serializer = SetPortofolioRequiredInfoSerializer(user, data=request.data)
|
|
if serializer.is_valid():
|
|
serializer.save()
|
|
user.is_custom_url = True
|
|
user.save()
|
|
return Response({"message": "updated successfully"}, status=status.HTTP_202_ACCEPTED)
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |