Be less secretive about users; allow limited anonymous /users/id access.

Anonymous users can now obtain full_name and email fields from any
user. Authenticated users can also obtain those fields from other
users, and all info about themselves.
This commit is contained in:
2016-04-26 17:27:56 +02:00
parent d5c2df371a
commit cf203b04f8
4 changed files with 63 additions and 16 deletions

View File

@@ -66,21 +66,32 @@ def check_user_access(request, lookup):
# No access when not logged in.
current_user = g.get('current_user')
if current_user is None:
raise Forbidden()
current_user_id = current_user['user_id'] if current_user else None
# Admins can do anything and get everything, except the 'auth' block.
if user_has_role(u'admin'):
return
# Only allow access to the current user.
if '_id' in lookup:
if str(lookup['_id']) != str(current_user['user_id']):
raise Forbidden()
return
if not lookup and not current_user:
raise Forbidden()
# Add a filter to only return the current user.
lookup['_id'] = current_user['user_id']
if '_id' not in lookup:
lookup['_id'] = current_user['user_id']
def check_put_access(request, lookup):
"""Only allow PUT to the current user, or all users if admin."""
if user_has_role(u'admin'):
return
current_user = g.get('current_user')
if not current_user:
raise Forbidden()
if str(lookup['_id']) != str(current_user['user_id']):
raise Forbidden()
def after_fetching_user(user):
@@ -88,6 +99,23 @@ def after_fetching_user(user):
# custom end-points.
user.pop('auth', None)
current_user = g.get('current_user')
current_user_id = current_user['user_id'] if current_user else None
# Admins can do anything and get everything, except the 'auth' block.
if user_has_role(u'admin'):
return
# Only allow full access to the current user.
if str(user['_id']) == str(current_user_id):
return
# Remove all fields except public ones.
public_fields = {'full_name', 'email'}
for field in list(user.keys()):
if field not in public_fields:
del user[field]
def after_fetching_user_resource(response):
for user in response['_items']:
@@ -97,7 +125,7 @@ def after_fetching_user_resource(response):
def setup_app(app):
app.on_pre_GET_users += check_user_access
app.on_post_GET_users += post_GET_user
app.on_pre_PUT_users += check_user_access
app.on_pre_PUT_users += check_put_access
app.on_pre_PUT_users += before_replacing_user
app.on_replaced_users += after_replacing_user
app.on_fetched_item_users += after_fetching_user

View File

@@ -707,7 +707,7 @@ users = {
'resource_methods': ['GET'],
'item_methods': ['GET', 'PUT'],
'public_methods': [],
'public_item_methods': ['GET'],
# By default don't include the 'auth' field. It can still be obtained
# using projections, though, so we block that in hooks.