def _validate_event_types(event_types): if not isinstance(event_types, (tuple, list)) or len(event_types) == 0: raise InvalidValue(['event_types']) invalid_event_types = [ e for e in event_types if e not in ALL_EVENT_TYPES and e != '*' ] if len(invalid_event_types) > 0: raise InvalidValue(['event_types'])
def register(consumer_id, display_name=None, description=None, notes=None, capabilities=None, rsa_pub=None): """ Registers a new Consumer :param consumer_id: unique identifier for the consumer :type consumer_id: str :param rsa_pub: The consumer public key used for message authentication. :type rsa_pub: str :param display_name: user-friendly name for the consumer :type display_name: str :param description: user-friendly text describing the consumer :type description: str :param notes: key-value pairs to pragmatically tag the consumer :type notes: dict :param capabilities: operations supported on the consumer :type capabilities: dict :raises DuplicateResource: if there is already a consumer or a used with the requested ID :raises InvalidValue: if any of the fields is unacceptable :return: A tuple of: (consumer, certificate) :rtype: tuple """ if not is_consumer_id_valid(consumer_id): raise InvalidValue(['id']) collection = Consumer.get_collection() consumer = collection.find_one({'id': consumer_id}) if consumer is not None: raise DuplicateResource(consumer_id) if notes is not None and not isinstance(notes, dict): raise InvalidValue(['notes']) if capabilities is not None and not isinstance(capabilities, dict): raise InvalidValue(['capabilities']) # Use the ID for the display name if one was not specified display_name = display_name or consumer_id # Creation consumer = Consumer(consumer_id, display_name, description, notes, capabilities, rsa_pub) _id = collection.save(consumer, safe=True) # Generate certificate cert_gen_manager = factory.cert_generation_manager() expiration_date = config.config.getint('security', 'consumer_cert_expiration') key, certificate = cert_gen_manager.make_cert(consumer_id, expiration_date, uid=str(_id)) factory.consumer_history_manager().record_event(consumer_id, 'consumer_registered') return consumer, Bundle.join(key, certificate)
def bind(consumer_id, repo_id, distributor_id, notify_agent, binding_config): """ Bind consumer to a specific distributor associated with a repository. This call is idempotent. :param consumer_id: uniquely identifies the consumer. :type consumer_id: str :param repo_id: uniquely identifies the repository. :type repo_id: str :param distributor_id: uniquely identifies a distributor. :type distributor_id: str :return: The Bind object :rtype: SON :raise MissingResource: when given consumer does not exist. :raise InvalidValid: when the repository or distributor id is invalid, or if the notify_agent value is invalid """ # Validation missing_values = BindManager._validate_consumer_repo( consumer_id, repo_id, distributor_id) if missing_values: if 'consumer_id' in missing_values: # This is passed in via the URL so a 404 should be raised raise MissingResource( consumer_id=missing_values['consumer_id']) else: # Everything else is a parameter so raise a 400 raise InvalidValue(missing_values.keys()) # ensure notify_agent is a boolean if not isinstance(notify_agent, bool): raise InvalidValue(['notify_agent']) # perform the bind collection = Bind.get_collection() try: bind = Bind(consumer_id, repo_id, distributor_id, notify_agent, binding_config) collection.save(bind, safe=True) except DuplicateKeyError: BindManager._update_binding(consumer_id, repo_id, distributor_id, notify_agent, binding_config) BindManager._reset_bind(consumer_id, repo_id, distributor_id) # fetch the inserted/updated bind bind = BindManager.get_bind(consumer_id, repo_id, distributor_id) # update history details = {'repo_id': repo_id, 'distributor_id': distributor_id} manager = factory.consumer_history_manager() manager.record_event(consumer_id, 'repo_bound', details) return bind
def register(self, id, display_name=None, description=None, notes=None, capabilities=None): """ Registers a new Consumer @param id: unique identifier for the consumer @type id: str @param display_name: user-friendly name for the consumer @type display_name: str @param description: user-friendly text describing the consumer @type description: str @param notes: key-value pairs to programmatically tag the consumer @type notes: dict @param capabilities: operations permitted on the consumer @type capabilities: dict @raises DuplicateResource: if there is already a consumer or a used with the requested ID @raises InvalidValue: if any of the fields is unacceptable """ if not is_consumer_id_valid(id): raise InvalidValue(['id']) existing_consumer = Consumer.get_collection().find_one({'id' : id}) if existing_consumer is not None: raise DuplicateResource(id) if notes is not None and not isinstance(notes, dict): raise InvalidValue(['notes']) if capabilities is not None and not isinstance(capabilities, dict): raise InvalidValue(['capabilities']) # Use the ID for the display name if one was not specified display_name = display_name or id # Generate certificate cert_gen_manager = factory.cert_generation_manager() expiration_date = config.config.getint('security', 'consumer_cert_expiration') key, crt = cert_gen_manager.make_cert(id, expiration_date) # Creation create_me = Consumer(id, display_name, description, notes, capabilities, certificate=crt.strip()) Consumer.get_collection().save(create_me, safe=True) factory.consumer_history_manager().record_event(id, 'consumer_registered') create_me.certificate = Bundle.join(key, crt) return create_me
def add_user_to_role(role_id, login): """ Add a user to a role. This has the side-effect of granting all the permissions granted to the role to the user. :param role_id: role identifier :type role_id: str :param login: login of user :type login: str :raise MissingResource: if the given role or user does not exist """ role = Role.get_collection().find_one({'id': role_id}) if role is None: raise MissingResource(role_id) user = User.get_collection().find_one({'login': login}) if user is None: raise InvalidValue(['login']) if role_id in user['roles']: return user['roles'].append(role_id) User.get_collection().save(user, safe=True) for item in role['permissions']: factory.permission_manager().grant(item['resource'], login, item.get('permission', []))
def delete_user(login): """ Deletes the given user. Deletion of last superuser is not permitted. @param login: identifies the user being deleted @type login: str @raise MissingResource: if the given user does not exist @raise InvalidValue: if login value is invalid """ # Raise exception if login is invalid if login is None or invalid_type(login, basestring): raise InvalidValue(['login']) # Check whether user exists found = User.get_collection().find_one({'login': login}) if found is None: raise MissingResource(login) # Make sure user is not the last super user if factory.user_query_manager().is_last_super_user(login): raise PulpDataException(_("The last superuser [%s] cannot be deleted" % login)) # Revoke all permissions from the user permission_manager = factory.permission_manager() permission_manager.revoke_all_permissions_from_user(login) User.get_collection().remove({'login': login})
def get_content_unit_keys(self, content_type, unit_ids): """ Return the keys and values that will uniquely identify the content units that match the given unique ids. @param content_type: unique id of content collection @type content_type: str @param unit_ids: list of unique content unit ids @type unit_ids: list of str's @return: two tuples of the same length, one of ids the second of key dicts the same index in each tuple corresponds to a single content unit @rtype: tuple of (possibly empty) tuples """ try: key_fields = units_controller.get_unit_key_fields_for_type( content_type) except ValueError: raise InvalidValue(['content_type']) all_fields = ['_id'] _flatten_keys(all_fields, key_fields) collection = content_types_db.type_units_collection(content_type) cursor = collection.find({'_id': { '$in': unit_ids }}, projection=all_fields) dicts = tuple(dict(d) for d in cursor) ids = tuple(d.pop('_id') for d in dicts) return (ids, dicts)
def create_role(role_id, display_name=None, description=None): """ Creates a new Pulp role. :param role_id: unique identifier for the role :type role_id: str :param display_name: user-readable name of the role :type display_name: str :param description: free form text used to describe the role :type description: str :raise DuplicateResource: if there is already a role with the requested name :raise InvalidValue: if any of the fields are unacceptable """ existing_role = Role.get_collection().find_one({'id': role_id}) if existing_role is not None: raise DuplicateResource(role_id) if role_id is None or _ROLE_NAME_REGEX.match(role_id) is None: raise InvalidValue(['role_id']) # Use the ID for the display name if one was not specified display_name = display_name or role_id # Creation create_me = Role(id=role_id, display_name=display_name, description=description) Role.get_collection().save(create_me, safe=True) # Retrieve the role to return the SON object created = Role.get_collection().find_one({'id': role_id}) return created
def post(self, request): """ Creates an async task to regenerate content applicability data for given consumers. body {consumer_criteria:<dict>} :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :raises MissingValue: if some parameters are missing :raises InvalidValue: if some parameters are invalid :raises OperationPostponed: when an async operation is performed. """ body = request.body_as_json consumer_criteria = body.get('consumer_criteria', None) if consumer_criteria is None: raise MissingValue('consumer_criteria') try: consumer_criteria = Criteria.from_client_input(consumer_criteria) except: raise InvalidValue('consumer_criteria') task_tags = [tags.action_tag('content_applicability_regeneration')] async_result = regenerate_applicability_for_consumers.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_PROFILE_APPLICABILITY_TYPE, tags.RESOURCE_ANY_ID, (consumer_criteria.as_dict(), ), tags=task_tags) raise OperationPostponed(async_result)
def record_event(self, consumer_id, event_type, event_details=None): """ @ivar consumer_id: identifies the consumer @type id: str @param type: event type @type type: str @param details: event details @type details: dict @raises MissingResource: if the given consumer does not exist @raises InvalidValue: if any of the fields is unacceptable """ # Check that consumer exists for all except registration event existing_consumer = Consumer.get_collection().find_one( {'id': consumer_id}) if not existing_consumer and event_type != TYPE_CONSUMER_UNREGISTERED: raise MissingResource(consumer=consumer_id) invalid_values = [] if event_type not in TYPES: invalid_values.append('event_type') if event_details is not None and not isinstance(event_details, dict): invalid_values.append('event_details') if invalid_values: raise InvalidValue(invalid_values) event = ConsumerHistoryEvent(consumer_id, self._originator(), event_type, event_details) ConsumerHistoryEvent.get_collection().save(event)
def add_user_to_role(role_id, login): """ Add a user to a role. This has the side-effect of granting all the permissions granted to the role to the user. :param role_id: role identifier :type role_id: str :param login: login of user :type login: str :raise MissingResource: if the given role does not exist :raise InvalidValue: if some params are invalid """ role = Role.get_collection().find_one({'id': role_id}) if role is None: raise MissingResource(role_id) user = model.User.objects(login=login).first() if user is None: raise InvalidValue(['login']) if role_id in user.roles: return user.roles.append(role_id) user.save() for item in role['permissions']: factory.permission_manager().grant(item['resource'], login, item.get('permission', []))
def link_referenced_content_units(self, from_type, from_id, to_type, to_ids): """ Link referenced content units. @param from_type: unique id of the parent content collection @type from_type: str @param from_id: unique id of the parent content unit @type from_id: str @param to_type: unique id of the child content collection @type to_type: str @param to_ids: list of unique ids of child content units @types child_ids: tuple of list """ collection = content_types_db.type_units_collection(from_type) parent = collection.find_one({'_id': from_id}) if parent is None: raise InvalidValue(['from_type']) parent_type_def = content_types_db.type_definition(from_type) if to_type not in parent_type_def['referenced_types']: raise Exception() children = parent.setdefault('_%s_references' % to_type, []) for id_ in to_ids: if id_ in children: continue children.append(id_) collection.update({'_id': from_id}, parent, safe=True)
def create_consumer_group(self, group_id, display_name=None, description=None, consumer_ids=None, notes=None): """ Create a new consumer group. @param group_id: unique id of the consumer group @param display_name: display name of the consumer group @type display_name: str or None @param description: description of the consumer group @type description: str or None @param consumer_ids: list of ids for consumers initially belonging to the consumer group @type consumer_ids: list or None @param notes: notes for the consumer group @type notes: dict or None @return: SON representation of the consumer group @rtype: L{bson.SON} """ if group_id is None or _CONSUMER_GROUP_ID_REGEX.match( group_id) is None: raise InvalidValue(['group_id']) collection = ConsumerGroup.get_collection() consumer_group = ConsumerGroup(group_id, display_name, description, consumer_ids, notes) try: collection.insert(consumer_group, safe=True) except DuplicateKeyError: raise pulp_exceptions.DuplicateResource( group_id), None, sys.exc_info()[2] group = collection.find_one({'id': group_id}) return group
def put(self, request, upload_id, offset): """ Upload to a specific file upload. :param request: WSGI request object, body contains bits to upload :type request: django.core.handlers.wsgi.WSGIRequest :param upload_id: id of the initialized upload :type upload_id: str :param offset: place in the uploaded file to start writing :type offset: str of an integer :return: response containing null :rtype: django.http.HttpResponse :raises: pulp.server.exceptions.MissingResource if upload ID does not exist :raises: InvalidValue if offset cannot be converted to an integer """ try: offset = int(offset) except ValueError: raise InvalidValue(['offset']) upload_manager = factory.content_upload_manager() # If the upload ID doesn't exists, either because it was not initialized # or was deleted, the call to the manager will raise missing resource upload_manager.save_data(upload_id, offset, request.body) return generate_json_response(None)
def POST(self, group_id): """ Create a bind association between the consumers belonging to the given consumer group by id included in the URL path and a repo-distributor specified in the POST body: {repo_id:<str>, distributor_id:<str>}. Designed to be idempotent so only MissingResource is expected to be raised by manager. :param group_id: The consumer group to bind. :type group_id: str :return: list of call requests :rtype: list """ body = self.params() repo_id = body.get('repo_id') distributor_id = body.get('distributor_id') binding_config = body.get('binding_config', None) options = body.get('options', {}) notify_agent = body.get('notify_agent', True) missing_resources = verify_group_resources(group_id, repo_id, distributor_id) if missing_resources: if 'group_id' in missing_resources: raise MissingResource(**missing_resources) else: raise InvalidValue(list(missing_resources)) bind_args_tuple = (group_id, repo_id, distributor_id, notify_agent, binding_config, options) async_task = bind.apply_async(bind_args_tuple) raise pulp_exceptions.OperationPostponed(async_task)
def set_importer(repo_id, importer_type_id, repo_plugin_config): """ Configures an importer to be used for the given repository. Keep in mind this method is written assuming single importer for a repo. The domain model technically supports multiple importers, but this call is what enforces the single importer behavior. :param repo_id: identifies the repo :type repo_id: str :param importer_type_id: identifies the type of importer being added; must correspond to an importer loaded at server startup :type importer_type_id: str :param repo_plugin_config: configuration values for the importer; may be None :type repo_plugin_config: dict :raise MissingResource: if repo_id does not represent a valid repo :raise InvalidImporterConfiguration: if the importer cannot be initialized for the given repo """ repo_coll = Repo.get_collection() importer_coll = RepoImporter.get_collection() # Validation repo = repo_coll.find_one({'id' : repo_id}) if repo is None: raise MissingResource(repo_id) if not plugin_api.is_valid_importer(importer_type_id): raise InvalidValue(['importer_type_id']) importer_instance, plugin_config = plugin_api.get_importer_by_id(importer_type_id) # Convention is that a value of None means unset. Remove any keys that # are explicitly set to None so the plugin will default them. if repo_plugin_config is not None: clean_config = dict([(k, v) for k, v in repo_plugin_config.items() if v is not None]) else: clean_config = None # Let the importer plugin verify the configuration call_config = PluginCallConfiguration(plugin_config, clean_config) transfer_repo = common_utils.to_transfer_repo(repo) transfer_repo.working_dir = common_utils.importer_working_dir(importer_type_id, repo_id) try: result = importer_instance.validate_config(transfer_repo, call_config) # For backward compatibility with plugins that don't yet return the tuple if isinstance(result, bool): valid_config = result message = None else: valid_config, message = result except Exception, e: logger.exception( 'Exception received from importer [%s] while validating config' % importer_type_id) raise PulpDataException(e.args), None, sys.exc_info()[2]
def create_repo(self, repo_id, display_name=None, description=None, notes=None): """ Creates a new Pulp repository that is not associated with any importers or distributors (those are added later through separate calls). :param repo_id: unique identifier for the repo :type repo_id: str :param display_name: user-friendly name for the repo :type display_name: str :param description: user-friendly text describing the repo's contents :type description: str :param notes: key-value pairs to programmatically tag the repo :type notes: dict :raise DuplicateResource: if there is already a repo with the requested ID :raise InvalidValue: if any of the fields are unacceptable """ existing_repo = Repo.get_collection().find_one({'id': repo_id}) if existing_repo is not None: raise DuplicateResource(repo_id) if repo_id is None or not is_repo_id_valid(repo_id): raise InvalidValue(['repo_id']) if notes is not None and not isinstance(notes, dict): raise InvalidValue(['notes']) # Use the ID for the display name if one was not specified display_name = display_name or repo_id # Creation create_me = Repo(repo_id, display_name, description, notes) Repo.get_collection().save(create_me, safe=True) # Retrieve the repo to return the SON object created = Repo.get_collection().find_one({'id': repo_id}) return created
def create_user(login, password=None, name=None, roles=None): """ Creates a new Pulp user and adds it to specified to roles. @param login: login name / unique identifier for the user @type login: str @param password: password for login credentials @type password: str @param name: user's full name @type name: str @param roles: list of roles user will belong to @type roles: list @raise DuplicateResource: if there is already a user with the requested login @raise InvalidValue: if any of the fields are unacceptable """ existing_user = User.get_collection().find_one({'login': login}) if existing_user is not None: raise DuplicateResource(login) invalid_values = [] if login is None or _USER_LOGIN_REGEX.match(login) is None: invalid_values.append('login') if invalid_type(name, basestring): invalid_values.append('name') if invalid_type(roles, list): invalid_values.append('roles') if invalid_values: raise InvalidValue(invalid_values) # Use the login for name of the user if one was not specified name = name or login roles = roles or None # Encode plain-text password hashed_password = None if password: hashed_password = factory.password_manager().hash_password(password) # Creation create_me = User(login=login, password=hashed_password, name=name, roles=roles) User.get_collection().save(create_me) # Grant permissions permission_manager = factory.permission_manager() permission_manager.grant_automatic_permissions_for_user(create_me['login']) # Retrieve the user to return the SON object created = User.get_collection().find_one({'login': login}) created.pop('password') return created
def test_import_uploaded_unit_importer_error_reraise_pulp_exception( self, mock_repo_qs): importer_controller.set_importer('repo-u', 'mock-importer', {}) mock_plugins.MOCK_IMPORTER.upload_unit.side_effect = InvalidValue( ['filename']) upload_id = self.upload_manager.initialize_upload() self.assertRaises(InvalidValue, self.upload_manager.import_uploaded_unit, 'repo-u', 'mock-type', {}, {}, upload_id)
def delete(self, request, consumer_id, repo_id, distributor_id): """ Delete a bind association between the specified consumer and repo-distributor. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param consumer_id: A consumer ID. :type consumer_id: str :param repo_id: A repo ID. :type repo_id: str :param distributor_id: A distributor ID. :type distributor_id: str :raises OperationPostponed: will dispatch a task if 'notify_agent' is set to True :raises InvalidValue: if some parameters are invalid :return: Response representing the deleted binding(in case 'notify agent' is set to False) :rtype: django.http.HttpResponse """ body = request.body_as_json forced = body.get('force', False) if not isinstance(forced, bool): raise InvalidValue(['force']) options = body.get('options', {}) if not isinstance(options, dict): raise InvalidValue(['options']) if forced: call_report = consumer_controller.force_unbind( consumer_id, repo_id, distributor_id, options) else: call_report = consumer_controller.unbind(consumer_id, repo_id, distributor_id, options) if call_report.spawned_tasks: raise OperationPostponed(call_report) else: return generate_json_response_with_pulp_encoder( call_report.serialize())
def grant(resource, login, operations): """ Grant permission on a resource for a user and a set of operations. :param resource: uri path representing a pulp resource :type resource: str :param login: login of user to grant permissions to :type login: str :param operations:list of allowed operations being granted :type operations: list or tuple of integers :raises InvalidValue: if some params are invalid """ # we don't grant permissions to the system if login == system.SYSTEM_LOGIN: return user = User.get_collection().find_one({'login': login}) if user is None: raise InvalidValue(['login']) # Make sure resource is a valid string or unicode if not isinstance(resource, basestring): raise InvalidValue(resource) # Get or create permission if it doesn't already exist permission = Permission.get_collection().find_one({'resource': resource}) if permission is None: permission = PermissionManager.create_permission(resource) current_ops = factory.permission_query_manager().find_user_permission(permission, user['login'], create=True) for o in operations: if o in current_ops: continue current_ops.append(o) Permission.get_collection().save(permission, safe=True)
def name_to_operation(name): """ Convert a operation name to an operation value Returns None if the name does not correspond to an operation @type name: str @param name: operation name @rtype: int or None @return: operation value """ name = name.upper() if name not in factory.permission_manager().operation_names: raise InvalidValue('operations') return factory.permission_manager().operation_names.index(name)
def _build_multi_keys_spec(content_type, unit_keys_dicts): """ Build a mongo db spec document for a query on the given content_type collection out of multiple content unit key dictionaries. :param content_type: unique id of the content type collection :type content_type: str :param unit_keys_dicts: list of key dictionaries whose key, value pairs can be used as unique identifiers for a single content unit :type unit_keys_dicts: list of dict :return: mongo db spec document for locating documents in a collection :rtype: dict :raises ValueError: if any of the key dictionaries do not match the unique fields of the collection """ # keys dicts validation constants try: unit_key_fields = units_controller.get_unit_key_fields_for_type( content_type) except ValueError: raise InvalidValue(['content_type']) key_fields = [] _flatten_keys(key_fields, unit_key_fields) key_fields_set = set(key_fields) extra_keys_msg = _( 'keys dictionary found with superfluous keys %(a)s, valid keys are %(b)s' ) missing_keys_msg = _( 'keys dictionary missing keys %(a)s, required keys are %(b)s') keys_errors = [] # Validate all of the keys in the unit_keys_dict for keys_dict in unit_keys_dicts: # keys dict validation keys_dict_set = set(keys_dict) extra_keys = keys_dict_set.difference(key_fields_set) if extra_keys: keys_errors.append(extra_keys_msg % { 'a': ','.join(extra_keys), 'b': ','.join(key_fields) }) missing_keys = key_fields_set.difference(keys_dict_set) if missing_keys: keys_errors.append(missing_keys_msg % { 'a': ','.join(missing_keys), 'b': ','.join(key_fields) }) if keys_errors: value_error_msg = '\n'.join(keys_errors) raise ValueError(value_error_msg) # Build the spec spec = {'$or': unit_keys_dicts} return spec
def remove_permissions_from_role(role_id, resource, operations): """ Remove permissions from a role. :param role_id: role identifier :type role_id: str :param resource: resource path to revoke permissions from :type resource: str :param operations: list or tuple :type operations: list of allowed operations being revoked :raise InvalidValue: if some params are invalid :raise PulpDataException: if role is a superuser role """ if role_id == SUPER_USER_ROLE: raise PulpDataException(_('super-users role cannot be changed')) role = Role.get_collection().find_one({'id': role_id}) if role is None: raise InvalidValue(['role_id']) resource_permission = {} current_ops = [] for item in role['permissions']: if item['resource'] == resource: resource_permission = item current_ops = resource_permission['permission'] if not current_ops: return for o in operations: if o not in current_ops: continue current_ops.remove(o) users = factory.user_query_manager().find_users_belonging_to_role( role_id) for user in users: other_roles = factory.role_query_manager().get_other_roles( role, user['roles']) user_ops = _operations_not_granted_by_roles( resource, operations, other_roles) factory.permission_manager().revoke(resource, user['login'], user_ops) # in no more allowed operations, remove the resource if not current_ops: role['permissions'].remove(resource_permission) Role.get_collection().save(role, safe=True)
def PUT(self, upload_id, offset): # If the upload ID doesn't exists, either because it was not initialized # or was deleted, the call to the manager will raise missing resource try: offset = int(offset) except ValueError: raise InvalidValue(['offset']) upload_manager = factory.content_upload_manager() data = self.data() upload_manager.save_data(upload_id, offset, data) return self.ok(None)
def operation_names_to_values(self, names): """ Convert a list of operation names to operation values :param names: names of operations to convert to values :type name: list or tuple of str's :rtype: list of int's :return: list of operation values :raises InvalidValue: when any of the given operation names is invalid """ if names is None: raise InvalidValue('operation_names') operations = [self.operation_name_to_value(n) for n in names] return operations
def revoke(resource, login, operations): """ Revoke permission on a resource for a user and a set of operations. :param resource: uri path representing a pulp resource :type resource: str :param login: login of user to revoke permissions from :type login: str :param operations: list of allowed operations being revoked :type operations: list or tuple of integers :raises InvalidValue: if some params are invalid """ permission_query_manager = factory.permission_query_manager() # we don't revoke permissions from the system if login == system.SYSTEM_LOGIN: return user = User.get_collection().find_one({'login': login}) if user is None: raise InvalidValue(['login']) permission = Permission.get_collection().find_one( {'resource': resource}) if permission is None: return current_ops = permission_query_manager.find_user_permission( permission, user['login']) if not current_ops: return for o in operations: if o not in current_ops: continue current_ops.remove(o) # delete the user from this permission if there are no more allowed operations if not current_ops: permission_query_manager.delete_user_permission( permission, user['login']) # delete the permission if there are no more users if not permission['users']: PermissionManager.delete_permission(resource) return Permission.get_collection().save(permission)
def operation_name_to_value(self, name): """ Convert an operation name to an operation value :param name: operation name :type name: str :rtype: int :return: operation value :raises InvalidValue: when given operation name is invalid """ if name is not None: name = name.upper() if name not in authorization.OPERATION_NAMES: raise InvalidValue('operation_name') return authorization.OPERATION_NAMES.index(name)
def _get_content_types(self): """ Get the list of content_types that the caller wishes to limit the response to. If the caller did not include content types, this will return None. :return: The list of content_types that the applicability query should be limited to, or None if not specified :rtype: list or None """ body = self.params() content_types = body.get('content_types', None) if content_types is not None and not isinstance(content_types, list): raise InvalidValue('content_types must index an array.') return content_types
def _publish_distribution_packages_link(self, distribution_unit): """ Create a Packages directory in the repo that is a sym link back to the root directory of the repository. This is required for compatibility with RHEL 5. Also create the directory that is specified by packagesdir section in the config file :param distribution_unit: The unit for the distribution from which the list of files to be published should be pulled from. :type distribution_unit: pulp_rpm.plugins.db.models.Distribution """ symlink_dir = self.get_working_dir() package_path = None if distribution_unit.packagedir: # The packages_dir is a relative directory that exists underneath the repo directory # Verify that this directory is valid. package_path = os.path.join(symlink_dir, distribution_unit.packagedir) real_symlink_dir = os.path.realpath(symlink_dir) real_package_path = os.path.realpath(package_path) common_prefix = os.path.commonprefix( [real_symlink_dir, real_package_path]) if not common_prefix.startswith(real_symlink_dir): # the specified package path is not contained within the directory # raise a validation exception msg = _( 'Error publishing repository: %(repo)s. The treeinfo file specified a ' 'packagedir \"%(packagedir)s\" that is not contained within the repository' % { 'repo': self.get_repo().repo_id, 'packagedir': package_path }) logger.info(msg) raise InvalidValue(KEY_PACKAGEDIR) self.package_dirs.append(real_package_path) if os.path.islink(package_path): # a package path exists as a symlink we are going to remove it since # the _create_symlink will create a real directory os.unlink(package_path) default_packages_symlink = os.path.join(symlink_dir, 'Packages') if package_path != default_packages_symlink: # Add the Packages directory to the content directory self.package_dirs.append(default_packages_symlink)
def __init__(self, module_filename): InvalidValue.__init__(self, module_filename) self.module_filename = module_filename