Orgs: refresh all members' roles after org changed roles

This commit is contained in:
Sybren A. Stüvel 2017-08-24 11:18:53 +02:00
parent d41e2bbce4
commit 1e1bd83baf
3 changed files with 52 additions and 1 deletions

View File

@ -4,7 +4,6 @@ Assumes role names that are given to users by organization membership
start with the string "org-". start with the string "org-".
""" """
import enum
import logging import logging
import typing import typing
@ -231,6 +230,20 @@ class OrgManager:
raise ValueError(f'Organization {org_id} not found') raise ValueError(f'Organization {org_id} not found')
return org return org
def refresh_all_user_roles(self, org_id: bson.ObjectId):
"""Refreshes the roles of all members."""
assert isinstance(org_id, bson.ObjectId)
org = self._get_org(org_id, projection={'members': 1})
members = org.get('members')
if not members:
self._log.info('Organization %s has no members, nothing to refresh.', org_id)
return
for uid in members:
self.refresh_roles(uid)
def refresh_roles(self, user_id: bson.ObjectId): def refresh_roles(self, user_id: bson.ObjectId):
"""Refreshes the user's roles to own roles + organizations' roles.""" """Refreshes the user's roles to own roles + organizations' roles."""
@ -238,6 +251,8 @@ class OrgManager:
from pillar.api.service import do_badger from pillar.api.service import do_badger
self._log.info('Refreshing roles for user %s', user_id)
org_coll = current_app.db('organizations') org_coll = current_app.db('organizations')
# Aggregate all org-given roles for this user. # Aggregate all org-given roles for this user.

View File

@ -136,6 +136,7 @@ class OrganizationPatchHandler(patch_handler.AbstractPatchHandler):
'location': patch.get('location', '').strip(), 'location': patch.get('location', '').strip(),
} }
refresh_user_roles = False
if user.has_cap('admin'): if user.has_cap('admin'):
if 'seat_count' in patch: if 'seat_count' in patch:
update['seat_count'] = int(patch['seat_count']) update['seat_count'] = int(patch['seat_count'])
@ -147,6 +148,7 @@ class OrganizationPatchHandler(patch_handler.AbstractPatchHandler):
'Invalid role given, all roles must start with "org-"') 'Invalid role given, all roles must start with "org-"')
update['org_roles'] = org_roles update['org_roles'] = org_roles
refresh_user_roles = True
self.log.info('User %s edits Organization %s: %s', current_user_id, org_id, update) self.log.info('User %s edits Organization %s: %s', current_user_id, org_id, update)
@ -171,6 +173,10 @@ class OrganizationPatchHandler(patch_handler.AbstractPatchHandler):
current_user_id, org_id, result.matched_count) current_user_id, org_id, result.matched_count)
raise wz_exceptions.BadRequest() raise wz_exceptions.BadRequest()
if refresh_user_roles:
self.log.info('Organization roles set for org %s, refreshing users', org_id)
current_app.org_manager.refresh_all_user_roles(org_id)
return '', 204 return '', 204

View File

@ -357,6 +357,36 @@ class OrganizationPatchTest(AbstractPillarTest):
self.assertEqual('Open Source animation studio', db_org['description']) self.assertEqual('Open Source animation studio', db_org['description'])
self.assertEqual('https://blender.institute/', db_org['website']) self.assertEqual('https://blender.institute/', db_org['website'])
def test_change_roles(self):
self.enter_app_context()
om = self.app.org_manager
self.create_user(24 * '1', roles={'admin'}, token='uberadmin')
admin_uid = self.create_user(24 * 'a', token='admin-token')
org_doc = om.create_new_org('Хакеры', admin_uid, 25, org_roles={'org-subscriber'})
org_id = org_doc['_id']
# First assign the user, then change the organization's roles.
# This should refresh the roles on all its members.
member1_uid = self.create_user(24 * 'b', email='member1@example.com', roles={'betatester'})
om.assign_single_user(org_id, user_id=member1_uid)
# Try the PATCH to change the roles
self.patch(f'/api/organizations/{org_id}',
json={
'op': 'edit-from-web',
'name': ' Blender Institute ',
'description': '\nOpen Source animation studio ',
'website': ' https://blender.institute/ ',
'org_roles': ['org-subscriber', 'org-flamenco'],
},
auth_token='uberadmin',
expected_status=204)
db_user = self.fetch_user_from_db(member1_uid)
self.assertEqual({'betatester', 'org-subscriber', 'org-flamenco'}, set(db_user['roles']))
def test_assign_admin(self): def test_assign_admin(self):
self.enter_app_context() self.enter_app_context()
om = self.app.org_manager om = self.app.org_manager