From 8c8f5720fa00ca5b33bc4d2258bfbe09d2a3dcd1 Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Fri, 29 Nov 2019 13:00:29 +0100 Subject: Add all accessible tenants --- .../controller/api/integration/user/User.java | 12 +++++++----- .../restapi/filter/AthenzRoleFilter.java | 22 +++++++--------------- .../restapi/filter/AthenzRoleFilterTest.java | 14 +++++++------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java index 35dcd54799b..bfa4963e005 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java @@ -2,19 +2,21 @@ package com.yahoo.vespa.hosted.controller.api.integration.user; import java.util.Objects; +/** + * @author smorgrav + */ public class User { + public static final String ATTRIBUTE_NAME = User.class.getName(); + private final String name; private final String email; private final String nickname; private final String picture; public User(String email, String name, String nickname, String picture) { - Objects.requireNonNull(email); - Objects.requireNonNull(name); - - this.name = name; - this.email = email; + this.name = Objects.requireNonNull(name); + this.email = Objects.requireNonNull(email); this.nickname = nickname; this.picture = picture; } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java index 56b2de33478..361aad93133 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java @@ -15,14 +15,14 @@ import com.yahoo.vespa.athenz.api.AthenzUser; import com.yahoo.vespa.athenz.client.zms.ZmsClientException; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.TenantController; +import com.yahoo.vespa.hosted.controller.api.integration.athenz.ApplicationAction; import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzClientFactory; import com.yahoo.vespa.hosted.controller.api.role.Role; import com.yahoo.vespa.hosted.controller.api.role.SecurityContext; -import com.yahoo.vespa.hosted.controller.api.integration.athenz.ApplicationAction; import com.yahoo.vespa.hosted.controller.athenz.impl.AthenzFacade; +import com.yahoo.vespa.hosted.controller.security.Credentials; import com.yahoo.vespa.hosted.controller.tenant.AthenzTenant; import com.yahoo.vespa.hosted.controller.tenant.Tenant; -import com.yahoo.vespa.hosted.controller.tenant.UserTenant; import com.yahoo.yolean.Exceptions; import java.net.URI; @@ -82,13 +82,13 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { AthenzIdentity identity = principal.getIdentity(); + Set roleMemberships = new HashSet<>(); if (athenz.hasHostedOperatorAccess(identity)) - return Set.of(Role.hostedOperator()); + roleMemberships.add(Role.hostedOperator()); - // A principal can be both tenant admin and tenantPipeline - Set roleMemberships = new HashSet<>(); - if (tenant.isPresent() && isTenantAdmin(identity, tenant.get())) - roleMemberships.add(Role.athenzTenantAdmin(tenant.get().name())); + // Add all tenants that are accessible for this request + athenz.accessibleTenants(tenants.asList(), new Credentials(principal)) + .forEach(accessibleTenant -> roleMemberships.add(Role.athenzTenantAdmin(accessibleTenant.name()))); if (identity.getDomain().equals(SCREWDRIVER_DOMAIN) && application.isPresent() && tenant.isPresent()) // NOTE: Only fine-grained deploy authorization for Athenz tenants @@ -114,14 +114,6 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { : Set.copyOf(roleMemberships); } - private boolean isTenantAdmin(AthenzIdentity identity, Tenant tenant) { - switch (tenant.type()) { - case athenz: return athenz.hasTenantAdminAccess(identity, ((AthenzTenant) tenant).domain()); - case user: return ((UserTenant) tenant).is(identity.getName()) || athenz.hasHostedOperatorAccess(identity); - default: throw new IllegalArgumentException("Unexpected tenant type '" + tenant.type() + "'."); - } - } - private boolean hasDeployerAccess(AthenzIdentity identity, AthenzDomain tenantDomain, ApplicationName application) { try { return athenz.hasApplicationAccess(identity, diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java index ee9a7ff78df..0aba88ccc77 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java @@ -10,11 +10,11 @@ import com.yahoo.vespa.athenz.api.AthenzUser; import com.yahoo.vespa.hosted.controller.ControllerTester; import com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId; import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId; -import com.yahoo.vespa.hosted.controller.api.role.Role; import com.yahoo.vespa.hosted.controller.api.integration.athenz.ApplicationAction; -import com.yahoo.vespa.hosted.controller.athenz.HostedAthenzIdentities; import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzClientFactoryMock; import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzDbMock; +import com.yahoo.vespa.hosted.controller.api.role.Role; +import com.yahoo.vespa.hosted.controller.athenz.HostedAthenzIdentities; import org.junit.Before; import org.junit.Test; @@ -72,13 +72,13 @@ public class AthenzRoleFilterTest { public void testTranslations() { // Hosted operators are always members of the hostedOperator role. - assertEquals(Set.of(Role.hostedOperator()), + assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner()), filter.roles(HOSTED_OPERATOR, NO_CONTEXT_PATH)); - assertEquals(Set.of(Role.hostedOperator()), + assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner()), filter.roles(HOSTED_OPERATOR, TENANT_CONTEXT_PATH)); - assertEquals(Set.of(Role.hostedOperator()), + assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner()), filter.roles(HOSTED_OPERATOR, APPLICATION_CONTEXT_PATH)); // Tenant admins are members of the athenzTenantAdmin role within their tenant subtree. @@ -91,10 +91,10 @@ public class AthenzRoleFilterTest { assertEquals(Set.of(Role.athenzTenantAdmin(TENANT)), filter.roles(TENANT_ADMIN, APPLICATION_CONTEXT_PATH)); - assertEquals(Set.of(Role.everyone()), + assertEquals(Set.of(Role.athenzTenantAdmin(TENANT)), filter.roles(TENANT_ADMIN, TENANT2_CONTEXT_PATH)); - assertEquals(Set.of(Role.everyone()), + assertEquals(Set.of(Role.athenzTenantAdmin(TENANT)), filter.roles(TENANT_ADMIN, APPLICATION2_CONTEXT_PATH)); // Build services are members of the tenantPipeline role within their application subtree. -- cgit v1.2.3 From af8f8a269d5b4572d29a310d596905b4e3c8273c Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Fri, 29 Nov 2019 14:33:21 +0100 Subject: Relax name requirement --- .../com/yahoo/vespa/hosted/controller/api/integration/user/User.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java index bfa4963e005..ac64df7713f 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java @@ -9,14 +9,14 @@ public class User { public static final String ATTRIBUTE_NAME = User.class.getName(); - private final String name; private final String email; + private final String name; private final String nickname; private final String picture; public User(String email, String name, String nickname, String picture) { - this.name = Objects.requireNonNull(name); this.email = Objects.requireNonNull(email); + this.name = name; this.nickname = nickname; this.picture = picture; } -- cgit v1.2.3