diff options
Diffstat (limited to 'controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java')
-rw-r--r-- | controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java index 0c808e30c2a..b7080a763f0 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java @@ -10,16 +10,17 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId; import com.yahoo.vespa.hosted.controller.api.identifiers.UserGroup; import com.yahoo.vespa.hosted.controller.api.identifiers.UserId; import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService; -import com.yahoo.vespa.hosted.controller.athenz.AthenzClientFactory; -import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils; -import com.yahoo.vespa.hosted.controller.athenz.NToken; +import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzClientFactory; +import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzIdentity; +import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzPrincipal; +import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzUser; +import com.yahoo.vespa.hosted.controller.api.integration.athenz.NToken; import com.yahoo.vespa.hosted.controller.common.ContextAttributes; import com.yahoo.vespa.hosted.controller.restapi.filter.NTokenRequestFilter; import javax.ws.rs.ForbiddenException; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.SecurityContext; -import java.security.Principal; import java.util.Optional; import java.util.logging.Logger; @@ -54,27 +55,26 @@ public class Authorizer { Optional<Tenant> tenant = controller.tenants().tenant(tenantId); if ( ! tenant.isPresent()) return; - UserId userId = getUserId(request); - if (isTenantAdmin(userId, tenant.get())) return; + AthenzIdentity identity = getIdentity(request); + if (isTenantAdmin(identity, tenant.get())) return; - throw loggedForbiddenException("User " + userId + " does not have write access to tenant " + tenantId); + throw loggedForbiddenException("User " + identity.getFullName() + " does not have write access to tenant " + tenantId); } - public UserId getUserId(HttpRequest request) { - String name = getPrincipal(request).getName(); - if (name == null) - throw loggedForbiddenException("Not authorized: User name is null"); - return new UserId(name); + public AthenzIdentity getIdentity(HttpRequest request) { + return getPrincipal(request).getIdentity(); } /** Returns the principal or throws forbidden */ // TODO: Avoid REST exceptions - public Principal getPrincipal(HttpRequest request) { + public AthenzPrincipal getPrincipal(HttpRequest request) { return getPrincipalIfAny(request).orElseThrow(() -> Authorizer.loggedForbiddenException("User is not authenticated")); } /** Returns the principal if there is any */ - public Optional<Principal> getPrincipalIfAny(HttpRequest request) { - return securityContextOf(request).map(SecurityContext::getUserPrincipal); + public Optional<AthenzPrincipal> getPrincipalIfAny(HttpRequest request) { + return securityContextOf(request) + .map(SecurityContext::getUserPrincipal) + .map(AthenzPrincipal.class::cast); } public Optional<NToken> getNToken(HttpRequest request) { @@ -93,26 +93,36 @@ public class Authorizer { return new ForbiddenException(formattedMessage); } - private boolean isTenantAdmin(UserId userId, Tenant tenant) { + private boolean isTenantAdmin(AthenzIdentity identity, Tenant tenant) { switch (tenant.tenantType()) { case ATHENS: - return isAthenzTenantAdmin(userId, tenant.getAthensDomain().get()); - case OPSDB: - return isGroupMember(userId, tenant.getUserGroup().get()); - case USER: - return isUserTenantOwner(tenant.getId(), userId); + return isAthenzTenantAdmin(identity, tenant.getAthensDomain().get()); + case OPSDB: { + if (!(identity instanceof AthenzUser)) { + return false; + } + AthenzUser user = (AthenzUser) identity; + return isGroupMember(user.getUserId(), tenant.getUserGroup().get()); + } + case USER: { + if (!(identity instanceof AthenzUser)) { + return false; + } + AthenzUser user = (AthenzUser) identity; + return isUserTenantOwner(tenant.getId(), user.getUserId()); + } } throw new IllegalArgumentException("Unknown tenant type: " + tenant.tenantType()); } - private boolean isAthenzTenantAdmin(UserId userId, AthenzDomain tenantDomain) { + private boolean isAthenzTenantAdmin(AthenzIdentity athenzIdentity, AthenzDomain tenantDomain) { return athenzClientFactory.createZmsClientWithServicePrincipal() - .hasTenantAdminAccess(AthenzUtils.createPrincipal(userId), tenantDomain); + .hasTenantAdminAccess(athenzIdentity, tenantDomain); } - public boolean isAthenzDomainAdmin(UserId userId, AthenzDomain tenantDomain) { + public boolean isAthenzDomainAdmin(AthenzIdentity identity, AthenzDomain tenantDomain) { return athenzClientFactory.createZmsClientWithServicePrincipal() - .isDomainAdmin(AthenzUtils.createPrincipal(userId), tenantDomain); + .isDomainAdmin(identity, tenantDomain); } public boolean isGroupMember(UserId userId, UserGroup userGroup) { |