def setUp(self): self.mock_validator = mock.MagicMock() self.addCleanup(setattr, self, 'mock_validator', mock.MagicMock()) auth_code = AuthorizationCodeGrant( request_validator=self.mock_validator) auth_code.save_authorization_code = mock.MagicMock() implicit = ImplicitGrant(request_validator=self.mock_validator) implicit.save_token = mock.MagicMock() openid_connect_auth = OpenIDConnectAuthCode(self.mock_validator) openid_connect_implicit = OpenIDConnectImplicit(self.mock_validator) response_types = { 'code': auth_code, 'token': implicit, 'id_token': openid_connect_implicit, 'id_token token': openid_connect_implicit, 'code token': openid_connect_auth, 'code id_token': openid_connect_auth, 'code token id_token': openid_connect_auth, 'none': auth_code } self.expires_in = 1800 token = tokens.BearerToken(self.mock_validator, expires_in=self.expires_in) self.endpoint = AuthorizationEndpoint(default_response_type='code', default_token_type=token, response_types=response_types)
def __init__(self, request_validator, token_generator=None, token_expires_in=None, refresh_token_generator=None, **kwargs): """Construct a new web application server. :param request_validator: An implementation of oauthlib.oauth2.RequestValidator. :param token_expires_in: An int or a function to generate a token expiration offset (in seconds) given a oauthlib.common.Request object. :param token_generator: A function to generate a token from a request. :param refresh_token_generator: A function to generate a token from a request for the refresh token. :param kwargs: Extra parameters to pass to authorization-, token-, resource-, and revocation-endpoint constructors. """ implicit_grant = ImplicitGrant(request_validator) auth_grant = AuthorizationCodeGrant(request_validator) refresh_grant = RefreshTokenGrant(request_validator) openid_connect_auth = OpenIDConnectAuthCode(request_validator) resource_owner_password_credentials_grant = ResourceOwnerPasswordCredentialsGrant( request_validator) bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) AuthorizationEndpoint.__init__(self, default_response_type='code', response_types={ 'code': auth_grant, 'code+token': openid_connect_auth, 'code+id_token': openid_connect_auth, 'code+token+id_token': openid_connect_auth, 'code token': openid_connect_auth, 'code id_token': openid_connect_auth, 'code token id_token': openid_connect_auth, 'token': implicit_grant }, default_token_type=bearer) TokenEndpoint.__init__(self, default_grant_type='authorization_code', grant_types={ 'authorization_code': auth_grant, 'refresh_token': refresh_grant, 'password': resource_owner_password_credentials_grant }, default_token_type=bearer) ResourceEndpoint.__init__(self, default_token='Bearer', token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator)
def setUp(self): self.request = Request('http://a.b/path') self.request.scopes = ('hello', 'openid') self.request.expires_in = 1800 self.request.client_id = 'abcdef' self.request.code = '1234' self.request.response_type = 'code' self.request.grant_type = 'authorization_code' self.request.redirect_uri = 'https://a.b/cb' self.request.state = 'abc' self.mock_validator = mock.MagicMock() self.mock_validator.authenticate_client.side_effect = self.set_client self.mock_validator.get_id_token.side_effect = get_id_token_mock self.auth = OpenIDConnectAuthCode(request_validator=self.mock_validator) self.url_query = 'https://a.b/cb?code=abc&state=abc' self.url_fragment = 'https://a.b/cb#code=abc&state=abc'
def setUp(self): self.request = Request('http://a.b/path') self.request.decoded_body = ( ("client_id", "me"), ("code", "code"), ("redirect_url", "https://a.b/cb"), ) self.request_validator = mock.MagicMock() self.auth_grant = AuthorizationCodeGrant(self.request_validator) self.openid_connect_auth = OpenIDConnectAuthCode( self.request_validator)
def setUp(self): self.mock_validator = mock.MagicMock() self.mock_validator.authenticate_client.side_effect = self.set_client grant = OpenIDConnectAuthCode(request_validator=self.mock_validator) bearer = BearerToken(self.mock_validator) self.endpoint = AuthorizationEndpoint(grant, bearer, response_types={'code': grant}) params = { 'prompt': 'consent', 'state': 'abc', 'redirect_uri': 'https://a.b/cb', 'response_type': 'code', 'client_id': 'abcdef', 'scope': 'hello openid' } self.url = 'http://a.b/path?' + urlencode(params)
class OpenIDAuthCodeTest(TestCase): def setUp(self): self.request = Request('http://a.b/path') self.request.scopes = ('hello', 'openid') self.request.expires_in = 1800 self.request.client_id = 'abcdef' self.request.code = '1234' self.request.response_type = 'code' self.request.grant_type = 'authorization_code' self.request.redirect_uri = 'https://a.b/cb' self.request.state = 'abc' self.mock_validator = mock.MagicMock() self.mock_validator.authenticate_client.side_effect = self.set_client self.mock_validator.get_id_token.side_effect = get_id_token_mock self.auth = OpenIDConnectAuthCode(request_validator=self.mock_validator) self.url_query = 'https://a.b/cb?code=abc&state=abc' self.url_fragment = 'https://a.b/cb#code=abc&state=abc' def set_client(self, request): request.client = mock.MagicMock() request.client.client_id = 'mocked' return True @mock.patch('oauthlib.common.generate_token') def test_authorization(self, generate_token): scope, info = self.auth.validate_authorization_request(self.request) generate_token.return_value = 'abc' bearer = BearerToken(self.mock_validator) h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertURLEqual(h['Location'], self.url_query) self.assertEqual(b, None) self.assertEqual(s, 302) @mock.patch('oauthlib.common.generate_token') def test_no_prompt_authorization(self, generate_token): generate_token.return_value = 'abc' scope, info = self.auth.validate_authorization_request(self.request) self.request.prompt = 'none' self.assertRaises(OIDCNoPrompt, self.auth.validate_authorization_request, self.request) # prompt == none requires id token hint bearer = BearerToken(self.mock_validator) h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=invalid_request', h['Location']) self.assertEqual(b, None) self.assertEqual(s, 302) self.request.id_token_hint = '*****@*****.**' h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertURLEqual(h['Location'], self.url_query) self.assertEqual(b, None) self.assertEqual(s, 302) # Test alernative response modes self.request.response_mode = 'fragment' h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertURLEqual(h['Location'], self.url_fragment, parse_fragment=True) # Ensure silent authentication and authorization is done self.mock_validator.validate_silent_login.return_value = False self.mock_validator.validate_silent_authorization.return_value = True h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=login_required', h['Location']) self.mock_validator.validate_silent_login.return_value = True self.mock_validator.validate_silent_authorization.return_value = False h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=consent_required', h['Location']) # ID token hint must match logged in user self.mock_validator.validate_silent_authorization.return_value = True self.mock_validator.validate_user_match.return_value = False h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=login_required', h['Location']) def set_scopes(self, client_id, code, client, request): request.scopes = self.request.scopes request.state = self.request.state request.user = '******' return True def test_create_token_response(self): self.request.response_type = None self.mock_validator.validate_code.side_effect = self.set_scopes bearer = BearerToken(self.mock_validator) h, token, s = self.auth.create_token_response(self.request, bearer) token = json.loads(token) self.assertEqual(self.mock_validator.save_token.call_count, 1) self.assertIn('access_token', token) self.assertIn('refresh_token', token) self.assertIn('expires_in', token) self.assertIn('scope', token) self.assertIn('id_token', token) self.assertIn('openid', token['scope']) self.mock_validator.reset_mock() self.request.scopes = ('hello', 'world') h, token, s = self.auth.create_token_response(self.request, bearer) token = json.loads(token) self.assertEqual(self.mock_validator.save_token.call_count, 1) self.assertIn('access_token', token) self.assertIn('refresh_token', token) self.assertIn('expires_in', token) self.assertIn('scope', token) self.assertNotIn('id_token', token) self.assertNotIn('openid', token['scope'])
def __init__(self, request_validator, token_expires_in=None, token_generator=None, refresh_token_generator=None, *args, **kwargs): """Construct a new all-grants-in-one server. :param request_validator: An implementation of oauthlib.oauth2.RequestValidator. :param token_expires_in: An int or a function to generate a token expiration offset (in seconds) given a oauthlib.common.Request object. :param token_generator: A function to generate a token from a request. :param refresh_token_generator: A function to generate a token from a request for the refresh token. :param kwargs: Extra parameters to pass to authorization-, token-, resource-, and revocation-endpoint constructors. """ auth_grant = AuthorizationCodeGrant(request_validator) implicit_grant = ImplicitGrant(request_validator) password_grant = ResourceOwnerPasswordCredentialsGrant( request_validator) credentials_grant = ClientCredentialsGrant(request_validator) refresh_grant = RefreshTokenGrant(request_validator) openid_connect_auth = OpenIDConnectAuthCode(request_validator) openid_connect_implicit = OpenIDConnectImplicit(request_validator) bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) auth_grant_choice = AuthCodeGrantDispatcher( default_auth_grant=auth_grant, oidc_auth_grant=openid_connect_auth) # See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#Combinations for valid combinations # noqa # internally our AuthorizationEndpoint will ensure they can appear in any order for any valid combination # noqa AuthorizationEndpoint.__init__( self, default_response_type='code', response_types={ 'code': auth_grant_choice, 'token': implicit_grant, 'id_token': openid_connect_implicit, 'id_token token': openid_connect_implicit, 'code token': openid_connect_auth, 'code id_token': openid_connect_auth, 'code token id_token': openid_connect_auth, 'none': auth_grant }, default_token_type=bearer) TokenEndpoint.__init__( self, default_grant_type='authorization_code', grant_types={ 'authorization_code': openid_connect_auth, 'password': password_grant, 'client_credentials': credentials_grant, 'refresh_token': refresh_grant, 'openid': openid_connect_auth }, default_token_type=bearer) ResourceEndpoint.__init__( self, default_token='Bearer', token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator)
class OpenIDAuthCodeTest(TestCase): def setUp(self): self.request = Request('http://a.b/path') self.request.scopes = ('hello', 'openid') self.request.expires_in = 1800 self.request.client_id = 'abcdef' self.request.code = '1234' self.request.response_type = 'code' self.request.grant_type = 'authorization_code' self.request.redirect_uri = 'https://a.b/cb' self.request.state = 'abc' self.mock_validator = mock.MagicMock() self.mock_validator.authenticate_client.side_effect = self.set_client self.mock_validator.get_id_token.side_effect = get_id_token_mock self.auth = OpenIDConnectAuthCode(request_validator=self.mock_validator) self.url_query = 'https://a.b/cb?code=abc&state=abc' self.url_fragment = 'https://a.b/cb#code=abc&state=abc' def set_client(self, request): request.client = mock.MagicMock() request.client.client_id = 'mocked' return True @mock.patch('oauthlib.common.generate_token') def test_authorization(self, generate_token): scope, info = self.auth.validate_authorization_request(self.request) generate_token.return_value = 'abc' bearer = BearerToken(self.mock_validator) self.request.response_mode = 'query' h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertURLEqual(h['Location'], self.url_query) self.assertEqual(b, None) self.assertEqual(s, 302) self.request.response_mode = 'fragment' h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertURLEqual(h['Location'], self.url_fragment, parse_fragment=True) self.assertEqual(b, None) self.assertEqual(s, 302) @mock.patch('oauthlib.common.generate_token') def test_no_prompt_authorization(self, generate_token): generate_token.return_value = 'abc' scope, info = self.auth.validate_authorization_request(self.request) self.request.prompt = 'none' self.assertRaises(OIDCNoPrompt, self.auth.validate_authorization_request, self.request) # prompt == none requires id token hint bearer = BearerToken(self.mock_validator) h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=invalid_request', h['Location']) self.assertEqual(b, None) self.assertEqual(s, 302) self.request.response_mode = 'query' self.request.id_token_hint = '*****@*****.**' h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertURLEqual(h['Location'], self.url_query) self.assertEqual(b, None) self.assertEqual(s, 302) # Test alernative response modes self.request.response_mode = 'fragment' h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertURLEqual(h['Location'], self.url_fragment, parse_fragment=True) # Ensure silent authentication and authorization is done self.mock_validator.validate_silent_login.return_value = False self.mock_validator.validate_silent_authorization.return_value = True h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=login_required', h['Location']) self.mock_validator.validate_silent_login.return_value = True self.mock_validator.validate_silent_authorization.return_value = False h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=consent_required', h['Location']) # ID token hint must match logged in user self.mock_validator.validate_silent_authorization.return_value = True self.mock_validator.validate_user_match.return_value = False h, b, s = self.auth.create_authorization_response(self.request, bearer) self.assertIn('error=login_required', h['Location']) def set_scopes(self, client_id, code, client, request): request.scopes = self.request.scopes request.state = self.request.state request.user = '******' return True def test_create_token_response(self): self.request.response_type = None self.mock_validator.validate_code.side_effect = self.set_scopes bearer = BearerToken(self.mock_validator) h, token, s = self.auth.create_token_response(self.request, bearer) token = json.loads(token) self.assertEqual(self.mock_validator.save_token.call_count, 1) self.assertIn('access_token', token) self.assertIn('refresh_token', token) self.assertIn('expires_in', token) self.assertIn('scope', token) self.assertIn('id_token', token) self.assertIn('openid', token['scope']) self.mock_validator.reset_mock() self.request.scopes = ('hello', 'world') h, token, s = self.auth.create_token_response(self.request, bearer) token = json.loads(token) self.assertEqual(self.mock_validator.save_token.call_count, 1) self.assertIn('access_token', token) self.assertIn('refresh_token', token) self.assertIn('expires_in', token) self.assertIn('scope', token) self.assertNotIn('id_token', token) self.assertNotIn('openid', token['scope'])
def setUp(self): super(OpenIDAuthCodeInterferenceTest, self).setUp() self.auth = OpenIDConnectAuthCode(request_validator=self.mock_validator)