2015-03-04 19:24:41 +00:00
|
|
|
import re
|
|
|
|
|
2015-01-30 20:20:36 +00:00
|
|
|
from django.http import HttpResponse
|
|
|
|
from django.http import JsonResponse
|
2015-03-04 19:24:41 +00:00
|
|
|
|
2015-02-18 18:07:22 +00:00
|
|
|
from oidc_provider.lib.errors import *
|
|
|
|
from oidc_provider.lib.claims import *
|
|
|
|
from oidc_provider.lib.utils.params import *
|
|
|
|
from oidc_provider.models import *
|
|
|
|
from oidc_provider import settings
|
2015-01-08 20:55:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
class UserInfoEndpoint(object):
|
|
|
|
|
|
|
|
def __init__(self, request):
|
|
|
|
self.request = request
|
2015-01-09 17:59:23 +00:00
|
|
|
self.params = Params()
|
2015-01-08 20:55:24 +00:00
|
|
|
self._extract_params()
|
|
|
|
|
|
|
|
def _extract_params(self):
|
|
|
|
# TODO: Maybe add other ways of passing access token
|
|
|
|
# http://tools.ietf.org/html/rfc6750#section-2
|
|
|
|
self.params.access_token = self._get_access_token()
|
|
|
|
|
|
|
|
def _get_access_token(self):
|
2015-01-28 18:19:36 +00:00
|
|
|
"""
|
2015-01-08 20:55:24 +00:00
|
|
|
Get the access token using Authorization Request Header Field method.
|
|
|
|
See: http://tools.ietf.org/html/rfc6750#section-2.1
|
|
|
|
|
|
|
|
Return a string.
|
2015-01-28 18:19:36 +00:00
|
|
|
"""
|
2015-01-08 20:55:24 +00:00
|
|
|
auth_header = self.request.META.get('HTTP_AUTHORIZATION', '')
|
|
|
|
|
|
|
|
if re.compile('^Bearer\s{1}.+$').match(auth_header):
|
|
|
|
access_token = auth_header.split()[1]
|
|
|
|
else:
|
|
|
|
access_token = ''
|
|
|
|
|
|
|
|
return access_token
|
|
|
|
|
|
|
|
def validate_params(self):
|
|
|
|
try:
|
|
|
|
self.token = Token.objects.get(access_token=self.params.access_token)
|
|
|
|
|
2015-04-21 20:14:26 +00:00
|
|
|
if self.token.has_expired():
|
|
|
|
raise UserInfoError('invalid_token')
|
|
|
|
|
2015-05-07 19:12:45 +00:00
|
|
|
if not ('openid' in self.token.scope):
|
|
|
|
raise UserInfoError('insufficient_scope')
|
|
|
|
|
2015-01-08 20:55:24 +00:00
|
|
|
except Token.DoesNotExist:
|
|
|
|
raise UserInfoError('invalid_token')
|
|
|
|
|
|
|
|
def create_response_dic(self):
|
2015-01-28 18:19:36 +00:00
|
|
|
"""
|
2015-01-08 20:55:24 +00:00
|
|
|
Create a diccionary with all the requested claims about the End-User.
|
|
|
|
See: http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
|
|
|
|
|
|
|
|
Return a diccionary.
|
2015-01-28 18:19:36 +00:00
|
|
|
"""
|
2015-01-08 20:55:24 +00:00
|
|
|
dic = {
|
|
|
|
'sub': self.token.id_token.get('sub'),
|
|
|
|
}
|
|
|
|
|
2015-01-30 20:20:36 +00:00
|
|
|
standard_claims = StandardScopeClaims(self.token.user, self.token.scope)
|
|
|
|
|
2015-01-08 20:55:24 +00:00
|
|
|
dic.update(standard_claims.create_response_dic())
|
|
|
|
|
2015-02-26 19:14:36 +00:00
|
|
|
extra_claims = settings.get('OIDC_EXTRA_SCOPE_CLAIMS')(
|
2015-01-30 20:20:36 +00:00
|
|
|
self.token.user, self.token.scope)
|
|
|
|
|
|
|
|
dic.update(extra_claims.create_response_dic())
|
|
|
|
|
2015-01-08 20:55:24 +00:00
|
|
|
return dic
|
|
|
|
|
|
|
|
@classmethod
|
2015-01-29 15:54:13 +00:00
|
|
|
def response(cls, dic):
|
2015-01-08 20:55:24 +00:00
|
|
|
response = JsonResponse(dic, status=200)
|
|
|
|
response['Cache-Control'] = 'no-store'
|
|
|
|
response['Pragma'] = 'no-cache'
|
|
|
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
@classmethod
|
2015-01-29 15:54:13 +00:00
|
|
|
def error_response(cls, code, description, status):
|
2015-01-08 20:55:24 +00:00
|
|
|
response = HttpResponse(status=status)
|
|
|
|
response['WWW-Authenticate'] = 'error="{0}", error_description="{1}"'.format(code, description)
|
|
|
|
|
|
|
|
return response
|