Ejemplo n.º 1
0
 def test_unavailability(self):
     validator = RequestValidator()
     server = Server(validator)
     server.available = False
     h, b, s = server.create_authorization_response('https://example.com')
     self.assertIn("temporarily_unavailable", b)
     self.assertEqual(s, 503)
Ejemplo n.º 2
0
    def server(self):
        """All in one endpoints."""
        app = self.get_app()
        expires_in = app.config.get('OAUTH_PROVIDER_TOKEN_EXPIRES_IN')
        if hasattr(self, '_validator'):
            return Server(self._validator, token_expires_in=expires_in)

        if hasattr(self, '_clientgetter') and \
           hasattr(self, '_tokengetter') and \
           hasattr(self, '_tokensetter') and \
           hasattr(self, '_grantgetter') and \
           hasattr(self, '_grantsetter'):

            usergetter = None
            if hasattr(self, '_usergetter'):
                usergetter = self._usergetter

            validator = OAuth2RequestValidator(
                clientgetter=self._clientgetter,
                tokengetter=self._tokengetter,
                grantgetter=self._grantgetter,
                usergetter=usergetter,
                tokensetter=self._tokensetter,
                grantsetter=self._grantsetter,
            )
            return Server(validator, token_expires_in=expires_in)
        raise RuntimeError('application not bound to required getters')
Ejemplo n.º 3
0
 def test_error_catching(self):
     validator = RequestValidator()
     server = Server(validator)
     server.catch_errors = True
     h, b, s = server.create_authorization_response('https://example.com')
     self.assertIn("server_error", b)
     self.assertEqual(s, 500)
Ejemplo n.º 4
0
    def server(self):
        """
        All in one endpoints. This property is created automaticly
        if you have implemented all the getters and setters.
        However, if you are not satisfied with the getter and setter,
        you can create a validator with :class:`OAuth2RequestValidator`::
            class MyValidator(OAuth2RequestValidator):
                def validate_client_id(self, client_id):
                    # do something
                    return True
        And assign the validator for the provider::
            oauth._validator = MyValidator()
        """
        expires_in = self.app.config.get('OAUTH2_PROVIDER_TOKEN_EXPIRES_IN')
        token_generator = self.app.config.get(
            'OAUTH2_PROVIDER_TOKEN_GENERATOR', None)
        if token_generator and not callable(token_generator):
            token_generator = import_string(token_generator)

        refresh_token_generator = self.app.config.get(
            'OAUTH2_PROVIDER_REFRESH_TOKEN_GENERATOR', None)
        if refresh_token_generator and not callable(refresh_token_generator):
            refresh_token_generator = import_string(refresh_token_generator)

        if hasattr(self, '_validator'):
            return Server(
                self._validator,
                token_expires_in=expires_in,
                token_generator=token_generator,
                refresh_token_generator=refresh_token_generator,
            )

        if hasattr(self, '_clientgetter') and \
           hasattr(self, '_tokengetter') and \
           hasattr(self, '_tokensetter') and \
           hasattr(self, '_grantgetter') and \
           hasattr(self, '_grantsetter'):

            usergetter = None
            if hasattr(self, '_usergetter'):
                usergetter = self._usergetter

            validator = OAuth2RequestValidator(
                clientgetter=self._clientgetter,
                tokengetter=self._tokengetter,
                grantgetter=self._grantgetter,
                usergetter=usergetter,
                tokensetter=self._tokensetter,
                grantsetter=self._grantsetter,
            )
            self._validator = validator
            return Server(
                validator,
                token_expires_in=expires_in,
                token_generator=token_generator,
                refresh_token_generator=refresh_token_generator,
            )
        raise RuntimeError('application not bound to required getters')
Ejemplo n.º 5
0
 def setUp(self):
     self.validator = mock.MagicMock(spec=RequestValidator)
     self.validator.get_default_redirect_uri.return_value = TestScopeHandling.DEFAULT_REDIRECT_URI
     self.validator.authenticate_client.side_effect = self.set_client
     self.server = Server(self.validator)
     self.web = WebApplicationServer(self.validator)
     self.mobile = MobileApplicationServer(self.validator)
     self.legacy = LegacyApplicationServer(self.validator)
     self.backend = BackendApplicationServer(self.validator)
Ejemplo n.º 6
0
 def test_error_catching(self):
     validator = RequestValidator()
     server = Server(validator)
     server.catch_errors = True
     h, b, s = server.create_token_response(
         'https://example.com', body='grant_type=authorization_code&code=abc'
     )
     self.assertIn("server_error", b)
     self.assertEqual(s, 500)
Ejemplo n.º 7
0
def token_endpoint(request):
    validator = RequestValidator()
    server = Server(validator)

    uri, http_method, body, headers = extract_params(request)
    server_response = server.create_token_response(
        uri, http_method, body, headers, {},
    )
    return create_response(*server_response)
Ejemplo n.º 8
0
    def setUp(self):
        self.validator = mock.MagicMock(spec=RequestValidator)
        self.validator.get_default_redirect_uri.return_value = TestClaimsHandling.DEFAULT_REDIRECT_URI
        self.validator.authenticate_client.side_effect = self.set_client

        self.validator.save_authorization_code.side_effect = self.save_claims_with_code
        self.validator.validate_code.side_effect = self.retrieve_claims_saved_with_code
        self.validator.save_token.side_effect = self.save_claims_with_bearer_token

        self.server = Server(self.validator)
Ejemplo n.º 9
0
class AuthorizationView(View):

    def __init__(self):
        validator = DjangoValidator()
        # TODO: this should probably be tunable through settings
        self._authorization_endpoint = Server(validator)
        self._error_uri = reverse('oauth2_error')

    def get(self, request, *args, **kwargs):
        uri, http_method, body, headers = extract_params(request)
        redirect_uri = request.GET.get('redirect_uri', None)
        log.debug('Found redirect uri %s.', redirect_uri)
        try:
            scopes, credentials = self._authorization_endpoint.validate_authorization_request(
                    uri, http_method, body, headers)
            log.debug('Saving credentials to session, %r.', credentials)
            request.session['oauth2_credentials'] = credentials
            kwargs['scopes'] = scopes
            kwargs.update(credentials)
            actual_view = get_actual_authorization_view(request)
            log.debug('Invoking actual view method, %r.', actual_view)
            return actual_view(request, *args, **kwargs)

        except errors.FatalClientError as e:
            log.debug('Fatal client error, redirecting to error page.')
            return HttpResponseRedirect(e.in_uri(self._error_uri))

        except errors.OAuth2Error as e:
            log.debug('Client error, redirecting back to client.')
            # TODO: remove after federico PR
            e.redirect_uri = redirect_uri or 'https://localhost'
            return HttpResponseRedirect(e.in_uri(e.redirect_uri))

    @csrf_exempt
    def post(self, request, *args, **kwargs):
        uri, http_method, body, headers = extract_params(request)
        scopes, credentials = get_authorization(request)
        log.debug('Fetched credentials view, %r.', credentials)
        credentials.update(request.session.get('oauth2_credentials', {}))
        log.debug('Fetched credentials from session, %r.', credentials)
        redirect_uri = credentials.get('redirect_uri')
        log.debug('Found redirect uri %s.', redirect_uri)
        try:
            url, headers, body, status = self._authorization_endpoint.create_authorization_response(
                    uri, http_method, body, headers, scopes, credentials)
            log.debug('Authorization successful, redirecting to client.')
            return HttpResponseRedirect(url)
        except errors.FatalClientError as e:
            log.debug('Fatal client error, redirecting to error page.')
            return HttpResponseRedirect(e.in_uri(self._error_uri))
        except errors.OAuth2Error as e:
            log.debug('Client error, redirecting back to client.')
            return HttpResponseRedirect(e.in_uri(redirect_uri))
Ejemplo n.º 10
0
class AuthorizationView(View):
    def __init__(self):
        validator = DjangoValidator()
        # TODO: this should probably be tunable through settings
        self._authorization_endpoint = Server(validator)
        self._error_uri = reverse('oauth2_error')

    def get(self, request, *args, **kwargs):
        uri, http_method, body, headers = extract_params(request)
        redirect_uri = request.GET.get('redirect_uri', None)
        log.debug('Found redirect uri %s.', redirect_uri)
        try:
            scopes, credentials = self._authorization_endpoint.validate_authorization_request(
                uri, http_method, body, headers)
            log.debug('Saving credentials to session, %r.', credentials)
            request.session['oauth2_credentials'] = credentials
            kwargs['scopes'] = scopes
            kwargs.update(credentials)
            actual_view = get_actual_authorization_view(request)
            log.debug('Invoking actual view method, %r.', actual_view)
            return actual_view(request, *args, **kwargs)

        except errors.FatalClientError as e:
            log.debug('Fatal client error, redirecting to error page.')
            return HttpResponseRedirect(e.in_uri(self._error_uri))

        except errors.OAuth2Error as e:
            log.debug('Client error, redirecting back to client.')
            # TODO: remove after federico PR
            e.redirect_uri = redirect_uri or 'https://localhost'
            return HttpResponseRedirect(e.in_uri(e.redirect_uri))

    @csrf_exempt
    def post(self, request, *args, **kwargs):
        uri, http_method, body, headers = extract_params(request)
        scopes, credentials = get_authorization(request)
        log.debug('Fetched credentials view, %r.', credentials)
        credentials.update(request.session.get('oauth2_credentials', {}))
        log.debug('Fetched credentials from session, %r.', credentials)
        redirect_uri = credentials.get('redirect_uri')
        log.debug('Found redirect uri %s.', redirect_uri)
        try:
            url, headers, body, status = self._authorization_endpoint.create_authorization_response(
                uri, http_method, body, headers, scopes, credentials)
            log.debug('Authorization successful, redirecting to client.')
            return HttpResponseRedirect(url)
        except errors.FatalClientError as e:
            log.debug('Fatal client error, redirecting to error page.')
            return HttpResponseRedirect(e.in_uri(self._error_uri))
        except errors.OAuth2Error as e:
            log.debug('Client error, redirecting back to client.')
            return HttpResponseRedirect(e.in_uri(redirect_uri))
Ejemplo n.º 11
0
def token_endpoint(request):
    validator = RequestValidator()
    server = Server(validator)

    uri, http_method, body, headers = extract_params(request)
    server_response = server.create_token_response(
        uri,
        http_method,
        body,
        headers,
        {},
    )
    return create_response(*server_response)
Ejemplo n.º 12
0
def verify_request(request, scopes):
    validator = RequestValidator()
    server = Server(validator)

    uri, http_method, body, headers = extract_params(request)

    valid, r = server.verify_request(
        uri, http_method, body, headers, scopes,
    )

    if not valid:
        raise HTTPUnauthorized()

    return r.user
Ejemplo n.º 13
0
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        oauth2 = JSONOAuthLibCore(Server(OAuth2V1Validator()))
        uri, headers, body, status = oauth2.create_token_response(request)
        return Response(json.loads(body), status=status)
Ejemplo n.º 14
0
class IamRequestValidator(IRequestValidator):
    def __init__(self, validator: OauthlibRequestValidator):
        self._server = Server(validator)

    def validate_pre_auth_request(self, request: ff.Message):
        http_request = request.headers.get('http_request')
        return self._server.validate_authorization_request(
            f'{http_request["headers"]["Host"]}{http_request["url"]}',
            http_request['method'], '', http_request['headers'])

    def validate_post_auth_request(self, request: ff.Message):
        pass

    def create_response(self, request: ff.Message):
        return self._server.create_authorization_response(
            request.headers.get('uri'), request.headers.get('http_method'),
            request.to_dict(), request.headers)
Ejemplo n.º 15
0
    def setUp(self):
        super().setUp()
        self.oauth = BottleOAuth2(self.app)
        self.validator = mock.MagicMock()
        self.server = Server(self.validator)
        self.oauth.initialize(self.server)

        self.fake_response = ({}, "", "200 fooOK")
Ejemplo n.º 16
0
def get_oauthlib_core():
    """
    Utility function that take a request and returns an instance of
    `oauth2_provider.backends.OAuthLibCore`
    """
    from oauthlib.oauth2 import Server

    server = Server(oauth2_settings.OAUTH2_VALIDATOR_CLASS())
    return OAuthLibCore(server)
Ejemplo n.º 17
0
def get_oauthlib_core():
    """
    Utility function that take a request and returns an instance of `oauth2_provider.backends.OAuthLibCore`
    """
    from oauth2_provider.oauth2_validators import OAuth2Validator
    from oauthlib.oauth2 import Server

    server = Server(OAuth2Validator())
    return OAuthLibCore(server)
Ejemplo n.º 18
0
 def _validate(request, *args, **kwargs):
     validator = OAuth2Validator()
     core = OAuthLibCore(Server(validator))
     valid, oauthlib_req = core.verify_request(request, scopes = _scopes)
     if valid:
         request.client = oauthlib_req.client
         request.resource_owner = oauthlib_req.user
         return view_func(request, *args, **kwargs)
     return HttpResponseForbidden()
Ejemplo n.º 19
0
 def setUp(self):
     self.validator = mock.MagicMock(spec=RequestValidator)
     self.validator.get_default_redirect_uri.return_value = TestScopeHandling.DEFAULT_REDIRECT_URI
     self.validator.authenticate_client.side_effect = self.set_client
     self.server = Server(self.validator)
     self.web = WebApplicationServer(self.validator)
     self.mobile = MobileApplicationServer(self.validator)
     self.legacy = LegacyApplicationServer(self.validator)
     self.backend = BackendApplicationServer(self.validator)
Ejemplo n.º 20
0
 def get_response(self):
     oauth2 = JSONOAuthLibCore(Server(OAuth2V1Validator()))
     url, headers, body, status = oauth2.create_revocation_response(
         self.request)
     if status != 200:
         result = json.loads(body)
     else:
         result = {"detail": _("success logout")}
     return Response(result, status=status)
Ejemplo n.º 21
0
    def setUp(self):
        self.validator = mock.MagicMock(spec=RequestValidator)
        self.validator.get_default_redirect_uri.return_value = TestClaimsHandling.DEFAULT_REDIRECT_URI
        self.validator.authenticate_client.side_effect = self.set_client

        self.validator.save_authorization_code.side_effect = self.save_claims_with_code
        self.validator.validate_code.side_effect = self.retrieve_claims_saved_with_code
        self.validator.save_token.side_effect = self.save_claims_with_bearer_token

        self.server = Server(self.validator)
Ejemplo n.º 22
0
        def _validate(request, *args, **kwargs):
            core = OAuthLibCore(Server(OAuth2Validator()))
            valid, oauthlib_req = core.verify_request(request, scopes=[])
            if valid:
                # Note, resource_owner is not a very good name for this
                request.resource_owner = oauthlib_req.user
                request.oauth = oauthlib_req
                return view_func(request, *args, **kwargs)

            return build_error_response(401, 'The token authentication failed.')
Ejemplo n.º 23
0
    def setUp(self):
        super().setUp()
        self.oauth = BottleOAuth2(self.app)
        self.validator = mock.MagicMock()
        self.server = Server(self.validator)
        self.oauth.initialize(self.server)

        self.fake_response = ({
            "Content-Type": "application/x-www-form-urlencoded"
        }, "a=b&c=d", "200 FooOK")
Ejemplo n.º 24
0
    def setUp(self):
        super().setUp()
        self.oauth = BottleOAuth2(self.app)
        self.validator = mock.MagicMock()
        self.server = Server(self.validator)
        self.oauth.initialize(self.server)

        self.fake_response = ({
            "Content-Type": "application/json"
        }, "{'valid': true, 'foo': 'bar'}", "200 FooOK")
Ejemplo n.º 25
0
    def setUp(self):
        super().setUp()
        self.oauth = BottleOAuth2(self.app)
        self.validator = mock.MagicMock()
        self.server = Server(self.validator)
        self.oauth.initialize(self.server)

        self.fake_request = AttrDict(client="foo",
                                     user="******",
                                     scopes=['banana', 'pinapple'])
Ejemplo n.º 26
0
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = self.request.data
        oauth2 = JSONOAuthLibCore(Server(OAuth2V1Validator()))
        uri, headers, body, status = oauth2.create_token_response(request)

        data = json.loads(body)
        if status != 200:
            raise ValidationError({'username': [data['error']]})

        return Response(data, status=status)
Ejemplo n.º 27
0
    def authenticate(self, request):
        """
        Authenticate the request
        """
        server = Server(OAuthValidator())
        handler = OAuthHandler(server)
        valid, r = handler.verify_request(request, scopes=[])

        if valid:
            return r.user, r.access_token
        else:
            return None
Ejemplo n.º 28
0
        def validator(request, *args, **kwargs):
            from oauth2_provider.oauth2_validators import OAuth2Validator
            from oauth2_provider.oauth2_backends import OAuthLibCore
            from oauthlib.oauth2 import Server

            core = OAuthLibCore(Server(OAuth2Validator()))
            valid, oauthlib_req = core.verify_request(request, scopes=scopes)
            if valid:
                request.token = oauthlib_req.access_token
                return f(request, *args, **kwargs)
            return JsonResponseForbidden({
                "error": "invalid token",
                "code": "INVALID_TOKEN"
            })
Ejemplo n.º 29
0
    def test_server_metadata(self):
        endpoint = Server(None)
        metadata = MetadataEndpoint(
            [endpoint], {
                "issuer": 'https://foo.bar',
                "authorization_endpoint": "https://foo.bar/authorize",
                "introspection_endpoint": "https://foo.bar/introspect",
                "revocation_endpoint": "https://foo.bar/revoke",
                "token_endpoint": "https://foo.bar/token",
                "jwks_uri": "https://foo.bar/certs",
                "scopes_supported": ["email", "profile"]
            })
        expected_claims = {
            "issuer":
            "https://foo.bar",
            "authorization_endpoint":
            "https://foo.bar/authorize",
            "introspection_endpoint":
            "https://foo.bar/introspect",
            "revocation_endpoint":
            "https://foo.bar/revoke",
            "token_endpoint":
            "https://foo.bar/token",
            "jwks_uri":
            "https://foo.bar/certs",
            "scopes_supported": ["email", "profile"],
            "grant_types_supported": [
                "authorization_code", "password", "client_credentials",
                "refresh_token", "implicit"
            ],
            "token_endpoint_auth_methods_supported":
            ["client_secret_post", "client_secret_basic"],
            "response_types_supported": ["code", "token"],
            "response_modes_supported": ["query", "fragment"],
            "code_challenge_methods_supported": ["plain", "S256"],
            "revocation_endpoint_auth_methods_supported":
            ["client_secret_post", "client_secret_basic"],
            "introspection_endpoint_auth_methods_supported":
            ["client_secret_post", "client_secret_basic"]
        }

        def sort_list(claims):
            for k in claims.keys():
                claims[k] = sorted(claims[k])

        sort_list(metadata.claims)
        sort_list(expected_claims)
        self.assertEqual(sorted(metadata.claims.items()),
                         sorted(expected_claims.items()))
Ejemplo n.º 30
0
    def server(self):
        validator_key = '_validator'
        if hasattr(self, validator_key):
            return Server(
                getattr(self, validator_key),
                token_expires_in=self._token_expires_in,
                token_generator=self._token_generator,
                refresh_token_generator=self._refresh_token_generator,
            )

        if hasattr(self, '_clientgetter') and \
                hasattr(self, '_tokengetter') and \
                hasattr(self, '_tokensetter') and \
                hasattr(self, '_grantgetter') and \
                hasattr(self, '_grantsetter'):

            usergetter = None
            if hasattr(self, '_usergetter'):
                usergetter = self._usergetter

            validator = self.oauth_validator(
                service=self.service,
                clientgetter=getattr(self, '_clientgetter'),
                tokengetter=getattr(self, '_tokengetter'),
                grantgetter=getattr(self, '_grantgetter'),
                usergetter=usergetter,
                tokensetter=getattr(self, '_tokensetter'),
                grantsetter=getattr(self, '_grantsetter'))
            setattr(self, validator_key, validator)
            return Server(
                validator,
                token_expires_in=self._token_expires_in,
                token_generator=self._token_generator,
                refresh_token_generator=self._refresh_token_generator,
            )
        raise RuntimeError('application not bound to required getters')
Ejemplo n.º 31
0
    def server(self):
        """
        All in one endpoints. This property is created automaticaly
        if you have implemented all the getters and setters.

        However, if you are not satisfied with the getter and setter,
        you can create a validator with :class:`OAuth2RequestValidator`::

            class MyValidator(OAuth2RequestValidator):
                def validate_client_id(self, client_id):
                    # do something
                    return True

        And assign the validator for the provider::

            oauth._validator = MyValidator()
        """
        if not self._server:
            if not self._validator:
                accessors = [
                    '_clientgetter', '_tokengetter', '_tokensetter',
                    '_grantgetter', '_grantsetter'
                ]
                for accessor in accessors:
                    if not hasattr(self, accessor):
                        raise RuntimeError(
                            'Missing required accessor {}'.format(accessor))

                self._validator = OAuthValidator(
                    clientgetter=self._clientgetter,
                    tokengetter=self._tokengetter,
                    grantgetter=self._grantgetter,
                    usergetter=self._usergetter,
                    tokensetter=self._tokensetter,
                    grantsetter=self._grantsetter,
                )
            self._server = Server(
                self._validator,
                token_expires_in=self._expires_in,
                token_generator=self._token_generator,
                refresh_token_generator=self._refresh_token_generator,
            )
        return self._server
Ejemplo n.º 32
0
    def __call__(self, request):
        # 正式环境下要检查AccessToken
        if not settings.DEBUG:
            if "account_spider" in request.path:
                authorization = request.META.get("HTTP_AUTHORIZATION", "")
                token = request.GET.get("token", "")
                authorization_session = request.session.get("authorization")
                if token:
                    request.META["HTTP_AUTHORIZATION"] = "Bearer %s" % token
                    request.session['authorization'] = "Bearer %s" % token
                elif authorization:
                    request.session['authorization'] = authorization
                elif authorization_session:
                    request.META["HTTP_AUTHORIZATION"] = authorization_session
                validator = OAuth2Validator()
                core = OAuthLibCore(Server(validator))
                valid, oauthlib_req = core.verify_request(request, scopes=[])
                if not valid:
                    return HttpResponseForbidden()
                request.resource_owner = oauthlib_req.user

        return self.get_response(request)
Ejemplo n.º 33
0
class AuthorizationEndpoint(object):

    def __init__(self, request):
        self.request = request
        self.validator = RequestValidator()
        self.server = Server(self.validator)

    @view_config(route_name='oauth2_authorization_endpoint',
                 renderer='templates/application_authorization.pt',
                 permission='add-authorized-app',
                 request_method='GET')
    def get(self):
        uri, http_method, body, headers = extract_params(self.request)

        try:
            scopes, credentials = self.server.validate_authorization_request(
                uri, http_method, body, headers,
            )

            app = self.validator.get_client(credentials['client_id'])

            try:
                auth_app = Session.query(AuthorizedApplication).filter(
                    AuthorizedApplication.user == self.request.user,
                    AuthorizedApplication.scope == scopes,
                    AuthorizedApplication.redirect_uri == credentials['redirect_uri'],
                    AuthorizedApplication.response_type == credentials['response_type'],
                    AuthorizedApplication.application == app,
                ).one()
            except NoResultFound:
                auth_app = None

            if auth_app is not None:
                credentials['user'] = self.request.user
                server_response = self.server.create_authorization_response(
                    uri, http_method, body, headers, scopes, credentials,
                )
                return create_response(*server_response)
            else:
                authorship_information = app.user.email

                pretty_scopes = self.validator.get_pretty_scopes(scopes)
                return {
                    'response_type': credentials['response_type'],
                    'client_id': credentials['client_id'],
                    'redirect_uri': credentials['redirect_uri'],
                    'state': credentials['state'],
                    'scope': ' '.join(scopes),
                    'app': app,
                    'scopes': pretty_scopes,
                    'authorship_information': authorship_information,
                }
        except FatalClientError as e:
            return response_from_error(e)

        except OAuth2Error as e:
            return HTTPFound(e.in_uri(e.redirect_uri))

    @view_config(route_name='oauth2_authorization_endpoint',
                 permission='add-authorized-app',
                 request_method='POST')
    def post(self):
        uri, http_method, body, headers = extract_params(self.request)

        redirect_uri = self.request.POST.get('redirect_uri')
        if 'submit' in self.request.POST:
            scope = self.request.POST.get('scope', '')
            scopes = scope.split()
            credentials = {
                'client_id': self.request.POST.get('client_id'),
                'redirect_uri': redirect_uri,
                'response_type': self.request.POST.get('response_type'),
                'state': self.request.POST.get('state'),
                'user': self.request.user,
            }
            try:
                server_response = self.server.create_authorization_response(
                    uri, http_method, body, headers, scopes, credentials,
                )

                app = Session.query(Application).filter(
                    Application.id == credentials['client_id'],
                ).one()

                try:
                    auth_app = Session.query(AuthorizedApplication).filter(
                        AuthorizedApplication.user == self.request.user,
                        AuthorizedApplication.application == app,
                    ).one()
                except NoResultFound:
                    auth_app = AuthorizedApplication(
                        user=self.request.user,
                        application=app,
                    )

                auth_app.redirect_uri = credentials['redirect_uri']
                auth_app.response_type = credentials['response_type']
                auth_app.scope = scopes

                Session.add(auth_app)

                return create_response(*server_response)
            except FatalClientError as e:
                return response_from_error(e)

        elif 'cancel' in self.request.POST:
            e = AccessDeniedError()
            return HTTPFound(e.in_uri(redirect_uri))
Ejemplo n.º 34
0
 def __init__(self):
     validator = DjangoValidator()
     # TODO: this should probably be tunable through settings
     self._authorization_endpoint = Server(validator)
     self._error_uri = reverse('oauth2_error')
Ejemplo n.º 35
0
class TestClaimsHandling(TestCase):

    DEFAULT_REDIRECT_URI = 'http://i.b./path'

    def set_scopes(self, scopes):
        def set_request_scopes(client_id, code, client, request):
            request.scopes = scopes
            return True

        return set_request_scopes

    def set_user(self, request):
        request.user = '******'
        request.client_id = 'bar'
        request.client = mock.MagicMock()
        request.client.client_id = 'mocked'
        return True

    def set_client(self, request):
        request.client = mock.MagicMock()
        request.client.client_id = 'mocked'
        return True

    def save_claims_with_code(self, client_id, code, request, *args, **kwargs):
        # a real validator would save the claims with the code during save_authorization_code()
        self.claims_from_auth_code_request = request.claims
        self.scopes = request.scopes.split()

    def retrieve_claims_saved_with_code(self, client_id, code, client, request,
                                        *args, **kwargs):
        request.claims = self.claims_from_auth_code_request
        request.scopes = self.scopes

        return True

    def save_claims_with_bearer_token(self, token, request, *args, **kwargs):
        # a real validator would save the claims with the access token during save_bearer_token()
        self.claims_saved_with_bearer_token = request.claims

    def setUp(self):
        self.validator = mock.MagicMock(spec=RequestValidator)
        self.validator.get_default_redirect_uri.return_value = TestClaimsHandling.DEFAULT_REDIRECT_URI
        self.validator.authenticate_client.side_effect = self.set_client

        self.validator.save_authorization_code.side_effect = self.save_claims_with_code
        self.validator.validate_code.side_effect = self.retrieve_claims_saved_with_code
        self.validator.save_token.side_effect = self.save_claims_with_bearer_token

        self.server = Server(self.validator)

    def test_claims_stored_on_code_creation(self):

        claims = {
            "id_token": {
                "claim_1": None,
                "claim_2": {
                    "essential": True
                }
            },
            "userinfo": {
                "claim_3": {
                    "essential": True
                },
                "claim_4": None
            }
        }

        claims_urlquoted = '%7B%22id_token%22%3A%20%7B%22claim_2%22%3A%20%7B%22essential%22%3A%20true%7D%2C%20%22claim_1%22%3A%20null%7D%2C%20%22userinfo%22%3A%20%7B%22claim_4%22%3A%20null%2C%20%22claim_3%22%3A%20%7B%22essential%22%3A%20true%7D%7D%7D'
        uri = 'http://example.com/path?client_id=abc&scope=openid+test_scope&response_type=code&claims=%s'

        h, b, s = self.server.create_authorization_response(
            uri % claims_urlquoted, scopes='openid test_scope')

        self.assertDictEqual(self.claims_from_auth_code_request, claims)

        code = get_query_credentials(h['Location'])['code'][0]
        token_uri = 'http://example.com/path'
        _, body, _ = self.server.create_token_response(
            token_uri, body='grant_type=authorization_code&code=%s' % code)

        self.assertDictEqual(self.claims_saved_with_bearer_token, claims)

    def test_invalid_claims(self):
        uri = 'http://example.com/path?client_id=abc&scope=openid+test_scope&response_type=code&claims=this-is-not-json'

        h, b, s = self.server.create_authorization_response(
            uri, scopes='openid test_scope')
        error = get_query_credentials(h['Location'])['error'][0]
        error_desc = get_query_credentials(
            h['Location'])['error_description'][0]
        self.assertEqual(error, 'invalid_request')
        self.assertEqual(error_desc, "Malformed claims parameter")
Ejemplo n.º 36
0
class TestClaimsHandling(TestCase):

    DEFAULT_REDIRECT_URI = 'http://i.b./path'

    def set_scopes(self, scopes):
        def set_request_scopes(client_id, code, client, request):
            request.scopes = scopes
            return True
        return set_request_scopes

    def set_user(self, request):
        request.user = '******'
        request.client_id = 'bar'
        request.client = mock.MagicMock()
        request.client.client_id = 'mocked'
        return True

    def set_client(self, request):
        request.client = mock.MagicMock()
        request.client.client_id = 'mocked'
        return True

    def save_claims_with_code(self, client_id, code, request, *args, **kwargs):
        # a real validator would save the claims with the code during save_authorization_code()
        self.claims_from_auth_code_request = request.claims
        self.scopes = request.scopes.split()

    def retrieve_claims_saved_with_code(self, client_id, code, client, request, *args, **kwargs):
        request.claims = self.claims_from_auth_code_request
        request.scopes = self.scopes

        return True

    def save_claims_with_bearer_token(self, token, request, *args, **kwargs):
        # a real validator would save the claims with the access token during save_bearer_token()
        self.claims_saved_with_bearer_token = request.claims

    def setUp(self):
        self.validator = mock.MagicMock(spec=RequestValidator)
        self.validator.get_default_redirect_uri.return_value = TestClaimsHandling.DEFAULT_REDIRECT_URI
        self.validator.authenticate_client.side_effect = self.set_client

        self.validator.save_authorization_code.side_effect = self.save_claims_with_code
        self.validator.validate_code.side_effect = self.retrieve_claims_saved_with_code
        self.validator.save_token.side_effect = self.save_claims_with_bearer_token

        self.server = Server(self.validator)

    def test_claims_stored_on_code_creation(self):

        claims = {
            "id_token": {
                "claim_1": None,
                "claim_2": {
                    "essential": True
                }
            },
            "userinfo": {
                "claim_3": {
                    "essential": True
                },
                "claim_4": None
            }
        }

        claims_urlquoted='%7B%22id_token%22%3A%20%7B%22claim_2%22%3A%20%7B%22essential%22%3A%20true%7D%2C%20%22claim_1%22%3A%20null%7D%2C%20%22userinfo%22%3A%20%7B%22claim_4%22%3A%20null%2C%20%22claim_3%22%3A%20%7B%22essential%22%3A%20true%7D%7D%7D'
        uri = 'http://example.com/path?client_id=abc&scope=openid+test_scope&response_type=code&claims=%s'

        h, b, s = self.server.create_authorization_response(uri % claims_urlquoted, scopes='openid test_scope')

        self.assertDictEqual(self.claims_from_auth_code_request, claims)

        code = get_query_credentials(h['Location'])['code'][0]
        token_uri = 'http://example.com/path'
        _, body, _ = self.server.create_token_response(token_uri,
                                                    body='grant_type=authorization_code&code=%s' % code)

        self.assertDictEqual(self.claims_saved_with_bearer_token, claims)

    def test_invalid_claims(self):
        uri = 'http://example.com/path?client_id=abc&scope=openid+test_scope&response_type=code&claims=this-is-not-json'

        h, b, s = self.server.create_authorization_response(uri, scopes='openid test_scope')
        error = get_query_credentials(h['Location'])['error'][0]
        error_desc = get_query_credentials(h['Location'])['error_description'][0]
        self.assertEqual(error, 'invalid_request')
        self.assertEqual(error_desc, "Malformed claims parameter")
Ejemplo n.º 37
0
class TestScopeHandling(TestCase):

    DEFAULT_REDIRECT_URI = 'http://i.b./path'

    def set_scopes(self, scopes):
        def set_request_scopes(client_id, code, client, request):
            request.scopes = scopes
            return True
        return set_request_scopes

    def set_user(self, request):
        request.user = '******'
        request.client_id = 'bar'
        request.client = mock.MagicMock()
        request.client.client_id = 'mocked'
        return True

    def set_client(self, request):
        request.client = mock.MagicMock()
        request.client.client_id = 'mocked'
        return True

    def setUp(self):
        self.validator = mock.MagicMock(spec=RequestValidator)
        self.validator.get_default_redirect_uri.return_value = TestScopeHandling.DEFAULT_REDIRECT_URI
        self.validator.authenticate_client.side_effect = self.set_client
        self.server = Server(self.validator)
        self.web = WebApplicationServer(self.validator)
        self.mobile = MobileApplicationServer(self.validator)
        self.legacy = LegacyApplicationServer(self.validator)
        self.backend = BackendApplicationServer(self.validator)

    def test_scope_extraction(self):
        scopes = (
            ('images', ['images']),
            ('images+videos', ['images', 'videos']),
            ('images+videos+openid', ['images', 'videos', 'openid']),
            ('http%3A%2f%2fa.b%2fvideos', ['http://a.b/videos']),
            ('http%3A%2f%2fa.b%2fvideos+pics', ['http://a.b/videos', 'pics']),
            ('pics+http%3A%2f%2fa.b%2fvideos', ['pics', 'http://a.b/videos']),
            ('http%3A%2f%2fa.b%2fvideos+https%3A%2f%2fc.d%2Fsecret', ['http://a.b/videos', 'https://c.d/secret']),
        )

        uri = 'http://example.com/path?client_id=abc&scope=%s&response_type=%s'
        for scope, correct_scopes in scopes:
            scopes, _ = self.web.validate_authorization_request(
                    uri % (scope, 'code'))
            self.assertItemsEqual(scopes, correct_scopes)
            scopes, _ = self.mobile.validate_authorization_request(
                    uri % (scope, 'token'))
            self.assertItemsEqual(scopes, correct_scopes)
            scopes, _ = self.server.validate_authorization_request(
                uri % (scope, 'code'))
            self.assertItemsEqual(scopes, correct_scopes)

    def test_scope_preservation(self):
        scope = 'pics+http%3A%2f%2fa.b%2fvideos'
        decoded_scope = 'pics http://a.b/videos'
        auth_uri = 'http://example.com/path?client_id=abc&response_type='
        token_uri = 'http://example.com/path'

        # authorization grant
        for backend_server_type in ['web', 'server']:
            h, _, s = getattr(self, backend_server_type).create_authorization_response(
                    auth_uri + 'code', scopes=decoded_scope.split(' '))
            self.validator.validate_code.side_effect = self.set_scopes(decoded_scope.split(' '))
            self.assertEqual(s, 302)
            self.assertIn('Location', h)
            code = get_query_credentials(h['Location'])['code'][0]
            _, body, _ = getattr(self, backend_server_type).create_token_response(token_uri,
                    body='grant_type=authorization_code&code=%s' % code)
            self.assertEqual(json.loads(body)['scope'], decoded_scope)

        # implicit grant
        for backend_server_type in ['mobile', 'server']:
            h, _, s = getattr(self, backend_server_type).create_authorization_response(
                    auth_uri + 'token', scopes=decoded_scope.split(' '))
            self.assertEqual(s, 302)
            self.assertIn('Location', h)
            self.assertEqual(get_fragment_credentials(h['Location'])['scope'][0], decoded_scope)

        # resource owner password credentials grant
        for backend_server_type in ['legacy', 'server']:
            body = 'grant_type=password&username=abc&password=secret&scope=%s'

            _, body, _ = getattr(self, backend_server_type).create_token_response(token_uri,
                    body=body % scope)
            self.assertEqual(json.loads(body)['scope'], decoded_scope)

        # client credentials grant
        for backend_server_type in ['backend', 'server']:
            body = 'grant_type=client_credentials&scope=%s'
            self.validator.authenticate_client.side_effect = self.set_user
            _, body, _ = getattr(self, backend_server_type).create_token_response(token_uri,
                    body=body % scope)
            self.assertEqual(json.loads(body)['scope'], decoded_scope)

    def test_scope_changed(self):
        scope = 'pics+http%3A%2f%2fa.b%2fvideos'
        scopes = ['images', 'http://a.b/videos']
        decoded_scope = 'images http://a.b/videos'
        auth_uri = 'http://example.com/path?client_id=abc&response_type='
        token_uri = 'http://example.com/path'

        # authorization grant
        h, _, s = self.web.create_authorization_response(
                auth_uri + 'code', scopes=scopes)
        self.assertEqual(s, 302)
        self.assertIn('Location', h)
        code = get_query_credentials(h['Location'])['code'][0]
        self.validator.validate_code.side_effect = self.set_scopes(scopes)
        _, body, _ = self.web.create_token_response(token_uri,
                body='grant_type=authorization_code&code=%s' % code)
        self.assertEqual(json.loads(body)['scope'], decoded_scope)

        # implicit grant
        self.validator.validate_scopes.side_effect = self.set_scopes(scopes)
        h, _, s = self.mobile.create_authorization_response(
                auth_uri + 'token', scopes=scopes)
        self.assertEqual(s, 302)
        self.assertIn('Location', h)
        self.assertEqual(get_fragment_credentials(h['Location'])['scope'][0], decoded_scope)

        # resource owner password credentials grant
        self.validator.validate_scopes.side_effect = self.set_scopes(scopes)
        body = 'grant_type=password&username=abc&password=secret&scope=%s'
        _, body, _ = self.legacy.create_token_response(token_uri,
                body=body % scope)
        self.assertEqual(json.loads(body)['scope'], decoded_scope)

        # client credentials grant
        self.validator.validate_scopes.side_effect = self.set_scopes(scopes)
        self.validator.authenticate_client.side_effect = self.set_user
        body = 'grant_type=client_credentials&scope=%s'
        _, body, _ = self.backend.create_token_response(token_uri,
                body=body % scope)

        self.assertEqual(json.loads(body)['scope'], decoded_scope)

    def test_invalid_scope(self):
        scope = 'pics+http%3A%2f%2fa.b%2fvideos'
        auth_uri = 'http://example.com/path?client_id=abc&response_type='
        token_uri = 'http://example.com/path'

        self.validator.validate_scopes.return_value = False

        # authorization grant
        h, _, s = self.web.create_authorization_response(
                auth_uri + 'code', scopes=['invalid'])
        self.assertEqual(s, 302)
        self.assertIn('Location', h)
        error = get_query_credentials(h['Location'])['error'][0]
        self.assertEqual(error, 'invalid_scope')

        # implicit grant
        h, _, s = self.mobile.create_authorization_response(
                auth_uri + 'token', scopes=['invalid'])
        self.assertEqual(s, 302)
        self.assertIn('Location', h)
        error = get_fragment_credentials(h['Location'])['error'][0]
        self.assertEqual(error, 'invalid_scope')

        # resource owner password credentials grant
        body = 'grant_type=password&username=abc&password=secret&scope=%s'
        _, body, _ = self.legacy.create_token_response(token_uri,
                body=body % scope)
        self.assertEqual(json.loads(body)['error'], 'invalid_scope')

        # client credentials grant
        self.validator.authenticate_client.side_effect = self.set_user
        body = 'grant_type=client_credentials&scope=%s'
        _, body, _ = self.backend.create_token_response(token_uri,
                body=body % scope)
        self.assertEqual(json.loads(body)['error'], 'invalid_scope')
Ejemplo n.º 38
0
 def __init__(self, validator: OauthlibRequestValidator):
     self._server = Server(validator)
Ejemplo n.º 39
0
 def __init__(self, request):
     self.request = request
     self.validator = RequestValidator()
     self.server = Server(self.validator)