X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/67552e19bc548b78c18967e97f0c0328074a3576..b0b9c1f0f9f4cc0f5c4d00d913735ab6a81bf214:/src/api/piston_patch.py diff --git a/src/api/piston_patch.py b/src/api/piston_patch.py index 4bf9b615d..6a80e15cd 100644 --- a/src/api/piston_patch.py +++ b/src/api/piston_patch.py @@ -1,112 +1,64 @@ # -*- coding: utf-8 -*- +# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# +from oauthlib.oauth1 import AuthorizationEndpoint, OAuth1Error +from django.contrib.auth.decorators import login_required +from django import forms +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import render +from .request_validator import PistonRequestValidator +from .utils import oauthlib_request, oauthlib_response -# modified from django-piston -import base64 -import hmac -from django import forms -from django.conf import settings -from django.contrib.auth.decorators import login_required -from django.core.urlresolvers import get_callable -from django.http import HttpResponseRedirect, HttpResponse -from django.shortcuts import render_to_response -from django.template.context import RequestContext -from piston import oauth -from piston.authentication import initialize_server_request, INVALID_PARAMS_RESPONSE, send_oauth_error +class HttpResponseAppRedirect(HttpResponseRedirect): + allowed_schemes = HttpResponseRedirect.allowed_schemes + ['wolnelekturyapp'] class OAuthAuthenticationForm(forms.Form): oauth_token = forms.CharField(widget=forms.HiddenInput) oauth_callback = forms.CharField(widget=forms.HiddenInput) # changed from URLField - too strict # removed authorize_access - redundant - csrf_signature = forms.CharField(widget=forms.HiddenInput) - - def __init__(self, *args, **kwargs): - forms.Form.__init__(self, *args, **kwargs) - - self.fields['csrf_signature'].initial = self.initial_csrf_signature - - def clean_csrf_signature(self): - sig = self.cleaned_data['csrf_signature'] - token = self.cleaned_data['oauth_token'] - - sig1 = OAuthAuthenticationForm.get_csrf_signature(settings.SECRET_KEY, token) - - if sig != sig1: - raise forms.ValidationError("CSRF signature is not valid") - - return sig - - def initial_csrf_signature(self): - token = self.initial['oauth_token'] - return OAuthAuthenticationForm.get_csrf_signature(settings.SECRET_KEY, token) - - @staticmethod - def get_csrf_signature(key, token): - # Check signature... - import hashlib # 2.5 - hashed = hmac.new(key, token, hashlib.sha1) - - # calculate the digest base 64 - return base64.b64encode(hashed.digest()) -# The only thing changed in the views below is the form used - - -def oauth_auth_view(request, token, callback, params): - form = OAuthAuthenticationForm(initial={ - 'oauth_token': token.key, - 'oauth_callback': callback, - }) - - return render_to_response('piston/authorize_token.html', - {'form': form}, RequestContext(request)) +class OAuth1AuthorizationEndpoint(AuthorizationEndpoint): + def create_verifier(self, request, credentials): + verifier = super(OAuth1AuthorizationEndpoint, self).create_verifier(request, credentials) + return { + 'oauth_token': verifier['oauth_token'], + } @login_required def oauth_user_auth(request): - oauth_server, oauth_request = initialize_server_request(request) - - if oauth_request is None: - return INVALID_PARAMS_RESPONSE - - try: - token = oauth_server.fetch_request_token(oauth_request) - except oauth.OAuthError, err: - return send_oauth_error(err) - - try: - callback = oauth_server.get_callback(oauth_request) - except: - callback = None + endpoint = OAuth1AuthorizationEndpoint(PistonRequestValidator()) if request.method == "GET": - params = oauth_request.get_normalized_parameters() - - oauth_view = getattr(settings, 'OAUTH_AUTH_VIEW', None) - if oauth_view is None: - return oauth_auth_view(request, token, callback, params) - else: - return get_callable(oauth_view)(request, token, callback, params) - elif request.method == "POST": + # Why not just get oauth_token here? + # This is fairly straightforward, in't? try: - form = OAuthAuthenticationForm(request.POST) - if form.is_valid(): - token = oauth_server.authorize_token(token, request.user) - args = '?' + token.to_string(only_key=True) - else: - args = '?error=%s' % 'Access not granted by user.' - - if not callback: - callback = getattr(settings, 'OAUTH_CALLBACK_VIEW') - return get_callable(callback)(request, token) + realms, credentials = endpoint.get_realms_and_credentials( + **oauthlib_request(request)) + except OAuth1Error as e: + return HttpResponse(e.message, status=400) + callback = request.GET.get('oauth_callback') - response = HttpResponseRedirect(callback + args) + form = OAuthAuthenticationForm(initial={ + 'oauth_token': credentials['resource_owner_key'], + 'oauth_callback': callback, + }) - except oauth.OAuthError, err: - response = send_oauth_error(err) - else: - response = HttpResponse('Action not allowed.') + return render(request, 'piston/authorize_token.html', {'form': form}) - return response + elif request.method == "POST": + try: + response = oauthlib_response( + endpoint.create_authorization_response( + credentials={"user": request.user}, + **oauthlib_request(request) + ) + ) + except OAuth1Error as e: + return HttpResponse(e.message, status=400) + else: + return response