import urllib from django.http import JsonResponse from oidc_provider.lib.errors import * from oidc_provider.lib.utils.common import get_issuer from oidc_provider.lib.utils.params import * from oidc_provider.lib.utils.token import * from oidc_provider.models import * from oidc_provider import settings class TokenEndpoint(object): def __init__(self, request): self.request = request self.params = Params() self._extract_params() def _extract_params(self): query_dict = self.request.POST self.params.client_id = query_dict.get('client_id', '') self.params.client_secret = query_dict.get('client_secret', '') self.params.redirect_uri = urllib.unquote( query_dict.get('redirect_uri', '')) self.params.grant_type = query_dict.get('grant_type', '') self.params.code = query_dict.get('code', '') self.params.state = query_dict.get('state', '') def validate_params(self): if not (self.params.grant_type == 'authorization_code'): raise TokenError('unsupported_grant_type') try: self.client = Client.objects.get(client_id=self.params.client_id) if not (self.client.client_secret == self.params.client_secret): raise TokenError('invalid_client') if not (self.params.redirect_uri in self.client.redirect_uris): raise TokenError('invalid_client') self.code = Code.objects.get(code=self.params.code) if not (self.code.client == self.client) and \ not self.code.has_expired(): raise TokenError('invalid_grant') except Client.DoesNotExist: raise TokenError('invalid_client') except Code.DoesNotExist: raise TokenError('invalid_grant') def create_response_dic(self): sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR')( user=self.code.user) id_token_dic = create_id_token( iss=get_issuer(), sub=sub, aud=self.client.client_id, auth_time=self.code.user.last_login) token = create_token( user=self.code.user, client=self.code.client, id_token_dic=id_token_dic, scope=self.code.scope) # Store the token. token.save() # We don't need to store the code anymore. self.code.delete() id_token = encode_id_token(id_token_dic, self.client.client_secret) dic = { 'access_token': token.access_token, 'token_type': 'bearer', 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'), 'id_token': id_token, } return dic @classmethod def response(cls, dic, status=200): """ Create and return a response object. """ response = JsonResponse(dic, status=status) response['Cache-Control'] = 'no-store' response['Pragma'] = 'no-cache' return response