"""Custom tokens based on django-rest-framework-simple-jwt""" from rest_framework_simplejwt.settings import api_settings from rest_framework_simplejwt.tokens import Token, AccessToken, RefreshToken, BlacklistMixin from authorization.models import JWTRefreshToken, JWTAccessToken class GMToken(Token): """Custom JWT Token class""" @classmethod def for_user(cls, user): """ Returns an authorization token for the given user that will be provided after authenticating the user's credentials. """ user_id = getattr(user, api_settings.USER_ID_FIELD) if not isinstance(user_id, int): user_id = str(user_id) token = cls() token[api_settings.USER_ID_CLAIM] = user_id return token class GMBlacklistMixin(BlacklistMixin): """ If the `rest_framework_simplejwt.token_blacklist` app was configured to be used, tokens created from `BlacklistMixin` subclasses will insert themselves into an outstanding token list and also check for their membership in a token blacklist. """ @classmethod def for_user(cls, user, source: int = None): """Create a refresh token.""" token = super().for_user(user) token['user'] = user.get_user_info() JWTRefreshToken.objects.make(user=user, token=token, source=source) return token class GMRefreshToken(GMBlacklistMixin, GMToken, RefreshToken): """GM refresh token""" @property def access_token(self): """ Returns an access token created from this refresh token. Copies all claims present in this refresh token to the new access token except those claims listed in the `no_copy_claims` attribute. """ from account.models import User access_token = AccessToken() # Use instantiation time of refresh token as relative timestamp for # access token "exp" claim. This ensures that both a refresh and # access token expire relative to the same time if they are created as # a pair. access_token.set_exp(from_time=self.current_time) no_copy = self.no_copy_claims for claim, value in self.payload.items(): if claim in no_copy: continue access_token[claim] = value # Create a record in DB user = User.objects.get(id=self.payload.get('user_id')) JWTAccessToken.objects.make(user=user, access_token=access_token, refresh_token=self) return access_token