diff --git a/microsite_api/microsite_api/urls.py b/microsite_api/microsite_api/urls.py index 1b994eb..b2defc5 100644 --- a/microsite_api/microsite_api/urls.py +++ b/microsite_api/microsite_api/urls.py @@ -21,9 +21,11 @@ from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView urlpatterns = [ path('admin/', admin.site.urls), - path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), - path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), - path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'), + path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), + path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), + path('token/verify/', TokenVerifyView.as_view(), name='token_verify'), + + path('auth/', include('user_auth.urls')), path('profile/', include('user_profile.urls')), path('location/', include('location.urls')), diff --git a/microsite_api/user_auth/__init__.py b/microsite_api/user_auth/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/microsite_api/user_auth/admin.py b/microsite_api/user_auth/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/microsite_api/user_auth/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/microsite_api/user_auth/apps.py b/microsite_api/user_auth/apps.py new file mode 100644 index 0000000..58bb320 --- /dev/null +++ b/microsite_api/user_auth/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class UserAuthConfig(AppConfig): + name = 'user_auth' diff --git a/microsite_api/user_auth/migrations/__init__.py b/microsite_api/user_auth/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/microsite_api/user_auth/models.py b/microsite_api/user_auth/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/microsite_api/user_auth/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/microsite_api/user_auth/serializers.py b/microsite_api/user_auth/serializers.py new file mode 100644 index 0000000..8e4a2ce --- /dev/null +++ b/microsite_api/user_auth/serializers.py @@ -0,0 +1,5 @@ +from rest_framework import serializers + +class SSOLoginSerializer(serializers.Serializer): + username = serializers.CharField() + password = serializers.CharField(write_only=True) \ No newline at end of file diff --git a/microsite_api/user_auth/tests.py b/microsite_api/user_auth/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/microsite_api/user_auth/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/microsite_api/user_auth/urls.py b/microsite_api/user_auth/urls.py new file mode 100644 index 0000000..1f1d51b --- /dev/null +++ b/microsite_api/user_auth/urls.py @@ -0,0 +1,9 @@ +from django.urls import path +from rest_framework.urlpatterns import format_suffix_patterns +from user_auth import views + +urlpatterns = [ + path('token/', views.SSOLoginView.as_view()), +] + +urlpatterns = format_suffix_patterns(urlpatterns) \ No newline at end of file diff --git a/microsite_api/user_auth/views.py b/microsite_api/user_auth/views.py new file mode 100644 index 0000000..9394676 --- /dev/null +++ b/microsite_api/user_auth/views.py @@ -0,0 +1,76 @@ +# views.py +import requests +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from django.contrib.auth import get_user_model +from rest_framework_simplejwt.tokens import RefreshToken + +from .serializers import SSOLoginSerializer + +User = get_user_model() + +class SSOLoginView(APIView): + permission_classes = [] + + def post(self, request): + serializer = SSOLoginSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + + username = serializer.validated_data["username"] + password = serializer.validated_data["password"] + + # Call SSO + sso_response = requests.post( + "http://127.0.0.1:8080/auth/jwt/create/", + json={ + "username": username, + "password": password + }, + timeout=5 + ) + + if sso_response.status_code != 200: + return Response( + {"detail": "Invalid credentials"}, + status=status.HTTP_401_UNAUTHORIZED + ) + + sso_data = sso_response.json() + sso_token = sso_data.get("access") + sso_refresh = sso_data.get("refresh") + + sso_response_user = requests.get( + "http://127.0.0.1:8080/auth/users/me/", + headers={"Authorization": f"JWT {sso_token}"}, + timeout=5 + ) + + if (sso_response_user.status_code != 200): + return Response( + {"detail": "Failed to fetch user data from SSO"}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR + ) + + sso_user = sso_response_user.json() + + # Sync user lokal (optional) + user, created = User.objects.get_or_create( + username=username, + defaults={ + "email": sso_user.get("email", "") + } + ) + + # Generate JWT lokal + refresh = RefreshToken.for_user(user) + + return Response({ + "refresh": str(refresh), + "access": str(refresh.access_token), + "user": { + "id": user.id, + "username": user.username, + "email": user.email, + } + }) \ No newline at end of file