Orgs: refresh all members' roles after org changed roles
This commit is contained in:
parent
d41e2bbce4
commit
1e1bd83baf
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user