use of bio.terra.workspace.service.resource.controlled.model.ControlledResource in project terra-workspace-manager by DataBiosphere.
the class ResourceDao method storeResource.
private void storeResource(WsmResource resource) {
// TODO: add resource locking to fix this
// We create resources in flights, so we have steps that call resource creation that may
// get run more than once. The safe solution is to "lock" the resource by writing the flight id
// into the row at creation. Then it is possible on a re-insert to know whether the error is
// because this flight step is re-running or because some other flight used the same resource
// id. The small risk we have here is that a duplicate resource id of will appear to be
// successfully created, but in fact will be silently rejected.
final String countSql = "SELECT COUNT(*) FROM resource WHERE resource_id = :resource_id";
MapSqlParameterSource countParams = new MapSqlParameterSource().addValue("resource_id", resource.getResourceId().toString());
Integer count = jdbcTemplate.queryForObject(countSql, countParams, Integer.class);
if (count != null && count == 1) {
return;
}
final String sql = "INSERT INTO resource (workspace_id, cloud_platform, resource_id, name, description, stewardship_type," + " exact_resource_type, resource_type, cloning_instructions, attributes," + " access_scope, managed_by, associated_app, assigned_user, private_resource_state)" + " VALUES (:workspace_id, :cloud_platform, :resource_id, :name, :description, :stewardship_type," + " :exact_resource_type, :resource_type, :cloning_instructions, cast(:attributes AS jsonb)," + " :access_scope, :managed_by, :associated_app, :assigned_user, :private_resource_state)";
final var params = new MapSqlParameterSource().addValue("workspace_id", resource.getWorkspaceId().toString()).addValue("cloud_platform", resource.getResourceType().getCloudPlatform().toString()).addValue("resource_id", resource.getResourceId().toString()).addValue("name", resource.getName()).addValue("description", resource.getDescription()).addValue("stewardship_type", resource.getStewardshipType().toSql()).addValue("exact_resource_type", resource.getResourceType().toSql()).addValue("resource_type", resource.getResourceFamily().toSql()).addValue("cloning_instructions", resource.getCloningInstructions().toSql()).addValue("attributes", resource.attributesToJson());
if (resource.getStewardshipType().equals(CONTROLLED)) {
ControlledResource controlledResource = resource.castToControlledResource();
// noinspection deprecation
params.addValue("access_scope", controlledResource.getAccessScope().toSql()).addValue("managed_by", controlledResource.getManagedBy().toSql()).addValue("associated_app", controlledResource.getApplicationId()).addValue("assigned_user", controlledResource.getAssignedUser().orElse(null)).addValue("private_resource_state", controlledResource.getPrivateResourceState().map(PrivateResourceState::toSql).orElse(null));
} else {
params.addValue("access_scope", null).addValue("managed_by", null).addValue("associated_app", null).addValue("assigned_user", null).addValue("private_resource_state", null);
}
try {
jdbcTemplate.update(sql, params);
logger.info("Inserted record for resource {} for workspace {}", resource.getResourceId(), resource.getWorkspaceId());
} catch (DuplicateKeyException e) {
throw new DuplicateResourceException(String.format("A resource already exists in the workspace that has the same name (%s) or the same id (%s)", resource.getName(), resource.getResourceId().toString()));
}
}
use of bio.terra.workspace.service.resource.controlled.model.ControlledResource in project terra-workspace-manager by DataBiosphere.
the class SamServiceTest method duplicateResourceDeleteIgnored.
@Test
void duplicateResourceDeleteIgnored() throws Exception {
ControlledResource bucketResource = ControlledResourceFixtures.makeDefaultControlledGcsBucketBuilder(workspaceId).build();
samService.createControlledResource(bucketResource, null, null, defaultUserRequest());
samService.deleteControlledResource(bucketResource, defaultUserRequest());
samService.deleteControlledResource(bucketResource, defaultUserRequest());
}
use of bio.terra.workspace.service.resource.controlled.model.ControlledResource in project terra-workspace-manager by DataBiosphere.
the class SamServiceTest method duplicateResourceCreateIgnored.
@Test
void duplicateResourceCreateIgnored() throws Exception {
ControlledResource bucketResource = ControlledResourceFixtures.makeDefaultControlledGcsBucketBuilder(workspaceId).build();
samService.createControlledResource(bucketResource, null, null, defaultUserRequest());
// This duplicate call should complete without throwing.
samService.createControlledResource(bucketResource, null, null, defaultUserRequest());
// Delete the bucket so we can clean up the workspace.
samService.deleteControlledResource(bucketResource, defaultUserRequest());
}
use of bio.terra.workspace.service.resource.controlled.model.ControlledResource in project terra-workspace-manager by DataBiosphere.
the class PrivateResourceCleanupServiceTest method cleanupResourcesSuppressExceptions_cleansApplicationPrivateResource_succeeds.
@Test
@DisabledIfEnvironmentVariable(named = "TEST_ENV", matches = BUFFER_SERVICE_DISABLED_ENVS_REG_EX)
void cleanupResourcesSuppressExceptions_cleansApplicationPrivateResource_succeeds() {
// Default user owns the workspace and group. Secondary user has workspace membership via group.
// Add second user to group
addUserToGroup(groupName, userAccessUtils.getSecondUserEmail(), ownerGroupApi);
// Add group to workspace as writer
SamRethrow.onInterrupted(() -> samService.grantWorkspaceRole(workspace.getWorkspaceId(), userAccessUtils.defaultUserAuthRequest(), WsmIamRole.WRITER, groupEmail), "grantWorkspaceRole");
// Enable the WSM test app in this workspace. This has a test user as the "service account" so
// we can delegate credentials normally.
App appConfig = getAppBySa(applicationAccessUtils.getApplicationSaEmail());
UUID appId = UUID.fromString(appConfig.getIdentifier());
AuthenticatedUserRequest appRequest = applicationAccessUtils.applicationSaAuthenticatedUserRequest();
wsmApplicationService.enableWorkspaceApplication(userAccessUtils.defaultUserAuthRequest(), workspace.getWorkspaceId(), appId);
// Create application private bucket assigned to second user.
ControlledResourceFields commonFields = ControlledResourceFixtures.makeDefaultControlledResourceFieldsBuilder().workspaceId(workspace.getWorkspaceId()).accessScope(AccessScopeType.ACCESS_SCOPE_PRIVATE).managedBy(ManagedByType.MANAGED_BY_APPLICATION).applicationId(appId).assignedUser(userAccessUtils.getSecondUserEmail()).build();
ControlledGcsBucketResource resource = ControlledGcsBucketResource.builder().common(commonFields).bucketName(ControlledResourceFixtures.uniqueBucketName()).build();
ApiGcpGcsBucketCreationParameters creationParameters = new ApiGcpGcsBucketCreationParameters().location("us-central1");
// Create resource as application.
controlledResourceService.createControlledResourceSync(resource, ControlledResourceIamRole.WRITER, appRequest, creationParameters);
// Verify second user can read the private resource in Sam.
SamRethrow.onInterrupted(() -> samService.checkAuthz(userAccessUtils.secondUserAuthRequest(), resource.getCategory().getSamResourceName(), resource.getResourceId().toString(), SamControlledResourceActions.READ_ACTION), "checkResourceAuth");
// Remove second user from workspace via group.
removeUserFromGroup(groupName, userAccessUtils.getSecondUserEmail(), ownerGroupApi);
// Verify second user is no longer in workspace, but still has resource access because cleanup
// hasn't run yet.
assertFalse(SamRethrow.onInterrupted(() -> samService.isAuthorized(userAccessUtils.secondUserAuthRequest(), SamResource.WORKSPACE, resource.getWorkspaceId().toString(), SamWorkspaceAction.READ), "checkResourceAuth"));
assertTrue(SamRethrow.onInterrupted(() -> samService.isAuthorized(userAccessUtils.secondUserAuthRequest(), resource.getCategory().getSamResourceName(), resource.getResourceId().toString(), SamControlledResourceActions.READ_ACTION), "checkResourceAuth"));
// Manually enable and run cleanup.
privateResourceCleanupConfiguration.setEnabled(true);
// Calling "cleanupResources" manually lets us skip waiting for the cronjob to trigger.
privateResourceCleanupService.cleanupResourcesSuppressExceptions();
// Verify second user can no longer read the resource.
assertFalse(SamRethrow.onInterrupted(() -> samService.isAuthorized(userAccessUtils.secondUserAuthRequest(), resource.getCategory().getSamResourceName(), resource.getResourceId().toString(), SamControlledResourceActions.READ_ACTION), "checkResourceAuth"));
// Verify resource is marked "abandoned"
ControlledResource dbResource = resourceDao.getResource(resource.getWorkspaceId(), resource.getResourceId()).castToControlledResource();
assertEquals(PrivateResourceState.ABANDONED, dbResource.getPrivateResourceState().get());
// Application can still read the resource, because applications have EDITOR role on their
// application-private resources.
assertTrue(SamRethrow.onInterrupted(() -> samService.isAuthorized(appRequest, resource.getCategory().getSamResourceName(), resource.getResourceId().toString(), SamControlledResourceActions.READ_ACTION), "checkResourceAuth"));
}
use of bio.terra.workspace.service.resource.controlled.model.ControlledResource in project terra-workspace-manager by DataBiosphere.
the class PrivateResourceCleanupServiceTest method cleanupResourcesSuppressExceptions_cleansUserPrivateResource_succeeds.
@Test
@DisabledIfEnvironmentVariable(named = "TEST_ENV", matches = BUFFER_SERVICE_DISABLED_ENVS_REG_EX)
void cleanupResourcesSuppressExceptions_cleansUserPrivateResource_succeeds() {
// Default user owns the workspace and group. Secondary user has workspace membership via group.
// Add second user to group
addUserToGroup(groupName, userAccessUtils.getSecondUserEmail(), ownerGroupApi);
// Add group to workspace as writer
SamRethrow.onInterrupted(() -> samService.grantWorkspaceRole(workspace.getWorkspaceId(), userAccessUtils.defaultUserAuthRequest(), WsmIamRole.WRITER, groupEmail), "grantWorkspaceRole");
// Create private bucket as second user.
ControlledResourceFields commonFields = ControlledResourceFixtures.makeDefaultControlledResourceFieldsBuilder().workspaceId(workspace.getWorkspaceId()).accessScope(AccessScopeType.ACCESS_SCOPE_PRIVATE).managedBy(ManagedByType.MANAGED_BY_USER).assignedUser(userAccessUtils.getSecondUserEmail()).build();
ControlledGcsBucketResource resource = ControlledGcsBucketResource.builder().common(commonFields).bucketName(ControlledResourceFixtures.uniqueBucketName()).build();
ApiGcpGcsBucketCreationParameters creationParameters = new ApiGcpGcsBucketCreationParameters().location("us-central1");
controlledResourceService.createControlledResourceSync(resource, ControlledResourceIamRole.EDITOR, userAccessUtils.defaultUserAuthRequest(), creationParameters);
// Verify second user can read the private resource in Sam.
SamRethrow.onInterrupted(() -> samService.checkAuthz(userAccessUtils.secondUserAuthRequest(), resource.getCategory().getSamResourceName(), resource.getResourceId().toString(), SamControlledResourceActions.READ_ACTION), "checkResourceAuth");
// Remove second user from workspace via group
removeUserFromGroup(groupName, userAccessUtils.getSecondUserEmail(), ownerGroupApi);
// Verify second user is no longer in workspace, but still has resource access because cleanup
// hasn't run yet.
assertFalse(SamRethrow.onInterrupted(() -> samService.isAuthorized(userAccessUtils.secondUserAuthRequest(), SamResource.WORKSPACE, resource.getWorkspaceId().toString(), SamWorkspaceAction.READ), "checkResourceAuth"));
assertTrue(SamRethrow.onInterrupted(() -> samService.isAuthorized(userAccessUtils.secondUserAuthRequest(), resource.getCategory().getSamResourceName(), resource.getResourceId().toString(), SamControlledResourceActions.READ_ACTION), "checkResourceAuth"));
// Manually enable and run cleanup.
privateResourceCleanupConfiguration.setEnabled(true);
// Calling "cleanupResources" manually lets us skip waiting for the cronjob to trigger.
privateResourceCleanupService.cleanupResourcesSuppressExceptions();
// Verify second user can no longer read the resource.
assertFalse(SamRethrow.onInterrupted(() -> samService.isAuthorized(userAccessUtils.secondUserAuthRequest(), resource.getCategory().getSamResourceName(), resource.getResourceId().toString(), SamControlledResourceActions.READ_ACTION), "checkResourceAuth"));
// Verify resource is marked "abandoned"
ControlledResource dbResource = resourceDao.getResource(resource.getWorkspaceId(), resource.getResourceId()).castToControlledResource();
assertEquals(PrivateResourceState.ABANDONED, dbResource.getPrivateResourceState().get());
}
Aggregations