Search in sources :

Example 6 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class ProfileControllerTest method testMe_userBeforeSuccessCloudProjectTooManyConflicts.

@Test
public void testMe_userBeforeSuccessCloudProjectTooManyConflicts() throws Exception {
    createUser();
    when(fireCloudService.isRequesterEnabledInFirecloud()).thenReturn(true);
    String projectName = BILLING_PROJECT_PREFIX + user.getUserId();
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName);
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-1");
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-2");
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-3");
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-4");
    try {
        cloudProfileController.getMe();
        fail("ServerErrorException expected");
    } catch (ServerErrorException e) {
    // expected
    }
    // When too many conflicts occur, the user doesn't have their project name set or first
    // sign in time.
    assertUser(PRIMARY_EMAIL, CONTACT_EMAIL, FAMILY_NAME, GIVEN_NAME, DataAccessLevel.UNREGISTERED, null, null);
    verify(fireCloudService).registerUser(CONTACT_EMAIL, GIVEN_NAME, FAMILY_NAME);
    verify(fireCloudService).createAllOfUsBillingProject(projectName);
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-1");
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-2");
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-3");
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-4");
}
Also used : ServerErrorException(org.pmiops.workbench.exceptions.ServerErrorException) ApiException(org.pmiops.workbench.firecloud.ApiException) DataJpaTest(org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest) Test(org.junit.Test)

Example 7 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class WorkspacesControllerTest method testCloneNotFound.

@Test(expected = NotFoundException.class)
public void testCloneNotFound() throws Exception {
    doThrow(new ApiException(404, "")).when(fireCloudService).getWorkspace("doesnot", "exist");
    CloneWorkspaceRequest req = new CloneWorkspaceRequest();
    Workspace modWorkspace = new Workspace();
    modWorkspace.setName("cloned");
    modWorkspace.setNamespace("cloned-ns");
    req.setWorkspace(modWorkspace);
    ResearchPurpose modPurpose = new ResearchPurpose();
    modPurpose.setAncestry(true);
    modWorkspace.setResearchPurpose(modPurpose);
    workspacesController.cloneWorkspace("doesnot", "exist", req);
}
Also used : CloneWorkspaceRequest(org.pmiops.workbench.model.CloneWorkspaceRequest) ApiException(org.pmiops.workbench.firecloud.ApiException) Workspace(org.pmiops.workbench.model.Workspace) ResearchPurpose(org.pmiops.workbench.model.ResearchPurpose) DataJpaTest(org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest) Test(org.junit.Test)

Example 8 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class WorkspacesControllerTest method testClonePermissionDenied.

@Test(expected = NotFoundException.class)
public void testClonePermissionDenied() throws Exception {
    Workspace workspace = createDefaultWorkspace();
    workspace = workspacesController.createWorkspace(workspace).getBody();
    // Clone with a different user.
    User cloner = new User();
    cloner.setEmail("cloner@gmail.com");
    cloner.setUserId(456L);
    cloner.setFreeTierBillingProjectName("TestBillingProject1");
    cloner.setDisabled(false);
    cloner = userDao.save(cloner);
    when(userProvider.get()).thenReturn(cloner);
    // Permission denied manifests as a 404 in Firecloud.
    when(fireCloudService.getWorkspace(workspace.getNamespace(), workspace.getName())).thenThrow(new ApiException(404, ""));
    CloneWorkspaceRequest req = new CloneWorkspaceRequest();
    Workspace modWorkspace = new Workspace();
    modWorkspace.setName("cloned");
    modWorkspace.setNamespace("cloned-ns");
    req.setWorkspace(modWorkspace);
    ResearchPurpose modPurpose = new ResearchPurpose();
    modPurpose.setAncestry(true);
    modWorkspace.setResearchPurpose(modPurpose);
    workspacesController.cloneWorkspace(workspace.getNamespace(), workspace.getId(), req);
}
Also used : User(org.pmiops.workbench.db.model.User) CloneWorkspaceRequest(org.pmiops.workbench.model.CloneWorkspaceRequest) Workspace(org.pmiops.workbench.model.Workspace) ApiException(org.pmiops.workbench.firecloud.ApiException) ResearchPurpose(org.pmiops.workbench.model.ResearchPurpose) DataJpaTest(org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest) Test(org.junit.Test)

Example 9 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class AuthInterceptor method preHandle.

/**
 * Returns true iff the request is auth'd and should proceed. Publishes authenticated user info
 * using Spring's SecurityContext.
 * @param handler The Swagger-generated ApiController. It contains our handler as a private
 *     delegate.
 */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // OPTIONS methods requests don't need authorization.
    if (request.getMethod().equals(HttpMethods.OPTIONS)) {
        return true;
    }
    HandlerMethod method = (HandlerMethod) handler;
    boolean isAuthRequired = false;
    ApiOperation apiOp = AnnotationUtils.findAnnotation(method.getMethod(), ApiOperation.class);
    if (apiOp != null) {
        for (Authorization auth : apiOp.authorizations()) {
            if (auth.value().equals(authName)) {
                isAuthRequired = true;
                break;
            }
        }
    }
    if (!isAuthRequired) {
        return true;
    }
    String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
    if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
        log.warning("No bearer token found in request");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    String token = authorizationHeader.substring("Bearer".length()).trim();
    Userinfoplus userInfo;
    try {
        userInfo = userInfoService.getUserInfo(token);
    } catch (HttpResponseException e) {
        log.log(Level.WARNING, "{0} response getting user info for bearer token {1}: {2}", new Object[] { e.getStatusCode(), token, e.getStatusMessage() });
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    // TODO: check Google group membership to ensure user is in registered user group
    String userEmail = userInfo.getEmail();
    WorkbenchConfig workbenchConfig = workbenchConfigProvider.get();
    if (workbenchConfig.auth.serviceAccountApiUsers.contains(userEmail)) {
        // Whitelisted service accounts are able to make API calls, too.
        // TODO: stop treating service accounts as normal users, have a separate table for them,
        // administrators.
        User user = userDao.findUserByEmail(userEmail);
        if (user == null) {
            user = userService.createServiceAccountUser(userEmail);
        }
        SecurityContextHolder.getContext().setAuthentication(new UserAuthentication(user, userInfo, token, UserType.SERVICE_ACCOUNT));
        log.log(Level.INFO, "{0} service account in use", userInfo.getEmail());
        return true;
    }
    String gsuiteDomainSuffix = "@" + workbenchConfig.googleDirectoryService.gSuiteDomain;
    if (!userEmail.endsWith(gsuiteDomainSuffix)) {
        try {
            // If the email isn't in our GSuite domain, try FireCloud; we could be dealing with a
            // pet service account. In both AofU and FireCloud, the pet SA is treated as if it were
            // the user it was created for.
            userEmail = fireCloudService.getMe().getUserInfo().getUserEmail();
        } catch (ApiException e) {
            log.log(Level.INFO, "FireCloud lookup for {0} failed, can't access the workbench: {1}", new Object[] { userInfo.getEmail(), e.getMessage() });
            response.sendError(e.getCode());
            return false;
        }
        if (!userEmail.endsWith(gsuiteDomainSuffix)) {
            log.log(Level.INFO, "User {0} isn't in domain {1}, can't access the workbench", new Object[] { userEmail, gsuiteDomainSuffix });
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return false;
        }
    }
    User user = userDao.findUserByEmail(userEmail);
    if (user == null) {
        // TODO(danrodney): start populating contact email in Google account, use it here.
        user = userService.createUser(userInfo.getGivenName(), userInfo.getFamilyName(), userInfo.getEmail(), null);
    } else {
        if (user.getDisabled()) {
            throw new ForbiddenException(ExceptionUtils.errorResponse(ErrorCode.USER_DISABLED, "This user account has been disabled."));
        }
    }
    SecurityContextHolder.getContext().setAuthentication(new UserAuthentication(user, userInfo, token, UserType.RESEARCHER));
    // TODO: setup this in the context, get rid of log statement
    log.log(Level.INFO, "{0} logged in", userInfo.getEmail());
    if (!hasRequiredAuthority(method, user)) {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
        return false;
    }
    return true;
}
Also used : Userinfoplus(com.google.api.services.oauth2.model.Userinfoplus) WorkbenchConfig(org.pmiops.workbench.config.WorkbenchConfig) ForbiddenException(org.pmiops.workbench.exceptions.ForbiddenException) User(org.pmiops.workbench.db.model.User) HttpResponseException(com.google.api.client.http.HttpResponseException) UserAuthentication(org.pmiops.workbench.auth.UserAuthentication) HandlerMethod(org.springframework.web.method.HandlerMethod) Authorization(io.swagger.annotations.Authorization) ApiOperation(io.swagger.annotations.ApiOperation) ApiException(org.pmiops.workbench.firecloud.ApiException)

Example 10 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class WorkspaceServiceImpl method updateUserRoles.

@Override
public Workspace updateUserRoles(Workspace workspace, Set<WorkspaceUserRole> userRoleSet) {
    Map<Long, WorkspaceUserRole> userRoleMap = new HashMap<Long, WorkspaceUserRole>();
    for (WorkspaceUserRole userRole : userRoleSet) {
        userRole.setWorkspace(workspace);
        userRoleMap.put(userRole.getUser().getUserId(), userRole);
    }
    ArrayList<WorkspaceACLUpdate> updateACLRequestList = new ArrayList<WorkspaceACLUpdate>();
    Iterator<WorkspaceUserRole> dbUserRoles = workspace.getWorkspaceUserRoles().iterator();
    while (dbUserRoles.hasNext()) {
        WorkspaceUserRole currentUserRole = dbUserRoles.next();
        WorkspaceUserRole mapValue = userRoleMap.get(currentUserRole.getUser().getUserId());
        if (mapValue != null) {
            currentUserRole.setRole(mapValue.getRole());
            userRoleMap.remove(currentUserRole.getUser().getUserId());
        } else {
            // This is how to remove a user from the FireCloud ACL:
            // Pass along an update request with NO ACCESS as the given access level.
            WorkspaceACLUpdate removedUser = new WorkspaceACLUpdate();
            removedUser.setEmail(currentUserRole.getUser().getEmail());
            removedUser.setCanCompute(false);
            removedUser.setCanShare(false);
            removedUser.setAccessLevel(WorkspaceAccessLevel.NO_ACCESS.toString());
            updateACLRequestList.add(removedUser);
            dbUserRoles.remove();
        }
    }
    for (Entry<Long, WorkspaceUserRole> remainingRole : userRoleMap.entrySet()) {
        workspace.getWorkspaceUserRoles().add(remainingRole.getValue());
    }
    for (WorkspaceUserRole currentWorkspaceUser : workspace.getWorkspaceUserRoles()) {
        WorkspaceACLUpdate currentUpdate = new WorkspaceACLUpdate();
        currentUpdate.setEmail(currentWorkspaceUser.getUser().getEmail());
        currentUpdate.setCanCompute(false);
        if (currentWorkspaceUser.getRole() == WorkspaceAccessLevel.OWNER) {
            currentUpdate.setCanShare(true);
            currentUpdate.setAccessLevel(WorkspaceAccessLevel.OWNER.toString());
        } else if (currentWorkspaceUser.getRole() == WorkspaceAccessLevel.WRITER) {
            currentUpdate.setCanShare(false);
            currentUpdate.setAccessLevel(WorkspaceAccessLevel.WRITER.toString());
        } else {
            currentUpdate.setCanShare(false);
            currentUpdate.setAccessLevel(WorkspaceAccessLevel.READER.toString());
        }
        updateACLRequestList.add(currentUpdate);
    }
    try {
        WorkspaceACLUpdateResponseList fireCloudResponse = fireCloudService.updateWorkspaceACL(workspace.getWorkspaceNamespace(), workspace.getFirecloudName(), updateACLRequestList);
        if (fireCloudResponse.getUsersNotFound().size() != 0) {
            String usersNotFound = "";
            for (int i = 0; i < fireCloudResponse.getUsersNotFound().size(); i++) {
                if (i > 0) {
                    usersNotFound += ", ";
                }
                usersNotFound += fireCloudResponse.getUsersNotFound().get(i).getEmail();
            }
            throw new BadRequestException(usersNotFound);
        }
    } catch (ApiException e) {
        if (e.getCode() == 400) {
            throw new BadRequestException(e.getResponseBody());
        } else if (e.getCode() == 404) {
            throw new NotFoundException("Workspace not found.");
        } else if (e.getCode() == 500) {
            throw new ServerErrorException(e);
        } else {
            throw new ServerUnavailableException(e);
        }
    }
    return this.saveWithLastModified(workspace);
}
Also used : HashMap(java.util.HashMap) WorkspaceACLUpdateResponseList(org.pmiops.workbench.firecloud.model.WorkspaceACLUpdateResponseList) ArrayList(java.util.ArrayList) ServerUnavailableException(org.pmiops.workbench.exceptions.ServerUnavailableException) NotFoundException(org.pmiops.workbench.exceptions.NotFoundException) WorkspaceUserRole(org.pmiops.workbench.db.model.WorkspaceUserRole) BadRequestException(org.pmiops.workbench.exceptions.BadRequestException) ServerErrorException(org.pmiops.workbench.exceptions.ServerErrorException) WorkspaceACLUpdate(org.pmiops.workbench.firecloud.model.WorkspaceACLUpdate) ApiException(org.pmiops.workbench.firecloud.ApiException)

Aggregations

ApiException (org.pmiops.workbench.firecloud.ApiException)15 User (org.pmiops.workbench.db.model.User)8 Test (org.junit.Test)6 ServerErrorException (org.pmiops.workbench.exceptions.ServerErrorException)5 AuthorityRequired (org.pmiops.workbench.annotations.AuthorityRequired)4 WorkbenchConfig (org.pmiops.workbench.config.WorkbenchConfig)4 Profile (org.pmiops.workbench.model.Profile)4 DataJpaTest (org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest)4 ArrayList (java.util.ArrayList)3 BadRequestException (org.pmiops.workbench.exceptions.BadRequestException)3 Userinfoplus (com.google.api.services.oauth2.model.Userinfoplus)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 Timestamp (java.sql.Timestamp)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Function (java.util.function.Function)2 Level (java.util.logging.Level)2 Logger (java.util.logging.Logger)2 Collectors (java.util.stream.Collectors)2 Provider (javax.inject.Provider)2