Add project_manage_users endpoint
Manage users of a project. In this initial implementation, we handle addition and removal of a user to the admin group of a project. No changes are done on the project itself.
This commit is contained in:
parent
d93d1091f9
commit
0b1664a83c
@ -2,6 +2,7 @@ import copy
|
|||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from bson import ObjectId
|
||||||
from eve.methods.post import post_internal
|
from eve.methods.post import post_internal
|
||||||
from eve.methods.patch import patch_internal
|
from eve.methods.patch import patch_internal
|
||||||
from flask import g, Blueprint, request, abort, current_app
|
from flask import g, Blueprint, request, abort, current_app
|
||||||
@ -216,6 +217,50 @@ def create_project(overrides=None):
|
|||||||
return jsonify(project, status=201, headers={'Location': '/projects/%s' % project['_id']})
|
return jsonify(project, status=201, headers={'Location': '/projects/%s' % project['_id']})
|
||||||
|
|
||||||
|
|
||||||
|
@blueprint.route('/users', methods=['POST'])
|
||||||
|
@authorization.require_login()
|
||||||
|
def project_manage_users():
|
||||||
|
"""Manage users of a project. In this initial implementation, we handle
|
||||||
|
addition and removal of a user to the admin group of a project.
|
||||||
|
No changes are done on the project itself.
|
||||||
|
"""
|
||||||
|
|
||||||
|
project_id = request.form['project_id']
|
||||||
|
target_user_id = request.form['user_id']
|
||||||
|
action = request.form['action']
|
||||||
|
user_id = g.current_user['user_id']
|
||||||
|
|
||||||
|
projects_collection = current_app.data.driver.db['projects']
|
||||||
|
project = projects_collection.find_one({'_id': ObjectId(project_id)})
|
||||||
|
# Check if the current_user is owner of the project
|
||||||
|
# TODO: check based on permissions
|
||||||
|
if project['user'] != user_id:
|
||||||
|
return abort_with_error(403)
|
||||||
|
# Get admin group
|
||||||
|
# TODO: improve this by checking actual permissions
|
||||||
|
admin_group_id = project['permissions']['groups'][0]['group']
|
||||||
|
# Additional check for admin group (if group name is the same as project id)
|
||||||
|
groups_collection = current_app.data.driver.db['groups']
|
||||||
|
group = groups_collection.find_one({'_id': admin_group_id})
|
||||||
|
if group['name'] != project_id:
|
||||||
|
return abort_with_error(403)
|
||||||
|
|
||||||
|
# Get the user and add the admin group to it
|
||||||
|
if action == 'add':
|
||||||
|
operation = '$addToSet'
|
||||||
|
elif action == 'remove':
|
||||||
|
operation = '$pull'
|
||||||
|
else:
|
||||||
|
return abort_with_error(403)
|
||||||
|
|
||||||
|
users_collection = current_app.data.driver.db['users']
|
||||||
|
users_collection.update({'_id': ObjectId(target_user_id)},
|
||||||
|
{operation: {'groups': admin_group_id}})
|
||||||
|
|
||||||
|
# Return the project in the response.
|
||||||
|
return jsonify({'status': 'success'})
|
||||||
|
|
||||||
|
|
||||||
def abort_with_error(status):
|
def abort_with_error(status):
|
||||||
"""Aborts with the given status, or 500 if the status doesn't indicate an error.
|
"""Aborts with the given status, or 500 if the status doesn't indicate an error.
|
||||||
|
|
||||||
|
@ -302,3 +302,53 @@ class ProjectEditTest(AbstractProjectTest):
|
|||||||
project = json.loads(resp.data)
|
project = json.loads(resp.data)
|
||||||
|
|
||||||
return project
|
return project
|
||||||
|
|
||||||
|
def test_add_remove_user(self):
|
||||||
|
# Create test project
|
||||||
|
project_info = self._create_user_and_project([u'subscriber'])
|
||||||
|
project_id = project_info['_id']
|
||||||
|
project_add_user_url = '/p/users'
|
||||||
|
|
||||||
|
# Create another user we can try to share the project with
|
||||||
|
other_user_id = 'f00dd00df00dd00df00dd00d'
|
||||||
|
self._create_user_with_token(['subscriber'], 'other-token',
|
||||||
|
user_id=other_user_id)
|
||||||
|
|
||||||
|
# Make request payload
|
||||||
|
payload = {
|
||||||
|
'project_id': project_id,
|
||||||
|
'user_id': other_user_id,
|
||||||
|
'action': 'add'}
|
||||||
|
|
||||||
|
resp = self.client.post(project_add_user_url,
|
||||||
|
data=payload,
|
||||||
|
headers={
|
||||||
|
'Authorization': self.make_header('token'),
|
||||||
|
'If-Match': project_info['_etag']})
|
||||||
|
self.assertEqual(200, resp.status_code, resp.data)
|
||||||
|
|
||||||
|
with self.app.test_request_context():
|
||||||
|
groups = self.app.data.driver.db['groups']
|
||||||
|
users = self.app.data.driver.db['users']
|
||||||
|
|
||||||
|
# Get other_user document
|
||||||
|
db_user = users.find_one(ObjectId(other_user_id))
|
||||||
|
|
||||||
|
# Get the admin group (has same name as project id)
|
||||||
|
# TODO: handle case when user has multiple groups
|
||||||
|
admin_group_id = db_user['groups'][0]
|
||||||
|
admin_group = groups.find_one({'_id': admin_group_id})
|
||||||
|
|
||||||
|
# Check if admin group name matches
|
||||||
|
self.assertEqual(admin_group['name'], str(project_info['_id']))
|
||||||
|
|
||||||
|
# Update payload to remove the user we just added
|
||||||
|
payload['action'] = 'remove'
|
||||||
|
|
||||||
|
resp = self.client.post(project_add_user_url,
|
||||||
|
data=payload,
|
||||||
|
headers={
|
||||||
|
'Authorization': self.make_header('token'),
|
||||||
|
'If-Match': project_info['_etag']})
|
||||||
|
self.assertEqual(200, resp.status_code, resp.data)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user