1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from unittest import mock
from oauthlib.common import Request
from oauthlib.oauth2.rfc6749 import errors
from oauthlib.oauth2.rfc6749.tokens import BearerToken
from oauthlib.openid.connect.core.grant_types.exceptions import OIDCNoPrompt
from oauthlib.openid.connect.core.grant_types.implicit import ImplicitGrant
from tests.oauth2.rfc6749.grant_types.test_implicit import ImplicitGrantTest
from tests.unittest import TestCase
from .test_authorization_code import get_id_token_mock
class OpenIDImplicitInterferenceTest(ImplicitGrantTest):
"""Test that OpenID don't interfere with normal OAuth 2 flows."""
def setUp(self):
super(OpenIDImplicitInterferenceTest, self).setUp()
self.auth = ImplicitGrant(request_validator=self.mock_validator)
class OpenIDImplicitTest(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.response_type = 'id_token token'
self.request.redirect_uri = 'https://a.b/cb'
self.request.state = 'abc'
self.request.nonce = 'xyz'
self.mock_validator = mock.MagicMock()
self.mock_validator.get_id_token.side_effect = get_id_token_mock
self.auth = ImplicitGrant(request_validator=self.mock_validator)
token = 'MOCKED_TOKEN'
self.url_query = 'https://a.b/cb?state=abc&token_type=Bearer&expires_in=3600&scope=hello+openid&access_token=abc&id_token=%s' % token
self.url_fragment = 'https://a.b/cb#state=abc&token_type=Bearer&expires_in=3600&scope=hello+openid&access_token=abc&id_token=%s' % token
@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_fragment, parse_fragment=True)
self.assertEqual(b, None)
self.assertEqual(s, 302)
self.request.response_type = 'id_token'
token = 'MOCKED_TOKEN'
url = 'https://a.b/cb#state=abc&id_token=%s' % token
h, b, s = self.auth.create_authorization_response(self.request, bearer)
self.assertURLEqual(h['Location'], url, 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)
bearer = BearerToken(self.mock_validator)
self.request.id_token_hint = 'me@email.com'
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)
# Test alernative response modes
self.request.response_mode = 'query'
h, b, s = self.auth.create_authorization_response(self.request, bearer)
self.assertURLEqual(h['Location'], self.url_query)
# 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'])
@mock.patch('oauthlib.common.generate_token')
def test_required_nonce(self, generate_token):
generate_token.return_value = 'abc'
self.request.nonce = None
self.assertRaises(errors.InvalidRequestError, self.auth.validate_authorization_request, self.request)
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)
class OpenIDImplicitNoAccessTokenTest(OpenIDImplicitTest):
def setUp(self):
super(OpenIDImplicitNoAccessTokenTest, self).setUp()
self.request.response_type = 'id_token'
token = 'MOCKED_TOKEN'
self.url_query = 'https://a.b/cb?state=abc&id_token=%s' % token
self.url_fragment = 'https://a.b/cb#state=abc&id_token=%s' % token
@mock.patch('oauthlib.common.generate_token')
def test_required_nonce(self, generate_token):
generate_token.return_value = 'abc'
self.request.nonce = None
self.assertRaises(errors.InvalidRequestError, self.auth.validate_authorization_request, self.request)
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)
|