Allow user updates in create_service_account() calls.

This commit is contained in:
Sybren A. Stüvel 2016-12-14 14:41:06 +01:00
parent 8115bc2ad5
commit 01cc52bba9
2 changed files with 49 additions and 16 deletions

View File

@ -162,7 +162,7 @@ def manage_user_group_membership(db_user, role, action):
return user_groups return user_groups
def create_service_account(email, roles, service): def create_service_account(email, roles, service, update_existing=None):
"""Creates a service account with the given roles + the role 'service'. """Creates a service account with the given roles + the role 'service'.
:param email: email address associated with the account :param email: email address associated with the account
@ -170,9 +170,39 @@ def create_service_account(email, roles, service):
:param roles: iterable of role names :param roles: iterable of role names
:param service: dict of the 'service' key in the user. :param service: dict of the 'service' key in the user.
:type service: dict :type service: dict
:param update_existing: callback function that receives an existing user to update
for this service, in case the email address is already in use by someone.
If not given or None, updating existing users is disallowed, and a ValueError
exception is thrown instead.
:return: tuple (user doc, token doc) :return: tuple (user doc, token doc)
""" """
from pillar.api.utils import remove_private_keys
# Find existing
users_coll = current_app.db()['users']
user = users_coll.find_one({'email': email})
if user:
# Check whether updating is allowed at all.
if update_existing is None:
raise ValueError('User %s already exists' % email)
# Compute the new roles, and assign.
roles = list(set(roles).union({u'service'}).union(user['roles']))
user['roles'] = list(roles)
# Let the caller perform any required updates.
log.info('Updating existing user %s to become service account for %s',
email, roles)
update_existing(user['service'])
# Try to store the updated user.
result, _, _, status = current_app.put_internal('users',
remove_private_keys(user),
_id=user['_id'])
expected_status = 200
else:
# Create a user with the correct roles. # Create a user with the correct roles.
roles = list(set(roles).union({u'service'})) roles = list(set(roles).union({u'service'}))
user = {'username': email, user = {'username': email,
@ -184,7 +214,9 @@ def create_service_account(email, roles, service):
'email': email, 'email': email,
'service': service} 'service': service}
result, _, _, status = current_app.post_internal('users', user) result, _, _, status = current_app.post_internal('users', user)
if status != 201: expected_status = 201
if status != expected_status:
raise SystemExit('Error creating user {}: {}'.format(email, result)) raise SystemExit('Error creating user {}: {}'.format(email, result))
user.update(result) user.update(result)

View File

@ -315,17 +315,18 @@ def badger(action, user_email, role):
log.info('Status : %i', status) log.info('Status : %i', status)
def create_service_account(email, service_roles, service_definition): def create_service_account(email, service_roles, service_definition, update_existing=None):
from pillar.api import service from pillar.api import service
from pillar.api.utils import dumps from pillar.api.utils import dumps
account, token = service.create_service_account( account, token = service.create_service_account(
email, email,
service_roles, service_roles,
service_definition service_definition,
update_existing=update_existing
) )
print('Account created:') print('Service account information:')
print(dumps(account, indent=4, sort_keys=True)) print(dumps(account, indent=4, sort_keys=True))
print() print()
print('Access token: %s' % token['token']) print('Access token: %s' % token['token'])