diff --git a/server/src/main/java/com/epam/aidial/core/server/security/AccessService.java b/server/src/main/java/com/epam/aidial/core/server/security/AccessService.java index b30957b9..72edd1e7 100644 --- a/server/src/main/java/com/epam/aidial/core/server/security/AccessService.java +++ b/server/src/main/java/com/epam/aidial/core/server/security/AccessService.java @@ -208,6 +208,7 @@ public static Map> getAppResourceAcc public static Map> getAppResourceAccess( Set resources, ProxyContext context, String deployment) { + String appPath = BucketBuilder.APPDATA_PATTERN.formatted(UrlUtil.encodePath(deployment)); Map> result = new HashMap<>(); String location = BucketBuilder.buildAppDataBucket(context); for (ResourceDescriptor resource : resources) { @@ -216,11 +217,16 @@ public static Map> getAppResourceAcc } String parentPath = resource.getParentPath(); - String filePath = (parentPath == null) - ? resource.getName() - : parentPath + ResourceDescriptor.PATH_SEPARATOR + resource.getName(); + String filePath; + if (resource.isFolder()) { + filePath = parentPath; + } else { + filePath = parentPath == null + ? resource.getName() + : parentPath + ResourceDescriptor.PATH_SEPARATOR + resource.getName(); + } - if (filePath.startsWith(BucketBuilder.APPDATA_PATTERN.formatted(UrlUtil.encodePath(deployment)))) { + if (filePath != null && filePath.startsWith(appPath)) { result.put(resource, ResourceAccessType.ALL); } } diff --git a/server/src/main/java/com/epam/aidial/core/server/service/PublicationUtil.java b/server/src/main/java/com/epam/aidial/core/server/service/PublicationUtil.java index 4c3e5b78..1dd1e4c6 100644 --- a/server/src/main/java/com/epam/aidial/core/server/service/PublicationUtil.java +++ b/server/src/main/java/com/epam/aidial/core/server/service/PublicationUtil.java @@ -117,11 +117,10 @@ static String buildTargetFolderForCustomAppFiles(String targetUrl, EncryptionSer throw new IllegalArgumentException("target url must be an application type"); } String appName = descriptor.getName(); - List folders = descriptor.getParentFolders(); - if (folders.isEmpty()) { + String appPath = descriptor.getParentPath(); + if (appPath == null) { return "." + appName + ResourceDescriptor.PATH_SEPARATOR; } else { - String appPath = String.join(ResourceDescriptor.PATH_SEPARATOR, folders); return appPath + ResourceDescriptor.PATH_SEPARATOR + "." + appName + ResourceDescriptor.PATH_SEPARATOR; } } diff --git a/server/src/test/java/com/epam/aidial/core/server/service/AccessServiceTest.java b/server/src/test/java/com/epam/aidial/core/server/service/AccessServiceTest.java new file mode 100644 index 00000000..93e1344b --- /dev/null +++ b/server/src/test/java/com/epam/aidial/core/server/service/AccessServiceTest.java @@ -0,0 +1,82 @@ +package com.epam.aidial.core.server.service; + +import com.epam.aidial.core.server.ProxyContext; +import com.epam.aidial.core.server.data.ApiKeyData; +import com.epam.aidial.core.server.data.ResourceTypes; +import com.epam.aidial.core.server.security.AccessService; +import com.epam.aidial.core.storage.data.ResourceAccessType; +import com.epam.aidial.core.storage.resource.ResourceDescriptor; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AccessServiceTest { + + @Test + public void testGetAppResourceAccess_RootFolder() { + ProxyContext context = mock(ProxyContext.class); + ApiKeyData apiKeyData = new ApiKeyData(); + apiKeyData.setPerRequestKey("key"); + when(context.getApiKeyData()).thenReturn(apiKeyData); + when(context.getUserSub()).thenReturn("user"); + when(context.getSourceDeployment()).thenReturn("source"); + ResourceDescriptor descriptor = new ResourceDescriptor(ResourceTypes.FILE, null, List.of(), "bucket", "Users/user/", true); + + Map> result = AccessService.getAppResourceAccess(Set.of(descriptor), context); + + assertTrue(result.isEmpty()); + } + + @Test + public void testGetAppResourceAccess_Folder() { + ProxyContext context = mock(ProxyContext.class); + ApiKeyData apiKeyData = new ApiKeyData(); + apiKeyData.setPerRequestKey("key"); + when(context.getApiKeyData()).thenReturn(apiKeyData); + when(context.getUserSub()).thenReturn("user"); + when(context.getSourceDeployment()).thenReturn("source"); + ResourceDescriptor descriptor = new ResourceDescriptor(ResourceTypes.FILE, null, List.of("folder"), "bucket", "Users/user/", true); + + Map> result = AccessService.getAppResourceAccess(Set.of(descriptor), context); + + assertTrue(result.isEmpty()); + } + + @Test + public void testGetAppResourceAccess_File() { + ProxyContext context = mock(ProxyContext.class); + ApiKeyData apiKeyData = new ApiKeyData(); + apiKeyData.setPerRequestKey("key"); + when(context.getApiKeyData()).thenReturn(apiKeyData); + when(context.getUserSub()).thenReturn("user"); + when(context.getSourceDeployment()).thenReturn("source"); + ResourceDescriptor descriptor = new ResourceDescriptor(ResourceTypes.FILE, "file.json", List.of(), "bucket", "Users/user/", false); + + Map> result = AccessService.getAppResourceAccess(Set.of(descriptor), context); + + assertTrue(result.isEmpty()); + } + + @Test + public void testGetAppResourceAccess_AppDataFile() { + ProxyContext context = mock(ProxyContext.class); + ApiKeyData apiKeyData = new ApiKeyData(); + apiKeyData.setPerRequestKey("key"); + when(context.getApiKeyData()).thenReturn(apiKeyData); + when(context.getUserSub()).thenReturn("user"); + when(context.getSourceDeployment()).thenReturn("app"); + ResourceDescriptor descriptor = new ResourceDescriptor(ResourceTypes.FILE, "file.json", List.of("appdata", "app"), "bucket", "Users/user/", false); + + Map> result = AccessService.getAppResourceAccess(Set.of(descriptor), context); + + assertTrue(result.containsKey(descriptor)); + assertEquals(ResourceAccessType.ALL, result.get(descriptor)); + } +}