Skip to content

Commit

Permalink
Testing
Browse files Browse the repository at this point in the history
  • Loading branch information
aherbst-broad committed Jun 24, 2024
1 parent ac28b5d commit aa22ec6
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ private void addWsmResourceOwnerPolicy(CreateResourceRequestV2 request) {
* Find the email of the application and add it to the incoming policy.
*
* @param editorPolicy editor policy
* @throws InterruptedException on interrupt while waiting on retries
* @param application Application being added to the policy
*/
private void addApplicationResourceEditorPolicy(
AccessPolicyMembershipRequest editorPolicy, WsmWorkspaceApplication application) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,6 @@ public void createControlledResource(
ControlledResource resource,
@Nullable ControlledResourceIamRole privateIamRole,
@Nullable String assignedUserEmail,
@Nullable String applicationEmail,
AuthenticatedUserRequest userRequest)
throws InterruptedException {

Expand All @@ -1017,8 +1016,9 @@ public void createControlledResource(
// so it always gets the appropriate permissions (the user request is not always
// from the application, i.e., when a resource is cloned)
WsmWorkspaceApplication app = null;
if (resource.getCategory().equals(ControlledResourceCategory.APPLICATION_PRIVATE)
|| resource.getCategory().equals(ControlledResourceCategory.APPLICATION_SHARED)) {
if (resource.getApplicationId() != null
&& ((resource.getCategory().equals(ControlledResourceCategory.APPLICATION_PRIVATE)
|| resource.getCategory().equals(ControlledResourceCategory.APPLICATION_SHARED)))) {
app =
applicationService.getWorkspaceApplicationByWorkspaceId(
resource.getWorkspaceId(), resource.getApplicationId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ public CreateControlledResourceFlight(FlightMap inputParameters, Object beanBag)
resource,
privateResourceIamRole,
resource.getAssignedUser().orElse(null),
flightBeanBag.getApplicationService(),
userRequest));

// Get the cloud context and store it in the working map
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
import bio.terra.workspace.service.iam.SamService;
import bio.terra.workspace.service.iam.model.ControlledResourceIamRole;
import bio.terra.workspace.service.resource.controlled.model.ControlledResource;
import bio.terra.workspace.service.resource.controlled.model.ManagedByType;
import bio.terra.workspace.service.workspace.WsmApplicationService;
import bio.terra.workspace.service.workspace.model.WsmWorkspaceApplication;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -22,42 +19,27 @@ public class CreateSamResourceStep implements Step {
private final ControlledResourceIamRole privateResourceIamRole;
private final String assignedUserEmail;
private final AuthenticatedUserRequest userRequest;
private final WsmApplicationService applicationService;

private final Logger logger = LoggerFactory.getLogger(CreateSamResourceStep.class);

public CreateSamResourceStep(
SamService samService,
ControlledResource resource,
@Nullable ControlledResourceIamRole privateResourceIamRole,
@Nullable String assignedUserEmail,
WsmApplicationService applicationService,
AuthenticatedUserRequest userRequest) {
this.samService = samService;
this.resource = resource;
this.privateResourceIamRole = privateResourceIamRole;
this.assignedUserEmail = assignedUserEmail;
this.userRequest = userRequest;
this.applicationService = applicationService;
}

@Override
public StepResult doStep(FlightContext flightContext)
throws InterruptedException, RetryException {
if (resource.getManagedBy().equals(ManagedByType.MANAGED_BY_APPLICATION)) {
WsmWorkspaceApplication app =
applicationService.getWorkspaceApplication(
resource.getWorkspaceId(), resource.getApplicationId());

samService.createControlledResource(
resource,
privateResourceIamRole,
assignedUserEmail,
app.getApplication().getServiceAccount(),
userRequest);
} else {
samService.createControlledResource(
resource, privateResourceIamRole, assignedUserEmail, null, userRequest);
}
samService.createControlledResource(
resource, privateResourceIamRole, assignedUserEmail, userRequest);
return StepResult.getStepResultSuccess();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public static ControlledAzureDiskResource.Builder makeDefaultAzureDiskBuilder(
.cloningInstructions(CloningInstructions.COPY_RESOURCE)
.accessScope(AccessScopeType.fromApi(ApiAccessScope.PRIVATE_ACCESS))
.managedBy(ManagedByType.fromApi(ApiManagedBy.APPLICATION))
.applicationId("leo")
.region(DEFAULT_AZURE_RESOURCE_REGION)
.assignedUser(assignedUser)
.iamRole(ControlledResourceIamRole.EDITOR)
Expand Down Expand Up @@ -295,6 +296,7 @@ public static ControlledAzureVmResource.Builder makeDefaultControlledAzureVmReso
.cloningInstructions(CloningInstructions.COPY_RESOURCE)
.accessScope(AccessScopeType.fromApi(ApiAccessScope.PRIVATE_ACCESS))
.managedBy(ManagedByType.fromApi(ApiManagedBy.APPLICATION))
.applicationId("leo")
.assignedUser(assignedUser)
.iamRole(ControlledResourceIamRole.EDITOR)
.build())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package bio.terra.workspace.service.iam;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.junit.jupiter.api.Assertions.*;

import bio.terra.workspace.common.BaseSpringBootUnitTest;
import bio.terra.workspace.common.exception.InternalLogicException;
import bio.terra.workspace.common.utils.GcpUtils;
import bio.terra.workspace.service.iam.model.ControlledResourceIamRole;
import bio.terra.workspace.service.resource.controlled.model.ControlledResourceCategory;
import bio.terra.workspace.service.workspace.model.WsmApplication;
import bio.terra.workspace.service.workspace.model.WsmWorkspaceApplication;
import org.broadinstitute.dsde.workbench.client.sam.model.CreateResourceRequestV2;
import org.junit.jupiter.api.Test;

class ControlledResourceSamPolicyBuilderTest extends BaseSpringBootUnitTest {

@Test
void addPolicies_userPrivate() {
var policyBuilder =
new ControlledResourceSamPolicyBuilder(
ControlledResourceIamRole.EDITOR,
"fake@example.com",
ControlledResourceCategory.USER_PRIVATE,
null);
var request = new CreateResourceRequestV2();

policyBuilder.addPolicies(request);

assertThat(
request.getPolicies().get(ControlledResourceIamRole.OWNER.toSamRole()).getMemberEmails(),
contains(GcpUtils.getWsmSaEmail()));
assertThat(
request.getPolicies().get(ControlledResourceIamRole.EDITOR.toSamRole()).getMemberEmails(),
contains("fake@example.com"));
}

@Test
void addPolicies_userPrivateWihtoutPrivateEmailFails() {
var policyBuilder =
new ControlledResourceSamPolicyBuilder(
ControlledResourceIamRole.DELETER, null, ControlledResourceCategory.USER_PRIVATE, null);
var request = new CreateResourceRequestV2();

assertThrows(InternalLogicException.class, () -> policyBuilder.addPolicies(request));
}

@Test
void addPolicies_applicationShared() {
var app =
new WsmWorkspaceApplication()
.application(new WsmApplication().serviceAccount("fake-svc@example.com"));
var policyBuilder =
new ControlledResourceSamPolicyBuilder(
ControlledResourceIamRole.READER,
null,
ControlledResourceCategory.APPLICATION_SHARED,
app);
var request = new CreateResourceRequestV2();

policyBuilder.addPolicies(request);

assertThat(
request.getPolicies().get(ControlledResourceIamRole.OWNER.toSamRole()).getMemberEmails(),
contains(GcpUtils.getWsmSaEmail()));
assertThat(
request.getPolicies().get(ControlledResourceIamRole.EDITOR.toSamRole()).getMemberEmails(),
contains("fake-svc@example.com"));
}

@Test
void addPolicies_applicationSharedWithNoAppFails() {
var policyBuilder =
new ControlledResourceSamPolicyBuilder(
ControlledResourceIamRole.EDITOR,
null,
ControlledResourceCategory.APPLICATION_SHARED,
null);
var request = new CreateResourceRequestV2();

assertThrows(InternalLogicException.class, () -> policyBuilder.addPolicies(request));
}

@Test
void addPolicies_applicationSharedWithUserEmailFails() {
var app =
new WsmWorkspaceApplication()
.application(new WsmApplication().serviceAccount("fake-svc@example.com"));
var policyBuilder =
new ControlledResourceSamPolicyBuilder(
ControlledResourceIamRole.DELETER,
"fake@example.com",
ControlledResourceCategory.APPLICATION_SHARED,
app);
var request = new CreateResourceRequestV2();

assertThrows(InternalLogicException.class, () -> policyBuilder.addPolicies(request));
}

@Test
void addPolicies_applicationPrivate() {
var policyBuilder =
new ControlledResourceSamPolicyBuilder(
ControlledResourceIamRole.WRITER,
"fake@example.com",
ControlledResourceCategory.APPLICATION_PRIVATE,
new WsmWorkspaceApplication()
.application(new WsmApplication().serviceAccount("fake-svc@example.com")));
var request = new CreateResourceRequestV2();

policyBuilder.addPolicies(request);

assertThat(
request.getPolicies().get(ControlledResourceIamRole.EDITOR.toSamRole()).getMemberEmails(),
contains("fake-svc@example.com"));
assertThat(
request.getPolicies().get(ControlledResourceIamRole.WRITER.toSamRole()).getMemberEmails(),
contains("fake@example.com"));
}

@Test
void addPolicies_applicationPrivateWithNoAppFails() {
var policyBuilder =
new ControlledResourceSamPolicyBuilder(
ControlledResourceIamRole.EDITOR,
null,
ControlledResourceCategory.APPLICATION_PRIVATE,
null);
var request = new CreateResourceRequestV2();

assertThrows(InternalLogicException.class, () -> policyBuilder.addPolicies(request));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ void workspaceReaderIsSharedResourceReader() throws Exception {

ControlledResource bucketResource =
ControlledGcpResourceFixtures.makeDefaultControlledGcsBucketBuilder(workspaceUuid).build();
samService.createControlledResource(bucketResource, null, null, null, defaultUserRequest());
samService.createControlledResource(bucketResource, null, null, defaultUserRequest());

// Workspace reader should have read access on a user-shared resource via inheritance
assertTrue(
Expand Down Expand Up @@ -447,7 +447,6 @@ void workspaceReaderIsNotPrivateResourceReader() throws Exception {
bucketResource,
ControlledResourceIamRole.EDITOR,
userAccessUtils.getDefaultUserEmail(),
null,
defaultUserRequest());

// Workspace reader should not have read access on a private resource.
Expand All @@ -472,9 +471,9 @@ void workspaceReaderIsNotPrivateResourceReader() throws Exception {
void duplicateResourceCreateIgnored() throws Exception {
ControlledResource bucketResource =
ControlledGcpResourceFixtures.makeDefaultControlledGcsBucketBuilder(workspaceUuid).build();
samService.createControlledResource(bucketResource, null, null, null, defaultUserRequest());
samService.createControlledResource(bucketResource, null, null, defaultUserRequest());
// This duplicate call should complete without throwing.
samService.createControlledResource(bucketResource, null, null, null, defaultUserRequest());
samService.createControlledResource(bucketResource, null, null, defaultUserRequest());
// Delete the bucket so we can clean up the workspace.
samService.deleteControlledResource(bucketResource, defaultUserRequest());
}
Expand All @@ -483,7 +482,7 @@ void duplicateResourceCreateIgnored() throws Exception {
void duplicateResourceDeleteIgnored() throws Exception {
ControlledResource bucketResource =
ControlledGcpResourceFixtures.makeDefaultControlledGcsBucketBuilder(workspaceUuid).build();
samService.createControlledResource(bucketResource, null, null, null, defaultUserRequest());
samService.createControlledResource(bucketResource, null, null, defaultUserRequest());

samService.deleteControlledResource(bucketResource, defaultUserRequest());
samService.deleteControlledResource(bucketResource, defaultUserRequest());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ public void createVmWithFailureMakeSureNetworkInterfaceIsNotAbandoned()
.cloningInstructions(CloningInstructions.COPY_RESOURCE)
.accessScope(AccessScopeType.fromApi(ApiAccessScope.PRIVATE_ACCESS))
.managedBy(ManagedByType.fromApi(ApiManagedBy.APPLICATION))
.applicationId("leo")
.assignedUser(userEmail)
.iamRole(ControlledResourceIamRole.EDITOR)
.build())
Expand Down
9 changes: 9 additions & 0 deletions service/src/test/resources/application-connected-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ workspace:
use-crl: true
use-janitor: true


application:
configurations:
leo:
name: Leonardo
description: Leonardo application SA
service-account: leonardo-dev@broad-dsde-dev.iam.gserviceaccount.com
state: operating

spend:
spend-profiles:
- id: wm-default-spend-profile
Expand Down

0 comments on commit aa22ec6

Please sign in to comment.