summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserManagement.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Roles.java8
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControl.java61
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControlRequests.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java1
6 files changed, 58 insertions, 18 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserManagement.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserManagement.java
index 7dd7e6a6172..c78dcc76854 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserManagement.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserManagement.java
@@ -15,7 +15,7 @@ public interface UserManagement {
/** Creates the given role, or throws if the role already exists. */
void createRole(RoleId role);
- /** Deletes the given role, or throws if it doesn't already exist.. */
+ /** Deletes the given role, or throws if it doesn't already exist. */
void deleteRole(RoleId role);
/** Ensures the given users exist, and are part of the given role, or throws if the role does not exist. */
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Roles.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Roles.java
index a6a4fdaf16c..f6149bf6e88 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Roles.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Roles.java
@@ -1,8 +1,10 @@
package com.yahoo.vespa.hosted.controller.api.role;
+import com.google.inject.Inject;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.TenantName;
+import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
import java.util.Objects;
@@ -17,6 +19,12 @@ public class Roles {
private final SystemName system;
+
+ @Inject
+ public Roles(ZoneRegistry zones) {
+ this(zones.system());
+ }
+
/** Creates a Roles which can be used to create bound roles for the given system. */
public Roles(SystemName system) {
this.system = Objects.requireNonNull(system);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
index 19148a6c9bd..d1a6e39a1dd 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
@@ -61,7 +61,7 @@ public class TenantController {
.collect(Collectors.toList());
}
- /** Returns the lsit of tenants accessible to the given user. */
+ /** Returns the list of tenants accessible to the given user. */
public List<Tenant> asList(Credentials credentials) {
return accessControl.accessibleTenants(asList(), credentials);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControl.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControl.java
index 67d7a02a915..d1806fb5747 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControl.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControl.java
@@ -2,10 +2,17 @@ package com.yahoo.vespa.hosted.controller.security;
import com.google.inject.Inject;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.api.integration.organization.BillingInfo;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Marketplace;
+import com.yahoo.vespa.hosted.controller.api.integration.user.RoleId;
+import com.yahoo.vespa.hosted.controller.api.integration.user.UserId;
+import com.yahoo.vespa.hosted.controller.api.integration.user.UserManagement;
+import com.yahoo.vespa.hosted.controller.api.role.ApplicationRole;
+import com.yahoo.vespa.hosted.controller.api.role.Roles;
+import com.yahoo.vespa.hosted.controller.api.role.TenantRole;
import com.yahoo.vespa.hosted.controller.tenant.CloudTenant;
import com.yahoo.vespa.hosted.controller.tenant.Tenant;
@@ -19,21 +26,28 @@ import java.util.List;
public class CloudAccessControl implements AccessControl {
private final Marketplace marketplace;
+ private final UserManagement userManagement;
+ private final Roles roles;
@Inject
- public CloudAccessControl(Marketplace marketplace) {
+ public CloudAccessControl(Marketplace marketplace, UserManagement userManagement, Roles roles) {
this.marketplace = marketplace;
+ this.userManagement = userManagement;
+ this.roles = roles;
}
@Override
public CloudTenant createTenant(TenantSpec tenantSpec, Credentials credentials, List<Tenant> existing) {
CloudTenantSpec spec = (CloudTenantSpec) tenantSpec;
+ CloudTenant tenant = new CloudTenant(spec.tenant(), new BillingInfo("customer", "Vespa"));
+ // CloudTenant tenant new CloudTenant(spec.tenant(), marketplace.resolveCustomer(spec.getRegistrationToken()));
+ // TODO Enable the above when things work.
- // Do things ...
+ RoleId ownerRole = RoleId.fromRole(roles.tenantOwner(spec.tenant()));
+ userManagement.createRole(ownerRole);
+ userManagement.addUsers(ownerRole, List.of(new UserId(credentials.user().getName())));
- // return new CloudTenant(spec.tenant(), marketplace.resolveCustomer(spec.getRegistrationToken()));
- // TODO Enable the above when things work.
- return new CloudTenant(spec.tenant(), new BillingInfo("customer", "Vespa"));
+ return tenant;
}
@Override
@@ -43,31 +57,48 @@ public class CloudAccessControl implements AccessControl {
@Override
public void deleteTenant(TenantName tenant, Credentials credentials) {
-
// Probably terminate customer subscription?
- // Delete tenant group
-
+ tenantRoles(tenant).stream()
+ .map(RoleId::fromRole)
+ .filter(userManagement.listRoles()::contains)
+ .forEach(userManagement::deleteRole);
}
@Override
public void createApplication(ApplicationId application, Credentials credentials) {
-
- // Create application group?
-
+ RoleId ownerRole = RoleId.fromRole(roles.applicationOwner(application.tenant(), application.application()));
+ userManagement.createRole(ownerRole);
+ userManagement.addUsers(ownerRole, List.of(new UserId(credentials.user().getName())));
}
@Override
public void deleteApplication(ApplicationId id, Credentials credentials) {
-
- // Delete application group?
-
+ applicationRoles(id.tenant(), id.application()).stream()
+ .map(RoleId::fromRole)
+ .filter(userManagement.listRoles()::contains)
+ .forEach(userManagement::deleteRole);
}
@Override
public List<Tenant> accessibleTenants(List<Tenant> tenants, Credentials credentials) {
- // Get credential things (token with roles or something) and check what it's good for.
+ // TODO: Get credential things (token with roles or something) and check what it's good for.
+ // TODO ... or ignore this here, and compute it somewhere else.
return Collections.emptyList();
}
+ private List<TenantRole> tenantRoles(TenantName tenant) {
+ return List.of(roles.tenantOperator(tenant),
+ roles.tenantAdmin(tenant),
+ roles.tenantOwner(tenant));
+ }
+
+ private List<ApplicationRole> applicationRoles(TenantName tenant, ApplicationName application) {
+ return List.of(roles.applicationReader(tenant, application),
+ roles.applicationDeveloper(tenant, application),
+ roles.applicationOperator(tenant, application),
+ roles.applicationAdmin(tenant, application),
+ roles.applicationOwner(tenant, application));
+ }
+
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControlRequests.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControlRequests.java
index 631d4debe88..ea931616211 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControlRequests.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudAccessControlRequests.java
@@ -20,7 +20,7 @@ public class CloudAccessControlRequests implements AccessControlRequests {
@Override
public Credentials credentials(TenantName tenant, Inspector requestObject, HttpRequest request) {
- // TODO Pick out JWT data and return a specialised credentials thing.
+ // TODO Include roles, if this is to be used for displaying accessible data.
return new Credentials(request.getUserPrincipal());
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java
index ddc8d68e08b..c21d4b4b0bf 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java
@@ -95,6 +95,7 @@ public class ControllerContainerTest {
" <component id='com.yahoo.vespa.hosted.controller.integration.ApplicationStoreMock'/>\n" +
" <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.MockTesterCloud'/>\n" +
" <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.MockMailer'/>\n" +
+ " <component id='com.yahoo.vespa.hosted.controller.api.role.Roles'/>\n" +
" <component id='com.yahoo.vespa.hosted.controller.security.AthenzAccessControlRequests'/>\n" +
" <component id='com.yahoo.vespa.hosted.controller.athenz.impl.AthenzFacade'/>\n" +
" <handler id='com.yahoo.vespa.hosted.controller.restapi.application.ApplicationApiHandler'>\n" +