Example #1
0
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'])
Example #2
0
File: cud.py Project: zjhuntin/pulp
    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)
Example #3
0
File: bind.py Project: omps/pulp
    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
Example #4
0
    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
Example #5
0
File: cud.py Project: beav/pulp
    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', []))
Example #6
0
    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})
Example #7
0
 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)
Example #8
0
File: cud.py Project: beav/pulp
    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
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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', []))
Example #12
0
 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)
Example #13
0
    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
Example #14
0
    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)
Example #15
0
    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)
Example #16
0
    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]
Example #17
0
    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
Example #18
0
    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
Example #19
0
 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)
Example #20
0
    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())
Example #21
0
    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)
Example #22
0
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)
Example #23
0
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
Example #24
0
File: cud.py Project: zjhuntin/pulp
    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)
Example #25
0
    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)
Example #26
0
    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
Example #27
0
File: cud.py Project: ktdreyer/pulp
    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)
Example #28
0
    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)
Example #29
0
    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
Example #30
0
    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)
Example #31
0
 def __init__(self, module_filename):
     InvalidValue.__init__(self, module_filename)
     self.module_filename = module_filename