def test_no_response_type_in_post(self): create_and_login_user(self.testapp) _, app_id, _ = create_client() res = self.testapp.get( '/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': app_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res = self.testapp.post( '/oauth2/endpoints/authorization', { 'submit': 'Authorize', # missing response_type 'client_id': app_id, 'redirect_uri': 'https://example.com/callback', 'scope': 'read-passwords', }, status=302) self.assertEqual(res.status, '302 Found') self._assert_error(res.location, 'invalid_request', 'Missing response_type parameter.')
def test_valid_request(self): _, user_id = create_and_login_user(self.testapp) _, application_id, application_secret = create_client() # First authorize the app res = self.testapp.get( '/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res = self.testapp.post( '/oauth2/endpoints/authorization', { 'submit': 'Authorize', 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', 'scope': 'read-passwords', }) self.assertEqual(res.status, '302 Found') grant = Session.query(AuthorizationCode).filter( AuthorizationCode.application_id == application_id, AuthorizationCode.user_id == user_id, ).one() code = grant.code # now send the token request headers = { 'Authorization': auth_basic_encode(application_id, application_secret), } res = self.testapp.post('/oauth2/endpoints/token', { 'grant_type': 'authorization_code', 'code': code, }, headers=headers) self.assertEqual(res.status, '200 OK') self.assertEqual(res.headers['Cache-Control'], 'no-store') self.assertEqual(res.headers['Pragma'], 'no-cache') # the grant code should be removed try: grant = Session.query(AuthorizationCode).filter( AuthorizationCode.application_id == application_id, AuthorizationCode.user_id == user_id, ).one() except NoResultFound: grant = None self.assertEqual(grant, None) # and an access token should be created self.assertEqual(res.json['token_type'], 'Bearer') self.assertEqual(res.json['expires_in'], 3600) access_code = Session.query(AccessCode).filter( AccessCode.code == res.json['access_token'], ).one() self.assertNotEqual(access_code, None)
def test_valid_request(self): _, user_id = create_and_login_user(self.testapp) _, application_id, application_secret = create_client() # First authorize the app res = self.testapp.get('/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res = self.testapp.post('/oauth2/endpoints/authorization', { 'submit': 'Authorize', 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', 'scope': 'read-passwords', }) self.assertEqual(res.status, '302 Found') grant = Session.query(AuthorizationCode).filter( AuthorizationCode.application_id == application_id, AuthorizationCode.user_id == user_id, ).one() code = grant.code # now send the token request headers = { 'Authorization': auth_basic_encode(application_id, application_secret), } res = self.testapp.post('/oauth2/endpoints/token', { 'grant_type': 'authorization_code', 'code': code, }, headers=headers) self.assertEqual(res.status, '200 OK') self.assertEqual(res.headers['Cache-Control'], 'no-store') self.assertEqual(res.headers['Pragma'], 'no-cache') # the grant code should be removed try: grant = Session.query(AuthorizationCode).filter( AuthorizationCode.application_id == application_id, AuthorizationCode.user_id == user_id, ).one() except NoResultFound: grant = None self.assertEqual(grant, None) # and an access token should be created self.assertEqual(res.json['token_type'], 'Bearer') self.assertEqual(res.json['expires_in'], 3600) access_code = Session.query(AccessCode).filter( AccessCode.code == res.json['access_token'], ).one() self.assertNotEqual(access_code, None)
def test_no_response_type(self): create_and_login_user(self.testapp) _, app_id, _ = create_client() res = self.testapp.get('/oauth2/endpoints/authorization', { 'client_id': app_id, }, status=302) self.assertEqual(res.status, '302 Found') self._assert_error(res.location, 'invalid_request', 'Missing response_type parameter.')
def test_invalid_redirect_callback(self): create_and_login_user(self.testapp) _, app_id, _ = create_client() res = self.testapp.get('/oauth2/endpoints/authorization', { 'client_id': app_id, 'response_type': 'code', 'redirect_uri': 'https://example.com/bad-callback', }, status=400) self.assertEqual(res.status, '400 Bad Request') res.mustcontain('Error is: mismatching_redirect_uri')
def test_usupported_grant_type(self): _, app_id, app_secret = create_client() headers = { 'Authorization': auth_basic_encode(app_id, app_secret), } res = self.testapp.post('/oauth2/endpoints/token', { 'grant_type': 'foo', }, headers=headers, status=400) self.assertEqual(res.json, { 'error': 'unsupported_grant_type' })
def test_bad_client_secret(self): _, app_id, _ = create_client() headers = { 'Authorization': auth_basic_encode(app_id, 'secret'), } res = self.testapp.post('/oauth2/endpoints/token', { 'grant_type': 'password', }, headers=headers, status=401) self.assertEqual(res.json, { 'error': 'invalid_client' })
def test_already_authorized_app(self): _, user_id = create_and_login_user(self.testapp) _, application_id, _ = create_client() count = Session.query(AuthorizedApplication).filter( AuthorizedApplication.user_id == user_id, ).count() self.assertEqual(count, 0) # do an initial authorization res = self.testapp.get('/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res = self.testapp.post('/oauth2/endpoints/authorization', { 'submit': 'Authorize', 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', 'scope': 'read-passwords', }) self.assertEqual(res.status, '302 Found') count = Session.query(AuthorizedApplication).filter( AuthorizedApplication.user_id == user_id, ).count() self.assertEqual(count, 1) # Now do a second authorization res = self.testapp.get('/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '302 Found') count = Session.query(AuthorizedApplication).filter( AuthorizedApplication.user_id == user_id, ).count() self.assertEqual(count, 1) grants = Session.query(AuthorizationCode).filter( AuthorizationCode.application_id == application_id, AuthorizationCode.user_id == user_id, ) # There are two grants now self.assertEqual(grants.count(), 2) code = grants.all()[1].code location = 'https://example.com/callback?code=%s' % code self.assertEqual(res.location, location)
def test_non_authorized_app_yet(self): _, user_id = create_and_login_user(self.testapp) _, application_id, _ = create_client() count = Session.query(AuthorizedApplication).filter( AuthorizedApplication.user_id == user_id, ).count() self.assertEqual(count, 0) res = self.testapp.get('/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res.mustcontain('Authorize Application') res.mustcontain('Permissions:') res.mustcontain('Access your passwords') res.mustcontain('Allow access') res.mustcontain('No, thanks') res.mustcontain('You can revoke this authorization in the future.') res = self.testapp.post('/oauth2/endpoints/authorization', { 'submit': 'Authorize', 'response_type': 'code', 'client_id': application_id, 'redirect_uri': 'https://example.com/callback', 'scope': 'read-passwords', }) self.assertEqual(res.status, '302 Found') # Check that the app is authorized now query = Session.query(AuthorizedApplication).filter( AuthorizedApplication.user_id == user_id, ) self.assertEqual(query.count(), 1) auth = query[0] self.assertEqual(auth.redirect_uri, 'https://example.com/callback') self.assertEqual(auth.response_type, 'code') self.assertEqual(auth.application.id, application_id) self.assertEqual(auth.scope, ['read-passwords']) self.assertEqual(auth.user_id, user_id) self.assertEqual(auth.application_id, application_id) # Check the right redirect url grant = Session.query(AuthorizationCode).filter( AuthorizationCode.application_id == application_id, AuthorizationCode.user_id == user_id, ).one() self.assertEqual(grant.application.id, application_id) location = 'https://example.com/callback?code=%s' % grant.code self.assertEqual(res.location, location)
def test_invalid_code(self): _, app_id, app_secret = create_client() headers = { 'Authorization': auth_basic_encode(app_id, app_secret), } res = self.testapp.post('/oauth2/endpoints/token', { 'grant_type': 'authorization_code', 'code': 'this-code-does-not-exist', }, headers=headers, status=401) self.assertEqual(res.json, { 'error': 'invalid_grant', })
def test_missing_code(self): _, app_id, app_secret = create_client() headers = { 'Authorization': auth_basic_encode(app_id, app_secret), } res = self.testapp.post('/oauth2/endpoints/token', { 'grant_type': 'authorization_code', }, headers=headers, status=400) self.assertEqual(res.json, { 'error': 'invalid_request', 'error_description': 'Missing code parameter.', })
def test_expired_token(self): user_id, app_id, _ = create_client() expiration = datetime.datetime(2014, 2, 23, 7, 0) access_code = AccessCode( code='1234', code_type='Bearer', expiration=expiration, scope=['scope1'], user_id=user_id, application_id=app_id, ) with transaction.manager: Session.add(access_code) Session.flush() request = FakeRequest(headers={'Authorization': 'Bearer 1234'}) self.assertRaises(HTTPUnauthorized, verify_request, request, ['scope1'])
def setUp(self): super(ViewTests, self).setUp() self.owner_id, self.app_id, _ = create_client() self.user, self.user_id = create_user() self.access_code = '1234' self.auth_header = {'Authorization': 'Bearer %s' % self.access_code} expiration = datetime.datetime(2014, 2, 23, 9, 0) access_code = AccessCode(code=self.access_code, code_type='Bearer', expiration=expiration, scope=['read-passwords', 'write-passwords'], application_id=self.app_id, user_id=self.user_id) with transaction.manager: Session.add(access_code) Session.flush()
def test_valid_user(self): user_id, app_id, _ = create_client() expiration = datetime.datetime(2014, 2, 23, 9, 0) access_code = AccessCode( code='1234', code_type='Bearer', expiration=expiration, scope=['scope1'], user_id=user_id, application_id=app_id, ) with transaction.manager: Session.add(access_code) Session.flush() request = FakeRequest(headers={'Authorization': 'Bearer 1234'}) user = verify_request(request, ['scope1']) self.assertEqual(user.id, user_id)
def test_user_cancel(self): create_and_login_user(self.testapp) _, app_id, _ = create_client() res = self.testapp.get('/oauth2/endpoints/authorization', { 'client_id': app_id, 'response_type': 'code', 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res = self.testapp.post('/oauth2/endpoints/authorization', { 'cancel': 'No thanks', 'response_type': 'code', 'client_id': app_id, 'redirect_uri': 'https://example.com/callback', 'scope': 'read-passwords', }) self.assertEqual(res.status, '302 Found') self.assertEqual(res.location, 'https://example.com/callback?error=access_denied')
def test_invalid_redirect_callback_in_post(self): create_and_login_user(self.testapp) _, app_id, _ = create_client() res = self.testapp.get('/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': app_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res = self.testapp.post('/oauth2/endpoints/authorization', { 'submit': 'Authorize', 'response_type': 'code', 'client_id': app_id, 'redirect_uri': 'https://example.malicious.com/callback', 'scope': 'read-passwords', }, status=400) self.assertEqual(res.status, '400 Bad Request') res.mustcontain('Error is: mismatching_redirect_uri')
def test_no_response_type_in_post(self): create_and_login_user(self.testapp) _, app_id, _ = create_client() res = self.testapp.get('/oauth2/endpoints/authorization', { 'response_type': 'code', 'client_id': app_id, 'redirect_uri': 'https://example.com/callback', }) self.assertEqual(res.status, '200 OK') res = self.testapp.post('/oauth2/endpoints/authorization', { 'submit': 'Authorize', # missing response_type 'client_id': app_id, 'redirect_uri': 'https://example.com/callback', 'scope': 'read-passwords', }, status=302) self.assertEqual(res.status, '302 Found') self._assert_error(res.location, 'invalid_request', 'Missing response_type parameter.')
def setUp(self): super(DecoratorsTests, self).setUp() self.owner_id, self.app_id, _ = create_client() _, self.user_id = create_user()
def setUp(self): super(RequestValidatorTests, self).setUp() self.owner_id, self.app_id, self.app_secret = create_client() _, self.user_id = create_user()