def test_scope_list(self, app): scope = ApiOAuth2ScopeFactory() second_scope = ApiOAuth2ScopeFactory() url_scopes = '/{}scopes/'.format(API_BASE) res_scopes = app.get(url_scopes) # test_scope_list_success assert res_scopes.status_code == 200 assert res_scopes.content_type == 'application/vnd.api+json' # test_scope_list_count_correct total = res_scopes.json['links']['meta']['total'] assert total == 2 # test_private_scope_excluded second_scope.is_public = False second_scope.save() res_scopes = app.get(url_scopes) assert res_scopes.status_code == 200 total = res_scopes.json['links']['meta']['total'] assert total == 1 assert second_scope.name != res_scopes.json['data'][0]['id'] assert scope.name == res_scopes.json['data'][0]['id']
def test_invalid_token_creation(self, app, url_token_list, data_sample, user_one, tokens_user_one, write_token): # cannot create a token with a name over 100 characters data_sample['data']['attributes']['name'] = 'a' * 101 res = app.post_json_api(url_token_list, data_sample, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 assert 'Ensure this value has at most 100 characters (it has 101).' in res.json[ 'errors'][0]['detail'] # test_cannot_create_admin_token data_sample['data']['attributes']['scopes'] = 'osf.admin' res = app.post_json_api(url_token_list, data_sample, auth=user_one.auth, expect_errors=True) assert res.status_code == 404 # test_cannot_create_usercreate_token scope = ApiOAuth2ScopeFactory(name='osf.users.create') scope.is_public = False scope.save() data_sample['data']['attributes']['scopes'] = 'osf.users.create' res = app.post_json_api(url_token_list, data_sample, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 assert res.json['errors'][0][ 'detail'] == 'User requested invalid scope.'
def test_add_multiple_scopes_when_creating_token(self, app, url_token_list, data_sample, user_one, read_scope): write_scope = ApiOAuth2ScopeFactory() data_sample['data']['relationships']['scopes']['data'].append({ 'type': 'scopes', 'id': write_scope.name }) res = app.post_json_api(url_token_list, data_sample, auth=user_one.auth, expect_errors=True) assert res.status_code == 201 assert len(res.json['data']['embeds']['scopes']['data']) == 2 assert res.json['data']['embeds']['scopes']['data'][0][ 'id'] == read_scope.name assert res.json['data']['embeds']['scopes']['data'][1][ 'id'] == write_scope.name assert 'scopes' in res.json['data']['relationships'] assert 'scopes' not in res.json['data']['attributes'] token = ApiOAuth2PersonalToken.objects.get(_id=res.json['data']['id']) assert len(token.scopes.all()) == 2 token_scope_names = [scope.name for scope in token.scopes.all()] assert read_scope.name in token_scope_names assert write_scope.name in token_scope_names
def test_admin_scoped_token_can_create_and_send_email( self, mock_auth, mock_mail, app, user, email_unconfirmed, data, url_base): token = ApiOAuth2PersonalToken( owner=user, name='Admin Token', ) scope = ApiOAuth2ScopeFactory() scope.name = 'osf.admin' scope.save() token.scopes.add(scope) mock_cas_resp = CasResponse(authenticated=True, user=user._id, attributes={ 'accessToken': token.token_id, 'accessTokenScope': [s.name for s in token.scopes.all()] }) mock_auth.return_value = user, mock_cas_resp assert OSFUser.objects.filter(username=email_unconfirmed).count() == 0 res = app.post_json_api( '{}?send_email=true'.format(url_base), data, headers={'Authorization': 'Bearer {}'.format(token.token_id)}) assert res.status_code == 201 assert res.json['data']['attributes']['username'] == email_unconfirmed assert OSFUser.objects.filter(username=email_unconfirmed).count() == 1 assert mock_mail.call_count == 1
def test_improperly_scoped_token_can_not_create_or_email( self, mock_auth, mock_mail, app, user, email_unconfirmed, data, url_base): token = ApiOAuth2PersonalToken( owner=user, name='Unauthorized Token', ) token.save() scope = ApiOAuth2ScopeFactory() scope.name = 'unauthorized scope' scope.save() token.scopes.add(scope) mock_cas_resp = CasResponse(authenticated=True, user=user._id, attributes={ 'accessToken': token.token_id, 'accessTokenScope': [s.name for s in token.scopes.all()] }) mock_auth.return_value = user, mock_cas_resp assert OSFUser.objects.filter(username=email_unconfirmed).count() == 0 res = app.post_json_api( '{}?send_email=true'.format(url_base), data, headers={'Authorization': 'Bearer {}'.format(token.token_id)}, expect_errors=True) assert res.status_code == 403 assert OSFUser.objects.filter(username=email_unconfirmed).count() == 0 assert mock_mail.call_count == 0
def test_admin_scoped_token_has_admin(self, mock_auth): token = ApiOAuth2PersonalToken( owner=self.user, name='Admin Token', ) token.save() scope = ApiOAuth2ScopeFactory() scope.name = 'osf.admin' scope.save() token.scopes.add(scope) mock_cas_resp = CasResponse(authenticated=True, user=self.user._id, attributes={ 'accessToken': token.token_id, 'accessTokenScope': [s.name for s in token.scopes.all()] }) mock_auth.return_value = self.user, mock_cas_resp res = self.app.get( self.url, headers={'Authorization': 'Bearer {}'.format(token.token_id)}) assert_equal(res.status_code, 200) assert_equal(res.json['meta'][ADMIN], True)
def test_cannot_create_token_with_private_scope(self, app, url_token_list, data_sample, user_one): scope = ApiOAuth2ScopeFactory() scope.is_public = False scope.save() data_sample['data']['relationships']['scopes']['data'][0][ 'id'] = scope.name res = app.post_json_api(url_token_list, data_sample, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 assert res.json['errors'][0][ 'detail'] == 'User requested invalid scope.'
def test_update_token_add_scope(self, mock_revoke, app, user_one, token_user_one, url_token_detail): mock_revoke.return_value = True original_scope = token_user_one.scopes.first() scope = ApiOAuth2ScopeFactory() correct = post_payload(scopes=scope.name) res = app.put_json_api(url_token_detail, correct, auth=user_one.auth, expect_errors=True) assert res.status_code == 200 scopes_data = res.json['data']['embeds']['scopes']['data'] assert len(scopes_data) == 1 assert scopes_data[0]['id'] == scope.name assert scope.name != original_scope.name
def test_scope_detail(self, app): scope = ApiOAuth2ScopeFactory() url_scope = '/{}scopes/{}/'.format(API_BASE, scope.name) res_scope = app.get(url_scope) data_scope = res_scope.json['data'] # test_scope_detail_success assert res_scope.status_code == 200 assert res_scope.content_type == 'application/vnd.api+json' # test_scope_top_level assert data_scope['type'] == 'scopes' assert data_scope['id'] == scope.name # test_scope_attributes: assert data_scope['attributes']['description'] == scope.description assert data_scope['attributes']['description'] != ''
def test_scope_detail_errors(self, app): scope = ApiOAuth2ScopeFactory() user = AuthUserFactory() # Scope Not Found url_scope = '/{}scopes/{}/'.format(API_BASE, 'not_found_scope') res = app.get(url_scope, expect_errors=True) assert res.status_code == 404 scope.is_public = False scope.save() # Private scope, Unauthenticated url_scope = '/{}scopes/{}/'.format(API_BASE, scope.name) res = app.get(url_scope, expect_errors=True) assert res.status_code == 401 # Private scope, authenticated res = app.get(url_scope, auth=user.auth, expect_errors=True) assert res.status_code == 403
def post_payload(type_payload='tokens', scopes=None, name='A shiny updated token'): if not scopes: scopes = ApiOAuth2ScopeFactory().name return { 'data': { 'type': type_payload, 'attributes': { 'name': name, }, 'relationships': { 'scopes': { 'data': [{ 'type': 'scopes', 'id': scopes }] } } } }
def test_properly_scoped_token_can_create_without_username_but_not_send_email( self, mock_auth, mock_mail, app, user, data, url_base): token = ApiOAuth2PersonalToken( owner=user, name='Authorized Token', ) scope = ApiOAuth2ScopeFactory() scope.name = 'osf.users.create' scope.save() token.scopes.add(scope) mock_cas_resp = CasResponse( authenticated=True, user=user._id, attributes={ 'accessToken': token.token_id, 'accessTokenScope': [s.name for s in token.scopes.all()] } ) mock_auth.return_value = user, mock_cas_resp data['data']['attributes'] = {'full_name': 'No Email'} assert OSFUser.objects.filter(fullname='No Email').count() == 0 res = app.post_json_api( '{}?send_email=true'.format(url_base), data, headers={'Authorization': 'Bearer {}'.format(token.token_id)} ) assert res.status_code == 201 username = res.json['data']['attributes']['username'] try: UUID(username) except ValueError: raise AssertionError('Username is not a valid UUID') assert OSFUser.objects.filter(fullname='No Email').count() == 1 assert mock_mail.call_count == 0
def read_scope(self): return ApiOAuth2ScopeFactory()
def write_token(self): return ApiOAuth2ScopeFactory(name='osf.full_write')
def test_token_detail_crud_with_wrong_payload(self, app, url_token_list, url_token_detail, token_user_one, user_one, user_two): # test_non_owner_cant_delete res = app.delete(url_token_detail, auth=user_two.auth, expect_errors=True) assert res.status_code == 403 # test_create_with_admin_scope_fails admin_token = ApiOAuth2ScopeFactory(name='osf.admin') admin_token.is_public = False admin_token.save() injected_scope = post_attributes_payload(name='A shiny invalid token', scopes='osf.admin') res = app.post_json_api(url_token_list, injected_scope, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 # test_create_with_fake_scope_fails nonsense_scope = post_attributes_payload(name='A shiny invalid token', scopes='osf.nonsense') res = app.post_json_api(url_token_list, nonsense_scope, auth=user_one.auth, expect_errors=True) assert res.status_code == 404 # test_update_with_admin_scope_fails injected_scope = post_attributes_payload(name='A shiny invalid token', scopes='osf.admin') res = app.put_json_api(url_token_detail, injected_scope, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 # test_update_with_fake_scope_fails nonsense_scope = post_attributes_payload(name='A shiny invalid token', scopes='osf.nonsense') res = app.put_json_api(url_token_detail, nonsense_scope, auth=user_one.auth, expect_errors=True) assert res.status_code == 404 # test_update_token_incorrect_type incorrect_type = post_attributes_payload(type_payload='Wrong type.') res = app.put_json_api(url_token_detail, incorrect_type, auth=user_one.auth, expect_errors=True) assert res.status_code == 409 # test_update_token_no_type missing_type = post_attributes_payload(type_payload='') res = app.put_json_api(url_token_detail, missing_type, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 # test_update_token_no_attributes payload = { 'id': token_user_one._id, 'type': 'tokens', 'name': 'The token formerly known as Prince' } res = app.put_json_api(url_token_detail, payload, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 # test_partial_update_token_incorrect_type incorrect_type = post_attributes_payload(type_payload='Wrong type.') res = app.patch_json_api(url_token_detail, incorrect_type, auth=user_one.auth, expect_errors=True) assert res.status_code == 409 # test_partial_update_token_no_type missing_type = post_attributes_payload(type_payload='') res = app.patch_json_api(url_token_detail, missing_type, auth=user_one.auth, expect_errors=True) assert res.status_code == 400 # test token too long payload = post_payload(name='A' * 101) res = app.put_json_api(url_token_detail, payload, auth=user_one.auth, expect_errors=True) assert res.status_code == 400