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