diff --git a/.github/workflows/docker_deploy.yml b/.github/workflows/docker_deploy.yml new file mode 100644 index 0000000..25ba78b --- /dev/null +++ b/.github/workflows/docker_deploy.yml @@ -0,0 +1,47 @@ +name: Docker Deploy to EC2 + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Deploy Docker on EC2 + env: + PRIVATE_KEY: ${{ secrets.EC2_SSH_PRIVATE_KEY }} + run: | + echo "$PRIVATE_KEY" > private_key.pem + chmod 600 private_key.pem + scp -i private_key.pem -r * ubuntu@3.34.147.253:/home/ubuntu/DataFetcher/ + ssh -i private_key.pem ubuntu@3.34.147.253 'cd /home/ubuntu/DataFetcher/ && sudo docker stop buzzing_admin_container && sudo docker rm buzzing_admin_container && sudo docker build -t awsbuzzing_image . && sudo docker run -d -p 8081:8081 --name buzzing_admin_container awsbuzzing_image' + rm -f private_key.pem + + - name: Health Check + run: | + for i in {1..5}; do + response=$(curl -o /dev/null -s -w "%{http_code}" http://3.34.147.253:8081/auth/admin/main/) + if [ "$response" -eq 200 ]; then + echo "Server is healthy." + exit 0 + fi + echo "Check failed. Attempt: $i. Waiting for 10 seconds..." + sleep 10 + done + echo "Server health check failed after 5 attempts." + exit 1 + + - name: Send Slack notification + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + fields: repo,message,commit,author,action,eventName,ref,workflow,job,took + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + if: always() diff --git a/buzzing_admin/admin_views.py b/buzzing_admin/admin_views.py index 0070dd8..f1e6404 100644 --- a/buzzing_admin/admin_views.py +++ b/buzzing_admin/admin_views.py @@ -1,6 +1,14 @@ import hashlib -from django.views import View -from django.http import JsonResponse +from rest_framework.views import APIView +from rest_framework.response import Response +from drf_yasg.utils import swagger_auto_schema +from .swagger import ( + admin_login_view_schema, + admin_main_view_schema, + unban_user_view_schema, + report_detail_view_get_schema, + report_detail_view_post_schema +) from .models import Users, Report, Ban, BlackList,Spot,Comment import jwt import bcrypt @@ -15,34 +23,36 @@ @method_decorator(csrf_exempt, name='dispatch') #csrf token 비활성화 -class AdminLoginView(View): +class AdminLoginView(APIView): + @swagger_auto_schema(**admin_login_view_schema()) def post(self, request): data = json.loads(request.body) social_email = data.get('social_email') password = data.get('password') if not all([social_email, password]): - return JsonResponse({'message': 'INVALID_DATA'}, status=400) + return Response({'message': 'INVALID_DATA'}, status=400) try: user = Users.objects.get(social_email=social_email) if user.role != 'ROLE_ADMIN': - return JsonResponse({'message': 'NO_PERMISSION'}, status=403) + return Response({'message': 'NO_PERMISSION'}, status=403) if bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')): payload = {"user_id": user.user_id} token = jwt.encode(payload, JWT_SECRET_KEY, algorithm=ALGORITHM) - return JsonResponse({'AccessToken': token}, status=200) + return Response({'AccessToken': token}, status=200) - return JsonResponse({'message': 'INVALID_USER'}, status=401) + return Response({'message': 'INVALID_USER'}, status=401) except Users.DoesNotExist: - return JsonResponse({'message': 'INVALID_USER'}, status=401) + return Response({'message': 'INVALID_USER'}, status=401) @method_decorator(csrf_exempt, name='dispatch') # csrf token 비활성화 -class AdminMainView(View): +class AdminMainView(APIView): + @swagger_auto_schema(**admin_main_view_schema()) @authorization def get(self, request): #커서 페이징 @@ -91,14 +101,15 @@ def get(self, request): # 'social_email': user.social_email # }) - return JsonResponse({ + return Response({ 'reported_contents': reported_data, 'banned_users': banned_data, #'blacklisted_users': blacklist_data }, status=200) @method_decorator(csrf_exempt, name='dispatch') -class UnbanUserView(View): +class UnbanUserView(APIView): + @swagger_auto_schema(**unban_user_view_schema()) @authorization def post(self, request, user_id): try: @@ -111,15 +122,16 @@ def post(self, request, user_id): user.user_status = "NORMAL" user.save() - return JsonResponse({"message": "유저 정지 해제 완료."}, status=200) + return Response({"message": "유저 정지 해제 완료."}, status=200) except Ban.DoesNotExist: - return JsonResponse({"message": "밴 데이터가 없습니다."}, status=400) + return Response({"message": "밴 데이터가 없습니다."}, status=400) except Users.DoesNotExist: - return JsonResponse({"message": "해당 유저가 존재하지 않습니다."}, status=400) + return Response({"message": "해당 유저가 존재하지 않습니다."}, status=400) @method_decorator(csrf_exempt, name='dispatch') -class ReportDetailView(View): +class ReportDetailView(APIView): + @swagger_auto_schema(**report_detail_view_get_schema()) @authorization def get(self, request, report_id): report = get_object_or_404(Report, report_id=report_id) @@ -138,16 +150,18 @@ def get(self, request, report_id): elif report.report_target == 'COMMENT': comment = get_object_or_404(Comment, pk=report.target_id) data['content'] = comment.content - return JsonResponse(data, status=200) + return Response(data, status=200) + @swagger_auto_schema(**report_detail_view_post_schema()) + @authorization def post(self, request, report_id): report = get_object_or_404(Report, report_id=report_id) if Ban.objects.filter(banned_user=report.reported_user).exists(): - return JsonResponse({"message": "유저가 이미 밴 상태입니다.."}, status=400) + return Response({"message": "유저가 이미 밴 상태입니다.."}, status=400) if BlackList.objects.filter( social_email=hashlib.sha256(report.reported_user.social_email.encode()).hexdigest()).exists(): - return JsonResponse({"message": "유저가 이미 블랙리스트 상태입니다."}, status=400) + return Response({"message": "유저가 이미 블랙리스트 상태입니다."}, status=400) data = json.loads(request.body) action = data.get('action') ban_reason = data.get('ban_reason') # 정지 사유 @@ -205,4 +219,4 @@ def post(self, request, report_id): social_email=hashed_social_email ) - return JsonResponse({"message": "신고 처리 완료."}, status=200) \ No newline at end of file + return Response({"message": "신고 처리 완료."}, status=200) \ No newline at end of file