def test_editing_as_subscriber(self): """Test that we can set certain fields, but not all.""" from application.utils import remove_private_keys, PillarJSONEncoder dumps = functools.partial(json.dumps, cls=PillarJSONEncoder) project_info = self._create_user_and_project([u'subscriber']) project_url = '/projects/%(_id)s' % project_info resp = self.client.get(project_url, headers={'Authorization': self.make_header('token')}) project = json.loads(resp.data.decode('utf-8')) # Create another user we can try and assign the project to. other_user_id = 'f00dd00df00dd00df00dd00d' self._create_user_with_token(['subscriber'], 'other-token', user_id=other_user_id) # Unauthenticated should be forbidden resp = self.client.put('/projects/%s' % project['_id'], data=dumps(remove_private_keys(project)), headers={'Content-Type': 'application/json'}) self.assertEqual(403, resp.status_code) # Regular user should be able to PUT, but only be able to edit certain fields. put_project = remove_private_keys(project) put_project['url'] = u'very-offensive-url' put_project['description'] = u'Blender je besplatan set alata za izradu interaktivnog 3D ' \ u'sadržaja pod različitim operativnim sustavima.' put_project['name'] = u'โครงการปั่นเมฆ' put_project['summary'] = u'Это переведена на Google' put_project['status'] = 'pending' put_project['category'] = 'software' put_project['user'] = other_user_id # Try making the project public. This should update is_private as well. put_project['permissions']['world'] = ['GET'] resp = self.client.put(project_url, data=dumps(put_project), headers={'Authorization': self.make_header('token'), 'Content-Type': 'application/json', 'If-Match': project['_etag']}) self.assertEqual(200, resp.status_code, resp.data) # Re-fetch from database to see which fields actually made it there. # equal to put_project -> changed in DB # equal to project -> not changed in DB resp = self.client.get(project_url, headers={'Authorization': self.make_header('token')}) db_proj = json.loads(resp.data) self.assertEqual(project['url'], db_proj['url']) self.assertEqual(put_project['description'], db_proj['description']) self.assertEqual(put_project['name'], db_proj['name']) self.assertEqual(put_project['summary'], db_proj['summary']) self.assertEqual(project['status'], db_proj['status']) self.assertEqual(project['category'], db_proj['category']) # Project should be consistent. self.assertEqual(False, db_proj['is_private']) self.assertEqual(['GET'], db_proj['permissions']['world'])
def test_is_private_updated_by_world_permissions(self): """For backward compatibility, is_private should reflect absence of world-GET""" from application.utils import remove_private_keys, dumps project_url = '/projects/%s' % self.project_id put_project = remove_private_keys(self.project) # Create admin user. self._create_user_with_token(['admin'], 'admin-token', user_id='cafef00dbeef') # Make the project public put_project['permissions']['world'] = ['GET'] # make public put_project['is_private'] = True # This should be overridden. resp = self.client.put(project_url, data=dumps(put_project), headers={ 'Authorization': self.make_header('admin-token'), 'Content-Type': 'application/json', 'If-Match': self.project['_etag'] }) self.assertEqual(200, resp.status_code, resp.data) with self.app.test_request_context(): projects = self.app.data.driver.db['projects'] db_proj = projects.find_one(self.project_id) self.assertEqual(['GET'], db_proj['permissions']['world']) self.assertFalse(db_proj['is_private']) # Make the project private put_project['permissions']['world'] = [] resp = self.client.put(project_url, data=dumps(put_project), headers={ 'Authorization': self.make_header('admin-token'), 'Content-Type': 'application/json', 'If-Match': db_proj['_etag'] }) self.assertEqual(200, resp.status_code, resp.data) with self.app.test_request_context(): projects = self.app.data.driver.db['projects'] db_proj = projects.find_one(self.project_id) self.assertEqual([], db_proj['permissions']['world']) self.assertTrue(db_proj['is_private'])
def test_add_remove_user(self): from application.modules import projects from application.utils import dumps project_mng_user_url = '/p/users' # Use our API to add user to group payload = { 'project_id': self.project_id, 'user_id': self.other_user_id, 'action': 'add' } resp = self.client.post(project_mng_user_url, data=dumps(payload), content_type='application/json', headers={ 'Authorization': self.make_header('token'), 'If-Match': self.project['_etag'] }) self.assertEqual(200, resp.status_code, resp.data) # Check if the user is now actually member of the group. with self.app.test_request_context(): users = self.app.data.driver.db['users'] db_user = users.find_one(self.other_user_id) admin_group = projects.get_admin_group(self.project) self.assertIn(admin_group['_id'], db_user['groups']) # Update payload to remove the user we just added payload['action'] = 'remove' resp = self.client.post(project_mng_user_url, data=dumps(payload), content_type='application/json', headers={ 'Authorization': self.make_header('token'), 'If-Match': self.project['_etag'] }) self.assertEqual(200, resp.status_code, resp.data) # Check if the user is now actually removed from the group. with self.app.test_request_context(): users = self.app.data.driver.db['users'] db_user = users.find_one(self.other_user_id) self.assertNotIn(admin_group['_id'], db_user['groups'])
def test_edits_by_nonowner_subscriber(self): """A subscriber should only be able to edit their own projects.""" from application.utils import remove_private_keys, PillarJSONEncoder dumps = functools.partial(json.dumps, cls=PillarJSONEncoder) # Create test project. project = self._create_user_and_project([u'subscriber']) project_id = project['_id'] project_url = '/projects/%s' % project_id # Create test user. my_user_id = 'cafef00dbeefcafef00dbeef' self._create_user_with_token(['subscriber'], 'mortal-token', user_id=my_user_id) # Regular subscriber should not be able to do this. put_project = remove_private_keys(project) put_project['name'] = u'Болту́н -- нахо́дка для шпио́на.' put_project['user'] = my_user_id resp = self.client.put(project_url, data=dumps(put_project), headers={'Authorization': self.make_header('mortal-token'), 'Content-Type': 'application/json', 'If-Match': project['_etag']}) self.assertEqual(403, resp.status_code, resp.data)
def test_edits_by_nonowner_admin(self): """Any admin should be able to edit any project.""" from application.utils import remove_private_keys, PillarJSONEncoder dumps = functools.partial(json.dumps, cls=PillarJSONEncoder) # Create test project. project = self._create_user_and_project([u'subscriber']) project_id = project['_id'] project_url = '/projects/%s' % project_id # Create test user. self._create_user_with_token(['admin'], 'admin-token', user_id='cafef00dbeef') # Admin user should be able to PUT. put_project = remove_private_keys(project) put_project['name'] = u'โครงการปั่นเมฆ' resp = self.client.put(project_url, data=dumps(put_project), headers={ 'Authorization': self.make_header('admin-token'), 'Content-Type': 'application/json', 'If-Match': project['_etag'] }) self.assertEqual(200, resp.status_code, resp.data)
def test_edits_by_nonowner_subscriber(self): """A subscriber should only be able to edit their own projects.""" from application.utils import remove_private_keys, PillarJSONEncoder dumps = functools.partial(json.dumps, cls=PillarJSONEncoder) # Create test project. project = self._create_user_and_project([u'subscriber']) project_id = project['_id'] project_url = '/projects/%s' % project_id # Create test user. my_user_id = 'cafef00dbeefcafef00dbeef' self._create_user_with_token(['subscriber'], 'mortal-token', user_id=my_user_id) # Regular subscriber should not be able to do this. put_project = remove_private_keys(project) put_project['name'] = u'Болту́н -- нахо́дка для шпио́на.' put_project['user'] = my_user_id resp = self.client.put(project_url, data=dumps(put_project), headers={ 'Authorization': self.make_header('mortal-token'), 'Content-Type': 'application/json', 'If-Match': project['_etag'] }) self.assertEqual(403, resp.status_code, resp.data)
def test_add_remove_user(self): from application.modules import projects from application.utils import dumps project_mng_user_url = '/p/users' # Use our API to add user to group payload = { 'project_id': self.project_id, 'user_id': self.other_user_id, 'action': 'add'} resp = self.client.post(project_mng_user_url, data=dumps(payload), content_type='application/json', headers={ 'Authorization': self.make_header('token'), 'If-Match': self.project['_etag']}) self.assertEqual(200, resp.status_code, resp.data) # Check if the user is now actually member of the group. with self.app.test_request_context(): users = self.app.data.driver.db['users'] db_user = users.find_one(self.other_user_id) admin_group = projects.get_admin_group(self.project) self.assertIn(admin_group['_id'], db_user['groups']) # Update payload to remove the user we just added payload['action'] = 'remove' resp = self.client.post(project_mng_user_url, data=dumps(payload), content_type='application/json', headers={ 'Authorization': self.make_header('token'), 'If-Match': self.project['_etag']}) self.assertEqual(200, resp.status_code, resp.data) # Check if the user is now actually removed from the group. with self.app.test_request_context(): users = self.app.data.driver.db['users'] db_user = users.find_one(self.other_user_id) self.assertNotIn(admin_group['_id'], db_user['groups'])
def test_is_private_updated_by_world_permissions(self): """For backward compatibility, is_private should reflect absence of world-GET""" from application.utils import remove_private_keys, dumps project_url = '/projects/%s' % self.project_id put_project = remove_private_keys(self.project) # Create admin user. self._create_user_with_token(['admin'], 'admin-token', user_id='cafef00dbeef') # Make the project public put_project['permissions']['world'] = ['GET'] # make public put_project['is_private'] = True # This should be overridden. resp = self.client.put(project_url, data=dumps(put_project), headers={'Authorization': self.make_header('admin-token'), 'Content-Type': 'application/json', 'If-Match': self.project['_etag']}) self.assertEqual(200, resp.status_code, resp.data) with self.app.test_request_context(): projects = self.app.data.driver.db['projects'] db_proj = projects.find_one(self.project_id) self.assertEqual(['GET'], db_proj['permissions']['world']) self.assertFalse(db_proj['is_private']) # Make the project private put_project['permissions']['world'] = [] resp = self.client.put(project_url, data=dumps(put_project), headers={'Authorization': self.make_header('admin-token'), 'Content-Type': 'application/json', 'If-Match': db_proj['_etag']}) self.assertEqual(200, resp.status_code, resp.data) with self.app.test_request_context(): projects = self.app.data.driver.db['projects'] db_proj = projects.find_one(self.project_id) self.assertEqual([], db_proj['permissions']['world']) self.assertTrue(db_proj['is_private'])
def _post(self, data): from application.utils import dumps return self.client.post('/service/badger', data=dumps(data), headers={ 'Authorization': self.make_header(self.badger_token), 'Content-Type': 'application/json' })
def test_remove_self(self): """Every user should be able to remove themselves from a project, regardless of permissions. """ from application.modules import projects from application.utils import dumps project_mng_user_url = '/p/users' # Use our API to add user to group payload = { 'project_id': self.project_id, 'user_id': self.other_user_id, 'action': 'add' } resp = self.client.post( project_mng_user_url, data=dumps(payload), content_type='application/json', headers={'Authorization': self.make_header('token')}) self.assertEqual(200, resp.status_code, resp.data) # Update payload to remove the user we just added, and call it as that user. payload['action'] = 'remove' resp = self.client.post( project_mng_user_url, data=dumps(payload), content_type='application/json', headers={'Authorization': self.make_header('other-token')}) self.assertEqual(200, resp.status_code, resp.data) # Check if the user is now actually removed from the group. with self.app.test_request_context(): users = self.app.data.driver.db['users'] db_user = users.find_one(self.other_user_id) admin_group = projects.get_admin_group(self.project) self.assertNotIn(admin_group['_id'], db_user['groups'])
def test_editing_as_admin(self): """Test that we can set all fields as admin.""" from application.utils import remove_private_keys, PillarJSONEncoder dumps = functools.partial(json.dumps, cls=PillarJSONEncoder) project_info = self._create_user_and_project([u'subscriber', u'admin']) project_url = '/projects/%(_id)s' % project_info resp = self.client.get(project_url) project = json.loads(resp.data.decode('utf-8')) # Create another user we can try and assign the project to. other_user_id = 'f00dd00df00dd00df00dd00d' self._create_user_with_token(['subscriber'], 'other-token', user_id=other_user_id) # Admin user should be able to PUT everything. put_project = remove_private_keys(project) put_project['url'] = u'very-offensive-url' put_project['description'] = u'Blender je besplatan set alata za izradu interaktivnog 3D ' \ u'sadržaja pod različitim operativnim sustavima.' put_project['name'] = u'โครงการปั่นเมฆ' put_project['summary'] = u'Это переведена на Google' put_project['is_private'] = False put_project['status'] = 'pending' put_project['category'] = 'software' put_project['user'] = other_user_id resp = self.client.put(project_url, data=dumps(put_project), headers={ 'Authorization': self.make_header('token'), 'Content-Type': 'application/json', 'If-Match': project['_etag'] }) self.assertEqual(200, resp.status_code, resp.data) # Re-fetch from database to see which fields actually made it there. # equal to put_project -> changed in DB # equal to project -> not changed in DB resp = self.client.get('/projects/%s' % project['_id']) db_proj = json.loads(resp.data) self.assertEqual(put_project['url'], db_proj['url']) self.assertEqual(put_project['description'], db_proj['description']) self.assertEqual(put_project['name'], db_proj['name']) self.assertEqual(put_project['summary'], db_proj['summary']) self.assertEqual(put_project['is_private'], db_proj['is_private']) self.assertEqual(put_project['status'], db_proj['status']) self.assertEqual(put_project['category'], db_proj['category']) self.assertEqual(put_project['user'], db_proj['user'])
def test_remove_self(self): """Every user should be able to remove themselves from a project, regardless of permissions. """ from application.modules import projects from application.utils import dumps project_mng_user_url = '/p/users' # Use our API to add user to group payload = { 'project_id': self.project_id, 'user_id': self.other_user_id, 'action': 'add'} resp = self.client.post(project_mng_user_url, data=dumps(payload), content_type='application/json', headers={'Authorization': self.make_header('token')}) self.assertEqual(200, resp.status_code, resp.data) # Update payload to remove the user we just added, and call it as that user. payload['action'] = 'remove' resp = self.client.post(project_mng_user_url, data=dumps(payload), content_type='application/json', headers={'Authorization': self.make_header('other-token')}) self.assertEqual(200, resp.status_code, resp.data) # Check if the user is now actually removed from the group. with self.app.test_request_context(): users = self.app.data.driver.db['users'] db_user = users.find_one(self.other_user_id) admin_group = projects.get_admin_group(self.project) self.assertNotIn(admin_group['_id'], db_user['groups'])
def create_badger_account(email, badges): """ Creates a new service account that can give badges (i.e. roles). :param email: email address associated with the account :param badges: single space-separated argument containing the roles this account can assign and revoke. """ from application.modules import service from application.utils import dumps account, token = service.create_service_account( email, [u'badger'], {'badger': badges.strip().split()}) print('Account created:') print(dumps(account, indent=4, sort_keys=True)) print() print('Access token: %s' % token['token']) print(' expires on: %s' % token['expire_time'])
def create_badger_account(email, badges): """ Creates a new service account that can give badges (i.e. roles). :param email: email address associated with the account :param badges: single space-separated argument containing the roles this account can assign and revoke. """ from application.modules import service from application.utils import dumps account, token = service.create_service_account( email, [u'badger'], {'badger': badges.strip().split()} ) print('Account created:') print(dumps(account, indent=4, sort_keys=True)) print() print('Access token: %s' % token['token']) print(' expires on: %s' % token['expire_time'])
def test_edits_by_nonowner_admin(self): """Any admin should be able to edit any project.""" from application.utils import remove_private_keys, PillarJSONEncoder dumps = functools.partial(json.dumps, cls=PillarJSONEncoder) # Create test project. project = self._create_user_and_project([u'subscriber']) project_id = project['_id'] project_url = '/projects/%s' % project_id # Create test user. self._create_user_with_token(['admin'], 'admin-token', user_id='cafef00dbeef') # Admin user should be able to PUT. put_project = remove_private_keys(project) put_project['name'] = u'โครงการปั่นเมฆ' resp = self.client.put(project_url, data=dumps(put_project), headers={'Authorization': self.make_header('admin-token'), 'Content-Type': 'application/json', 'If-Match': project['_etag']}) self.assertEqual(200, resp.status_code, resp.data)
import logging from flask import Blueprint, request, current_app, g from eve.methods.get import get from eve.utils import config as eve_config from werkzeug.datastructures import MultiDict from werkzeug.exceptions import InternalServerError from application import utils from application.utils.authorization import require_login TL_PROJECTION = utils.dumps({ 'name': 1, 'url': 1, 'permissions': 1, }) TL_SORT = utils.dumps([('name', 1)]) TEXTURE_LIBRARY_QUERY_ARGS = { eve_config.QUERY_PROJECTION: TL_PROJECTION, eve_config.QUERY_SORT: TL_SORT, 'max_results': 'null', # this needs to be there, or we get a KeyError. } blueprint = Blueprint('blender_cloud', __name__) log = logging.getLogger(__name__) def keep_fetching_texture_libraries(proj_filter): groups = g.current_user['groups']
import logging from flask import Blueprint, request, current_app, g from eve.methods.get import get from eve.utils import config as eve_config from werkzeug.datastructures import MultiDict from werkzeug.exceptions import InternalServerError from application import utils from application.utils.authorization import require_login TL_PROJECTION = utils.dumps({'name': 1, 'url': 1, 'permissions': 1,}) TL_SORT = utils.dumps([('name', 1)]) TEXTURE_LIBRARY_QUERY_ARGS = { eve_config.QUERY_PROJECTION: TL_PROJECTION, eve_config.QUERY_SORT: TL_SORT, 'max_results': 'null', # this needs to be there, or we get a KeyError. } blueprint = Blueprint('blender_cloud', __name__) log = logging.getLogger(__name__) def keep_fetching_texture_libraries(proj_filter): groups = g.current_user['groups'] user_id = g.current_user['user_id'] page = 1 max_page = float('inf')
def _post(self, data): from application.utils import dumps return self.client.post('/service/badger', data=dumps(data), headers={'Authorization': self.make_header(self.badger_token), 'Content-Type': 'application/json'})