Beispiel #1
0
def has_perms_to_copy(request, view, action):
    """
    Check if the source and destination repository matches the usernames permissions.

    `Fail` the check at first missing permission.
    """
    serializer = view.serializer_class(data=request.data,
                                       context={"request": request})
    serializer.is_valid(raise_exception=True)

    for copy_action in serializer.data["config"]:
        dest_repo = NamedModelViewSet().get_resource(copy_action["dest_repo"],
                                                     RpmRepository)

        # Check if user has permissions to destination repository
        if not (request.user.has_perm("rpm.modify_content_rpmrepository",
                                      dest_repo)
                or request.user.has_perm("rpm.modify_content_rpmrepository")):
            return False

        # Get source repo object
        source_version = NamedModelViewSet().get_resource(
            copy_action["source_repo_version"], RepositoryVersion)

        source_repo = RpmRepository.objects.get(
            pk=source_version.repository_id)

        # Check if user has permissions to source repository
        if not (request.user.has_perm("rpm.view_rpmrepository", source_repo)
                or request.user.has_perm("rpm.view_rpmrepository")):
            return False

    return True
Beispiel #2
0
    def remove(self, request, pk):
        """
        Queues a task that creates a new RepositoryVersion by removing content units.
        """
        remove_content_units = []
        repository = self.get_object()
        serializer = serializers.RecursiveManageSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        if "content_units" in request.data:
            for url in request.data["content_units"]:
                if url == "*":
                    remove_content_units = [url]
                    break

                content = NamedModelViewSet.get_resource(url, Content)
                remove_content_units.append(content.pk)

        result = enqueue_with_reservation(
            tasks.recursive_remove_content,
            [repository],
            kwargs={
                "repository_pk": repository.pk,
                "content_units": remove_content_units
            },
        )
        return OperationPostponedResponse(result, request)
Beispiel #3
0
    def sign(self, request, pk):
        """
        Dispatches a sync task.

        This endpoint is in tech preview and can change at any time in the future.
        """
        content_units = {}

        repository = self.get_object()
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        signing_service = serializer.validated_data["signing_service"]
        content = serializer.validated_data["content_units"]

        if "*" in content:
            content_units_pks = ["*"]
        else:
            for url in content:
                content_units[NamedModelViewSet.extract_pk(url)] = url
            content_units_pks = list(content_units.keys())
            existing_content_units = CollectionVersion.objects.filter(pk__in=content_units_pks)
            self.verify_content_units(existing_content_units, content_units)

        result = dispatch(
            sign,
            exclusive_resources=[repository],
            kwargs={
                "repository_href": repository.pk,
                "content_hrefs": content_units_pks,
                "signing_service_href": signing_service.pk,
            },
        )
        return OperationPostponedResponse(result, request)
Beispiel #4
0
    def _process_config(self, config):
        """
        Change the hrefs into pks within config.

        This method also implicitly validates that the hrefs map to objects and it returns a list of
        repos so that the task can lock on them.
        """
        result = []
        # exclusive use of the destination repos is needed since new repository versions are being
        # created, but source repos can be accessed in a read-only fashion in parallel, so long
        # as there are no simultaneous modifications.
        shared_repos = []
        exclusive_repos = []

        for entry in config:
            r = dict()
            source_version = NamedModelViewSet().get_resource(
                entry["source_repo_version"], RepositoryVersion)
            dest_repo = NamedModelViewSet().get_resource(
                entry["dest_repo"], RpmRepository)
            r["source_repo_version"] = source_version.pk
            r["dest_repo"] = dest_repo.pk
            shared_repos.append(source_version.repository)
            exclusive_repos.append(dest_repo)

            if "dest_base_version" in entry:
                try:
                    r["dest_base_version"] = dest_repo.versions.get(
                        number=entry["dest_base_version"]).pk
                except RepositoryVersion.DoesNotExist:
                    message = _(
                        "Version {version} does not exist for repository "
                        "'{repo}'.").format(version=entry["dest_base_version"],
                                            repo=dest_repo.name)
                    raise DRFValidationError(detail=message)

            if entry.get("content") is not None:
                r["content"] = []
                for c in entry["content"]:
                    r["content"].append(NamedModelViewSet().extract_pk(c))
            result.append(r)

        return result, shared_repos, exclusive_repos
Beispiel #5
0
    def _process_config(self, config):
        """
        Change the hrefs into pks within config.

        This method also implicitly validates that the hrefs map to objects and it returns a list of
        repos so that the task can lock on them.
        """
        result = []
        exclusive_resources = []
        shared_resources = []

        for entry in config:
            r = dict()
            source_version = NamedModelViewSet().get_resource(
                entry["source_repo_version"], RepositoryVersion
            )
            dest_repo = NamedModelViewSet().get_resource(entry["dest_repo"], AnsibleRepository)
            r["source_repo_version"] = source_version.pk
            r["dest_repo"] = dest_repo.pk
            exclusive_resources.append(dest_repo)
            shared_resources.append(source_version.repository)

            if "dest_base_version" in entry:
                try:
                    r["dest_base_version"] = dest_repo.versions.get(
                        number=entry["dest_base_version"]
                    ).pk
                except RepositoryVersion.DoesNotExist:
                    message = _(
                        "Version {version} does not exist for repository " "'{repo}'."
                    ).format(version=entry["dest_base_version"], repo=dest_repo.name)
                    raise DRFValidationError(detail=message)

            if entry.get("content") is not None:
                r["content"] = []
                for c in entry["content"]:
                    r["content"].append(NamedModelViewSet().extract_pk(c))
            result.append(r)

        return result, exclusive_resources, shared_resources
Beispiel #6
0
    def add(self, request, pk):
        """
        Queues a task that creates a new RepositoryVersion by adding content units.
        """
        add_content_units = []
        repository = self.get_object()
        serializer = serializers.RecursiveManageSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        if 'content_units' in request.data:
            for url in request.data['content_units']:
                content = NamedModelViewSet.get_resource(url, Content)
                add_content_units.append(content.pk)

        result = enqueue_with_reservation(tasks.recursive_add_content,
                                          [repository],
                                          kwargs={
                                              'repository_pk': repository.pk,
                                              'content_units':
                                              add_content_units,
                                          })
        return OperationPostponedResponse(result, request)
Beispiel #7
0
    def add(self, request, pk):
        """
        Queues a task that creates a new RepositoryVersion by adding content units.
        """
        add_content_units = []
        repository = self.get_object()
        serializer = serializers.RecursiveManageSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        if "content_units" in request.data:
            for url in request.data["content_units"]:
                content = NamedModelViewSet.get_resource(url, Content)
                add_content_units.append(str(content.pk))

        result = dispatch(
            tasks.recursive_add_content,
            [repository],
            kwargs={
                "repository_pk": str(repository.pk),
                "content_units": add_content_units
            },
        )
        return OperationPostponedResponse(result, request)