diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java index 9424390c17f..dca9079978c 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/CatalogApplication.java @@ -56,6 +56,7 @@ import org.openmetadata.catalog.migration.Migration; import org.openmetadata.catalog.migration.MigrationConfiguration; import org.openmetadata.catalog.resources.CollectionRegistry; import org.openmetadata.catalog.resources.config.ConfigResource; +import org.openmetadata.catalog.resources.permissions.PermissionsResource; import org.openmetadata.catalog.resources.search.SearchResource; import org.openmetadata.catalog.security.AuthenticationConfiguration; import org.openmetadata.catalog.security.Authorizer; @@ -198,8 +199,10 @@ public class CatalogApplication extends Application { ContainerRequestFilter filter = NoopFilter.class.getConstructor().newInstance(); environment.jersey().register(filter); } - // Registering config api - environment.jersey().register(new ConfigResource(catalogConfig, authorizer)); + // Register config API + environment.jersey().register(new ConfigResource(catalogConfig)); + // Register permissions API + environment.jersey().register(new PermissionsResource(authorizer)); } private void registerEventFilter(CatalogApplicationConfig catalogConfig, Environment environment, Jdbi jdbi) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/config/ConfigResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/config/ConfigResource.java index 48728d15e35..ce8cc7b630b 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/config/ConfigResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/config/ConfigResource.java @@ -21,17 +21,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.SecurityContext; -import lombok.NonNull; import org.openmetadata.catalog.CatalogApplicationConfig; import org.openmetadata.catalog.resources.Collection; import org.openmetadata.catalog.security.AuthenticationConfiguration; -import org.openmetadata.catalog.security.Authorizer; import org.openmetadata.catalog.security.AuthorizerConfiguration; -import org.openmetadata.catalog.security.Permissions; -import org.openmetadata.catalog.security.SecurityUtil; @Path("/v1/config") @Api(value = "Get configuration") @@ -39,11 +33,9 @@ import org.openmetadata.catalog.security.SecurityUtil; @Collection(name = "config") public class ConfigResource { private final CatalogApplicationConfig catalogApplicationConfig; - private final Authorizer authorizer; - public ConfigResource(CatalogApplicationConfig catalogApplicationConfig, @NonNull Authorizer authorizer) { + public ConfigResource(CatalogApplicationConfig catalogApplicationConfig) { this.catalogApplicationConfig = catalogApplicationConfig; - this.authorizer = authorizer; } @GET @@ -89,19 +81,4 @@ public class ConfigResource { } return authorizerConfiguration; } - - @GET - @Path(("/permissions")) - @Operation( - summary = "Retrieves permissions for logged in user", - tags = "general", - responses = { - @ApiResponse( - responseCode = "200", - description = "Permissions for logged in user", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = Permissions.class))) - }) - public Permissions getPermissions(@Context SecurityContext securityContext) { - return new Permissions(authorizer.listPermissions(SecurityUtil.getAuthenticationContext(securityContext), null)); - } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/permissions/PermissionsResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/permissions/PermissionsResource.java new file mode 100644 index 00000000000..1aa1d207855 --- /dev/null +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/permissions/PermissionsResource.java @@ -0,0 +1,57 @@ +/* + * Copyright 2021 Collate + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openmetadata.catalog.resources.permissions; + +import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.SecurityContext; +import lombok.NonNull; +import org.openmetadata.catalog.resources.Collection; +import org.openmetadata.catalog.security.Authorizer; +import org.openmetadata.catalog.security.Permissions; +import org.openmetadata.catalog.security.SecurityUtil; + +@Path("/v1/permissions") +@Api(value = "Get permissions") +@Produces(MediaType.APPLICATION_JSON) +@Collection(name = "permissions") +public class PermissionsResource { + private final Authorizer authorizer; + + public PermissionsResource(@NonNull Authorizer authorizer) { + this.authorizer = authorizer; + } + + @GET + @Operation( + summary = "Retrieves permissions for logged in user", + tags = "general", + responses = { + @ApiResponse( + responseCode = "200", + description = "Permissions for logged in user", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = Permissions.class))) + }) + public Permissions getPermissions(@Context SecurityContext securityContext) { + return new Permissions(authorizer.listPermissions(SecurityUtil.getAuthenticationContext(securityContext), null)); + } +} diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationConfiguration.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationConfiguration.java index 685f3026a44..56a3795c360 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationConfiguration.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationConfiguration.java @@ -63,4 +63,25 @@ public class AuthenticationConfiguration { public void setCallbackUrl(String callbackUrl) { this.callbackUrl = callbackUrl; } + + @Override + public String toString() { + return "AuthenticationConfiguration{" + + "provider='" + + provider + + '\'' + + ", publicKey='" + + publicKey + + '\'' + + ", authority='" + + authority + + '\'' + + ", clientId='" + + clientId + + '\'' + + ", callbackUrl='" + + callbackUrl + + '\'' + + '}'; + } } diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/config/ConfigResourceTest.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/config/ConfigResourceTest.java index 4272aeb5a16..a6632b0f147 100644 --- a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/config/ConfigResourceTest.java +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/config/ConfigResourceTest.java @@ -14,108 +14,52 @@ package org.openmetadata.catalog.resources.config; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS; +import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.dropwizard.configuration.ConfigurationException; +import io.dropwizard.configuration.FileConfigurationSourceProvider; +import io.dropwizard.configuration.YamlConfigurationFactory; +import io.dropwizard.jackson.Jackson; +import io.dropwizard.jersey.validation.Validators; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; +import javax.validation.Validator; import javax.ws.rs.client.WebTarget; -import org.apache.http.client.HttpResponseException; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; +import org.openmetadata.catalog.CatalogApplicationConfig; import org.openmetadata.catalog.CatalogApplicationTest; -import org.openmetadata.catalog.entity.teams.Role; -import org.openmetadata.catalog.resources.teams.RoleResource; -import org.openmetadata.catalog.resources.teams.RoleResourceTest; -import org.openmetadata.catalog.resources.teams.UserResourceTest; -import org.openmetadata.catalog.security.Permissions; -import org.openmetadata.catalog.security.SecurityUtil; -import org.openmetadata.catalog.type.MetadataOperation; +import org.openmetadata.catalog.security.AuthenticationConfiguration; +import org.openmetadata.catalog.security.AuthorizerConfiguration; import org.openmetadata.catalog.util.TestUtils; @TestInstance(TestInstance.Lifecycle.PER_CLASS) class ConfigResourceTest extends CatalogApplicationTest { - private static final String DATA_STEWARD_ROLE_NAME = "DataSteward"; - private static final String DATA_CONSUMER_ROLE_NAME = "DataConsumer"; - private static final String DATA_STEWARD_USER_NAME = "user-data-steward"; - private static final String DATA_CONSUMER_USER_NAME = "user-data-consumer"; + + static CatalogApplicationConfig config; @BeforeAll - static void setup() throws IOException { - RoleResourceTest roleResourceTest = new RoleResourceTest(); - UserResourceTest userResourceTest = new UserResourceTest(); - - Role dataStewardRole = - roleResourceTest.getEntityByName(DATA_STEWARD_ROLE_NAME, RoleResource.FIELDS, ADMIN_AUTH_HEADERS); - userResourceTest.createEntity( - userResourceTest - .createRequest(DATA_STEWARD_USER_NAME, "", "", null) - .withRoles(List.of(dataStewardRole.getId())), - ADMIN_AUTH_HEADERS); - - Role dataConsumerRole = - roleResourceTest.getEntityByName(DATA_CONSUMER_ROLE_NAME, RoleResource.FIELDS, ADMIN_AUTH_HEADERS); - userResourceTest.createEntity( - userResourceTest - .createRequest(DATA_CONSUMER_USER_NAME, "", "", null) - .withRoles(List.of(dataConsumerRole.getId())), - ADMIN_AUTH_HEADERS); + static void setup() throws IOException, ConfigurationException { + // Get config object from test yaml file + ObjectMapper objectMapper = Jackson.newObjectMapper(); + Validator validator = Validators.newValidator(); + YamlConfigurationFactory factory = + new YamlConfigurationFactory<>(CatalogApplicationConfig.class, validator, objectMapper, "dw"); + config = factory.build(new FileConfigurationSourceProvider(), CONFIG_PATH); } - @ParameterizedTest - @MethodSource("getPermissionsTestParams") - void get_permissions(String username, Map expectedOperations) - throws HttpResponseException { - WebTarget target = getConfigResource("permissions"); - Map authHeaders = SecurityUtil.authHeaders(username + "@open-metadata.org"); - Permissions permissions = TestUtils.get(target, Permissions.class, authHeaders); - Map actualOperations = permissions.getMetadataOperations(); - - assertEquals(expectedOperations, actualOperations); + @Test + void get_auth_configs_200_OK() throws IOException { + WebTarget target = getConfigResource("auth"); + AuthenticationConfiguration auth = TestUtils.get(target, AuthenticationConfiguration.class, TEST_AUTH_HEADERS); + assertEquals(config.getAuthenticationConfiguration().toString(), auth.toString()); } - private Stream getPermissionsTestParams() { - return Stream.of( - Arguments.of( - TestUtils.ADMIN_USER_NAME, - new HashMap() { - { - put(MetadataOperation.SuggestDescription, Boolean.TRUE); - put(MetadataOperation.SuggestTags, Boolean.TRUE); - put(MetadataOperation.UpdateDescription, Boolean.TRUE); - put(MetadataOperation.UpdateLineage, Boolean.TRUE); - put(MetadataOperation.UpdateOwner, Boolean.TRUE); - put(MetadataOperation.UpdateTags, Boolean.TRUE); - } - }), - Arguments.of( - DATA_STEWARD_USER_NAME, - new HashMap() { - { - put(MetadataOperation.SuggestDescription, Boolean.FALSE); - put(MetadataOperation.SuggestTags, Boolean.FALSE); - put(MetadataOperation.UpdateDescription, Boolean.TRUE); - put(MetadataOperation.UpdateLineage, Boolean.TRUE); - put(MetadataOperation.UpdateOwner, Boolean.TRUE); - put(MetadataOperation.UpdateTags, Boolean.TRUE); - } - }), - Arguments.of( - DATA_CONSUMER_USER_NAME, - new HashMap() { - { - put(MetadataOperation.SuggestDescription, Boolean.FALSE); - put(MetadataOperation.SuggestTags, Boolean.FALSE); - put(MetadataOperation.UpdateDescription, Boolean.FALSE); - put(MetadataOperation.UpdateLineage, Boolean.FALSE); - put(MetadataOperation.UpdateOwner, Boolean.FALSE); - put(MetadataOperation.UpdateTags, Boolean.FALSE); - } - })); + @Test + void get_authorizer_configs_200_OK() throws IOException { + WebTarget target = getConfigResource("authorizer"); + AuthorizerConfiguration auth = TestUtils.get(target, AuthorizerConfiguration.class, TEST_AUTH_HEADERS); + assertEquals(config.getAuthorizerConfiguration().toString(), auth.toString()); } } diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/permissions/PermisssionsResourceTest.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/permissions/PermisssionsResourceTest.java new file mode 100644 index 00000000000..c44d7e2782f --- /dev/null +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/permissions/PermisssionsResourceTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2021 Collate + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openmetadata.catalog.resources.permissions; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; +import javax.ws.rs.client.WebTarget; +import org.apache.http.client.HttpResponseException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.openmetadata.catalog.CatalogApplicationTest; +import org.openmetadata.catalog.entity.teams.Role; +import org.openmetadata.catalog.resources.teams.RoleResource; +import org.openmetadata.catalog.resources.teams.RoleResourceTest; +import org.openmetadata.catalog.resources.teams.UserResourceTest; +import org.openmetadata.catalog.security.Permissions; +import org.openmetadata.catalog.security.SecurityUtil; +import org.openmetadata.catalog.type.MetadataOperation; +import org.openmetadata.catalog.util.TestUtils; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class PermisssionsResourceTest extends CatalogApplicationTest { + private static final String DATA_STEWARD_ROLE_NAME = "DataSteward"; + private static final String DATA_CONSUMER_ROLE_NAME = "DataConsumer"; + private static final String DATA_STEWARD_USER_NAME = "user-data-steward"; + private static final String DATA_CONSUMER_USER_NAME = "user-data-consumer"; + + @BeforeAll + static void setup() throws IOException { + RoleResourceTest roleResourceTest = new RoleResourceTest(); + UserResourceTest userResourceTest = new UserResourceTest(); + + Role dataStewardRole = + roleResourceTest.getEntityByName(DATA_STEWARD_ROLE_NAME, RoleResource.FIELDS, ADMIN_AUTH_HEADERS); + userResourceTest.createEntity( + userResourceTest + .createRequest(DATA_STEWARD_USER_NAME, "", "", null) + .withRoles(List.of(dataStewardRole.getId())), + ADMIN_AUTH_HEADERS); + + Role dataConsumerRole = + roleResourceTest.getEntityByName(DATA_CONSUMER_ROLE_NAME, RoleResource.FIELDS, ADMIN_AUTH_HEADERS); + userResourceTest.createEntity( + userResourceTest + .createRequest(DATA_CONSUMER_USER_NAME, "", "", null) + .withRoles(List.of(dataConsumerRole.getId())), + ADMIN_AUTH_HEADERS); + } + + @ParameterizedTest + @MethodSource("getPermissionsTestParams") + void get_permissions(String username, Map expectedOperations) + throws HttpResponseException { + WebTarget target = getResource("permissions"); + Map authHeaders = SecurityUtil.authHeaders(username + "@open-metadata.org"); + Permissions permissions = TestUtils.get(target, Permissions.class, authHeaders); + Map actualOperations = permissions.getMetadataOperations(); + + assertEquals(expectedOperations, actualOperations); + } + + private Stream getPermissionsTestParams() { + return Stream.of( + Arguments.of( + TestUtils.ADMIN_USER_NAME, + new HashMap() { + { + put(MetadataOperation.SuggestDescription, Boolean.TRUE); + put(MetadataOperation.SuggestTags, Boolean.TRUE); + put(MetadataOperation.UpdateDescription, Boolean.TRUE); + put(MetadataOperation.UpdateLineage, Boolean.TRUE); + put(MetadataOperation.UpdateOwner, Boolean.TRUE); + put(MetadataOperation.UpdateTags, Boolean.TRUE); + } + }), + Arguments.of( + DATA_STEWARD_USER_NAME, + new HashMap() { + { + put(MetadataOperation.SuggestDescription, Boolean.FALSE); + put(MetadataOperation.SuggestTags, Boolean.FALSE); + put(MetadataOperation.UpdateDescription, Boolean.TRUE); + put(MetadataOperation.UpdateLineage, Boolean.TRUE); + put(MetadataOperation.UpdateOwner, Boolean.TRUE); + put(MetadataOperation.UpdateTags, Boolean.TRUE); + } + }), + Arguments.of( + DATA_CONSUMER_USER_NAME, + new HashMap() { + { + put(MetadataOperation.SuggestDescription, Boolean.FALSE); + put(MetadataOperation.SuggestTags, Boolean.FALSE); + put(MetadataOperation.UpdateDescription, Boolean.FALSE); + put(MetadataOperation.UpdateLineage, Boolean.FALSE); + put(MetadataOperation.UpdateOwner, Boolean.FALSE); + put(MetadataOperation.UpdateTags, Boolean.FALSE); + } + })); + } +}