def make_success_redirect(self): """ Return a Django ``HttpResponseRedirect`` describing the request success. The custom authorization endpoint should return the result of this method when the user grants the Client's authorization request. The request is assumed to have successfully been vetted by the :py:meth:`validate` method. """ new_authorization_code = AuthorizationCode.objects.create( user=self.user, client=self.client, redirect_uri=(self.redirect_uri if self.request_redirect_uri else None) ) new_authorization_code.scopes = self.valid_scope_objects new_authorization_code.save() response_params = {'code': new_authorization_code.value} # From http://tools.ietf.org/html/rfc6749#section-4.1.2 : # # REQUIRED if the "state" parameter was present in the client # authorization request. The exact value received from the # client. # if self.state is not None: response_params['state'] = self.state return HttpResponseRedirect( update_parameters(self.redirect_uri, response_params))
def authorization_endpoint(request): auth_code_generator = AuthorizationCodeGenerator(missing_redirect_uri) try: auth_code_generator.validate(request) except AuthorizationError as authorization_error: return auth_code_generator.make_error_redirect(authorization_error) if request.method == 'GET': return render( request, authorization_template_name, { 'form': Form(), 'client': auth_code_generator.client, 'scopes': auth_code_generator.valid_scope_objects, 'form_action': update_parameters( authorization_endpoint_uri, auth_code_generator.get_request_uri_parameters( as_dict=True)), }) if request.method == 'POST': form = Form(request) if form.is_valid() and request.POST.get('user_action') == 'Accept': return auth_code_generator.make_success_redirect() else: return auth_code_generator.make_error_redirect()
def test_update_parameters_urlencodes_parameters_as_necessary(self): url = "https://locu.com/" parameters = {"?": "&", "#": "value"} updated_url = update_parameters(url, parameters) parsed_url = urlparse(updated_url) parsed_url_parameters = dict(parse_qsl(parsed_url.query)) for parameter, value in parameters.iteritems(): self.assertIn(parameter, parsed_url_parameters) self.assertEqual(value, parsed_url_parameters[parameter])
def test_update_parameters_adds_params_to_url(self): url = "https://locu.com/" parameters = {"value1": "True", "value2": "42424242", "foo": "bar"} updated_url = update_parameters(url, parameters) parsed_url = urlparse(updated_url) parsed_url_parameters = dict(parse_qsl(parsed_url.query)) for parameter, value in parameters.iteritems(): self.assertIn(parameter, parsed_url_parameters) self.assertEqual(value, parsed_url_parameters[parameter])
def test_update_parameters_encodes_unicode_with_encoding(self): url = "https://locu.com/" parameters = {u"nåme": "Peter", "foo": u"Bʼn"} utf8_encoded_parameters = {"n\xc3\xa5me": "Peter", "foo": "B\xc3\x85\xe2\x80\xb0"} updated_url = update_parameters(url, parameters) parsed_url = urlparse(updated_url) parsed_url_parameters = dict(parse_qsl(parsed_url.query)) for parameter, value in utf8_encoded_parameters.iteritems(): self.assertIn(parameter, parsed_url_parameters) self.assertEqual(value, parsed_url_parameters[parameter])
def test_update_parameters_urlencodes_parameters_as_necessary(self): url = 'https://locu.com/' parameters = { '?': '&', '#': 'value', } updated_url = update_parameters(url, parameters) parsed_url = urlparse(updated_url) parsed_url_parameters = dict(parse_qsl(parsed_url.query)) for parameter, value in parameters.iteritems(): self.assertIn(parameter, parsed_url_parameters) self.assertEqual(value, parsed_url_parameters[parameter])
def test_update_parameters_adds_params_to_url(self): url = 'https://locu.com/' parameters = { 'value1': 'True', 'value2': '42424242', 'foo': 'bar', } updated_url = update_parameters(url, parameters) parsed_url = urlparse(updated_url) parsed_url_parameters = dict(parse_qsl(parsed_url.query)) for parameter, value in parameters.iteritems(): self.assertIn(parameter, parsed_url_parameters) self.assertEqual(value, parsed_url_parameters[parameter])
def make_error_redirect(self, authorization_exception=None): """ Return a Django ``HttpResponseRedirect`` describing the request failure. If the :py:meth:`validate` method raises an error, the authorization endpoint should return the result of calling this method like so: >>> auth_code_generator = ( >>> AuthorizationCodeGenerator('/oauth2/missing_redirect_uri/')) >>> try: >>> auth_code_generator.validate(request) >>> except AuthorizationException as authorization_exception: >>> return auth_code_generator.make_error_redirect(authorization_exception) If there is no known Client ``redirect_uri`` (because it is malformed, or the Client is invalid, or if the supplied ``redirect_uri`` does not match the regsitered value, or some other request failure) then the response will redirect to the ``missing_redirect_uri`` passed to the :py:meth:`__init__` method. Also used to signify user denial; call this method without passing in the optional ``authorization_exception`` argument to return a generic :py:class:`AccessDenied` message. >>> if not user_accepted_request: >>> return auth_code_generator.make_error_redirect() """ if not self.redirect_uri: return HttpResponseRedirect(self.missing_redirect_uri) authorization_exception = (authorization_exception or AccessDenied('user denied the request')) response_params = get_error_details(authorization_exception) # From http://tools.ietf.org/html/rfc6749#section-4.1.2.1 : # # REQUIRED if the "state" parameter was present in the client # authorization request. The exact value received from the # client. # if self.state is not None: response_params['state'] = self.state return HttpResponseRedirect( update_parameters(self.redirect_uri, response_params))
def make_error_redirect(self, authorization_error=None): """ Return a Django ``HttpResponseRedirect`` describing the request failure. If the :py:meth:`validate` method raises an error, the authorization endpoint should return the result of calling this method like so: >>> auth_code_generator = ( >>> AuthorizationCodeGenerator('/oauth2/missing_redirect_uri/')) >>> try: >>> auth_code_generator.validate(request) >>> except AuthorizationError as authorization_error: >>> return auth_code_generator.make_error_redirect(authorization_error) If there is no known Client ``redirect_uri`` (because it is malformed, or the Client is invalid, or if the supplied ``redirect_uri`` does not match the regsitered value, or some other request failure) then the response will redirect to the ``missing_redirect_uri`` passed to the :py:meth:`__init__` method. Also used to signify user denial; call this method without passing in the optional ``authorization_error`` argument to return a generic :py:class:`AccessDenied` message. >>> if not user_accepted_request: >>> return auth_code_generator.make_error_redirect() """ if not self.redirect_uri: return HttpResponseRedirect(self.missing_redirect_uri) authorization_error = (authorization_error or AccessDenied('user denied the request')) response_params = get_error_details(authorization_error) # From http://tools.ietf.org/html/rfc6749#section-4.1.2.1 : # # REQUIRED if the "state" parameter was present in the client # authorization request. The exact value received from the # client. # if self.state is not None: response_params['state'] = self.state return HttpResponseRedirect( update_parameters(self.redirect_uri, response_params))
def test_update_parameters_encodes_unicode_with_encoding(self): url = 'https://locu.com/' parameters = { u'nåme': 'Peter', 'foo': u'Bʼn', } utf8_encoded_parameters = { 'n\xc3\xa5me': 'Peter', 'foo': 'B\xc3\x85\xe2\x80\xb0', } updated_url = update_parameters(url, parameters) parsed_url = urlparse(updated_url) parsed_url_parameters = dict(parse_qsl(parsed_url.query)) for parameter, value in utf8_encoded_parameters.iteritems(): self.assertIn(parameter, parsed_url_parameters) self.assertEqual(value, parsed_url_parameters[parameter])
def make_success_redirect(self): """ Return a Django ``HttpResponseRedirect`` describing the request success. The custom authorization endpoint should return the result of this method when the user grants the Client's authorization request. The request is assumed to have successfully been vetted by the :py:meth:`validate` method. """ try: new_authorization_code = AuthorizationCode.objects.create( user=self.user, client=self.client, redirect_uri=(self.request_redirect_uri if self.request_redirect_uri else self.redirect_uri)) except IntegrityError: # this should never be happening... from djoauth2.helpers import make_authorization_code new_authorization_code = AuthorizationCode.objects.create( user=self.user, client=self.client, value=make_authorization_code( settings.DJOAUTH2_AUTHORIZATION_CODE_LENGTH), redirect_uri=(self.request_redirect_uri if self.request_redirect_uri else self.redirect_uri)) new_authorization_code.scopes = self.valid_scope_objects new_authorization_code.save() response_params = {'code': new_authorization_code.value} # From http://tools.ietf.org/html/rfc6749#section-4.1.2 : # # REQUIRED if the "state" parameter was present in the client # authorization request. The exact value received from the # client. # if self.state is not None: response_params['state'] = self.state return HttpResponseRedirect( update_parameters(self.redirect_uri, response_params))
def authorization_endpoint(request): auth_code_generator = AuthorizationCodeGenerator(missing_redirect_uri) try: auth_code_generator.validate(request) except AuthorizationException as authorization_exception: return auth_code_generator.make_error_redirect(authorization_exception) if request.method == 'GET': return render(request, authorization_template_name, { 'form': Form(), 'client': auth_code_generator.client, 'scopes': auth_code_generator.valid_scope_objects, 'form_action': update_parameters( authorization_endpoint_uri, auth_code_generator.get_request_uri_parameters(as_dict=True)), }) if request.method == 'POST': form = Form(request) if form.is_valid() and request.POST.get('user_action') == 'Accept': return auth_code_generator.make_success_redirect() else: return auth_code_generator.make_error_redirect()
def make_success_redirect(self): """ Return a Django ``HttpResponseRedirect`` describing the request success. The custom authorization endpoint should return the result of this method when the user grants the Client's authorization request. The request is assumed to have successfully been vetted by the :py:meth:`validate` method. """ try: new_authorization_code = AuthorizationCode.objects.create( user=self.user, client=self.client, redirect_uri=(self.request_redirect_uri if self.request_redirect_uri else self.redirect_uri) ) except IntegrityError: # this should never be happening... from djoauth2.helpers import make_authorization_code new_authorization_code = AuthorizationCode.objects.create( user=self.user, client=self.client, value=make_authorization_code(settings.DJOAUTH2_AUTHORIZATION_CODE_LENGTH), redirect_uri=(self.request_redirect_uri if self.request_redirect_uri else self.redirect_uri) ) new_authorization_code.scopes = self.valid_scope_objects new_authorization_code.save() response_params = {'code': new_authorization_code.value} # From http://tools.ietf.org/html/rfc6749#section-4.1.2 : # # REQUIRED if the "state" parameter was present in the client # authorization request. The exact value received from the # client. # if self.state is not None: response_params['state'] = self.state return HttpResponseRedirect( update_parameters(self.redirect_uri, response_params))