Added /p/create entry point to create new projects.
This requires the user to be logged in. The project will be owned by that user.
This commit is contained in:
@@ -46,6 +46,7 @@ class AbstractPillarTest(TestMinimal):
|
||||
|
||||
from application import app
|
||||
|
||||
logging.getLogger('').setLevel(logging.DEBUG)
|
||||
logging.getLogger('application').setLevel(logging.DEBUG)
|
||||
logging.getLogger('werkzeug').setLevel(logging.DEBUG)
|
||||
logging.getLogger('eve').setLevel(logging.DEBUG)
|
||||
@@ -95,7 +96,7 @@ class AbstractPillarTest(TestMinimal):
|
||||
|
||||
return found['_id'], found
|
||||
|
||||
def create_user(self):
|
||||
def create_user(self, roles=('subscriber', )):
|
||||
with self.app.test_request_context():
|
||||
users = self.app.data.driver.db['users']
|
||||
assert isinstance(users, pymongo.collection.Collection)
|
||||
@@ -106,7 +107,7 @@ class AbstractPillarTest(TestMinimal):
|
||||
'_created': datetime.datetime(2016, 4, 15, 13, 15, 11, tzinfo=tz_util.utc),
|
||||
'username': 'tester',
|
||||
'groups': [],
|
||||
'roles': ['subscriber'],
|
||||
'roles': list(roles),
|
||||
'settings': {'email_communications': 1},
|
||||
'auth': [{'token': '',
|
||||
'user_id': unicode(BLENDER_ID_TEST_USERID),
|
||||
@@ -117,6 +118,17 @@ class AbstractPillarTest(TestMinimal):
|
||||
|
||||
return result.inserted_id
|
||||
|
||||
def create_valid_auth_token(self, user_id, token='token'):
|
||||
now = datetime.datetime.now(tz_util.utc)
|
||||
future = now + datetime.timedelta(days=1)
|
||||
|
||||
with self.app.test_request_context():
|
||||
from application.utils import authentication as auth
|
||||
|
||||
token_data = auth.store_token(user_id, token, future, None)
|
||||
|
||||
return token_data
|
||||
|
||||
def mock_blenderid_validate_unhappy(self):
|
||||
"""Sets up Responses to mock unhappy validation flow."""
|
||||
|
||||
|
@@ -280,4 +280,4 @@ EXAMPLE_PROJECT = {
|
||||
u'status': u'published',
|
||||
u'summary': u'Texture collection from all Blender Institute open projects.',
|
||||
u'url': u'textures',
|
||||
u'user': ObjectId('552b066b41acdf5dec4436f2')}
|
||||
u'user': ObjectId('552b066b41acdf5dec4436f2')}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import datetime
|
||||
import responses
|
||||
import json
|
||||
from bson import tz_util
|
||||
|
||||
from common_test_class import AbstractPillarTest, TEST_EMAIL_USER, TEST_EMAIL_ADDRESS
|
||||
@@ -93,3 +94,67 @@ class AuthenticationTests(AbstractPillarTest):
|
||||
found_token = auth.find_token('expired-sub', subclient)
|
||||
self.assertIsNotNone(found_token)
|
||||
self.assertNotEqual(token3['_id'], found_token['_id'])
|
||||
|
||||
@responses.activate
|
||||
def test_save_own_user(self):
|
||||
"""Tests that a user can't change their own fields."""
|
||||
|
||||
from application.utils import authentication as auth
|
||||
from application.utils import PillarJSONEncoder, remove_private_keys
|
||||
|
||||
user_id = self.create_user(roles=[u'subscriber'])
|
||||
|
||||
now = datetime.datetime.now(tz_util.utc)
|
||||
future = now + datetime.timedelta(days=1)
|
||||
|
||||
with self.app.test_request_context():
|
||||
auth.store_token(user_id, 'nonexpired-main', future, None)
|
||||
|
||||
with self.app.test_request_context(
|
||||
headers={'Authorization': self.make_header('nonexpired-main')}):
|
||||
self.assertTrue(auth.validate_token())
|
||||
|
||||
users = self.app.data.driver.db['users']
|
||||
db_user = users.find_one(user_id)
|
||||
|
||||
updated_fields = remove_private_keys(db_user)
|
||||
updated_fields['roles'] = ['admin', 'subscriber', 'demo'] # Try to elevate our roles.
|
||||
|
||||
# POSTing updated info to a specific user URL is not allowed by Eve.
|
||||
resp = self.client.post('/users/%s' % user_id,
|
||||
data=json.dumps(updated_fields, cls=PillarJSONEncoder),
|
||||
headers={'Authorization': self.make_header('nonexpired-main'),
|
||||
'Content-Type': 'application/json'})
|
||||
self.assertEqual(405, resp.status_code)
|
||||
|
||||
# POSTing with our _id to update shouldn't work either, as POST always creates new users.
|
||||
updated_fields_with_id = dict(_id=user_id, **updated_fields)
|
||||
resp = self.client.post('/users',
|
||||
data=json.dumps(updated_fields_with_id, cls=PillarJSONEncoder),
|
||||
headers={'Authorization': self.make_header('nonexpired-main'),
|
||||
'Content-Type': 'application/json'})
|
||||
self.assertEqual(422, resp.status_code)
|
||||
|
||||
# PUT and PATCH should not be allowed.
|
||||
resp = self.client.put('/users/%s' % user_id,
|
||||
data=json.dumps(updated_fields, cls=PillarJSONEncoder),
|
||||
headers={'Authorization': self.make_header('nonexpired-main'),
|
||||
'Content-Type': 'application/json'})
|
||||
self.assertEqual(403, resp.status_code)
|
||||
|
||||
updated_fields = {'roles': ['admin', 'subscriber', 'demo']}
|
||||
resp = self.client.patch('/users/%s' % user_id,
|
||||
data=json.dumps(updated_fields, cls=PillarJSONEncoder),
|
||||
headers={'Authorization': self.make_header('nonexpired-main'),
|
||||
'Content-Type': 'application/json'})
|
||||
self.assertEqual(403, resp.status_code)
|
||||
|
||||
# After all of this, the roles should be the same.
|
||||
with self.app.test_request_context(
|
||||
headers={'Authorization': self.make_header('nonexpired-main')}):
|
||||
self.assertTrue(auth.validate_token())
|
||||
|
||||
users = self.app.data.driver.db['users']
|
||||
db_user = users.find_one(user_id)
|
||||
|
||||
self.assertEqual([u'subscriber'], db_user['roles'])
|
||||
|
65
tests/test_project_management.py
Normal file
65
tests/test_project_management.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
"""Unit tests for creating and editing projects_blueprint."""
|
||||
|
||||
import json
|
||||
|
||||
import responses
|
||||
from bson import ObjectId
|
||||
|
||||
from common_test_class import AbstractPillarTest
|
||||
|
||||
|
||||
class ProjectCreationTest(AbstractPillarTest):
|
||||
@responses.activate
|
||||
def test_project_creation_wrong_role(self):
|
||||
user_id = self.create_user(roles=[u'whatever'])
|
||||
self.create_valid_auth_token(user_id, 'token')
|
||||
|
||||
resp = self.client.post('/p/create',
|
||||
headers={'Authorization': self.make_header('token')},
|
||||
data={'project_name': u'Prøject El Niño'})
|
||||
|
||||
self.assertEqual(403, resp.status_code)
|
||||
|
||||
# Test that the project wasn't created.
|
||||
with self.app.test_request_context():
|
||||
projects = self.app.data.driver.db['projects']
|
||||
self.assertEqual(0, len(list(projects.find())))
|
||||
|
||||
@responses.activate
|
||||
def test_project_creation_good_role(self):
|
||||
user_id = self.create_user(roles=[u'subscriber'])
|
||||
self.create_valid_auth_token(user_id, 'token')
|
||||
|
||||
resp = self.client.post('/p/create',
|
||||
headers={'Authorization': self.make_header('token')},
|
||||
data={'project_name': u'Prøject El Niñö'})
|
||||
|
||||
self.assertEqual(201, resp.status_code)
|
||||
project = json.loads(resp.data.decode('utf-8'))
|
||||
project_id = project['_id']
|
||||
|
||||
# Test that the Location header contains the location of the project document.
|
||||
self.assertEqual('http://localhost/projects/%s' % project_id,
|
||||
resp.headers['Location'])
|
||||
|
||||
# Check some of the more complex/interesting fields.
|
||||
self.assertEqual(u'Prøject El Niñö', project['name'])
|
||||
self.assertEqual(str(user_id), project['user'])
|
||||
self.assertEqual('p-%s' % project_id, project['url'])
|
||||
self.assertEqual(1, len(project['permissions']['groups']))
|
||||
|
||||
group_id = ObjectId(project['permissions']['groups'][0]['group'])
|
||||
|
||||
# Check that there is a group for the project, and that the user is member of it.
|
||||
with self.app.test_request_context():
|
||||
groups = self.app.data.driver.db['groups']
|
||||
users = self.app.data.driver.db['users']
|
||||
|
||||
group = groups.find_one(group_id)
|
||||
db_user = users.find_one(user_id)
|
||||
|
||||
self.assertEqual(str(project_id), group['name'])
|
||||
self.assertIn(group_id, db_user['groups'])
|
||||
|
Reference in New Issue
Block a user