| 1 |  |  | # Licensed to the StackStorm, Inc ('StackStorm') under one or more | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | # contributor license agreements.  See the NOTICE file distributed with | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | # this work for additional information regarding copyright ownership. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | # The ASF licenses this file to You under the Apache License, Version 2.0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | # (the "License"); you may not use this file except in compliance with | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | # the License.  You may obtain a copy of the License at | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | #     http://www.apache.org/licenses/LICENSE-2.0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | # Unless required by applicable law or agreed to in writing, software | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | # distributed under the License is distributed on an "AS IS" BASIS, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | # See the License for the specific language governing permissions and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | # limitations under the License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | Module for syncing RBAC definitions in the database with the ones from the filesystem. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | import itertools | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | from collections import defaultdict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | from mongoengine.queryset.visitor import Q | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | from st2common import log as logging | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | from st2common.models.db.auth import UserDB | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | from st2common.models.db.rbac import UserRoleAssignmentDB | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | from st2common.persistence.auth import User | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | from st2common.persistence.rbac import Role | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  | from st2common.persistence.rbac import UserRoleAssignment | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | from st2common.persistence.rbac import PermissionGrant | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | from st2common.persistence.rbac import GroupToRoleMapping | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | from st2common.services import rbac as rbac_services | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | from st2common.util.uid import parse_uid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  | LOG = logging.getLogger(__name__) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  | __all__ = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     'RBACDefinitionsDBSyncer', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     'RBACRemoteGroupToRoleSyncer' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  | ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  | class RBACDefinitionsDBSyncer(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     A class which makes sure that the role definitions and user role assignments in the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     match ones specified in the role definition files. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     The class works by simply deleting all the obsolete roles (either removed or updated) and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     creating new roles (either new roles or one which have been updated). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     Note #1: Our current datastore doesn't support transactions or similar which means that with | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     the current data model there is a short time frame during sync when the definitions inside the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     DB are out of sync with the ones in the file. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     Note #2: The operation of this class is idempotent meaning that if it's ran multiple time with | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     the same dataset, the end result / outcome will be the same. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |     def sync(self, role_definition_apis, role_assignment_apis, group_to_role_map_apis): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         Synchronize all the role definitions, user role assignments and remote group to local roles | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         maps. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         result = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |         result['roles'] = self.sync_roles(role_definition_apis) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         result['role_assignments'] = self.sync_users_role_assignments(role_assignment_apis) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         result['group_to_role_maps'] = self.sync_group_to_role_maps(group_to_role_map_apis) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         return result | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     def sync_roles(self, role_definition_apis): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |         Synchronize all the role definitions in the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |         :param role_dbs: RoleDB objects for the roles which are currently in the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |         :type role_dbs: ``list`` of :class:`RoleDB` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         :param role_definition_apis: RoleDefinition API objects for the definitions loaded from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |                                      the files. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |         :type role_definition_apis: ``list`` of :class:RoleDefinitionFileFormatAPI` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         :rtype: ``tuple`` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         LOG.info('Synchronizing roles...') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         # Retrieve all the roles currently in the DB | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |         role_dbs = rbac_services.get_all_roles(exclude_system=True) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |         role_db_names = [role_db.name for role_db in role_dbs] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         role_db_names = set(role_db_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         role_api_names = [role_definition_api.name for role_definition_api in role_definition_apis] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         role_api_names = set(role_api_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |         # A list of new roles which should be added to the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |         new_role_names = role_api_names.difference(role_db_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |         # A list of roles which need to be updated in the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |         updated_role_names = role_db_names.intersection(role_api_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |         # A list of roles which should be removed from the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |         removed_role_names = (role_db_names - role_api_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |         LOG.debug('New roles: %r' % (new_role_names)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         LOG.debug('Updated roles: %r' % (updated_role_names)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |         LOG.debug('Removed roles: %r' % (removed_role_names)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         # Build a list of roles to delete | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |         role_names_to_delete = updated_role_names.union(removed_role_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |         role_dbs_to_delete = [role_db for role_db in role_dbs if | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |                               role_db.name in role_names_to_delete] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |         # Build a list of roles to create | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         role_names_to_create = new_role_names.union(updated_role_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         role_apis_to_create = [role_definition_api for role_definition_api in role_definition_apis | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |                                if role_definition_api.name in role_names_to_create] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |         ######## | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |         # 1. Remove obsolete roles and associated permission grants from the DB | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |         ######## | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |         # Remove roles | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |         role_ids_to_delete = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |         for role_db in role_dbs_to_delete: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |             role_ids_to_delete.append(role_db.id) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |         LOG.debug('Deleting %s stale roles' % (len(role_ids_to_delete))) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |         Role.query(id__in=role_ids_to_delete, system=False).delete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |         LOG.debug('Deleted %s stale roles' % (len(role_ids_to_delete))) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         # Remove associated permission grants | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |         permission_grant_ids_to_delete = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |         for role_db in role_dbs_to_delete: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |             permission_grant_ids_to_delete.extend(role_db.permission_grants) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |         LOG.debug('Deleting %s stale permission grants' % (len(permission_grant_ids_to_delete))) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |         PermissionGrant.query(id__in=permission_grant_ids_to_delete).delete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         LOG.debug('Deleted %s stale permission grants' % (len(permission_grant_ids_to_delete))) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         ######## | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |         # 2. Add new / updated roles to the DB | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |         ######## | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |         LOG.debug('Creating %s new roles' % (len(role_apis_to_create))) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |         # Create new roles | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |         created_role_dbs = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |         for role_api in role_apis_to_create: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |             role_db = rbac_services.create_role(name=role_api.name, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |                                                 description=role_api.description) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |             # Create associated permission grants | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |             permission_grants = getattr(role_api, 'permission_grants', []) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |             for permission_grant in permission_grants: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |                 resource_uid = permission_grant.get('resource_uid', None) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |                 if resource_uid: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |                     resource_type, _ = parse_uid(resource_uid) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |                 else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |                     resource_type = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |                 permission_types = permission_grant['permission_types'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |                 assignment_db = rbac_services.create_permission_grant( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |                     role_db=role_db, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |                     resource_uid=resource_uid, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |                     resource_type=resource_type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |                     permission_types=permission_types) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |                 role_db.permission_grants.append(str(assignment_db.id)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |             created_role_dbs.append(role_db) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |         LOG.debug('Created %s new roles' % (len(created_role_dbs))) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |         LOG.info('Roles synchronized (%s created, %s updated, %s removed)' % | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |                  (len(new_role_names), len(updated_role_names), len(removed_role_names))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |         return [created_role_dbs, role_dbs_to_delete] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |     def sync_users_role_assignments(self, role_assignment_apis): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |         Synchronize role assignments for all the users in the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |         :param role_assignment_apis: Role assignments API objects for the assignments loaded | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |                                       from the files. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |         :type role_assignment_apis: ``list`` of :class:`UserRoleAssignmentFileFormatAPI` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |         :return: Dictionary with created and removed role assignments for each user. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |         :rtype: ``dict`` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |         assert isinstance(role_assignment_apis, (list, tuple)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |         LOG.info('Synchronizing users role assignments...') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |         # Note: We exclude remote assignments because sync tool is not supposed to manipulate | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |         # remote assignments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |         role_assignment_dbs = rbac_services.get_all_role_assignments(include_remote=False) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         user_dbs = User.get_all() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |         username_to_user_db_map = dict([(user_db.name, user_db) for user_db in user_dbs]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |         username_to_role_assignment_apis_map = defaultdict(list) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |         username_to_role_assignment_dbs_map = defaultdict(list) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |         for role_assignment_api in role_assignment_apis: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |             username = role_assignment_api.username | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |             username_to_role_assignment_apis_map[username].append(role_assignment_api) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |         for role_assignment_db in role_assignment_dbs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |             username = role_assignment_db.user | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |             username_to_role_assignment_dbs_map[username].append(role_assignment_db) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |         # Note: We process assignments for all the users (ones specified in the assignment files | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |         # and ones which are in the database). We want to make sure assignments are correctly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |         # deleted from the database for users which existing in the database, but have no | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |         # assignment file on disk and for assignments for users which don't exist in the database. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |         all_usernames = (username_to_user_db_map.keys() + | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |                          username_to_role_assignment_apis_map.keys() + | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |                          username_to_role_assignment_dbs_map.keys()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |         all_usernames = list(set(all_usernames)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |         results = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |         for username in all_usernames: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |             user_db = username_to_user_db_map.get(username, None) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |             if not user_db: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |                 # Note: We allow assignments to be created for the users which don't exist in the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |                 # DB yet because user creation in StackStorm is lazy (we only create UserDB) object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |                 # when user first logs in. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |                 user_db = UserDB(name=username) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |                 LOG.debug(('User "%s" doesn\'t exist in the DB, creating assignment anyway' % | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |                           (username))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |             role_assignment_apis = username_to_role_assignment_apis_map.get(username, []) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |             role_assignment_dbs = username_to_role_assignment_dbs_map.get(username, []) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |             # Additional safety assert to ensure we don't accidentally manipulate remote | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |             # assignments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |             for role_assignment_db in role_assignment_dbs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |                 assert role_assignment_db.is_remote is False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |             result = self._sync_user_role_assignments( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |                 user_db=user_db, role_assignment_dbs=role_assignment_dbs, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |                 role_assignment_apis=role_assignment_apis) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |             results[username] = result | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |         LOG.info('User role assignments synchronized') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |         return results | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |     def sync_group_to_role_maps(self, group_to_role_map_apis): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |         LOG.info('Synchronizing group to role maps...') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |         # Retrieve all the mappings currently in the db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |         group_to_role_map_dbs = rbac_services.get_all_group_to_role_maps() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |         # 1. Delete all the existing mappings in the db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |         group_to_role_map_to_delete = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |         for group_to_role_map_db in group_to_role_map_dbs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |             group_to_role_map_to_delete.append(group_to_role_map_db.id) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |         GroupToRoleMapping.query(id__in=group_to_role_map_to_delete).delete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |         # 2. Insert all mappings read from disk | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |         for group_to_role_map_api in group_to_role_map_apis: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |             source = getattr(group_to_role_map_api, 'file_path', None) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |             rbac_services.create_group_to_role_map(group=group_to_role_map_api.group, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |                                                    roles=group_to_role_map_api.roles, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |                                                    description=group_to_role_map_api.description, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |                                                    enabled=group_to_role_map_api.enabled, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |                                                    source=source) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |         LOG.info('Group to role map definitions synchronized.') | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 274 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 275 |  |  |     def _sync_user_role_assignments(self, user_db, role_assignment_dbs, role_assignment_apis): | 
            
                                                                        
                            
            
                                    
            
            
                | 276 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 277 |  |  |         Synchronize role assignments for a particular user. | 
            
                                                                        
                            
            
                                    
            
            
                | 278 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 279 |  |  |         :param user_db: User to synchronize the assignments for. | 
            
                                                                        
                            
            
                                    
            
            
                | 280 |  |  |         :type user_db: :class:`UserDB` | 
            
                                                                        
                            
            
                                    
            
            
                | 281 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 282 |  |  |         :param role_assignment_dbs: Existing user role assignments. | 
            
                                                                        
                            
            
                                    
            
            
                | 283 |  |  |         :type role_assignment_dbs: ``list`` of :class:`UserRoleAssignmentDB` | 
            
                                                                        
                            
            
                                    
            
            
                | 284 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 285 |  |  |         :param role_assignment_apis: List of user role assignments to apply. | 
            
                                                                        
                            
            
                                    
            
            
                | 286 |  |  |         :param role_assignment_apis: ``list`` of :class:`UserRoleAssignmentFileFormatAPI` | 
            
                                                                        
                            
            
                                    
            
            
                | 287 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 288 |  |  |         :rtype: ``tuple`` | 
            
                                                                        
                            
            
                                    
            
            
                | 289 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 290 |  |  |         db_roles = set([(entry.role, entry.source) for entry in role_assignment_dbs]) | 
            
                                                                        
                            
            
                                    
            
            
                | 291 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 292 |  |  |         api_roles = [ | 
            
                                                                        
                            
            
                                    
            
            
                | 293 |  |  |             list(itertools.izip_longest(entry.roles, [], fillvalue=entry.file_path)) | 
            
                                                                        
                            
            
                                    
            
            
                | 294 |  |  |             for entry in role_assignment_apis | 
            
                                                                        
                            
            
                                    
            
            
                | 295 |  |  |         ] | 
            
                                                                        
                            
            
                                    
            
            
                | 296 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 297 |  |  |         api_roles = set(list(itertools.chain.from_iterable(api_roles))) | 
            
                                                                        
                            
            
                                    
            
            
                | 298 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 299 |  |  |         # A list of new assignments which should be added to the database | 
            
                                                                        
                            
            
                                    
            
            
                | 300 |  |  |         new_roles = api_roles.difference(db_roles) | 
            
                                                                        
                            
            
                                    
            
            
                | 301 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 302 |  |  |         # A list of assignments which need to be updated in the database | 
            
                                                                        
                            
            
                                    
            
            
                | 303 |  |  |         updated_roles = db_roles.intersection(api_roles) | 
            
                                                                        
                            
            
                                    
            
            
                | 304 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 305 |  |  |         # A list of assignments which should be removed from the database | 
            
                                                                        
                            
            
                                    
            
            
                | 306 |  |  |         removed_roles = (db_roles - api_roles) | 
            
                                                                        
                            
            
                                    
            
            
                | 307 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 308 |  |  |         LOG.debug('New assignments for user "%s": %r' % (user_db.name, new_roles)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 309 |  |  |         LOG.debug('Updated assignments for user "%s": %r' % (user_db.name, updated_roles)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 310 |  |  |         LOG.debug('Removed assignments for user "%s": %r' % (user_db.name, removed_roles)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 311 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 312 |  |  |         # Build a list of role assignments to delete | 
            
                                                                        
                            
            
                                    
            
            
                | 313 |  |  |         roles_to_delete = updated_roles.union(removed_roles) | 
            
                                                                        
                            
            
                                    
            
            
                | 314 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 315 |  |  |         role_assignment_dbs_to_delete = [ | 
            
                                                                        
                            
            
                                    
            
            
                | 316 |  |  |             role_assignment_db for role_assignment_db in role_assignment_dbs | 
            
                                                                        
                            
            
                                    
            
            
                | 317 |  |  |             if (role_assignment_db.role, role_assignment_db.source) in roles_to_delete | 
            
                                                                        
                            
            
                                    
            
            
                | 318 |  |  |         ] | 
            
                                                                        
                            
            
                                    
            
            
                | 319 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 320 |  |  |         for role_name, assignment_source in roles_to_delete: | 
            
                                                                        
                            
            
                                    
            
            
                | 321 |  |  |             queryset_filter = ( | 
            
                                                                        
                            
            
                                    
            
            
                | 322 |  |  |                 Q(user=user_db.name) & | 
            
                                                                        
                            
            
                                    
            
            
                | 323 |  |  |                 Q(role=role_name) & | 
            
                                                                        
                            
            
                                    
            
            
                | 324 |  |  |                 Q(source=assignment_source) & | 
            
                                                                        
                            
            
                                    
            
            
                | 325 |  |  |                 (Q(is_remote=False) | Q(is_remote__exists=False)) | 
            
                                                                        
                            
            
                                    
            
            
                | 326 |  |  |             ) | 
            
                                                                        
                            
            
                                    
            
            
                | 327 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 328 |  |  |             UserRoleAssignmentDB.objects(queryset_filter).delete() | 
            
                                                                        
                            
            
                                    
            
            
                | 329 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 330 |  |  |             LOG.debug('Removed role "%s" from "%s" for user "%s".' % (role_name, assignment_source, | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 331 |  |  |                                                                       user_db.name)) | 
            
                                                                        
                            
            
                                    
            
            
                | 332 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 333 |  |  |         # Build a list of roles assignments to create | 
            
                                                                        
                            
            
                                    
            
            
                | 334 |  |  |         roles_to_create = new_roles.union(updated_roles) | 
            
                                                                        
                            
            
                                    
            
            
                | 335 |  |  |         created_role_assignment_dbs = [] | 
            
                                                                        
                            
            
                                    
            
            
                | 336 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 337 |  |  |         for role_name, assignment_source in roles_to_create: | 
            
                                                                        
                            
            
                                    
            
            
                | 338 |  |  |             role_db = Role.get(name=role_name) | 
            
                                                                        
                            
            
                                    
            
            
                | 339 |  |  |             if not role_db: | 
            
                                                                        
                            
            
                                    
            
            
                | 340 |  |  |                 msg = 'Role "%s" referenced in assignment file "%s" doesn\'t exist' | 
            
                                                                        
                            
            
                                    
            
            
                | 341 |  |  |                 raise ValueError(msg % (role_name, assignment_source)) | 
            
                                                                        
                            
            
                                    
            
            
                | 342 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 343 |  |  |             role_assignment_api = [r for r in role_assignment_apis if | 
            
                                                                        
                            
            
                                    
            
            
                | 344 |  |  |                                    r.file_path == assignment_source][0] | 
            
                                                                        
                            
            
                                    
            
            
                | 345 |  |  |             description = getattr(role_assignment_api, 'description', None) | 
            
                                                                        
                            
            
                                    
            
            
                | 346 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 347 |  |  |             assignment_db = rbac_services.assign_role_to_user( | 
            
                                                                        
                            
            
                                    
            
            
                | 348 |  |  |                 role_db=role_db, user_db=user_db, source=assignment_source, description=description) | 
            
                                                                        
                            
            
                                    
            
            
                | 349 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 350 |  |  |             created_role_assignment_dbs.append(assignment_db) | 
            
                                                                        
                            
            
                                    
            
            
                | 351 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 352 |  |  |             LOG.debug('Assigned role "%s" from "%s" for user "%s".' % | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 353 |  |  |                 (role_name, assignment_source, user_db.name)) | 
            
                                                                        
                            
            
                                    
            
            
                | 354 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 355 |  |  |         return (created_role_assignment_dbs, role_assignment_dbs_to_delete) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  | class RBACRemoteGroupToRoleSyncer(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |     Class which writes remote user role assignments based on the user group membership information | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |     provided by the auth backend and based on the group to role mapping definitions on disk. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |     def sync(self, user_db, groups): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |         :param user_db: User to sync the assignments for. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |         :type user: :class:`UserDB` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |         :param groups: A list of remote groups user is a member of. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |         :type groups: ``list`` of ``str`` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |         :return: A list of mappings which have been created. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |         :rtype: ``list`` of :class:`UserRoleAssignmentDB` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |         groups = list(set(groups)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |         extra = {'user_db': user_db, 'groups': groups} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |         LOG.info('Synchronizing remote role assignments for user "%s"' % (str(user_db)), | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |                  extra=extra) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |         # 1. Retrieve group to role mappings for the provided groups | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |         all_mapping_dbs = GroupToRoleMapping.query(group__in=groups) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |         enabled_mapping_dbs = [mapping_db for mapping_db in all_mapping_dbs if | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |                                mapping_db.enabled] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  |         disabled_mapping_dbs = [mapping_db for mapping_db in all_mapping_dbs if | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |                                 not mapping_db.enabled] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |         if not all_mapping_dbs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |             LOG.debug('No group to role mappings found for user "%s"' % (str(user_db)), extra=extra) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |         # 2. Remove all the existing remote role assignments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |         remote_assignment_dbs = UserRoleAssignment.query(user=user_db.name, is_remote=True) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |         existing_role_names = [assignment_db.role for assignment_db in remote_assignment_dbs] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |         existing_role_names = set(existing_role_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |         current_role_names = set([]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |         for mapping_db in all_mapping_dbs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |             for role in mapping_db.roles: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  |                 current_role_names.add(role) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |         # A list of new role assignments which should be added to the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |         new_role_names = current_role_names.difference(existing_role_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  |         # A list of role assignments which need to be updated in the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |         updated_role_names = existing_role_names.intersection(current_role_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |         # A list of role assignments which should be removed from the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |         removed_role_names = (existing_role_names - new_role_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  |         # Also remove any assignments for mappings which are disabled in the database | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |         for mapping_db in disabled_mapping_dbs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  |             for role in mapping_db.roles: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |                 removed_role_names.add(role) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |         LOG.debug('New role assignments: %r' % (new_role_names)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |         LOG.debug('Updated role assignments: %r' % (updated_role_names)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |         LOG.debug('Removed role assignments: %r' % (removed_role_names)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |         # Build a list of role assignments to delete | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |         role_names_to_delete = updated_role_names.union(removed_role_names) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  |         role_assignment_dbs_to_delete = [role_assignment_db for role_assignment_db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 |  |  |                                          in remote_assignment_dbs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  |                                          if role_assignment_db.role in role_names_to_delete] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 |  |  |         UserRoleAssignment.query(user=user_db.name, role__in=role_names_to_delete, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  |                                  is_remote=True).delete() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |         # 3. Create role assignments for all the current groups | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  |         created_assignments_dbs = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |         for mapping_db in enabled_mapping_dbs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |             extra['mapping_db'] = mapping_db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  |             for role_name in mapping_db.roles: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  |                 role_db = rbac_services.get_role_by_name(name=role_name) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 |  |  |                 if not role_db: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 |  |  |                     # Gracefully skip assignment for role which doesn't exist in the db | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 |  |  |                     LOG.info('Role with name "%s" for mapping "%s" not found, skipping assignment.' | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 |  |  |                              % (role_name, str(mapping_db)), extra=extra) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 |  |  |                     continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  |                 description = ('Automatic role assignment based on the remote user membership in ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 |  |  |                                'group "%s"' % (mapping_db.group)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 |  |  |                 assignment_db = rbac_services.assign_role_to_user(role_db=role_db, user_db=user_db, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 |  |  |                                                                   description=description, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 |  |  |                                                                   is_remote=True, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 |  |  |                                                                   source=mapping_db.source) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 |  |  |                 assert assignment_db.is_remote is True | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 |  |  |                 created_assignments_dbs.append(assignment_db) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 |  |  |         LOG.debug('Created %s new remote role assignments for user "%s"' % | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 |  |  |                   (len(created_assignments_dbs), str(user_db)), extra=extra) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 455 |  |  |         return (created_assignments_dbs, role_assignment_dbs_to_delete) | 
            
                                                        
            
                                    
            
            
                | 456 |  |  |  |