def revoke_application(request): assert_authenticated_user_is_registered(request) try: app_id = bson.ObjectId(request.matchdict['app']) except bson.errors.InvalidId: return HTTPBadRequest(body='Invalid application id') app = request.db.applications.find_one(app_id) if app is None: return HTTPNotFound() authorizator = Authorizator(request.db, app) if not authorizator.is_app_authorized(request.user): return HTTPUnauthorized() if 'submit' in request.POST: authorizator.remove_user_authorization(request.user) request.session.flash( _('The access to application ${app} has been revoked', mapping={'app': app['name']}), 'success', ) return HTTPFound( location=request.route_path('oauth2_authorized_applications')) return {'app': app}
def test_revoke_application(self): # this view required authentication res = self.testapp.get('/oauth2/applications/xxx/revoke') self.assertEqual(res.status, '200 OK') res.mustcontain('Log in') # Log in user_id = self.db.users.insert({ 'twitter_id': 'twitter1', 'screen_name': 'John Doe', 'first_name': 'John', 'last_name': 'Doe', 'email': '*****@*****.**', }) self.testapp.get('/__login/' + str(user_id)) res = self.testapp.get('/oauth2/applications/xxx/revoke', status=400) self.assertEqual(res.status, '400 Bad Request') res.mustcontain('Invalid application id') res = self.testapp.get( '/oauth2/applications/000000000000000000000000/revoke', status=404) self.assertEqual(res.status, '404 Not Found') # create a valid app app_id = self.db.applications.insert({ 'owner': bson.ObjectId(), 'name': 'Test Application', 'main_url': 'http://example.com', 'callback_url': 'http://example.com/callback', 'client_id': '123456', 'client_secret': 'secret', }) authorizator = Authorizator(self.db) credentials = { 'client_id': '123456', 'user': {'_id': user_id}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', } authorizator.store_user_authorization(['read-passwords'], credentials) res = self.testapp.get('/oauth2/applications/%s/revoke' % str(app_id)) self.assertEqual(res.status, '200 OK') res.mustcontain('Revoke authorization to application <span>Test Application</span>') res = self.testapp.post('/oauth2/applications/%s/revoke' % str(app_id), { 'submit': 'Yes, I am sure', }) self.assertEqual(res.status, '302 Found') self.assertEqual(res.location, 'http://localhost/oauth2/authorized-applications') self.assertFalse(authorizator.is_app_authorized(['read-passwords'], credentials))
def test_authorizator(self): app = {"_id": "app1"} authorizator = Authorizator(self.db, app) self.assertTrue(isinstance(authorizator.auth_codes, AuthorizationCodes)) self.assertTrue(isinstance(authorizator.access_codes, AccessCodes)) user = {"name": "John Doe", "authorized_apps": []} self.db.users.insert(user, safe=True) self.assertFalse(authorizator.is_app_authorized(user)) authorizator.store_user_authorization(user) user = self.db.users.find_one({"name": "John Doe"}) self.assertTrue(authorizator.is_app_authorized(user)) self.assertEqual(user["authorized_apps"], ["app1"]) authorizator.remove_user_authorization(user) user = self.db.users.find_one({"name": "John Doe"}) self.assertFalse(authorizator.is_app_authorized(user)) self.assertFalse("app1" in user["authorized_apps"])
def test_authorizator(self): app = {'_id': 'app1'} authorizator = Authorizator(self.db, app) self.assertTrue(isinstance(authorizator.auth_codes, AuthorizationCodes)) self.assertTrue(isinstance(authorizator.access_codes, AccessCodes)) user = {'name': 'John Doe', 'authorized_apps': []} self.db.users.insert(user, safe=True) self.assertFalse(authorizator.is_app_authorized(user)) authorizator.store_user_authorization(user) user = self.db.users.find_one({'name': 'John Doe'}) self.assertTrue(authorizator.is_app_authorized(user)) self.assertEqual(user['authorized_apps'], ['app1']) authorizator.remove_user_authorization(user) user = self.db.users.find_one({'name': 'John Doe'}) self.assertFalse(authorizator.is_app_authorized(user)) self.assertFalse('app1' in user['authorized_apps'])
class AuthorizatorTests(testing.TestCase): def setUp(self): super(AuthorizatorTests, self).setUp() self.authorizator = Authorizator(self.db) def test_is_app_authorized_no_authorized_apps(self): self.assertFalse(self.authorizator.is_app_authorized([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', })) def test_is_app_authorized_different_client_id(self): self.db.authorized_apps.insert({ 'client_id': 1, 'user': 1, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', 'scope': 'scope1 scope2', }) self.assertFalse(self.authorizator.is_app_authorized([ 'scope1', 'scope2', ], { 'client_id': 2, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', })) def test_is_app_authorized_different_user(self): self.db.authorized_apps.insert({ 'client_id': 1, 'user': 1, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', 'scope': 'scope1 scope2', }) self.assertFalse(self.authorizator.is_app_authorized([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 2}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', })) def test_is_app_authorized_different_redirect_uri(self): self.db.authorized_apps.insert({ 'client_id': 1, 'user': 1, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', 'scope': 'scope1 scope2', }) self.assertFalse(self.authorizator.is_app_authorized([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback-new', 'response_type': 'code', })) def test_is_app_authorized_different_response_type(self): self.db.authorized_apps.insert({ 'client_id': 1, 'user': 1, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', 'scope': 'scope1 scope2', }) self.assertFalse(self.authorizator.is_app_authorized([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'token', })) def test_is_app_authorized_different_scopes(self): self.db.authorized_apps.insert({ 'client_id': 1, 'user': 1, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', 'scope': 'scope1 scope2', }) self.assertFalse(self.authorizator.is_app_authorized([ 'scope1', 'scope2', 'scope3', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', })) def test_is_app_authorized_everything_equal(self): self.db.authorized_apps.insert({ 'client_id': 1, 'user': 1, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', 'scope': 'scope1 scope2', }) self.assertTrue(self.authorizator.is_app_authorized([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', })) def test_store_user_authorization_no_previous_authorization(self): self.assertEqual(self.db.authorized_apps.count(), 0) self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', }) self.assertEqual(self.db.authorized_apps.count(), 1) def test_store_user_authorization_previous_authorization(self): self.assertEqual(self.db.authorized_apps.count(), 0) self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', }) self.assertEqual(self.db.authorized_apps.count(), 1) # Store the same authorization again self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', }) # still only one record self.assertEqual(self.db.authorized_apps.count(), 1) def test_get_user_authorizations_empty(self): auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 0) def test_get_user_authorizations_one_authorization(self): self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', }) auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 1) self.assertEqual(auths[0]['client_id'], 1) self.assertEqual(auths[0]['redirect_uri'], 'http://example.com/callback') self.assertEqual(auths[0]['response_type'], 'code') self.assertEqual(auths[0]['scope'], 'scope1 scope2') def test_get_user_authorizations_two_authorization(self): self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', }) self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 2, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback2', 'response_type': 'code', }) self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 2, 'user': {'_id': 2}, 'redirect_uri': 'http://example.com/callback2', 'response_type': 'code', }) auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 2) self.assertEqual(auths[0]['client_id'], 1) self.assertEqual(auths[0]['redirect_uri'], 'http://example.com/callback') self.assertEqual(auths[0]['response_type'], 'code') self.assertEqual(auths[0]['scope'], 'scope1 scope2') self.assertEqual(auths[1]['client_id'], 2) self.assertEqual(auths[1]['redirect_uri'], 'http://example.com/callback2') self.assertEqual(auths[1]['response_type'], 'code') self.assertEqual(auths[1]['scope'], 'scope1 scope2') def test_remove_user_authorization(self): auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 0) self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback', 'response_type': 'code', }) auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 1) self.authorizator.remove_user_authorization({'_id': 1}, 1) auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 0) def test_remove_all_user_authorizations(self): auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 0) self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 1, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback/1', 'response_type': 'code', }) self.authorizator.store_user_authorization([ 'scope1', 'scope2', ], { 'client_id': 2, 'user': {'_id': 1}, 'redirect_uri': 'http://example.com/callback/2', 'response_type': 'code', }) auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 2) self.authorizator.remove_all_user_authorizations({'_id': 1}) auths = self.authorizator.get_user_authorizations({'_id': 1}) self.assertEqual(auths.count(), 0)
def authorization_endpoint(request): response_type = request.params.get('response_type') if response_type is None: return HTTPBadRequest('Missing required response_type') if response_type != 'code': return HTTPNotImplemented('Only code is supported') client_id = request.params.get('client_id') if client_id is None: return HTTPBadRequest('Missing required client_type') app = request.db.applications.find_one({'client_id': client_id}) if app is None: return HTTPNotFound() redirect_uri = request.params.get('redirect_uri') if redirect_uri is None: redirect_uri = app['callback_url'] else: if redirect_uri != app['callback_url']: return HTTPBadRequest( 'Redirect URI does not match registered callback URL') scope = request.params.get('scope', DEFAULT_SCOPE) state = request.params.get('state') user = assert_authenticated_user_is_registered(request) authorizator = Authorizator(request.db, app) if 'submit' in request.POST: if not authorizator.is_app_authorized(request.user): authorizator.store_user_authorization(request.user) code = authorizator.auth_codes.create( request.user['_id'], app['client_id'], scope) url = authorizator.auth_codes.get_redirect_url( code, redirect_uri, state) return HTTPFound(location=url) elif 'cancel' in request.POST: return HTTPFound(app['main_url']) else: if authorizator.is_app_authorized(user): code = authorizator.auth_codes.create( user['_id'], app['client_id'], scope) url = authorizator.auth_codes.get_redirect_url( code, redirect_uri, state) return HTTPFound(location=url) else: authorship_information = '' owner_id = app.get('owner', None) if owner_id is not None: owner = request.db.users.find_one({'_id': owner_id}) if owner: email = owner.get('email', None) if email: authorship_information = _('By ${owner}', mapping={'owner': email}) scopes = [SCOPE_NAMES.get(scope, scope) for scope in scope.split(' ')] return { 'response_type': response_type, 'client_id': client_id, 'redirect_uri': redirect_uri, 'scope': scope, 'state': state, 'app': app, 'scopes': scopes, 'authorship_information': authorship_information, }