private void prepareAndValidatePublicationRequest()

in server/src/main/java/com/epam/aidial/core/server/service/PublicationService.java [315:379]


    private void prepareAndValidatePublicationRequest(ProxyContext context, Publication publication,
                                                      String bucketName, String bucketLocation,
                                                      boolean isAdmin) {
        String targetFolder = publication.getTargetFolder();
        if (targetFolder == null) {
            throw new IllegalArgumentException("Publication \"targetFolder\" is missing");
        }

        // rules to the root publication folder are not allowed
        if (targetFolder.equals("public/") && publication.getRules() != null && !publication.getRules().isEmpty()) {
            throw new IllegalArgumentException("Rules are not allowed for root targetFolder");
        }

        // publication must contain resources or rule or both
        if ((publication.getResources() == null || publication.getResources().isEmpty()) && publication.getRules() == null) {
            throw new IllegalArgumentException("Publication must have at least one resource or rule");
        }

        ResourceUrl targetFolderUrl = ResourceUrl.parse(publication.getTargetFolder());

        if (!targetFolderUrl.startsWith(ResourceDescriptor.PUBLIC_BUCKET) || !targetFolderUrl.isFolder()) {
            throw new IllegalArgumentException("Publication \"targetUrl\" must start with: %s and ends with: %s"
                    .formatted(ResourceDescriptor.PUBLIC_BUCKET, ResourceDescriptor.PATH_SEPARATOR));
        }

        String id = UrlUtil.encodePathSegment(ids.get());
        String publicationUrl = String.join(ResourceDescriptor.PATH_SEPARATOR, "publications", bucketName, id);
        String reviewBucket = encodeReviewBucket(bucketLocation, id);
        targetFolder = targetFolderUrl.getUrl();

        publication.setUrl(publicationUrl);
        publication.setTargetFolder(targetFolder);
        publication.setCreatedAt(clock.getAsLong());
        publication.setStatus(Publication.Status.PENDING);

        addCustomApplicationRelatedFiles(context, publication);

        Set<String> urls = new HashSet<>();
        for (Publication.Resource resource : publication.getResources()) {
            Publication.ResourceAction action = resource.getAction();
            if (action == null) {
                throw new IllegalArgumentException("Resource \"action\" is missing");
            }

            if (action == Publication.ResourceAction.ADD || action == Publication.ResourceAction.ADD_IF_ABSENT) {
                validateResourceForAddition(context, resource, targetFolder, reviewBucket, urls);
            } else if (action == Publication.ResourceAction.DELETE) {
                validateResourceForDeletion(resource, targetFolder, urls, bucketName, isAdmin);
            } else {
                throw new UnsupportedOperationException("Unsupported resource action: " + action);
            }
        }

        Set<ResourceDescriptor> targetResources = publication.getResources().stream()
                .map(resource -> ResourceDescriptorFactory.fromPublicUrl(resource.getTargetUrl()))
                .collect(Collectors.toUnmodifiableSet());

        // validate if user has access to all target resources
        boolean hasPublicAccess = accessService.hasPublicAccess(targetResources, context);
        if (!hasPublicAccess) {
            throw new PermissionDeniedException("User don't have permissions to the provided target resources");
        }

        validateRules(publication);
    }