aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'controller-server/src/test')
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java6
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java21
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java7
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java230
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java20
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/user.json2
7 files changed, 162 insertions, 128 deletions
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java
index 355b63335c0..9dbebecdb25 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/TestIdentities.java
@@ -9,7 +9,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.RegionId;
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.athenz.AthenzUtils;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUser;
import com.yahoo.vespa.hosted.controller.athenz.NToken;
import com.yahoo.vespa.hosted.controller.athenz.filter.AthenzTestUtils;
@@ -35,7 +35,7 @@ public class TestIdentities {
public static Tenant tenant = Tenant.createOpsDbTenant(tenantId, userGroup1, property);
public static NToken userNToken = new NToken.Builder(
- "U1", AthenzUtils.createPrincipal(userId), AthenzTestUtils.generateRsaKeypair().getPrivate(), "0")
+ "U1", AthenzUser.fromUserId(userId), AthenzTestUtils.generateRsaKeypair().getPrivate(), "0")
.build();
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
index 20db038485d..5a3f048101a 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/AthenzPrincipalFilterTest.java
@@ -8,7 +8,7 @@ import com.yahoo.jdisc.handler.ResponseHandler;
import com.yahoo.jdisc.http.filter.DiscFilterRequest;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
-import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUser;
import com.yahoo.vespa.hosted.controller.athenz.InvalidTokenException;
import com.yahoo.vespa.hosted.controller.athenz.NToken;
import org.junit.Before;
@@ -44,7 +44,7 @@ public class AthenzPrincipalFilterTest {
@Before
public void before() {
validator = mock(NTokenValidator.class);
- principal = AthenzUtils.createPrincipal(new UserId("bob"));
+ principal = new AthenzPrincipal(AthenzUser.fromUserId(new UserId("bob")));
}
@Test
@@ -94,7 +94,7 @@ public class AthenzPrincipalFilterTest {
private static NToken createDummyToken() {
return new NToken.Builder(
- "U1", AthenzUtils.createPrincipal(new UserId("bob")), AthenzTestUtils.generateRsaKeypair().getPrivate(), "0")
+ "U1", AthenzUser.fromUserId(new UserId("bob")), AthenzTestUtils.generateRsaKeypair().getPrivate(), "0")
.build();
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java
index 70ba504df03..927910a89a1 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/athenz/filter/NTokenValidatorTest.java
@@ -2,7 +2,9 @@
package com.yahoo.vespa.hosted.controller.athenz.filter;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzIdentity;
import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUser;
import com.yahoo.vespa.hosted.controller.athenz.InvalidTokenException;
import com.yahoo.vespa.hosted.controller.athenz.NToken;
import com.yahoo.vespa.hosted.controller.athenz.ZmsKeystore;
@@ -15,7 +17,6 @@ import java.security.NoSuchAlgorithmException;
import java.util.Optional;
import static com.yahoo.vespa.hosted.controller.athenz.AthenzUtils.ZMS_ATHENZ_SERVICE;
-import static com.yahoo.vespa.hosted.controller.athenz.AthenzUtils.createPrincipal;
import static org.junit.Assert.assertEquals;
/**
@@ -25,7 +26,7 @@ public class NTokenValidatorTest {
private static final KeyPair TRUSTED_KEY = AthenzTestUtils.generateRsaKeypair();
private static final KeyPair UNKNOWN_KEY = AthenzTestUtils.generateRsaKeypair();
- private static final AthenzPrincipal PRINCIPAL = createPrincipal(new UserId("myuser"));
+ private static final AthenzIdentity IDENTITY = AthenzUser.fromUserId(new UserId("myuser"));
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@@ -33,15 +34,15 @@ public class NTokenValidatorTest {
@Test
public void valid_token_is_accepted() throws NoSuchAlgorithmException, InvalidTokenException {
NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), TRUSTED_KEY, "0");
+ NToken token = createNToken(IDENTITY, System.currentTimeMillis(), TRUSTED_KEY, "0");
AthenzPrincipal principal = validator.validate(token);
- assertEquals("user.myuser", principal.toYRN());
+ assertEquals("user.myuser", principal.getIdentity().getFullName());
}
@Test
public void invalid_signature_is_not_accepted() throws InvalidTokenException {
NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), UNKNOWN_KEY, "0");
+ NToken token = createNToken(IDENTITY, System.currentTimeMillis(), UNKNOWN_KEY, "0");
exceptionRule.expect(InvalidTokenException.class);
exceptionRule.expectMessage("NToken is expired or has invalid signature");
validator.validate(token);
@@ -50,7 +51,7 @@ public class NTokenValidatorTest {
@Test
public void expired_token_is_not_accepted() throws InvalidTokenException {
NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(PRINCIPAL, 1234 /*long time ago*/, TRUSTED_KEY, "0");
+ NToken token = createNToken(IDENTITY, 1234 /*long time ago*/, TRUSTED_KEY, "0");
exceptionRule.expect(InvalidTokenException.class);
exceptionRule.expectMessage("NToken is expired or has invalid signature");
validator.validate(token);
@@ -59,7 +60,7 @@ public class NTokenValidatorTest {
@Test
public void unknown_keyId_is_not_accepted() throws InvalidTokenException {
NTokenValidator validator = new NTokenValidator(createKeystore());
- NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), TRUSTED_KEY, "unknown-key-id");
+ NToken token = createNToken(IDENTITY, System.currentTimeMillis(), TRUSTED_KEY, "unknown-key-id");
exceptionRule.expect(InvalidTokenException.class);
exceptionRule.expectMessage("NToken has an unknown keyId");
validator.validate(token);
@@ -69,7 +70,7 @@ public class NTokenValidatorTest {
public void failing_to_find_key_should_throw_exception() throws InvalidTokenException {
ZmsKeystore keystore = (athensService, keyId) -> { throw new RuntimeException(); };
NTokenValidator validator = new NTokenValidator(keystore);
- NToken token = createNToken(PRINCIPAL, System.currentTimeMillis(), TRUSTED_KEY, "0");
+ NToken token = createNToken(IDENTITY, System.currentTimeMillis(), TRUSTED_KEY, "0");
exceptionRule.expect(InvalidTokenException.class);
exceptionRule.expectMessage("Failed to retrieve public key");
validator.validate(token);
@@ -82,8 +83,8 @@ public class NTokenValidatorTest {
: Optional.empty();
}
- private static NToken createNToken(AthenzPrincipal principal, long issueTime, KeyPair keyPair, String keyId) {
- return new NToken.Builder("U1", principal, keyPair.getPrivate(), keyId)
+ private static NToken createNToken(AthenzIdentity identity, long issueTime, KeyPair keyPair, String keyId) {
+ return new NToken.Builder("U1", identity, keyPair.getPrivate(), keyId)
.salt("1234")
.hostname("host")
.ip("1.2.3.4")
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
index 71ad6560126..fb0adcd3152 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
@@ -20,11 +20,10 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.Property;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
-import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
import com.yahoo.vespa.hosted.controller.athenz.ApplicationAction;
-import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzService;
import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock;
import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzDbMock;
@@ -108,7 +107,7 @@ public class ContainerControllerTester {
AthenzDomain athensDomain = new AthenzDomain(domainName);
AthenzDbMock.Domain domain = new AthenzDbMock.Domain(athensDomain);
domain.markAsVespaTenant();
- domain.admin(new AthenzPrincipal(new AthenzDomain("domain"), new UserId(userName)));
+ domain.admin(AthenzUtils.createAthenzIdentity(new AthenzDomain("domain"), userName));
mock.getSetup().addDomain(domain);
return athensDomain;
}
@@ -133,6 +132,6 @@ public class ContainerControllerTester {
mock.getSetup()
.domains.get(tenantDomain)
.applications.get(new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(application.id().application().value()))
- .addRoleMember(action, AthenzUtils.createPrincipal(screwdriverId));
+ .addRoleMember(action, AthenzService.fromScrewdriverId(screwdriverId));
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 540550e871d..7b05f0ce438 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.hosted.controller.restapi.application;
import com.yahoo.application.container.handler.Request;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.AthenzService;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.hosted.controller.Application;
@@ -24,8 +23,9 @@ import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.DeploymentJobs;
import com.yahoo.vespa.hosted.controller.application.DeploymentMetrics;
import com.yahoo.vespa.hosted.controller.athenz.ApplicationAction;
-import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
-import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzIdentity;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzService;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUser;
import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock;
import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzDbMock;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
@@ -60,6 +60,7 @@ import static com.yahoo.application.container.handler.Request.Method.PUT;
/**
* @author bratseth
* @author mpolden
+ * @author bjorncs
*/
public class ApplicationApiTest extends ControllerContainerTest {
@@ -73,9 +74,9 @@ public class ApplicationApiTest extends ControllerContainerTest {
.region("us-west-1")
.build();
- private static final String athenzUserDomain = "domain1";
-
- private static final String athenzScrewdriverDomain = AthenzUtils.SCREWDRIVER_DOMAIN.id();
+ private static final AthenzDomain ATHENZ_TENANT_DOMAIN = new AthenzDomain("domain1");
+ private static final ScrewdriverId SCREWDRIVER_ID = new ScrewdriverId("12345");
+ private static final UserId USER_ID = new UserId("myuser");
@Test
public void testApplicationApi() throws Exception {
@@ -83,7 +84,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
ContainerTester tester = controllerTester.containerTester();
tester.updateSystemVersion();
- addTenantAthenzDomain(athenzUserDomain, "mytenant"); // (Necessary but not provided in this API)
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID); // (Necessary but not provided in this API)
// GET API root
tester.assertResponse(request("/application/v4/", GET),
@@ -99,14 +100,16 @@ public class ApplicationApiTest extends ControllerContainerTest {
new File("cookiefreshness.json"));
// POST (add) a tenant without property ID
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// PUT (modify) a tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// GET the authenticated user (with associated tenants)
- tester.assertResponse(request("/application/v4/user", GET),
+ tester.assertResponse(request("/application/v4/user", GET).userIdentity(USER_ID),
new File("user.json"));
// GET all tenants
tester.assertResponse(request("/application/v4/tenant/", GET),
@@ -114,15 +117,17 @@ public class ApplicationApiTest extends ControllerContainerTest {
// Add another Athens domain, so we can try to create more tenants
- addTenantAthenzDomain("domain2", "mytenant"); // New domain to test tenant w/property ID
+ createAthenzDomainWithAdmin(new AthenzDomain("domain2"), USER_ID); // New domain to test tenant w/property ID
// Add property info for that property id, as well, in the mock organization.
addPropertyData((MockOrganization) controllerTester.controller().organization(), "1234");
// POST (add) a tenant with property ID
tester.assertResponse(request("/application/v4/tenant/tenant2", POST)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
new File("tenant-without-applications-with-id.json"));
// PUT (modify) a tenant with property ID
tester.assertResponse(request("/application/v4/tenant/tenant2", PUT)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
new File("tenant-without-applications-with-id.json"));
// GET a tenant with property ID
@@ -132,15 +137,18 @@ public class ApplicationApiTest extends ControllerContainerTest {
// Test legacy OpsDB tenants
// POST (add) an OpsDB tenant with property ID
tester.assertResponse(request("/application/v4/tenant/tenant3", POST)
+ .userIdentity(USER_ID)
.data("{\"userGroup\":\"group1\",\"property\":\"property1\",\"propertyId\":\"1234\"}"),
new File("opsdb-tenant-with-id-without-applications.json"));
// PUT (modify) the OpsDB tenant to set another property
tester.assertResponse(request("/application/v4/tenant/tenant3", PUT)
+ .userIdentity(USER_ID)
.data("{\"userGroup\":\"group1\",\"property\":\"property2\",\"propertyId\":\"4321\"}"),
new File("opsdb-tenant-with-new-id-without-applications.json"));
// POST (create) an application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
+ .userIdentity(USER_ID),
new File("application-reference.json"));
// GET a tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", GET),
@@ -151,11 +159,13 @@ public class ApplicationApiTest extends ControllerContainerTest {
new File("application-list.json"));
// POST triggering of a full deployment to an application (if version is omitted, current system version is used)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", POST)
+ .userIdentity(USER_ID)
.data("6.1.0"),
new File("application-deployment.json"));
// DELETE (cancel) ongoing change
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", DELETE)
+ .userIdentity(USER_ID),
new File("application-deployment-cancelled.json"));
// DELETE (cancel) again is a no-op
@@ -166,14 +176,16 @@ public class ApplicationApiTest extends ControllerContainerTest {
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
.data(entity)
- .domain(athenzUserDomain).user("mytenant"),
+ .userIdentity(USER_ID),
new File("deploy-result.json"));
// POST (deploy) an application to a zone. This simulates calls done by our tenant pipeline.
ApplicationId id = ApplicationId.from("tenant1", "application1", "default");
long screwdriverProjectId = 123;
- addScrewdriverUserToDomain("screwdriveruser1", "domain1"); // (Necessary but not provided in this API)
+ addScrewdriverUserToDeployRole(SCREWDRIVER_ID,
+ ATHENZ_TENANT_DOMAIN,
+ new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(id.application().value())); // (Necessary but not provided in this API)
// Trigger deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", POST)
@@ -183,7 +195,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// ... systemtest
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/", POST)
.data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default");
@@ -192,7 +204,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// ... staging
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default/", POST)
.data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default");
@@ -201,7 +213,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// ... prod zone
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/", POST)
.data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, screwdriverProjectId, false, DeploymentJobs.JobType.productionCorpUsEast1);
@@ -219,22 +231,22 @@ public class ApplicationApiTest extends ControllerContainerTest {
addIssues(controllerTester, ApplicationId.from("tenant1", "application1", "default"));
// GET at root, with "&recursive=deployment", returns info about all tenants, their applications and their deployments
tester.assertResponse(request("/application/v4/", GET)
- .domain("domain1").user("mytenant")
+ .userIdentity(USER_ID)
.recursive("deployment"),
new File("recursive-root.json"));
// GET at root, with "&recursive=tenant", returns info about all tenants, with limmited info about their applications.
tester.assertResponse(request("/application/v4/", GET)
- .domain("domain1").user("mytenant")
+ .userIdentity(USER_ID)
.recursive("tenant"),
new File("recursive-until-tenant-root.json"));
// GET at a tenant, with "&recursive=true", returns full info about their applications and their deployments
tester.assertResponse(request("/application/v4/tenant/tenant1/", GET)
- .domain("domain1").user("mytenant")
+ .userIdentity(USER_ID)
.recursive("true"),
new File("tenant1-recursive.json"));
// GET at an application, with "&recursive=true", returns full info about its deployments
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/", GET)
- .domain("domain1").user("mytenant")
+ .userIdentity(USER_ID)
.recursive("true"),
new File("application1-recursive.json"));
@@ -272,7 +284,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
byte[] data = new byte[0];
tester.assertResponse(request("/application/v4/user?user=newuser&domain=by", PUT)
.data(data)
- .domain(athenzUserDomain).user("newuser"),
+ .userIdentity(new UserId("newuser")),
new File("create-user-response.json"));
// OPTIONS return 200 OK
tester.assertResponse(request("/application/v4/", Request.Method.OPTIONS),
@@ -288,11 +300,13 @@ public class ApplicationApiTest extends ControllerContainerTest {
// SET global rotation override status
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", PUT)
+ .userIdentity(USER_ID)
.data("{\"reason\":\"because i can\"}"),
new File("global-rotation-put.json"));
// DELETE global rotation override status
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", DELETE)
+ .userIdentity(USER_ID)
.data("{\"reason\":\"because i can\"}"),
new File("global-rotation-delete.json"));
@@ -302,10 +316,10 @@ public class ApplicationApiTest extends ControllerContainerTest {
"{\"message\":\"Successfully copied environment hosted-instance_tenant1_application1_placeholder_component_default to hosted-instance_tenant1_application1_us-west-1_prod_default\"}");
// DELETE an application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE).userIdentity(USER_ID),
"");
// DELETE a tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE).userIdentity(USER_ID),
new File("tenant-without-applications.json"));
controllerTester.controller().deconstruct();
@@ -324,23 +338,28 @@ public class ApplicationApiTest extends ControllerContainerTest {
ContainerControllerTester controllerTester = new ContainerControllerTester(container, responseFiles);
ContainerTester tester = controllerTester.containerTester();
tester.updateSystemVersion();
- addTenantAthenzDomain(athenzUserDomain, "mytenant");
- addScrewdriverUserToDomain("screwdriveruser1", "domain1");
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
// Create tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST).userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// Create application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
+ .userIdentity(USER_ID),
new File("application-reference.json"));
+ // Grant deploy access
+ addScrewdriverUserToDeployRole(SCREWDRIVER_ID,
+ ATHENZ_TENANT_DOMAIN,
+ new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId("application1"));
+
// POST (deploy) an application to a prod zone - allowed when project ID is not specified
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/deploy", POST)
.data(entity)
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
}
@@ -350,18 +369,22 @@ public class ApplicationApiTest extends ControllerContainerTest {
ContainerControllerTester controllerTester = new ContainerControllerTester(container, responseFiles);
ContainerTester tester = controllerTester.containerTester();
tester.updateSystemVersion();
- addTenantAthenzDomain(athenzUserDomain, "mytenant");
- addScrewdriverUserToDomain("screwdriveruser1", "domain1");
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
// Create tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// Create application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
+ .userIdentity(USER_ID),
new File("application-reference.json"));
+ // Give Screwdriver project deploy access
+ addScrewdriverUserToDeployRole(SCREWDRIVER_ID, ATHENZ_TENANT_DOMAIN, new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId("application1"));
+
// Deploy
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.region("us-east-3")
@@ -375,7 +398,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// us-east-3
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east-3/instance/default/deploy", POST)
.data(deployData)
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, projectId, true, DeploymentJobs.JobType.productionUsEast3);
@@ -392,13 +415,13 @@ public class ApplicationApiTest extends ControllerContainerTest {
// us-west-1
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy", POST)
.data(deployData)
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, projectId, true, DeploymentJobs.JobType.productionUsWest1);
// us-east-3
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east-3/instance/default/deploy", POST)
- .data(deployData).domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .data(deployData).screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, projectId, true, DeploymentJobs.JobType.productionUsEast3);
@@ -411,7 +434,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
public void testErrorResponses() throws Exception {
ContainerTester tester = new ContainerTester(container, responseFiles);
tester.updateSystemVersion();
- addTenantAthenzDomain("domain1", "mytenant");
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
// PUT (update) non-existing tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
@@ -436,27 +459,32 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (add) a tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// POST (add) another tenant under the same domain
tester.assertResponse(request("/application/v4/tenant/tenant2", POST)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not create tenant 'tenant2': The Athens domain 'domain1' is already connected to tenant 'tenant1'\"}",
400);
// Add the same tenant again
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .userIdentity(USER_ID)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'tenant1' already exists\"}",
400);
// POST (create) an (empty) application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
+ .userIdentity(USER_ID),
new File("application-reference.json"));
// Create the same application again
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
+ .userIdentity(USER_ID),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"An application with id 'tenant1.application1' already exists\"}",
400);
@@ -467,44 +495,48 @@ public class ApplicationApiTest extends ControllerContainerTest {
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
.data(entity)
- .domain(athenzUserDomain).user("mytenant"),
+ .userIdentity(USER_ID),
new File("deploy-failure.json"), 400);
// POST (deploy) an application without available capacity
configServer.throwOnNextPrepare(new ConfigServerException(new URI("server-url"), "Failed to prepare application", ConfigServerException.ErrorCode.OUT_OF_CAPACITY, null));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
.data(entity)
- .domain(athenzUserDomain).user("mytenant"),
+ .userIdentity(USER_ID),
new File("deploy-out-of-capacity.json"), 400);
// POST (deploy) an application where activation fails
configServer.throwOnNextPrepare(new ConfigServerException(new URI("server-url"), "Failed to activate application", ConfigServerException.ErrorCode.ACTIVATION_CONFLICT, null));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
.data(entity)
- .domain(athenzUserDomain).user("mytenant"),
+ .userIdentity(USER_ID),
new File("deploy-activation-conflict.json"), 409);
// POST (deploy) an application where we get an internal server error
configServer.throwOnNextPrepare(new ConfigServerException(new URI("server-url"), "Internal server error", ConfigServerException.ErrorCode.INTERNAL_SERVER_ERROR, null));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
.data(entity)
- .domain(athenzUserDomain).user("mytenant"),
+ .userIdentity(USER_ID),
new File("deploy-internal-server-error.json"), 500);
// DELETE tenant which has an application
- tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
+ .userIdentity(USER_ID),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not delete tenant 'tenant1': This tenant has active applications\"}",
400);
// DELETE application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
+ .userIdentity(USER_ID),
"");
// DELETE application again - should produce 404
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
+ .userIdentity(USER_ID),
"{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete application 'tenant1.application1': Application not found\"}",
404);
// DELETE tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
+ .userIdentity(USER_ID),
new File("tenant-without-applications.json"));
// DELETE tenant again - should produce 404
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
@@ -520,48 +552,46 @@ public class ApplicationApiTest extends ControllerContainerTest {
@Test
public void testAuthorization() throws Exception {
ContainerTester tester = new ContainerTester(container, responseFiles);
- String authorizedUser = "mytenant";
- String unauthorizedUser = "othertenant";
+ UserId authorizedUser = USER_ID;
+ UserId unauthorizedUser = new UserId("othertenant");
// Mutation without an authorized user is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .domain("domain1").user(null),
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"User is not authenticated\"}",
403);
// ... but read methods are allowed
tester.assertResponse(request("/application/v4/tenant/", GET)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .domain("domain1").user(null),
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
"[]",
200);
- addTenantAthenzDomain("domain1", "mytenant");
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
// Creating a tenant for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .domain("domain1").user(unauthorizedUser),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"The user 'othertenant' is not admin in Athenz domain 'domain1'\"}",
+ .userIdentity(unauthorizedUser),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"The user 'user.othertenant' is not admin in Athenz domain 'domain1'\"}",
403);
// (Create it with the right tenant id)
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .domain("domain1").user(authorizedUser),
+ .userIdentity(authorizedUser),
new File("tenant-without-applications.json"),
200);
// Creating an application for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
- .domain("domain1").user(unauthorizedUser),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
+ .userIdentity(unauthorizedUser),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"User user.othertenant does not have write access to tenant tenant1\"}",
403);
// (Create it with the right tenant id)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
- .domain("domain1").user(authorizedUser),
+ .userIdentity(authorizedUser),
new File("application-reference.json"),
200);
@@ -569,41 +599,41 @@ public class ApplicationApiTest extends ControllerContainerTest {
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy", POST)
.data(entity)
- .domain(athenzUserDomain).user("mytenant"),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"Principal 'mytenant' is not a Screwdriver principal. Excepted principal with Athenz domain 'cd.screwdriver.project', got 'domain1'.\"}",
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"Principal 'user.myuser' is not a Screwdriver principal. Excepted principal with Athenz domain 'cd.screwdriver.project', got 'user'.\"}",
403);
// Deleting an application for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
- .domain("domain1").user(unauthorizedUser),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
+ .userIdentity(unauthorizedUser),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"User user.othertenant does not have write access to tenant tenant1\"}",
403);
// (Deleting it with the right tenant id)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
- .domain("domain1").user(authorizedUser),
+ .userIdentity(authorizedUser),
"",
200);
// Updating a tenant for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
.data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .domain("domain1").user(unauthorizedUser),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
+ .userIdentity(unauthorizedUser),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"User user.othertenant does not have write access to tenant tenant1\"}",
403);
// Change Athens domain
- addTenantAthenzDomain("domain2", "mytenant");
+ createAthenzDomainWithAdmin(new AthenzDomain("domain2"), USER_ID);
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
.data("{\"athensDomain\":\"domain2\", \"property\":\"property1\"}")
- .domain("domain1").user(authorizedUser),
+ .userIdentity(authorizedUser),
"{\"tenant\":\"tenant1\",\"type\":\"ATHENS\",\"athensDomain\":\"domain2\",\"property\":\"property1\",\"applications\":[]}",
200);
// Deleting a tenant for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
- .domain("domain1").user(unauthorizedUser),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
+ .userIdentity(unauthorizedUser),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"User user.othertenant does not have write access to tenant tenant1\"}",
403);
}
@@ -613,19 +643,20 @@ public class ApplicationApiTest extends ControllerContainerTest {
ContainerTester tester = controllerTester.containerTester();
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.upgradePolicy("default")
- .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("invalid.domain"), AthenzService.from("service"))
+ .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("invalid.domain"), com.yahoo.config.provision.AthenzService.from("service"))
.environment(Environment.prod)
.region("us-west-1")
.build();
long screwdriverProjectId = 123;
- AthenzDomain domain = addTenantAthenzDomain(athenzUserDomain, "mytenant");
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
- Application application = controllerTester.createApplication(athenzUserDomain, "tenant1", "application1");
- controllerTester.authorize(domain, new ScrewdriverId(Long.toString(screwdriverProjectId)), ApplicationAction.deploy, application);
+ Application application = controllerTester.createApplication(ATHENZ_TENANT_DOMAIN.id(), "tenant1", "application1");
+ ScrewdriverId screwdriverId = new ScrewdriverId(Long.toString(screwdriverProjectId));
+ controllerTester.authorize(ATHENZ_TENANT_DOMAIN, screwdriverId, ApplicationAction.deploy, application);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/", POST)
.data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
- .domain(athenzScrewdriverDomain).user("sd" + screwdriverProjectId),
+ .screwdriverIdentity(screwdriverId),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"Athenz domain in deployment.xml: [invalid.domain] must match tenant domain: [domain1]\"}",
403);
@@ -637,21 +668,23 @@ public class ApplicationApiTest extends ControllerContainerTest {
ContainerTester tester = controllerTester.containerTester();
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.upgradePolicy("default")
- .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("domain1"), AthenzService.from("service"))
+ .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("domain1"), com.yahoo.config.provision.AthenzService.from("service"))
.environment(Environment.prod)
.region("us-west-1")
.build();
long screwdriverProjectId = 123;
- AthenzDomain domain = addTenantAthenzDomain(athenzUserDomain, "mytenant");
+ ScrewdriverId screwdriverId = new ScrewdriverId(Long.toString(screwdriverProjectId));
- Application application = controllerTester.createApplication(athenzUserDomain, "tenant1", "application1");
- controllerTester.authorize(domain, new ScrewdriverId(Long.toString(screwdriverProjectId)), ApplicationAction.deploy, application);
+ createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
+
+ Application application = controllerTester.createApplication(ATHENZ_TENANT_DOMAIN.id(), "tenant1", "application1");
+ controllerTester.authorize(ATHENZ_TENANT_DOMAIN, screwdriverId, ApplicationAction.deploy, application);
// Allow systemtest to succeed by notifying completion of system test
controllerTester.notifyJobCompletion(application.id(), screwdriverProjectId, true, DeploymentJobs.JobType.component);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/", POST)
.data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
- .domain(athenzScrewdriverDomain).user("sd" + screwdriverProjectId),
+ .screwdriverIdentity(screwdriverId),
new File("deploy-result.json"));
}
@@ -692,8 +725,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
private final String path;
private final Request.Method method;
private byte[] data = new byte[0];
- private String domain = "domain1";
- private String user = "mytenant";
+ private AthenzIdentity identity;
private String contentType = "application/json";
private String recursive;
@@ -713,8 +745,8 @@ public class ApplicationApiTest extends ControllerContainerTest {
}
return data(out.toByteArray()).contentType(data.getContentType().getValue());
}
- private RequestBuilder domain(String domain) { this.domain = domain; return this; }
- private RequestBuilder user(String user) { this.user = user; return this; }
+ private RequestBuilder userIdentity(UserId userId) { this.identity = AthenzUser.fromUserId(userId); return this; }
+ private RequestBuilder screwdriverIdentity(ScrewdriverId screwdriverId) { this.identity = AthenzService.fromScrewdriverId(screwdriverId); return this; }
private RequestBuilder contentType(String contentType) { this.contentType = contentType; return this; }
private RequestBuilder recursive(String recursive) { this.recursive = recursive; return this; }
@@ -722,10 +754,13 @@ public class ApplicationApiTest extends ControllerContainerTest {
public Request get() {
Request request = new Request("http://localhost:8080" + path +
// user and domain parameters are translated to a Principal by MockAuthorizer as we do not run HTTP filters
- "?domain=" + domain + (user == null ? "" : "&user=" + user) +
- (recursive == null ? "" : "&recursive=" + recursive),
+ (recursive == null ? "" : "?recursive=" + recursive),
data, method);
request.getHeaders().put("Content-Type", contentType);
+ if (identity != null) {
+ request.getHeaders().put("Athenz-Identity-Domain", identity.getDomain().id());
+ request.getHeaders().put("Athenz-Identity-Name", identity.getName());
+ }
return request;
}
}
@@ -739,26 +774,27 @@ public class ApplicationApiTest extends ControllerContainerTest {
* In production this happens outside hosted Vespa, so there is no API for it and we need to reach down into the
* mock setup to replicate the action.
*/
- private AthenzDomain addTenantAthenzDomain(String domainName, String userName) {
+ private void createAthenzDomainWithAdmin(AthenzDomain domain, UserId userId) {
AthenzClientFactoryMock mock = (AthenzClientFactoryMock) container.components()
.getComponent(AthenzClientFactoryMock.class.getName());
- AthenzDomain athensDomain = new AthenzDomain(domainName);
- AthenzDbMock.Domain domain = new AthenzDbMock.Domain(athensDomain);
- domain.markAsVespaTenant();
- domain.admin(AthenzUtils.createPrincipal(new UserId(userName)));
- mock.getSetup().addDomain(domain);
- return athensDomain;
+ AthenzDbMock.Domain domainMock = new AthenzDbMock.Domain(domain);
+ domainMock.markAsVespaTenant();
+ domainMock.admin(AthenzUser.fromUserId(userId));
+ mock.getSetup().addDomain(domainMock);
}
/**
* In production this happens outside hosted Vespa, so there is no API for it and we need to reach down into the
* mock setup to replicate the action.
*/
- private void addScrewdriverUserToDomain(String screwdriverUserId, String domainName) {
+ private void addScrewdriverUserToDeployRole(ScrewdriverId screwdriverId,
+ AthenzDomain domain,
+ com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId applicationId) {
AthenzClientFactoryMock mock = (AthenzClientFactoryMock) container.components()
.getComponent(AthenzClientFactoryMock.class.getName());
- AthenzDbMock.Domain domain = mock.getSetup().domains.get(new AthenzDomain(domainName));
- domain.admin(new AthenzPrincipal(new AthenzDomain(athenzScrewdriverDomain), new UserId(screwdriverUserId)));
+ AthenzIdentity screwdriverIdentity = AthenzService.fromScrewdriverId(screwdriverId);
+ AthenzDbMock.Application athenzApplication = mock.getSetup().domains.get(domain).applications.get(applicationId);
+ athenzApplication.addRoleMember(ApplicationAction.deploy, screwdriverIdentity);
}
private void startAndTestChange(ContainerControllerTester controllerTester, ApplicationId application, long projectId,
@@ -773,7 +809,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
application.tenant().value(), application.application().value());
tester.assertResponse(request(testPath, POST)
.data(deployData)
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
tester.assertResponse(request(testPath, DELETE),
"Deactivated " + testPath.replaceFirst("/application/v4/", ""));
@@ -784,7 +820,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
application.tenant().value(), application.application().value());
tester.assertResponse(request(stagingPath, POST)
.data(deployData)
- .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ .screwdriverIdentity(SCREWDRIVER_ID),
new File("deploy-result.json"));
tester.assertResponse(request(stagingPath, DELETE),
"Deactivated " + stagingPath.replaceFirst("/application/v4/", ""));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java
index e5898b7a593..5899c767beb 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/MockAuthorizer.java
@@ -5,10 +5,10 @@ import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.TestIdentities;
import com.yahoo.vespa.hosted.controller.api.identifiers.AthenzDomain;
-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.AthenzPrincipal;
+import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
import com.yahoo.vespa.hosted.controller.athenz.NToken;
import javax.ws.rs.core.SecurityContext;
@@ -20,6 +20,7 @@ import java.util.Optional;
* This is necessary because filters are not currently executed when executing requests with Application.
*
* @author bratseth
+ * @author bjorncs
*/
@SuppressWarnings("unused") // injected
public class MockAuthorizer extends Authorizer {
@@ -30,10 +31,13 @@ public class MockAuthorizer extends Authorizer {
/** Returns a principal given by the request parameters 'domain' and 'user' */
@Override
- public Optional<Principal> getPrincipalIfAny(HttpRequest request) {
- if (request.getProperty("user") == null) return Optional.empty();
- return Optional.of(new AthenzPrincipal(new AthenzDomain(request.getProperty("domain")),
- new UserId(request.getProperty("user"))));
+ public Optional<AthenzPrincipal> getPrincipalIfAny(HttpRequest request) {
+ String domain = request.getHeader("Athenz-Identity-Domain");
+ String name = request.getHeader("Athenz-Identity-Name");
+ if (domain == null || name == null) return Optional.empty();
+ return Optional.of(
+ new AthenzPrincipal(
+ AthenzUtils.createAthenzIdentity(new AthenzDomain(domain), name)));
}
/** Returns the hardcoded NToken of {@link TestIdentities#userId} */
@@ -42,12 +46,6 @@ public class MockAuthorizer extends Authorizer {
return Optional.of(TestIdentities.userNToken);
}
- private static class MockPrincipal implements Principal {
-
- @Override
- public String getName() { return TestIdentities.userId.id(); }
-
- }
@Override
protected Optional<SecurityContext> securityContextOf(HttpRequest request) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/user.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/user.json
index d3927cbcfcf..79b9a785801 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/user.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/user.json
@@ -1,5 +1,5 @@
{
- "user": "mytenant",
+ "user": "myuser",
"tenants": @include(tenant-list.json),
"tenantExists": false
} \ No newline at end of file