def test_clients_two_apps(self): administrator = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') app1 = Application(name='Example app 1', main_url='https://example.com', callback_url='https://example.com/callback', image_url='https://example.com/image.png', description='example description', production_ready=True, user=administrator) app2 = Application(name='Example app 2', main_url='https://2.example.com', callback_url='https://2.example.com/callback', production_ready=False, user=administrator) with transaction.manager: Session.add(app1) Session.add(app2) Session.flush() res = self.testapp.get('/oauth2/clients') self.assertEqual(res.status, '200 OK') res.mustcontain( 'Available Clients', 'Example app 1', 'https://example.com', 'https://example.com/image.png', 'example description', no=('Example app 2', 'https://2.example.com'), )
def test_authorized_applications(self): administrator = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app1 = Application(name='Test Application 1', main_url='http://example.com/1', callback_url='http://example.com/1/callback', image_url='http://example.com/1/image.png', description='Test description 1', user=administrator) auth_app1 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/1/callback', application=app1, user=user, ) app2 = Application(name='Test Application 2', main_url='http://example.com/2', callback_url='http://example.com/2/callback', image_url='http://example.com/2/image.png', description='Test description 2', user=administrator) auth_app2 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/2/callback', application=app2, user=user, ) with transaction.manager: Session.add(user) Session.add(app1) Session.add(auth_app1) Session.add(app2) Session.add(auth_app2) Session.flush() user_id = user.id self.testapp.get('/__login/' + str(user_id)) res = self.testapp.get('/oauth2/authorized-applications') self.assertEqual(res.status, '200 OK') res.mustcontain('Authorized Applications') res.mustcontain('Test Application 1') res.mustcontain('Test Application 2')
def test_applications_list_apps_one_app(self): user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', main_url='https://example.com', callback_url='https://example.com/callback', production_ready=False) user.applications.append(app) with transaction.manager: Session.add(user) Session.flush() app_id = app.id user_id = user.id self.testapp.get('/__login/' + str(user_id)) res = self.testapp.get('/oauth2/applications') self.assertEqual(res.status, '200 OK') res.mustcontain('John') res.mustcontain('Log out') res.mustcontain('Developer Applications') res.mustcontain('Register new application') res.mustcontain(app_id) res.mustcontain('Test Application') res.mustcontain('https://example.com')
def test_application_edit_unauthorized(self): create_and_login_user(self.testapp) app = Application(name='Test Application', main_url='http://example.com', callback_url='http://example.com/callback', authorized_origins=['http://example.com', 'https://example.com'], production_ready=False, image_url='http://example.com/image.png', description='example description') other_user = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') other_user.applications.append(app) with transaction.manager: Session.add(other_user) Session.flush() app_id = app.id res = self.testapp.get('/oauth2/applications/%s/edit' % str(app_id), status=401) self.assertEqual(res.status, '401 Unauthorized')
def test_application_edit_invalid_change(self): user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', main_url='http://example.com', callback_url='http://example.com/callback', authorized_origins=['http://example.com', 'https://example.com'], production_ready=False, image_url='http://example.com/image.png', description='example description') user.applications.append(app) with transaction.manager: Session.add(user) Session.flush() app_id = app.id user_id = user.id self.testapp.get('/__login/' + str(user_id)) res = self.testapp.post('/oauth2/applications/%s/edit' % str(app_id), { 'submit': 'Save changes', }) self.assertEqual(res.status, '200 OK') res.mustcontain('There was a problem with your submission') res.mustcontain('Required')
def test_application_edit_cancel(self): user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', main_url='http://example.com', callback_url='http://example.com/callback', authorized_origins=['http://example.com', 'https://example.com'], production_ready=False, image_url='http://example.com/image.png', description='example description') user.applications.append(app) with transaction.manager: Session.add(user) Session.flush() app_id = app.id user_id = user.id self.testapp.get('/__login/' + str(user_id)) res = self.testapp.post('/oauth2/applications/%s/edit' % str(app_id), { 'cancel': 'Cancel', }) self.assertEqual(res.status, '302 Found') self.assertEqual(res.location, 'http://localhost/oauth2/applications')
def test_cors_headers_app_origins(self): cm = CORSManager('') user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', authorized_origins=['http://localhost']) user.applications.append(app) with transaction.manager: Session.add(user) Session.add(app) Session.flush() app_id = app.id request = DummyRequest(headers={'Origin': 'http://localhost'}, params={'client_id': app_id}) response = request.response cm.add_cors_header(request, response) self.assertEqual( response.headers, { 'Content-Type': 'text/html; charset=UTF-8', 'Content-Length': '0', 'Access-Control-Allow-Origin': 'http://localhost', })
def test_identity_providers_only_one_account(self): user1_id = create_and_login_user(self.testapp, email='*****@*****.**', email_verified=True) app1 = Application(name='Test Application', callback_url='https://example.com/callback/1') app2 = Application(name='Test Application', callback_url='https://example.com/callback/2') admin = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') admin.applications.append(app1) admin.applications.append(app2) auth_app1 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/1', application=app1, user_id=user1_id, ) auth_app2 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/2', application=app2, user_id=user1_id, ) password = Password(secret='s3cr3t', user_id=user1_id) with transaction.manager: Session.add(admin) Session.add(app1) Session.add(app2) Session.add(auth_app1) Session.add(auth_app2) Session.add(password) Session.flush() # one account is not enough for merging res = self.testapp.post('/identity-providers', { 'submit': 'Merge my accounts', }, status=400) self.assertEqual(res.status, '400 Bad Request') res.mustcontain('You do not have enough accounts to merge')
def test_revoke_application_app(self): administrator = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', main_url='http://example.com', callback_url='http://example.com/callback', user=administrator) auth_app = AuthorizedApplication( scope=['read-passwords'], response_type='code', redirect_uri='http://example.com/callback', application=app, user=user, ) with transaction.manager: Session.add(user) Session.add(app) Session.add(auth_app) Session.flush() user_id = user.id app_id = app.id self.testapp.get('/__login/' + str(user_id)) self.assertEqual(Session.query(Application).count(), 1) self.assertEqual(Session.query(AuthorizedApplication).count(), 1) 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') try: auth_app = Session.query(AuthorizedApplication).filter( AuthorizedApplication.application_id == app_id, AuthorizedApplication.user_id == user_id, ).one() except NoResultFound: auth_app = None self.assertEqual(auth_app, None) # the application should not be removed on cascade self.assertEqual(Session.query(Application).count(), 1)
def test_application_delete(self): user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', callback_url='https://example.com/callback', production_ready=False) user.applications.append(app) auth_app = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback', application=app, user=user, ) with transaction.manager: Session.add(user) Session.add(auth_app) Session.flush() app_id = app.id user_id = user.id self.testapp.get('/__login/' + str(user_id)) self.assertEqual(Session.query(Application).count(), 1) self.assertEqual(Session.query(AuthorizedApplication).count(), 1) res = self.testapp.get('/oauth2/applications/%s/delete' % str(app_id)) self.assertEqual(res.status, '200 OK') res.mustcontain('Delete Application <span>Test Application</span>') res.mustcontain('Are you sure you want to remove the application') res.mustcontain('Yes, I am sure') res.mustcontain('No, take me back to the application list') # now delete it res = self.testapp.post('/oauth2/applications/%s/delete' % str(app_id), {'submit': 'Yes, I am sure'}) self.assertEqual(res.status, '302 Found') self.assertEqual(res.location, 'http://localhost/oauth2/applications') try: app = Session.query(Application).filter( Application.id == app_id).one() except NoResultFound: app = None self.assertEqual(app, None) self.assertEqual(Session.query(User).count(), 1) self.assertEqual(Session.query(Application).count(), 0) # Related authorizations should be deleted on cascade self.assertEqual(Session.query(AuthorizedApplication).count(), 0)
def test_non_empty_database(self): with transaction.manager: user = User(first_name='John', last_name='Doe', email='*****@*****.**') Session.add(user) app1 = Application(user=user, name='Test application 1', main_url='http://example.com', callback_url='http://example.com/callback') Session.add(app1) app2 = Application(user=user, name='Test application 2', main_url='http://2.example.com', callback_url='http://2.example.com/callback') Session.add(app2) sys.argv = ['notused', self.conf_file_path] sys.stdout = StringIO() result = applications() self.assertEqual(result, None) stdout = sys.stdout.getvalue() expected_output = """Test application 1 %(tab)sOwner: John Doe <*****@*****.**> %(tab)sMain URL: http://example.com %(tab)sCallback URL: http://example.com/callback %(tab)sUsers: 0 Test application 2 %(tab)sOwner: John Doe <*****@*****.**> %(tab)sMain URL: http://2.example.com %(tab)sCallback URL: http://2.example.com/callback %(tab)sUsers: 0 """ % {'tab': '\t'} self.assertEqual(stdout, expected_output)
def test_destroy_user_who_owns_application_warning_message(self): user_id = create_and_login_user(self.testapp, email='*****@*****.**', email_verified=True) app = Application(name='Test Application', callback_url='https://example.com/callback/', user_id=user_id) with transaction.manager: Session.add(app) Session.flush() res = self.testapp.get('/destroy') res.mustcontain('This account can not be destroyed') res.mustcontain('You can not destroy this account because ' 'you are the owner of an application') res.mustcontain('Please remove the application first') res.mustcontain('Go to my appplications')
def setUp(self): super(RESTViewTests, self).setUp() self.access_code = '1234' self.user_id = create_user(email='*****@*****.**', email_verified=True, allow_google_analytics=True) app = Application(name='test-app') admin = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') admin.applications.append(app) with transaction.manager: Session.add(app) Session.add(admin) Session.flush() self.application_id = app.id
def developer_application_new(request): assert_authenticated_user_is_registered(request) schema = ApplicationSchema() button1 = Button('submit', _('Save application')) button1.css_class = 'btn-primary' button2 = Button('cancel', _('Cancel')) button2.css_class = 'btn-default' form = Form(schema, buttons=(button1, button2)) if 'submit' in request.POST: controls = request.POST.items() try: appstruct = form.validate(controls) except ValidationFailure as e: return {'form': e.render()} # the data is fine, save into the db application = Application( name=appstruct['name'], main_url=appstruct['main_url'], callback_url=appstruct['callback_url'], authorized_origins=appstruct['authorized_origins'], production_ready=appstruct['production_ready'], image_url=appstruct['image_url'], description=appstruct['description'], ) request.user.applications.append(application) request.session.flash( _('The application ${app} was created successfully', mapping={'app': appstruct['name']}), 'success') Session.add(request.user) return HTTPFound( location=request.route_path('oauth2_developer_applications')) elif 'cancel' in request.POST: return HTTPFound( location=request.route_path('oauth2_developer_applications')) # this is a GET return {'form': form.render()}
def test_destroy_user_who_owns_application_error_message(self): user_id = create_and_login_user(self.testapp, email='*****@*****.**', email_verified=True) app = Application(name='Test Application', callback_url='https://example.com/callback/', user_id=user_id) with transaction.manager: Session.add(app) Session.flush() res = self.testapp.post('/destroy', { 'reason': 'I do not need a password manager', 'submit': 'Yes, I am sure. Destroy my account', }, status=302) self.assertEqual(res.location, 'http://localhost/oauth2/applications') res = self.testapp.get('/oauth2/applications') res.mustcontain('You must remove your applications before ' 'destroying your account')
def create_client(): user = User(screen_name='Administrator', first_name='Alice', last_name='Doe', email='*****@*****.**') app = Application(user=user, name='Example', main_url='https://example.com', callback_url='https://example.com/callback', image_url='https://example.com/logo.png', description='Example description') with transaction.manager: Session.add(user) Session.add(app) Session.flush() owner_id = user.id app_id = app.id app_secret = app.secret return owner_id, app_id, app_secret
def test_identity_providers_two_accounts_two_selected(self): user1_id = create_and_login_user(self.testapp, email='*****@*****.**', email_verified=True) user2_id = create_user(email='*****@*****.**', email_verified=True, provider='google', external_id='google1') app1 = Application(name='Test Application', callback_url='https://example.com/callback/1') app2 = Application(name='Test Application', callback_url='https://example.com/callback/2') app3 = Application(name='Test Application', callback_url='https://example.com/callback/3') admin = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') admin.applications.append(app1) admin.applications.append(app2) admin.applications.append(app3) auth_app1 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/1', application=app1, user_id=user1_id, ) auth_app2 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/2', application=app2, user_id=user1_id, ) auth_app3 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/2', application=app2, user_id=user2_id, ) auth_app4 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/3', application=app3, user_id=user2_id, ) password1 = Password(secret='s3cr3t', user_id=user1_id) password2 = Password(secret='s3cr3t', user_id=user2_id) with transaction.manager: Session.add(admin) Session.add(app1) Session.add(app2) Session.add(app3) Session.add(auth_app1) Session.add(auth_app2) Session.add(auth_app3) Session.add(auth_app4) Session.add(password1) Session.add(password2) Session.flush() app1_id = app1.id app2_id = app2.id app3_id = app3.id # let's merge them res = self.testapp.post('/identity-providers', { 'account-%s' % str(user1_id): 'on', 'account-%s' % str(user2_id): 'on', 'submit': 'Merge my accounts', }, status=302) self.assertEqual(res.status, '302 Found') self.assertEqual(res.location, 'http://localhost/identity-providers') # the accounts have been merged self.assertEqual(2, Session.query(User).count()) user1_refreshed = Session.query(User).filter(User.id == user1_id).one() google_identity = Session.query(ExternalIdentity).filter( ExternalIdentity.user == user1_refreshed, ExternalIdentity.provider == 'google', ).one() self.assertEqual(google_identity.external_id, 'google1') auths = Session.query(AuthorizedApplication).filter( AuthorizedApplication.user == user1_refreshed, ) client_ids = [auth_app.application.id for auth_app in auths] self.assertEqual(set(client_ids), set([app1_id, app2_id, app3_id])) try: user2_refreshed = Session.query(User).filter( User.id == user2_id).one() except NoResultFound: user2_refreshed = None self.assertEqual(user2_refreshed, None) self.assertEqual( 2, Session.query(Password).filter( Password.user_id == user1_id).count())
def test_application_edit(self): user = User(screen_name='John Doe', first_name='John', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', main_url='http://example.com', callback_url='http://example.com/callback', authorized_origins=['http://example.com', 'https://example.com'], production_ready=False, image_url='http://example.com/image.png', description='example description') user.applications.append(app) with transaction.manager: Session.add(user) Session.flush() app_id = app.id app_secret = app.secret user_id = user.id self.testapp.get('/__login/' + str(user_id)) res = self.testapp.get('/oauth2/applications/%s/edit' % str(app_id)) self.assertEqual(res.status, '200 OK') res.mustcontain('Edit application <span>Test Application</span>') res.mustcontain('Name') res.mustcontain('Test Application') res.mustcontain('Main URL') res.mustcontain('http://example.com') res.mustcontain('Callback URL') res.mustcontain('http://example.com/callback') res.mustcontain('Authorized Origins') res.mustcontain("""http://example.com https://example.com""") res.mustcontain('Production ready') res.mustcontain('Image URL') res.mustcontain('http://example.com/image.png') res.mustcontain('Description') res.mustcontain('example description') res.mustcontain('Client Id') res.mustcontain(app_id) res.mustcontain('Client secret') res.mustcontain(app_secret) res.mustcontain('Save application') res.mustcontain('Delete application') res.mustcontain('Cancel') # Let's make some changes old_count = Session.query(Application).count() res = self.testapp.post('/oauth2/applications/%s/edit' % str(app_id), { 'name': 'Test Application 2', 'main_url': 'http://example.com/new', 'callback_url': 'http://example.com/new/callback', 'authorized_origins': 'http://client.example.com', 'production_ready': 'true', 'image_url': 'http://example.com/image2.png', 'description': 'example description 2', 'client_id': '123456-2', 'client_secret': 'secret2', 'submit': 'Save changes', }) self.assertEqual(res.status, '302 Found') self.assertEqual(res.location, 'http://localhost/oauth2/applications') new_app = Session.query(Application).filter(Application.id == app_id).one() self.assertEqual(new_app.name, 'Test Application 2') self.assertEqual(new_app.main_url, 'http://example.com/new') self.assertEqual(new_app.callback_url, 'http://example.com/new/callback') self.assertEqual(new_app.authorized_origins, ['http://client.example.com']) self.assertEqual(new_app.production_ready, True) self.assertEqual(new_app.image_url, 'http://example.com/image2.png') self.assertEqual(new_app.description, 'example description 2') # the Id and Secret shouldn't change self.assertEqual(new_app.id, app_id) self.assertEqual(new_app.secret, app_secret) new_count = Session.query(Application).count() self.assertEqual(old_count, new_count)
def test_destroy_success(self): user_id = create_and_login_user(self.testapp) # this user has a password, an authorized app and an access code password = Password(secret='s3cr3t', user_id=user_id) admin = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') app = Application(name='Test Application', callback_url='https://example.com/callback') admin.applications.append(app) auth_app = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback', application=app, user_id=user_id, ) access_code = AccessCode(code='1234', code_type='Bearer', expiration=datetime.datetime( 2014, 2, 23, 9, 0), scope=['read-userinfo'], user_id=user_id, application=app) with transaction.manager: Session.add(password) Session.add(admin) Session.add(app) Session.add(auth_app) Session.add(access_code) res = self.testapp.post('/destroy', { 'reason': 'I do not need a password manager', 'submit': 'Yes, I am sure. Destroy my account', }, status=302) self.assertEqual(res.location, 'http://localhost/') self.assertClearAuthCookie(res.headers) try: user = Session.query(User).filter(User.id == user_id).one() except NoResultFound: user = None self.assertEqual(user, None) identities = Session.query(ExternalIdentity).filter( ExternalIdentity.user_id == user_id).count() self.assertEqual(identities, 0) authorized_apps = Session.query(AuthorizedApplication).filter( AuthorizedApplication.user_id == user_id).count() self.assertEqual(authorized_apps, 0) access_codes = Session.query(AccessCode).filter( AccessCode.user_id == user_id).count() self.assertEqual(access_codes, 0) passwords = Session.query(Password).filter( Password.user_id == user_id).count() self.assertEqual(passwords, 0) res.request.registry = self.testapp.app.registry mailer = get_mailer(res.request) self.assertEqual(len(mailer.outbox), 1) self.assertEqual(mailer.outbox[0].subject, 'A user has destroyed his Yith Library account') self.assertEqual(mailer.outbox[0].recipients, ['*****@*****.**', '*****@*****.**']) self.assertTrue( 'I do not need a password manager' in mailer.outbox[0].body)
def test_identity_providers_two_accounts_only_one_selected(self): user1_id = create_and_login_user(self.testapp, email='*****@*****.**', email_verified=True) user2_id = create_user(email='*****@*****.**', email_verified=True, provider='google', external_id='google1') app1 = Application(name='Test Application', callback_url='https://example.com/callback/1') app2 = Application(name='Test Application', callback_url='https://example.com/callback/2') app3 = Application(name='Test Application', callback_url='https://example.com/callback/3') admin = User(screen_name='Alice doe', first_name='Alice', last_name='Doe', email='*****@*****.**') admin.applications.append(app1) admin.applications.append(app2) admin.applications.append(app3) auth_app1 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/1', application=app1, user_id=user1_id, ) auth_app2 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/2', application=app2, user_id=user1_id, ) auth_app3 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/2', application=app2, user_id=user2_id, ) auth_app4 = AuthorizedApplication( scope=['scope1'], response_type='code', redirect_uri='http://example.com/callback/3', application=app3, user_id=user2_id, ) password1 = Password(secret='s3cr3t', user_id=user1_id) password2 = Password(secret='s3cr3t', user_id=user2_id) with transaction.manager: Session.add(admin) Session.add(app1) Session.add(app2) Session.add(app3) Session.add(auth_app1) Session.add(auth_app2) Session.add(auth_app3) Session.add(auth_app4) Session.add(password1) Session.add(password2) Session.flush() # now the profile view should say I can merge my accounts res = self.testapp.get('/identity-providers') self.assertEqual(res.status, '200 OK') res.mustcontain('You are registered with the following accounts', 'Merge my accounts', 'If you merge your accounts') # if only one account is selected or fake accounts # are selected nothing is merged res = self.testapp.post('/identity-providers', { 'account-%s' % str(user1_id): 'on', 'account-000000000000000000000000': 'on', 'submit': 'Merge my accounts', }, status=302) self.assertEqual(res.status, '302 Found') self.assertEqual(res.location, 'http://localhost/identity-providers') self.assertEqual(3, Session.query(User).count()) self.assertEqual( 1, Session.query(Password).filter( Password.user_id == user1_id).count()) self.assertEqual( 1, Session.query(Password).filter( Password.user_id == user2_id).count())