def add_role_to_user_and_project(self, user_id, tenant_id, role_id): with sql.transaction() as session: self._get_project(session, tenant_id) self._get_role(session, role_id) try: with sql.transaction() as session: session.add(RoleAssignment( type=AssignmentType.USER_PROJECT, actor_id=user_id, target_id=tenant_id, role_id=role_id, inherited=False)) except sql.DBDuplicateEntry: msg = ('User %s already has role %s in tenant %s' % (user_id, role_id, tenant_id)) raise exception.Conflict(type='role grant', details=msg)
def create_project(self, project_id, project): project['name'] = clean.project_name(project['name']) new_project = self._encode_domain_id(project) with sql.transaction() as session: project_ref = Project.from_dict(new_project) session.add(project_ref) return project_ref.to_dict()
def delete_project_assignments(self, project_id): with sql.transaction() as session: q = session.query(RoleAssignment) q = q.filter_by(target_id=project_id).filter( RoleAssignment.type.in_((AssignmentType.USER_PROJECT, AssignmentType.GROUP_PROJECT)) ) q.delete(False)
def get_domain_by_name(self, domain_name): with sql.transaction() as session: try: ref = session.query(Domain).filter_by(name=domain_name).one() except sql.NotFound: raise exception.DomainNotFound(domain_id=domain_name) return ref.to_dict()
def list_implied_roles(self, prior_role_id): with sql.transaction() as session: query = session.query( ImpliedRoleTable).filter( ImpliedRoleTable.prior_role_id == prior_role_id) refs = query.all() return [ref.to_dict() for ref in refs]
def add_role_to_user_and_project(self, user_id, tenant_id, role_id): with sql.transaction() as session: self._get_project(session, tenant_id) self._get_role(session, role_id) try: metadata_ref = self._get_metadata(user_id, tenant_id, session=session) is_new = False except exception.MetadataNotFound: metadata_ref = {} is_new = True try: metadata_ref['roles'] = self._add_role_to_role_dicts( role_id, False, metadata_ref.get('roles', []), allow_existing=False) except KeyError: msg = ('User %s already has role %s in tenant %s' % (user_id, role_id, tenant_id)) raise exception.Conflict(type='role grant', details=msg) if is_new: self._create_metadata(session, user_id, tenant_id, metadata_ref) else: self._update_metadata(session, user_id, tenant_id, metadata_ref)
def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): with sql.transaction() as session: try: metadata_ref = self._get_metadata(user_id, tenant_id, session=session) except exception.MetadataNotFound: raise exception.RoleNotFound(message=_( 'Cannot remove role that has not been granted, %s') % role_id) try: metadata_ref['roles'] = self._remove_role_from_role_dicts( role_id, False, metadata_ref.get('roles', [])) except KeyError: raise exception.RoleNotFound(message=_( 'Cannot remove role that has not been granted, %s') % role_id) if metadata_ref['roles']: self._update_metadata(session, user_id, tenant_id, metadata_ref) else: q = session.query(UserProjectGrant) q = q.filter_by(user_id=user_id) q = q.filter_by(project_id=tenant_id) q.delete()
def delete_role(self, role_id): with sql.transaction() as session: ref = self._get_role(session, role_id) for metadata_ref in session.query(UserProjectGrant): try: self._delete_grant(session, role_id, user_id=metadata_ref.user_id, project_id=metadata_ref.project_id) except exception.RoleNotFound: pass for metadata_ref in session.query(UserDomainGrant): try: self._delete_grant(session, role_id, user_id=metadata_ref.user_id, domain_id=metadata_ref.domain_id) except exception.RoleNotFound: pass for metadata_ref in session.query(GroupProjectGrant): try: self._delete_grant(session, role_id, group_id=metadata_ref.group_id, project_id=metadata_ref.project_id) except exception.RoleNotFound: pass for metadata_ref in session.query(GroupDomainGrant): try: self._delete_grant(session, role_id, group_id=metadata_ref.group_id, domain_id=metadata_ref.domain_id) except exception.RoleNotFound: pass session.delete(ref)
def create_grant(self, role_id, user_id=None, group_id=None, domain_id=None, project_id=None, inherited_to_projects=False): with sql.transaction() as session: self._get_role(session, role_id) if domain_id: self._get_domain(session, domain_id) if project_id: self._get_project(session, project_id) if project_id and inherited_to_projects: msg = _('Inherited roles can only be assigned to domains') raise exception.Conflict(type='role grant', details=msg) try: metadata_ref = self._get_metadata(user_id, project_id, domain_id, group_id, session=session) is_new = False except exception.MetadataNotFound: metadata_ref = {} is_new = True metadata_ref['roles'] = self._add_role_to_role_dicts( role_id, inherited_to_projects, metadata_ref.get('roles', [])) if is_new: self._create_metadata(session, user_id, project_id, metadata_ref, domain_id, group_id) else: self._update_metadata(session, user_id, project_id, metadata_ref, domain_id, group_id)
def update_config_option(self, domain_id, group, option, value, sensitive=False): with sql.transaction() as session: ref = self._get_config_option(session, domain_id, group, option, sensitive) ref.value = value return ref.to_dict()
def list_role_assignments(self): def denormalize_role(ref): assignment = {} if ref.type == AssignmentType.USER_PROJECT: assignment['user_id'] = ref.actor_id assignment['project_id'] = ref.target_id elif ref.type == AssignmentType.USER_DOMAIN: assignment['user_id'] = ref.actor_id assignment['domain_id'] = ref.target_id elif ref.type == AssignmentType.GROUP_PROJECT: assignment['group_id'] = ref.actor_id assignment['project_id'] = ref.target_id elif ref.type == AssignmentType.GROUP_DOMAIN: assignment['group_id'] = ref.actor_id assignment['domain_id'] = ref.target_id else: raise exception.Error(message=_( 'Unexpected assignment type encountered, %s') % ref.type) assignment['role_id'] = ref.role_id if ref.inherited and (ref.type == AssignmentType.USER_DOMAIN or ref.type == AssignmentType.GROUP_DOMAIN): assignment['inherited_to_projects'] = 'projects' return assignment with sql.transaction() as session: refs = session.query(RoleAssignment).all() return [denormalize_role(ref) for ref in refs]
def delete_role(self, role_id): with sql.transaction() as session: ref = self._get_role(session, role_id) q = session.query(RoleAssignment) q = q.filter_by(role_id=role_id) q.delete(False) session.delete(ref)
def list_domain_ids_for_user(self, user_id, group_ids, hints, inherited=False): with sql.transaction() as session: query = session.query(RoleAssignment.target_id) filters = [] if user_id: sql_constraints = sqlalchemy.and_( RoleAssignment.actor_id == user_id, RoleAssignment.inherited == inherited, RoleAssignment.type == AssignmentType.USER_DOMAIN) filters.append(sql_constraints) if group_ids: sql_constraints = sqlalchemy.and_( RoleAssignment.actor_id.in_(group_ids), RoleAssignment.inherited == inherited, RoleAssignment.type == AssignmentType.GROUP_DOMAIN) filters.append(sql_constraints) if not filters: return [] query = query.filter(sqlalchemy.or_(*filters)).distinct() return [assignment.target_id for assignment in query.all()]
def get_sidinfo(self, sid_id): with sql.transaction() as session: sidinfo_ref = session.query(Sidinfo).get(sid_id) print("assignment/backends/sql.py: sidinfo = ", sidinfo_ref) if sidinfo_ref is None: return None return sidinfo_ref.to_dict()
def list_projects_for_user(self, user_id, group_ids, hints): # TODO(henry-nash): Now that we have a single assignment table, we # should be able to honor the hints list that is provided. with sql.transaction() as session: # First get a list of the projects and domains for which the user # has any kind of role assigned actor_list = [user_id] if group_ids: actor_list = actor_list + group_ids query = session.query(RoleAssignment) query = query.filter(RoleAssignment.actor_id.in_(actor_list)) assignments = query.all() project_ids = set() for assignment in assignments: # NOTE(rodrigods): First, we always include projects with # non-inherited assignments if ((assignment.type == AssignmentType.USER_PROJECT or assignment.type == AssignmentType.GROUP_PROJECT) and not assignment.inherited): project_ids.add(assignment.target_id) if not CONF.os_inherit.enabled: return self._project_ids_to_dicts(session, project_ids) # Inherited roles are enabled, so check to see if this user has any # inherited role (direct or group) on any parent project, in which # case we must add in all the projects in that parent's subtree. for assignment in assignments: if ((assignment.type == AssignmentType.USER_PROJECT or assignment.type == AssignmentType.GROUP_PROJECT) and assignment.inherited): project_ids.update( (x['id'] for x in self.list_projects_in_subtree(assignment.target_id))) # Use the same logic above to domains domain_ids = set() for assignment in assignments: if ((assignment.type == AssignmentType.USER_DOMAIN or assignment.type == AssignmentType.GROUP_DOMAIN) and assignment.inherited): domain_ids.add(assignment.target_id) # Get the projects that are owned by all of these domains and # add them in to the project id list if domain_ids: query = session.query(Project.id) query = query.filter(Project.domain_id.in_(domain_ids)) for project_ref in query.all(): project_ids.add(project_ref.id) return self._project_ids_to_dicts(session, project_ids)
def create_grant( self, role_id, user_id=None, group_id=None, domain_id=None, project_id=None, inherited_to_projects=False ): def calculate_type(user_id, group_id, project_id, domain_id): if user_id and project_id: return AssignmentType.USER_PROJECT elif user_id and domain_id: return AssignmentType.USER_DOMAIN elif group_id and project_id: return AssignmentType.GROUP_PROJECT elif group_id and domain_id: return AssignmentType.GROUP_DOMAIN else: message_data = ", ".join([user_id, group_id, project_id, domain_id]) raise exception.Error( message=_("Unexpected combination of grant attributes - " "User, Group, Project, Domain: %s") % message_data ) with sql.transaction() as session: self._get_role(session, role_id) if domain_id: self._get_domain(session, domain_id) if project_id: self._get_project(session, project_id) if project_id and inherited_to_projects: msg = _("Inherited roles can only be assigned to domains") raise exception.Conflict(type="role grant", details=msg) type = calculate_type(user_id, group_id, project_id, domain_id) try: with sql.transaction() as session: session.add( RoleAssignment( type=type, actor_id=user_id or group_id, target_id=project_id or domain_id, role_id=role_id, inherited=inherited_to_projects, ) ) except sql.DBDuplicateEntry: # The v3 grant APIs are silent if the assignment already exists pass
def list_user_ids_for_project(self, tenant_id): with sql.transaction() as session: query = session.query(RoleAssignment.actor_id) query = query.filter_by(type=AssignmentType.USER_PROJECT) query = query.filter_by(target_id=tenant_id) query = query.distinct('actor_id') assignments = query.all() return [assignment.actor_id for assignment in assignments]
def delete_id_mapping(self, public_id): with sql.transaction() as session: try: session.query(IDMapping).filter(IDMapping.public_id == public_id).delete() except sql.NotFound: # NOTE(morganfainberg): There is nothing to delete and nothing # to do. pass
def list_project_ids_from_domain_ids(self, domain_ids): if not domain_ids: return [] else: with sql.transaction() as session: query = session.query(Project.id) query = query.filter(Project.domain_id.in_(domain_ids)) return [x.id for x in query.all()]
def list_role_ids_from_domain_ids(self, domain_ids): if not domain_ids: return [] else: with sql.transaction() as session: query = session.query(RoleTalbe.id) query = ( query.filter(RoleTable.domain_id.in_(domain_ids)))
def release_registration(self, domain_id, type=None): """Silently delete anything registered for the domain specified.""" with sql.transaction() as session: query = session.query(ConfigRegister) if type: query = query.filter_by(type=type) query = query.filter_by(domain_id=domain_id) query.delete(False)
def create_config_option(self, domain_id, group, option, value, sensitive=False): with sql.transaction() as session: config_table = self.choose_table(sensitive) ref = config_table(domain_id=domain_id, group=group, option=option, value=value) session.add(ref) return ref.to_dict()
def create_protocol(self, idp_id, protocol_id, protocol): protocol['id'] = protocol_id protocol['idp_id'] = idp_id with sql.transaction() as session: self._get_idp(session, idp_id) protocol_ref = FederationProtocolModel.from_dict(protocol) session.add(protocol_ref) return protocol_ref.to_dict()
def list_roles_from_ids(self, ids): if not ids: return [] else: with sql.transaction() as session: query = session.query(RoleTable) query = query.filter(RoleTable.id.in_(ids)) return [role_ref.to_dict() for role_ref in query.all()]
def list_projects_from_ids(self, ids): if not ids: return [] else: with sql.transaction() as session: query = session.query(Project) query = query.filter(Project.id.in_(ids)) return [project_ref.to_dict() for project_ref in query.all()]
def delete_grant(self, role_id, user_id=None, group_id=None, domain_id=None, project_id=None, inherited_to_projects=False): with sql.transaction() as session: self._delete_grant(session=session, role_id=role_id, user_id=user_id, group_id=group_id, domain_id=domain_id, project_id=project_id, inherited_to_projects=inherited_to_projects)
def list_user_ids_for_project(self, tenant_id): with sql.transaction() as session: self._get_project(session, tenant_id) query = session.query(UserProjectGrant) query = query.filter(UserProjectGrant.project_id == tenant_id) project_refs = query.all() return [project_ref.user_id for project_ref in project_refs]
def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): with sql.transaction() as session: q = session.query(RoleAssignment) q = q.filter_by(actor_id=user_id) q = q.filter_by(target_id=tenant_id) q = q.filter_by(role_id=role_id) if q.delete() == 0: raise exception.RoleNotFound(message=_("Cannot remove role that has not been granted, %s") % role_id)
def create_mapping(self, mapping_id, mapping): ref = {} ref['id'] = mapping_id ref['rules'] = mapping.get('rules') with sql.transaction() as session: mapping_ref = MappingModel.from_dict(ref) session.add(mapping_ref) return mapping_ref.to_dict()
def list_role_assignments(self, role_id=None, user_id=None, group_ids=None, domain_id=None, project_ids=None, inherited_to_projects=None): def denormalize_role(ref): assignment = {} if ref.type == AssignmentType.USER_PROJECT: assignment['user_id'] = ref.actor_id assignment['project_id'] = ref.target_id elif ref.type == AssignmentType.USER_DOMAIN: assignment['user_id'] = ref.actor_id assignment['domain_id'] = ref.target_id elif ref.type == AssignmentType.GROUP_PROJECT: assignment['group_id'] = ref.actor_id assignment['project_id'] = ref.target_id elif ref.type == AssignmentType.GROUP_DOMAIN: assignment['group_id'] = ref.actor_id assignment['domain_id'] = ref.target_id else: raise exception.Error(message=_( 'Unexpected assignment type encountered, %s') % ref.type) assignment['role_id'] = ref.role_id if ref.inherited: assignment['inherited_to_projects'] = 'projects' return assignment with sql.transaction() as session: assignment_types = self._get_assignment_types( user_id, group_ids, project_ids, domain_id) targets = None if project_ids: targets = project_ids elif domain_id: targets = [domain_id] actors = None if group_ids: actors = group_ids elif user_id: actors = [user_id] query = session.query(RoleAssignment) if role_id: query = query.filter_by(role_id=role_id) if actors: query = query.filter(RoleAssignment.actor_id.in_(actors)) if targets: query = query.filter(RoleAssignment.target_id.in_(targets)) if assignment_types: query = query.filter(RoleAssignment.type.in_(assignment_types)) if inherited_to_projects is not None: query = query.filter_by(inherited=inherited_to_projects) return [denormalize_role(ref) for ref in query.all()]
def delete_group(self, group_id): with sql.transaction() as session: q = session.query(RoleAssignment) q = q.filter_by(actor_id=group_id) q.delete(False)
def delete_mapping(self, mapping_id): with sql.transaction() as session: mapping_ref = self._get_mapping(session, mapping_id) session.delete(mapping_ref)
def get_mapping(self, mapping_id): with sql.transaction() as session: mapping_ref = self._get_mapping(session, mapping_id) return mapping_ref.to_dict()
def list_mappings(self): with sql.transaction() as session: mappings = session.query(MappingModel) return [x.to_dict() for x in mappings]
def get_enabled_service_providers(self): with sql.transaction() as session: service_providers = session.query(ServiceProviderModel) service_providers = service_providers.filter_by(enabled=True) return service_providers
def list_projects(self, hints): with sql.transaction() as session: query = session.query(Project) project_refs = sql.filter_limit_query(Project, query, hints) return [project_ref.to_dict() for project_ref in project_refs]
def create_project(self, tenant_id, tenant): tenant['name'] = clean.project_name(tenant['name']) with sql.transaction() as session: tenant_ref = Project.from_dict(tenant) session.add(tenant_ref) return tenant_ref.to_dict()
def get_mapping_from_idp_and_protocol(self, idp_id, protocol_id): with sql.transaction() as session: protocol_ref = self._get_protocol(session, idp_id, protocol_id) mapping_id = protocol_ref.mapping_id mapping_ref = self._get_mapping(session, mapping_id) return mapping_ref.to_dict()
def get_role(self, role_id): with sql.transaction() as session: return self._get_role(session, role_id).to_dict()
def create_domain(self, domain_id, domain): with sql.transaction() as session: ref = Domain.from_dict(domain) session.add(ref) return ref.to_dict()
def delete_protocol(self, idp_id, protocol_id): with sql.transaction() as session: key_ref = self._get_protocol(session, idp_id, protocol_id) session.delete(key_ref)
def delete_idp(self, idp_id): with sql.transaction() as session: self._delete_assigned_protocols(session, idp_id) idp_ref = self._get_idp(session, idp_id) session.delete(idp_ref)
def delete_sp(self, sp_id): with sql.transaction() as session: sp_ref = self._get_sp(session, sp_id) session.delete(sp_ref)
def get_sp(self, sp_id): with sql.transaction() as session: sp_ref = self._get_sp(session, sp_id) return sp_ref.to_dict()
def list_sps(self): with sql.transaction() as session: sps = session.query(ServiceProviderModel) sps_list = [sp.to_dict() for sp in sps] return sps_list
def create_role(self, role_id, role): with sql.transaction() as session: ref = Role.from_dict(role) session.add(ref) return ref.to_dict()
def list_roles(self, hints): with sql.transaction() as session: query = session.query(Role) refs = sql.filter_limit_query(Role, query, hints) return [ref.to_dict() for ref in refs]
def get_protocol(self, idp_id, protocol_id): with sql.transaction() as session: protocol_ref = self._get_protocol(session, idp_id, protocol_id) return protocol_ref.to_dict()
def get_domain(self, domain_id): with sql.transaction() as session: return self._get_domain(session, domain_id).to_dict()
def list_protocols(self, idp_id): with sql.transaction() as session: q = session.query(FederationProtocolModel) q = q.filter_by(idp_id=idp_id) protocols = [protocol.to_dict() for protocol in q] return protocols
def get_idp(self, idp_id): with sql.transaction() as session: idp_ref = self._get_idp(session, idp_id) return idp_ref.to_dict()
def get_idp_from_remote_id(self, remote_id): with sql.transaction() as session: ref = self._get_idp_from_remote_id(session, remote_id) return ref.to_dict()
def get_project(self, tenant_id): with sql.transaction() as session: return self._get_project(session, tenant_id).to_dict()
def list_idps(self): with sql.transaction() as session: idps = session.query(IdentityProviderModel) idps_list = [idp.to_dict() for idp in idps] return idps_list
def create_sp(self, sp_id, sp): sp['id'] = sp_id with sql.transaction() as session: sp_ref = ServiceProviderModel.from_dict(sp) session.add(sp_ref) return sp_ref.to_dict()
def create_idp(self, idp_id, idp): idp['id'] = idp_id with sql.transaction() as session: idp_ref = IdentityProviderModel.from_dict(idp) session.add(idp_ref) return idp_ref.to_dict()
def list_projects_in_domain(self, domain_id): with sql.transaction() as session: self._get_domain(session, domain_id) query = session.query(Project) project_refs = query.filter_by(domain_id=domain_id) return [project_ref.to_dict() for project_ref in project_refs]