diff --git a/controller/api/frontend/src/main/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProvider.java b/controller/api/frontend/src/main/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProvider.java index cd3605fbf2..84ac7a95d8 100644 --- a/controller/api/frontend/src/main/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProvider.java +++ b/controller/api/frontend/src/main/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProvider.java @@ -16,11 +16,13 @@ import com.vmware.identity.openidconnect.client.ResourceServerAccessToken; import com.vmware.photon.controller.api.frontend.auth.fetcher.Multiplexed; import com.vmware.photon.controller.api.frontend.auth.fetcher.SecurityGroupFetcher; +import com.vmware.photon.controller.api.frontend.clients.DeploymentFeClient; import com.vmware.photon.controller.api.frontend.config.AuthConfig; import com.vmware.photon.controller.api.frontend.exceptions.external.ErrorCode; import com.vmware.photon.controller.api.frontend.exceptions.external.ExternalException; import com.vmware.photon.controller.api.frontend.resources.routes.AuthRoutes; import com.vmware.photon.controller.api.frontend.resources.routes.AvailableRoutes; +import com.vmware.photon.controller.api.model.Deployment; import com.google.inject.Inject; import org.glassfish.jersey.server.ContainerRequest; @@ -63,12 +65,16 @@ public class AuthPolicyProvider implements PolicyProvider { private final String defaultAdminGroup; + private final DeploymentFeClient deployerClient; + @Inject public AuthPolicyProvider(TransactionAuthorizationObjectResolver resolver, @Multiplexed SecurityGroupFetcher fetcher, - AuthConfig config) { + AuthConfig config, + DeploymentFeClient deploymentClient) { this.resolver = resolver; this.fetcher = fetcher; + this.deployerClient = deploymentClient; this.defaultAdminGroup = config.getAuthDomain() + DEFAULT_ADMIN_GROUP_NAME; } @@ -130,6 +136,15 @@ public void checkAccessPermissions(ContainerRequest request, ResourceServerAcces Set intersectionGroup = new HashSet<>(groups); intersectionGroup.add(this.defaultAdminGroup); + // This will give the system admin the same privileges as the default + // admin group, otherwise the system admin will get ACCESS_FORBIDDEN + // if a resource does not exist. + for (Deployment deployment : deployerClient.getAll()) { + if (deployment.getAuth() != null && deployment.getAuth().getSecurityGroups() != null) { + intersectionGroup.addAll(deployment.getAuth().getSecurityGroups()); + } + } + // Perform request and token group intersection, deny if empty. intersectionGroup.retainAll(tokenGroups); if (intersectionGroup.isEmpty()) { diff --git a/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthFilterTest.java b/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthFilterTest.java index 60de42152a..81e8d42838 100644 --- a/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthFilterTest.java +++ b/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthFilterTest.java @@ -15,6 +15,7 @@ import com.vmware.identity.openidconnect.client.ResourceServerAccessToken; import com.vmware.photon.controller.api.frontend.auth.fetcher.MultiplexedSecurityGroupFetcher; +import com.vmware.photon.controller.api.frontend.clients.DeploymentFeClient; import com.vmware.photon.controller.api.frontend.config.AuthConfig; import com.vmware.photon.controller.api.frontend.exceptions.external.ErrorCode; import com.vmware.photon.controller.api.frontend.exceptions.external.ExternalException; @@ -71,7 +72,8 @@ private void setUp() { AuthPolicyProvider provider = new AuthPolicyProvider( mock(TransactionAuthorizationObjectResolver.class), mock(MultiplexedSecurityGroupFetcher.class), - new AuthConfig()); + new AuthConfig(), + mock(DeploymentFeClient.class)); subject = new AuthFilter(config, provider); } diff --git a/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProviderTest.java b/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProviderTest.java index 64972c81aa..c01c578965 100644 --- a/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProviderTest.java +++ b/controller/api/frontend/src/test/java/com/vmware/photon/controller/api/frontend/auth/AuthPolicyProviderTest.java @@ -16,6 +16,7 @@ import com.vmware.identity.openidconnect.client.ResourceServerAccessToken; import com.vmware.photon.controller.api.frontend.auth.fetcher.MultiplexedSecurityGroupFetcher; import com.vmware.photon.controller.api.frontend.auth.fetcher.SecurityGroupFetcher; +import com.vmware.photon.controller.api.frontend.clients.DeploymentFeClient; import com.vmware.photon.controller.api.frontend.config.AuthConfig; import com.vmware.photon.controller.api.frontend.exceptions.external.ExternalException; import com.vmware.photon.controller.api.frontend.helpers.JerseyPropertiesDelegate; @@ -69,7 +70,8 @@ public void setUpCommon() { config = new AuthConfig(); config.setAuthDomain("esxcloud"); - policyProvider = new AuthPolicyProvider(resolver, fetcher, config); + policyProvider = new AuthPolicyProvider(resolver, fetcher, config, + mock(DeploymentFeClient.class)); } /** diff --git a/tests/integration_tests/spec/support/api_routes_helper.rb b/tests/integration_tests/spec/support/api_routes_helper.rb index d8c6a91a21..9f38a5d9d4 100644 --- a/tests/integration_tests/spec/support/api_routes_helper.rb +++ b/tests/integration_tests/spec/support/api_routes_helper.rb @@ -79,10 +79,10 @@ def self.auth_routes def self.clusters_routes(id = SecureRandom.uuid) [ - EsxCloud::ApiRoute.new(:get, "/clusters/#{id}", 404, 403, 403, 403, 403), - EsxCloud::ApiRoute.new(:post, "/clusters/#{id}/resize", 400, 403, 403, 403, 403), - EsxCloud::ApiRoute.new(:get, "/clusters/#{id}/vms", 404, 403, 403, 403, 403), - EsxCloud::ApiRoute.new(:delete, "/clusters/#{id}", 404, 403, 403, 403, 403) + EsxCloud::ApiRoute.new(:get, "/clusters/#{id}", 404, 404, 403, 403, 403), + EsxCloud::ApiRoute.new(:post, "/clusters/#{id}/resize", 400, 400, 403, 403, 403), + EsxCloud::ApiRoute.new(:get, "/clusters/#{id}/vms", 404, 404, 403, 403, 403), + EsxCloud::ApiRoute.new(:delete, "/clusters/#{id}", 404, 404, 403, 403, 403) ] end @@ -193,8 +193,8 @@ def self.projects_routes_with_virtual_networks_routes(id = SecureRandom.uuid) def self.resource_tickets_routes(id = SecureRandom.uuid) [ - EsxCloud::ApiRoute.new(:get, "/resource-tickets/#{id}", 404, 403, 403, 403, 403), - EsxCloud::ApiRoute.new(:get, "/resource-tickets/#{id}/tasks", 404, 403, 403, 403, 403) + EsxCloud::ApiRoute.new(:get, "/resource-tickets/#{id}", 404, 404, 403, 403, 403), + EsxCloud::ApiRoute.new(:get, "/resource-tickets/#{id}/tasks", 404, 404, 403, 403, 403) ] end