django-oidc-provider/oidc_provider/views.py

175 lines
5.1 KiB
Python
Raw Normal View History

2015-06-19 20:46:00 +00:00
import logging
2015-07-13 20:34:43 +00:00
from Crypto.PublicKey import RSA
from django.contrib.auth.views import redirect_to_login
2014-12-19 15:27:43 +00:00
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.shortcuts import render
from django.template.loader import render_to_string
2014-12-19 15:27:43 +00:00
from django.views.decorators.http import require_http_methods
from django.views.generic import View
2015-07-13 20:34:43 +00:00
from hashlib import md5
from jwkest import long_to_base64
2015-02-18 18:07:22 +00:00
from oidc_provider.lib.endpoints.authorize import *
from oidc_provider.lib.endpoints.discovery import *
2015-02-18 18:07:22 +00:00
from oidc_provider.lib.endpoints.token import *
from oidc_provider.lib.endpoints.userinfo import *
from oidc_provider.lib.errors import *
2015-07-13 20:34:43 +00:00
from oidc_provider.lib.utils.common import get_rsa_key
2014-12-19 15:27:43 +00:00
2015-06-19 20:46:00 +00:00
logger = logging.getLogger(__name__)
2014-12-19 15:27:43 +00:00
class AuthorizeView(View):
def get(self, request, *args, **kwargs):
authorize = AuthorizeEndpoint(request)
try:
authorize.validate_params()
if request.user.is_authenticated():
2015-03-19 17:04:32 +00:00
# Check if there's a hook setted.
hook_resp = settings.get('OIDC_AFTER_USERLOGIN_HOOK')(
request=request, user=request.user,
client=authorize.client)
if hook_resp:
return hook_resp
2015-06-24 15:40:00 +00:00
if settings.get('OIDC_SKIP_CONSENT_ENABLE'):
# Check if user previously give consent.
if authorize.client_has_user_consent():
uri = authorize.create_response_uri()
return HttpResponseRedirect(uri)
# Generate hidden inputs for the form.
context = {
2014-12-19 15:27:43 +00:00
'params': authorize.params,
}
hidden_inputs = render_to_string(
2015-02-18 18:07:22 +00:00
'oidc_provider/hidden_inputs.html', context)
2015-03-19 17:04:32 +00:00
# Remove `openid` from scope list
# since we don't need to print it.
authorize.params.scope.remove('openid')
context = {
2014-12-19 15:27:43 +00:00
'client': authorize.client,
'hidden_inputs': hidden_inputs,
'params': authorize.params,
2014-12-19 15:27:43 +00:00
}
2015-02-18 18:07:22 +00:00
return render(request, 'oidc_provider/authorize.html', context)
2014-12-19 15:27:43 +00:00
else:
path = request.get_full_path()
return redirect_to_login(path)
2014-12-19 15:27:43 +00:00
except (ClientIdError, RedirectUriError) as error:
context = {
'error': error.error,
'description': error.description,
}
2015-02-18 18:07:22 +00:00
return render(request, 'oidc_provider/error.html', context)
2014-12-19 15:27:43 +00:00
except (AuthorizeError) as error:
uri = error.create_uri(
authorize.params.redirect_uri,
authorize.params.state)
2014-12-19 15:27:43 +00:00
return HttpResponseRedirect(uri)
def post(self, request, *args, **kwargs):
authorize = AuthorizeEndpoint(request)
allow = True if request.POST.get('allow') else False
2015-06-15 19:04:44 +00:00
try:
authorize.validate_params()
2015-06-15 19:04:44 +00:00
if not allow:
raise AuthorizeError(authorize.params.redirect_uri,
'access_denied',
authorize.grant_type)
# Save the user consent given to the client.
authorize.set_client_user_consent()
2014-12-19 15:27:43 +00:00
uri = authorize.create_response_uri()
2014-12-19 15:27:43 +00:00
return HttpResponseRedirect(uri)
except (AuthorizeError) as error:
2015-01-30 20:20:36 +00:00
uri = error.create_uri(
authorize.params.redirect_uri,
authorize.params.state)
2014-12-19 15:27:43 +00:00
return HttpResponseRedirect(uri)
2014-12-19 15:27:43 +00:00
class TokenView(View):
def post(self, request, *args, **kwargs):
token = TokenEndpoint(request)
try:
token.validate_params()
dic = token.create_response_dic()
return TokenEndpoint.response(dic)
except (TokenError) as error:
return TokenEndpoint.response(error.create_dict(), status=400)
2014-12-19 15:27:43 +00:00
@require_http_methods(['GET', 'POST'])
def userinfo(request):
userinfo = UserInfoEndpoint(request)
try:
userinfo.validate_params()
dic = userinfo.create_response_dic()
return UserInfoEndpoint.response(dic)
except (UserInfoError) as error:
return UserInfoEndpoint.error_response(
error.code,
error.description,
error.status)
class ProviderInfoView(View):
def get(self, request, *args, **kwargs):
dic = ProviderInfoEndpoint.create_response_dic()
2015-06-19 20:46:00 +00:00
return JsonResponse(dic)
2015-07-13 20:34:43 +00:00
class JwksView(View):
def get(self, request, *args, **kwargs):
dic = dict(keys=[])
2015-07-23 19:07:55 +00:00
key = get_rsa_key().encode('utf-8')
2015-07-13 20:34:43 +00:00
public_key = RSA.importKey(key).publickey()
dic['keys'].append({
'kty': 'RSA',
'alg': 'RS256',
'use': 'sig',
'kid': md5(key).hexdigest(),
'n': long_to_base64(public_key.n).decode('utf-8'),
'e': long_to_base64(public_key.e).decode('utf-8'),
2015-07-13 20:34:43 +00:00
})
return JsonResponse(dic)