def check_user_necessary_labels(self, user, group): """ Check if `user` has all the necessary labels for membership in `group`. :param str name: name of the user to check :param str group: name of the group to check :returns: True if `user ` has all required labels, False otherwise :rtype: bool :raises ManagerError: if `user` or `group` is not defined in config """ user_entity = find_entity(self.entities, 'user', user) if not user_entity: raise ManagerError('User %s does not exist in config' % user) group_entity = find_entity(self.entities, 'group', group) if not group_entity: raise ManagerError('Group %s does not exist in config' % group) user_labels = self._get_labels(user_entity) required = self._list_necessary_labels(group_entity, include_self=True) result = all(label in user_labels for label in required) if result: self.lg.info('User %s DOES have all required labels for group %s', user, group) else: self.lg.info('User %s DOES NOT have required labels for group %s', user, group) return result
def build_graph(self, member): """ Find all entities of which `member` is a member. Utilizes the `graph` attribute for caching in case several entities with overlapping membership graphs are evaluated. :param FreeIPAEntity member: entity to search from :returns: list of entities that `member` is a member of :rtype: [FreeIPAEntity] """ result = self.graph.get(member, set()) if result: self.lg.debug('Membership for %s already calculated', member) return result self.lg.debug('Calculating membership graph for %s', member) memberof = member.data_repo.get('memberOf', {}) for entity_type, entity_list in memberof.iteritems(): for entity_name in entity_list: entity = find_entity(self.entities, entity_type, entity_name) result.add(entity) if entity in self.ancestors: self.ancestors[entity].append(member) else: self.ancestors[entity] = [member] result.update(self.build_graph(entity)) self.lg.debug('Found %d entities for %s', len(result), member) self.graph[member] = result return result
def check_user_membership(self, user, group): """ Check if `user` is a member of a `group`. This function serves as a wrapper for easy usage from other scripts. :param str user: name of the user to check :param str group: name of the group to check :returns: True if `user` is a member of `group`, False otherwise :rtype: bool """ user_entity = find_entity(self.entities, 'user', user) if not user_entity: raise ManagerError('User %s does not exist in config' % user) group_entity = find_entity(self.entities, 'group', group) if not group_entity: raise ManagerError('Group %s does not exist in config' % group) return bool(self.check_membership(user_entity, group_entity))
def list_groups(self, user): """ Find all groups that `user` is a member of. This function serves as a wrapper for easy import into other scripts. :param str user: name of the user to check :returns: generator of group names that `user` is a member of :rtype: generator """ user_entity = find_entity(self.entities, 'user', user) if not user_entity: raise ManagerError('User %s does not exist in config' % user) groups = self.build_graph(user_entity) return (i.name for i in groups)
def _resolve_entities(self, entity_list): """ Find entities from config based on their types and names. :param [str] entity_list: entities in type:name format :returns: list of resolved entities :rtype: [FreeIPAEntity] :raises ManagerError: if an entity is not defined in config """ result = [] for entity_type, entity_name in entity_list: resolved = find_entity(self.entities, entity_type, entity_name) if not resolved: raise ManagerError('%s %s not found in config' % (entity_type, entity_name)) result.append(resolved) return result
def check_label_necessary(self, label, group): """ Check if `label` is necessary for membership in `group`. :param str label: label value :param str group: name of the group to start the check from :returns: True if `label` is needed, False otherwise :rtype: bool :raises ManagerError: if `group` is not defined in config """ group_entity = find_entity(self.entities, 'group', group) if not group_entity: raise ManagerError('Group %s does not exist in config' % group) labels = self._list_necessary_labels(group_entity, include_self=True) result = label in labels if result: self.lg.info('Label %s IS necessary for group %s', label, group) else: self.lg.info("Label %s ISN'T necessary for group %s", label, group) return result
def list_necessary_labels(self, group): """ Find labels that an entity needs to have based on its membership. Serves as wrapper around the related private method (plus entity resolution based on group name). :param str group: name of group whose labels to list :returns: list of labels defined for nested groups (and entity itself) :rtype: [str] :raises ManagerError: if `group` is not defined in config """ group_entity = find_entity(self.entities, 'group', group) if not group_entity: raise ManagerError('Group %s does not exist in config' % group) labels = self._list_necessary_labels(group_entity, include_self=True) if labels: self.lg.info('Group %s requires labels: [%s]', group, ', '.join(labels)) else: self.lg.info('Group %s requires NO labels', group) return labels
def list_user_missing_labels(self, user): """ List labels that a user is missing and is expected to have based on their group membership. :param str user: name of user whose labels to check :returns: set of labels that `user` is missing :rtype: {str} :raises ManagerError: if `user` is not defined in config """ user_entity = find_entity(self.entities, 'user', user) if not user_entity: raise ManagerError('User %s does not exist in config' % user) necessary = set(self.list_necessary_labels(user_entity)) current = set(self._get_labels(user_entity)) missing = necessary.difference(current) if missing: self.lg.info('User %s misses labels: {%s}', user, ', '.join(missing)) else: self.lg.info('User %s misses NO labels', user) return missing