Skip to content

Commit

Permalink
IA-3516 Adapt the token API to multi-account users
Browse files Browse the repository at this point in the history
If a user request a token to api/token we should look if that user has a
tenant_user for the account corresponding to the app_id in the url, and
if it’s the case, send a token for that tenant_user on that account
instead of the token for the login user.
  • Loading branch information
bramj committed Oct 15, 2024
1 parent fdf32f5 commit e0c667f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
6 changes: 5 additions & 1 deletion hat/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,11 @@ def is_superuser(u):
),
}

SIMPLE_JWT = {"ACCESS_TOKEN_LIFETIME": timedelta(days=3650), "REFRESH_TOKEN_LIFETIME": timedelta(days=3651)}
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(days=3650),
"REFRESH_TOKEN_LIFETIME": timedelta(days=3651),
"TOKEN_OBTAIN_SERIALIZER": "iaso.serializers.CustomTokenObtainPairSerializer",
}

AWS_S3_REGION_NAME = os.getenv("AWS_S3_REGION_NAME", "eu-central-1")
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
Expand Down
2 changes: 1 addition & 1 deletion iaso/api/profiles/profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ def retrieve(self, request, *args, **kwargs):
pk = kwargs.get("pk")
if pk == PK_ME:
# if the user is a main_user, login as an account user
# TODO: remember the last account_user
# TODO: This is not a clean side-effect and should be improved.
if request.user.tenant_users.exists():
account_user = request.user.tenant_users.first().account_user
account_user.backend = "django.contrib.auth.backends.ModelBackend"
Expand Down
35 changes: 35 additions & 0 deletions iaso/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from django.contrib.auth.models import User

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from iaso.models import Project


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
"""
Override this method to be able to take into account the app_id query param.
If the user is a multi-account user, we return a token for the correct
"account user" (based on the `app_id`) instead of the main user that was
used for logging in.
"""
data = super().validate(attrs)

if self.user.tenant_users.exists():
request = self.context.get("request")
if request:
app_id = request.query_params.get("app_id", None)
project = Project.objects.get(app_id=app_id)

account_user = User.objects.filter(
tenant_user__main_user=self.user,
iaso_profile__account=project.account,
).first()

refresh = self.get_token(account_user)

data["refresh"] = str(refresh)
data["access"] = str(refresh.access_token)

return data

0 comments on commit e0c667f

Please sign in to comment.