Skip to content

Commit 85c1b8b

Browse files
Feat - Implemented refresh token
1 parent 57c28bd commit 85c1b8b

File tree

6 files changed

+49
-9
lines changed

6 files changed

+49
-9
lines changed

authentication/serializers.py

+5
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ class RegisterSerializer(serializers.Serializer):
2424
class LoginSerializer(serializers.Serializer):
2525
email = serializers.EmailField()
2626
password = serializers.CharField(write_only=True)
27+
28+
29+
class RefreshTokenSerializer(serializers.Serializer):
30+
refresh_token = serializers.CharField()
31+
user_sub = serializers.CharField()

authentication/services/cognito_service.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ def __init__(self, region, user_pool_id, app_client_id, app_client_secret):
1414
self.app_client_id = app_client_id
1515
self.app_client_secret = app_client_secret
1616

17-
def get_secret_hash(self, email):
18-
message = email + self.app_client_id
17+
def get_secret_hash(self, message):
18+
message = message + self.app_client_id
1919
dig = hmac.new(
2020
str(self.app_client_secret).encode("utf-8"), msg=str(message).encode("utf-8"), digestmod=hashlib.sha256
2121
).digest()
@@ -61,3 +61,17 @@ def login_user(self, email, password):
6161
return response
6262
except ClientError as e:
6363
raise e
64+
65+
def refresh_tokens(self, refresh_token, user_sub):
66+
try:
67+
response = self.client.initiate_auth(
68+
ClientId=self.app_client_id,
69+
AuthFlow="REFRESH_TOKEN_AUTH",
70+
AuthParameters={
71+
"REFRESH_TOKEN": refresh_token,
72+
"SECRET_HASH": self.get_secret_hash(user_sub),
73+
},
74+
)
75+
return response
76+
except ClientError as e:
77+
raise e

authentication/tests/tests.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ def setUp(self):
4242
@patch.object(CognitoService, "login_user")
4343
def test_login_user_success(self, mock_login_user):
4444
mock_login_user.return_value = {
45-
"AuthenticationResult": {"AccessToken": "mock_access_token", "IdToken": "mock_id_token"}
45+
"AuthenticationResult": {"AccessToken": "mock_access_token", "RefreshToken": "mock_refresh_token"}
4646
}
4747
response = self.client.post(self.url, self.data, format="json")
4848
self.assertEqual(response.status_code, status.HTTP_200_OK)
4949
self.assertEqual(response.data["access_token"], "mock_access_token")
50-
self.assertEqual(response.data["id_token"], "mock_id_token")
50+
self.assertEqual(response.data["refresh_token"], "mock_refresh_token")
5151

5252
@patch.object(CognitoService, "login_user")
5353
def test_login_user_failure(self, mock_login_user):

authentication/urls.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from django.urls import path
2-
from .views import RegisterView, LoginView, ProfileView
2+
from .views import RegisterView, LoginView, ProfileView, RefreshTokenView
33

44
urlpatterns = [
55
path("register/", RegisterView.as_view(), name="register"),
66
path("login/", LoginView.as_view(), name="login"),
77
path("profile/", ProfileView.as_view(), name="profile"),
8+
path("refresh-token/", RefreshTokenView.as_view(), name="refresh-token"),
89
]

authentication/views.py

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from rest_framework.views import APIView
22
from rest_framework.response import Response
33
from rest_framework import status
4-
from .serializers import RegisterSerializer, LoginSerializer
4+
from .serializers import RegisterSerializer, LoginSerializer, RefreshTokenSerializer
55
from .services.cognito_service import CognitoService
66
from django.conf import settings
77
from .models import User
@@ -44,7 +44,7 @@ def post(self, request):
4444
return Response(
4545
{
4646
"access_token": response["AuthenticationResult"]["AccessToken"],
47-
"id_token": response["AuthenticationResult"]["IdToken"],
47+
"refresh_token": response["AuthenticationResult"]["RefreshToken"],
4848
},
4949
status=status.HTTP_200_OK,
5050
)
@@ -53,6 +53,26 @@ def post(self, request):
5353
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
5454

5555

56+
class RefreshTokenView(APIView):
57+
def post(self, request):
58+
serializer = RefreshTokenSerializer(data=request.data)
59+
if serializer.is_valid():
60+
refresh_token = serializer.validated_data["refresh_token"]
61+
user_sub = serializer.validated_data["user_sub"]
62+
try:
63+
response = cognito_service.refresh_tokens(refresh_token, user_sub)
64+
return Response(
65+
{
66+
"access_token": response["AuthenticationResult"]["AccessToken"],
67+
},
68+
status=status.HTTP_200_OK,
69+
)
70+
except Exception as e:
71+
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
72+
else:
73+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
74+
75+
5676
class ProfileView(APIView):
5777
def get_user_id_from_token(self, request):
5878
try:

docker-compose.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ services:
2020
web:
2121
build:
2222
context: .
23-
dockerfile: Dockerfile
23+
dockerfile: Dev.Dockerfile
2424
container_name: web
2525
volumes:
2626
- .:/app
@@ -37,7 +37,7 @@ services:
3737
POSTGRES_PORT: ${DB_PORT}
3838
POSTGRES_HOST: ${DB_HOST}
3939
OPENAI_API_KEY: ${OPENAI_API_KEY}
40-
DJANGO_SETTINGS_MODULE: piggywallet.settings.prod
40+
DJANGO_SETTINGS_MODULE: piggywallet.settings.dev
4141

4242
networks:
4343
app_network:

0 commit comments

Comments
 (0)