Search in sources :

Example 1 with InternalLogicException

use of bio.terra.workspace.common.exception.InternalLogicException in project terra-workspace-manager by DataBiosphere.

the class GetCloudContextStep method doStep.

@Override
public StepResult doStep(FlightContext flightContext) throws InterruptedException, RetryException {
    // Get the cloud context and store it in the working map
    switch(cloudPlatform) {
        case AZURE:
            AzureCloudContext azureCloudContext = azureCloudContextService.getRequiredAzureCloudContext(workspaceId);
            flightContext.getWorkingMap().put(ControlledResourceKeys.AZURE_CLOUD_CONTEXT, azureCloudContext);
            break;
        case GCP:
            GcpCloudContext gcpCloudContext = gcpCloudContextService.getRequiredGcpCloudContext(workspaceId, userRequest);
            flightContext.getWorkingMap().put(ControlledResourceKeys.GCP_CLOUD_CONTEXT, gcpCloudContext);
            break;
        case ANY:
        default:
            // There cannot be an ANY resource that is also a controlled resource.
            throw new InternalLogicException("Invalid cloud platform for controlled resource: " + cloudPlatform);
    }
    return StepResult.getStepResultSuccess();
}
Also used : InternalLogicException(bio.terra.workspace.common.exception.InternalLogicException) AzureCloudContext(bio.terra.workspace.service.workspace.model.AzureCloudContext) GcpCloudContext(bio.terra.workspace.service.workspace.model.GcpCloudContext)

Example 2 with InternalLogicException

use of bio.terra.workspace.common.exception.InternalLogicException in project terra-workspace-manager by DataBiosphere.

the class ControlledResourceService method configureGcpPolicyForResource.

public Policy configureGcpPolicyForResource(ControlledResource resource, GcpCloudContext cloudContext, Policy currentPolicy, AuthenticatedUserRequest userRequest) throws InterruptedException {
    GcpPolicyBuilder gcpPolicyBuilder = new GcpPolicyBuilder(resource, cloudContext.getGcpProjectId(), currentPolicy);
    List<SyncMapping> syncMappings = resource.getCategory().getSyncMappings();
    for (SyncMapping syncMapping : syncMappings) {
        String policyGroup = null;
        switch(syncMapping.getRoleSource()) {
            case RESOURCE:
                policyGroup = samService.syncResourcePolicy(resource, syncMapping.getResourceRole().orElseThrow(badState), userRequest);
                break;
            case WORKSPACE:
                switch(syncMapping.getWorkspaceRole().orElseThrow(badState)) {
                    case OWNER:
                        policyGroup = cloudContext.getSamPolicyOwner().orElseThrow(badState);
                        break;
                    case WRITER:
                        policyGroup = cloudContext.getSamPolicyWriter().orElseThrow(badState);
                        break;
                    case READER:
                        policyGroup = cloudContext.getSamPolicyReader().orElseThrow(badState);
                        break;
                    case APPLICATION:
                        policyGroup = cloudContext.getSamPolicyApplication().orElseThrow(badState);
                        break;
                    default:
                        break;
                }
                break;
        }
        if (policyGroup == null) {
            throw new InternalLogicException("Policy group not set");
        }
        gcpPolicyBuilder.addResourceBinding(syncMapping.getTargetRole(), policyGroup);
    }
    return gcpPolicyBuilder.build();
}
Also used : InternalLogicException(bio.terra.workspace.common.exception.InternalLogicException) GcpPolicyBuilder(bio.terra.workspace.service.resource.controlled.cloud.gcp.GcpPolicyBuilder) SyncMapping(bio.terra.workspace.service.resource.controlled.ControlledResourceSyncMapping.SyncMapping)

Example 3 with InternalLogicException

use of bio.terra.workspace.common.exception.InternalLogicException in project terra-workspace-manager by DataBiosphere.

the class ControllerBase method computePrivateUserRole.

/**
 * Validate and provide defaulting for the private resource user. The property is never required.
 * The only time it is allowed is for application-private resources. If it is populated, we
 * validate the user email and the specified IAM roles.
 *
 * <p>user-private resources are always assigned to the caller. You can't create a user-private
 * resource and assign it to someone else. Because we can read the caller's email from the
 * AuthenticatedUserRequest, we don't need to supply assignedUser in the request body.
 *
 * <p>application-private resources can be assigned to users other than the caller. For example,
 * Leo could call WSM to create a VM (using the Leo SA's auth token) and request it be assigned to
 * user X, not to the Leo SA.
 *
 * @param commonFields common fields from a controlled resource create request
 * @param userRequest authenticate user
 * @return PrivateUserRole holding the user email and the role list
 */
public PrivateUserRole computePrivateUserRole(UUID workspaceId, ApiControlledResourceCommonFields commonFields, AuthenticatedUserRequest userRequest) {
    AccessScopeType accessScope = AccessScopeType.fromApi(commonFields.getAccessScope());
    ManagedByType managedBy = ManagedByType.fromApi(commonFields.getManagedBy());
    ApiPrivateResourceUser inputUser = commonFields.getPrivateResourceUser();
    // Shared access has no private user role
    if (accessScope == AccessScopeType.ACCESS_SCOPE_SHARED) {
        validateNoInputUser(inputUser);
        return new PrivateUserRole.Builder().present(false).build();
    }
    // Private access scope
    switch(managedBy) {
        case MANAGED_BY_APPLICATION:
            {
                // Supplying a user is optional for applications
                if (inputUser == null) {
                    return new PrivateUserRole.Builder().present(false).build();
                }
                // We have a private user, so make sure the email is present and valid
                String userEmail = commonFields.getPrivateResourceUser().getUserName();
                ControllerValidationUtils.validateEmail(userEmail);
                // Validate that the assigned user is a member of the workspace. It must have at least
                // READ action.
                SamRethrow.onInterrupted(() -> samService.userIsAuthorized(SamConstants.SamResource.WORKSPACE, workspaceId.toString(), SamConstants.SamWorkspaceAction.READ, userEmail, userRequest), "validate private user is workspace member");
                // Translate the incoming role list into our internal model form
                // This also validates that the incoming API model values are correct.
                List<ControlledResourceIamRole> roles = commonFields.getPrivateResourceUser().getPrivateResourceIamRoles().stream().map(ControlledResourceIamRole::fromApiModel).collect(Collectors.toList());
                if (roles.isEmpty()) {
                    throw new ValidationException("You must specify at least one role when you specify PrivateResourceIamRoles");
                }
                // The legal options for the assigned user of an application is READER
                // or WRITER. EDITOR is not allowed. We take the "max" of READER and WRITER.
                var maxRole = ControlledResourceIamRole.READER;
                for (ControlledResourceIamRole role : roles) {
                    if (role == ControlledResourceIamRole.WRITER) {
                        if (maxRole == ControlledResourceIamRole.READER) {
                            maxRole = role;
                        }
                    } else if (role != ControlledResourceIamRole.READER) {
                        throw new ValidationException("For application private controlled resources, only READER and WRITER roles are allowed. Found " + role.toApiModel());
                    }
                }
                return new PrivateUserRole.Builder().present(true).userEmail(userEmail).role(maxRole).build();
            }
        case MANAGED_BY_USER:
            {
                // TODO: PF-1218 The target state is that supplying a user is not allowed.
                // However, current CLI and maybe UI are supplying all or part of the structure,
                // so tolerate all states: no-input, only roles, roles and user
                /* Target state:
          // Supplying a user is not allowed. The creating user is always the assigned user.
          validateNoInputUser(inputUser);
          */
                // Fill in the user role for the creating user
                String userEmail = SamRethrow.onInterrupted(() -> samService.getUserEmailFromSam(userRequest), "getUserEmailFromSam");
                // matches the requesting name.
                if (inputUser != null && inputUser.getUserName() != null) {
                    if (!StringUtils.equalsIgnoreCase(userEmail, inputUser.getUserName())) {
                        throw new BadRequestException("User (" + userEmail + ") may only assign a private controlled resource to themselves");
                    }
                }
                // to different objects.
                return new PrivateUserRole.Builder().present(true).userEmail(userEmail).role(ControlledResourceIamRole.EDITOR).build();
            }
        default:
            throw new InternalLogicException("Unknown managedBy enum");
    }
}
Also used : ManagedByType(bio.terra.workspace.service.resource.controlled.model.ManagedByType) ValidationException(bio.terra.common.exception.ValidationException) InternalLogicException(bio.terra.workspace.common.exception.InternalLogicException) AccessScopeType(bio.terra.workspace.service.resource.controlled.model.AccessScopeType) ApiPrivateResourceUser(bio.terra.workspace.generated.model.ApiPrivateResourceUser) BadRequestException(bio.terra.common.exception.BadRequestException) List(java.util.List) ControlledResourceIamRole(bio.terra.workspace.service.iam.model.ControlledResourceIamRole) PrivateUserRole(bio.terra.workspace.service.resource.controlled.model.PrivateUserRole)

Example 4 with InternalLogicException

use of bio.terra.workspace.common.exception.InternalLogicException in project terra-workspace-manager by DataBiosphere.

the class ControlledResourceSamPolicyBuilder method addPolicies.

public void addPolicies(CreateResourceRequestV2 request) throws InterruptedException {
    Map<ControlledResourceIamRole, AccessPolicyMembershipV2> policyMap;
    // Owner is always WSM SA
    addWsmResourceOwnerPolicy(request);
    switch(category) {
        case USER_SHARED:
            // All other policies are inherited - nothing more to do
            break;
        case USER_PRIVATE:
            // Double check - this is validated earlier and should never happen.
            if (privateUserEmail == null || privateIamRole == null) {
                throw new InternalLogicException("Flight should never see user-private without a user email and iam role");
            }
            policyMap = makeInitialPolicyMap();
            policyMap.get(privateIamRole).addMemberEmailsItem(privateUserEmail);
            applyPolicyMap(request, policyMap);
            break;
        case APPLICATION_SHARED:
            // Double check - this is validated earlier and should never happen
            if (privateUserEmail != null) {
                throw new InternalLogicException("Flight should never see application-shared with a user email");
            }
            // Application is always editor on its resources; other policies are inherited
            AccessPolicyMembershipV2 editorPolicy = new AccessPolicyMembershipV2().addRolesItem(ControlledResourceIamRole.EDITOR.toSamRole());
            addApplicationResourceEditorPolicy(editorPolicy, userRequest);
            request.putPoliciesItem(ControlledResourceIamRole.EDITOR.toSamRole(), editorPolicy);
            break;
        case APPLICATION_PRIVATE:
            policyMap = makeInitialPolicyMap();
            // Application is always editor
            addApplicationResourceEditorPolicy(policyMap.get(ControlledResourceIamRole.EDITOR), userRequest);
            // if we have an assigned user, set up their permission
            if (privateUserEmail != null) {
                policyMap.get(privateIamRole).addMemberEmailsItem(privateUserEmail);
            }
            applyPolicyMap(request, policyMap);
            break;
    }
}
Also used : InternalLogicException(bio.terra.workspace.common.exception.InternalLogicException) AccessPolicyMembershipV2(org.broadinstitute.dsde.workbench.client.sam.model.AccessPolicyMembershipV2) ControlledResourceIamRole(bio.terra.workspace.service.iam.model.ControlledResourceIamRole)

Aggregations

InternalLogicException (bio.terra.workspace.common.exception.InternalLogicException)4 ControlledResourceIamRole (bio.terra.workspace.service.iam.model.ControlledResourceIamRole)2 BadRequestException (bio.terra.common.exception.BadRequestException)1 ValidationException (bio.terra.common.exception.ValidationException)1 ApiPrivateResourceUser (bio.terra.workspace.generated.model.ApiPrivateResourceUser)1 SyncMapping (bio.terra.workspace.service.resource.controlled.ControlledResourceSyncMapping.SyncMapping)1 GcpPolicyBuilder (bio.terra.workspace.service.resource.controlled.cloud.gcp.GcpPolicyBuilder)1 AccessScopeType (bio.terra.workspace.service.resource.controlled.model.AccessScopeType)1 ManagedByType (bio.terra.workspace.service.resource.controlled.model.ManagedByType)1 PrivateUserRole (bio.terra.workspace.service.resource.controlled.model.PrivateUserRole)1 AzureCloudContext (bio.terra.workspace.service.workspace.model.AzureCloudContext)1 GcpCloudContext (bio.terra.workspace.service.workspace.model.GcpCloudContext)1 List (java.util.List)1 AccessPolicyMembershipV2 (org.broadinstitute.dsde.workbench.client.sam.model.AccessPolicyMembershipV2)1