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
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)
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)
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
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
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)
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)