use of org.pmiops.workbench.config.WorkbenchConfig in project workbench by all-of-us.
the class ProfileController method createFirecloudUserAndBillingProject.
private String createFirecloudUserAndBillingProject(User user) {
try {
// If the user is already registered, their profile will get updated.
fireCloudService.registerUser(user.getContactEmail(), user.getGivenName(), user.getFamilyName());
} catch (ApiException e) {
log.log(Level.SEVERE, String.format("Error registering user: %s", e.getResponseBody()), e);
// We don't expect this to happen.
throw new ServerErrorException("Error registering user", e);
}
WorkbenchConfig workbenchConfig = workbenchConfigProvider.get();
long suffix;
if (workbenchEnvironment.isDevelopment()) {
// For local development, make one billing project per account based on a hash of the account
// email, and reuse it across database resets. (Assume we won't have any collisions;
// if we discover that somebody starts using our namespace, change it up.)
suffix = user.getEmail().hashCode();
} else {
// In other environments, create a suffix based on the user ID from the database. We will
// add a suffix if that billing project is already taken. (If the database is reset, we
// should consider switching the prefix.)
suffix = user.getUserId();
}
// GCP billing project names must be <= 30 characters. The per-user hash, an integer,
// is <= 10 chars.
String billingProjectNamePrefix = workbenchConfig.firecloud.billingProjectPrefix + suffix;
String billingProjectName = billingProjectNamePrefix;
int numAttempts = 0;
while (numAttempts < MAX_BILLING_PROJECT_CREATION_ATTEMPTS) {
try {
fireCloudService.createAllOfUsBillingProject(billingProjectName);
break;
} catch (ApiException e) {
if (e.getCode() == HttpStatus.CONFLICT.value()) {
if (workbenchEnvironment.isDevelopment()) {
// In local development, just re-use existing projects for the account. (We don't
// want to create a new billing project every time the database is reset.)
log.log(Level.WARNING, String.format("Project with name '%s' already exists; using it.", billingProjectName));
break;
} else {
numAttempts++;
// In cloud environments, keep trying billing project names until we find one
// that hasn't been used before, or we hit MAX_BILLING_PROJECT_CREATION_ATTEMPTS.
billingProjectName = billingProjectNamePrefix + "-" + numAttempts;
}
} else {
log.log(Level.SEVERE, String.format("Error creating billing project: %s", e.getResponseBody()), e);
throw new ServerErrorException("Error creating billing project", e);
}
}
}
if (numAttempts == MAX_BILLING_PROJECT_CREATION_ATTEMPTS) {
throw new ServerErrorException(String.format("Encountered %d billing project name " + "collisions; giving up", MAX_BILLING_PROJECT_CREATION_ATTEMPTS));
}
try {
// If the user is already a member of the billing project, this will have no effect.
fireCloudService.addUserToBillingProject(user.getEmail(), billingProjectName);
} catch (ApiException e) {
if (e.getCode() == HttpStatus.FORBIDDEN.value()) {
// AofU is not the owner of the billing project. This should only happen in local
// environments (and hopefully never, given the prefix we're using.) If it happens,
// we may need to pick a different prefix.
log.log(Level.SEVERE, String.format("Unable to add user to billing project %s: %s; " + "consider changing billing project prefix", billingProjectName, e.getResponseBody()), e);
throw new ServerErrorException("Unable to add user to billing project", e);
} else {
log.log(Level.SEVERE, String.format("Error adding user to billing project: %s", e.getResponseBody()), e);
throw new ServerErrorException("Error adding user to billing project", e);
}
}
return billingProjectName;
}
use of org.pmiops.workbench.config.WorkbenchConfig in project workbench by all-of-us.
the class BlockscoreServiceImplIntegrationTest method createConfig.
private static WorkbenchConfig createConfig() {
WorkbenchConfig config = new WorkbenchConfig();
config.googleCloudStorageService = new WorkbenchConfig.GoogleCloudStorageServiceConfig();
config.googleCloudStorageService.credentialsBucketName = "all-of-us-workbench-test-credentials";
return config;
}
use of org.pmiops.workbench.config.WorkbenchConfig in project workbench by all-of-us.
the class CloudStorageServiceImplIntegrationTest method createConfig.
private static WorkbenchConfig createConfig() {
WorkbenchConfig config = new WorkbenchConfig();
config.googleCloudStorageService = new WorkbenchConfig.GoogleCloudStorageServiceConfig();
config.googleCloudStorageService.credentialsBucketName = "all-of-us-workbench-test-credentials";
return config;
}
use of org.pmiops.workbench.config.WorkbenchConfig in project workbench by all-of-us.
the class ProfileControllerTest method setUp.
@Before
public void setUp() {
WorkbenchConfig config = new WorkbenchConfig();
config.firecloud = new FireCloudConfig();
config.firecloud.billingProjectPrefix = BILLING_PROJECT_PREFIX;
WorkbenchEnvironment environment = new WorkbenchEnvironment(true, "appId");
WorkbenchEnvironment cloudEnvironment = new WorkbenchEnvironment(false, "appId");
createAccountRequest = new CreateAccountRequest();
invitationVerificationRequest = new InvitationVerificationRequest();
Profile profile = new Profile();
profile.setContactEmail(CONTACT_EMAIL);
profile.setFamilyName(FAMILY_NAME);
profile.setGivenName(GIVEN_NAME);
profile.setUsername(USERNAME);
createAccountRequest.setProfile(profile);
createAccountRequest.setInvitationKey(INVITATION_KEY);
createAccountRequest.setPassword(PASSWORD);
invitationVerificationRequest.setInvitationKey(INVITATION_KEY);
googleUser = new com.google.api.services.admin.directory.model.User();
googleUser.setPrimaryEmail(PRIMARY_EMAIL);
clock = new FakeClock(NOW);
idVerificationRequest = new IdVerificationRequest();
idVerificationRequest.setFirstName("Bob");
UserService userService = new UserService(userProvider, userDao, adminActionHistoryDao, clock, fireCloudService, configProvider);
ProfileService profileService = new ProfileService(fireCloudService, mailChimpService, userDao);
this.profileController = new ProfileController(profileService, userProvider, userAuthenticationProvider, userDao, clock, userService, fireCloudService, directoryService, cloudStorageService, blockscoreService, mailChimpService, Providers.of(config), environment);
this.cloudProfileController = new ProfileController(profileService, userProvider, userAuthenticationProvider, userDao, clock, userService, fireCloudService, directoryService, cloudStorageService, blockscoreService, mailChimpService, Providers.of(config), cloudEnvironment);
}
use of org.pmiops.workbench.config.WorkbenchConfig 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;
}
Aggregations