Search in sources :

Example 26 with BadRequestException

use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.

the class ParticipantService method sendInstallLinkMessage.

/**
 * Send a message by either email or SMS, depending on the configuration of the account.
 * IMPORTANT: the email and phone are considered to be verified; pass null for these arguments
 * if the values are not verified. We do it this way so the IntentService can provide values
 * even before an account exists.
 */
public void sendInstallLinkMessage(App app, SmsType type, String healthCode, String email, Phone phone, String osName) {
    if (email == null && phone == null) {
        throw new BadRequestException(ACCOUNT_UNABLE_TO_BE_CONTACTED_ERROR);
    }
    if (app.getInstallLinks().isEmpty()) {
        throw new BadRequestException(NO_INSTALL_LINKS_ERROR);
    }
    String url = getInstallLink(osName, app.getInstallLinks());
    if (phone != null) {
        TemplateRevision revision = templateService.getRevisionForUser(app, SMS_APP_INSTALL_LINK);
        SmsMessageProvider.Builder builder = new SmsMessageProvider.Builder().withApp(app).withTemplateRevision(revision).withPromotionType().withPhone(phone).withToken(APP_INSTALL_URL_KEY, url);
        if (type == SmsType.PROMOTIONAL) {
            builder.withPromotionType();
        } else {
            builder.withTransactionType();
        }
        // Account hasn't been created yet, so there is no ID yet. Pass in null user ID to
        // SMS Service.
        smsService.sendSmsMessage(null, builder.build());
    } else {
        TemplateRevision revision = templateService.getRevisionForUser(app, EMAIL_APP_INSTALL_LINK);
        BasicEmailProvider provider = new BasicEmailProvider.Builder().withApp(app).withTemplateRevision(revision).withRecipientEmail(email).withType(EmailType.APP_INSTALL).withToken(APP_INSTALL_URL_KEY, url).build();
        sendMailService.sendEmail(provider);
    }
    // exists yet. We only publish it when this template is triggered for an existing account.
    if (healthCode != null) {
        activityEventService.publishInstallLinkSent(app, healthCode, getInstallDateTime());
    }
}
Also used : BasicEmailProvider(org.sagebionetworks.bridge.services.email.BasicEmailProvider) BadRequestException(org.sagebionetworks.bridge.exceptions.BadRequestException) TemplateRevision(org.sagebionetworks.bridge.models.templates.TemplateRevision) SmsMessageProvider(org.sagebionetworks.bridge.sms.SmsMessageProvider)

Example 27 with BadRequestException

use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.

the class ParticipantService method resendVerification.

public void resendVerification(App app, ChannelType type, String userId) {
    checkNotNull(app);
    checkArgument(isNotBlank(userId));
    StudyParticipant participant = getParticipant(app, userId, false);
    if (type == ChannelType.EMAIL) {
        if (participant.getEmail() == null) {
            throw new BadRequestException("Email address has not been set.");
        }
        AccountId accountId = AccountId.forEmail(app.getIdentifier(), participant.getEmail());
        accountWorkflowService.resendVerificationToken(type, accountId);
    } else if (type == ChannelType.PHONE) {
        if (participant.getPhone() == null) {
            throw new BadRequestException("Phone number has not been set.");
        }
        AccountId accountId = AccountId.forPhone(app.getIdentifier(), participant.getPhone());
        accountWorkflowService.resendVerificationToken(type, accountId);
    } else {
        throw new UnsupportedOperationException("Channel type not implemented");
    }
}
Also used : AccountId(org.sagebionetworks.bridge.models.accounts.AccountId) BadRequestException(org.sagebionetworks.bridge.exceptions.BadRequestException) StudyParticipant(org.sagebionetworks.bridge.models.accounts.StudyParticipant)

Example 28 with BadRequestException

use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.

the class ParticipantService method createSmsRegistration.

/**
 * This is a researcher API to backfill SMS notification registrations for a user. We generally prefer the app
 * register notifications, but sometimes the work can't be done on time, so we want study developers to have the
 * option of backfilling these.
 */
public void createSmsRegistration(App app, String userId) {
    checkNotNull(app);
    checkNotNull(userId);
    // Account must have a verified phone number.
    Account account = getAccountThrowingException(app.getIdentifier(), userId);
    if (!TRUE.equals(account.getPhoneVerified())) {
        throw new BadRequestException("Can't create SMS notification registration for user " + userId + ": user has no verified phone number");
    }
    // We need the account's request info to build the criteria context.
    RequestInfo requestInfo = requestInfoService.getRequestInfo(userId);
    if (requestInfo == null) {
        throw new BadRequestException("Can't create SMS notification registration for user " + userId + ": user has no request info");
    }
    Set<String> studyIds = BridgeUtils.collectStudyIds(account);
    CriteriaContext criteriaContext = new CriteriaContext.Builder().withAppId(app.getIdentifier()).withUserId(userId).withHealthCode(account.getHealthCode()).withClientInfo(requestInfo.getClientInfo()).withLanguages(requestInfo.getLanguages()).withUserDataGroups(account.getDataGroups()).withUserStudyIds(studyIds).build();
    // Participant must be consented.
    StudyParticipant participant = getParticipant(app, account, false);
    if (!TRUE.equals(participant.isConsented())) {
        throw new BadRequestException("Can't create SMS notification registration for user " + userId + ": user is not consented");
    }
    // Create registration.
    NotificationRegistration registration = NotificationRegistration.create();
    registration.setHealthCode(account.getHealthCode());
    registration.setProtocol(NotificationProtocol.SMS);
    registration.setEndpoint(account.getPhone().getNumber());
    // Create registration.
    notificationsService.createRegistration(app.getIdentifier(), criteriaContext, registration);
}
Also used : Account(org.sagebionetworks.bridge.models.accounts.Account) NotificationRegistration(org.sagebionetworks.bridge.models.notifications.NotificationRegistration) BadRequestException(org.sagebionetworks.bridge.exceptions.BadRequestException) StudyParticipant(org.sagebionetworks.bridge.models.accounts.StudyParticipant) RequestInfo(org.sagebionetworks.bridge.models.RequestInfo) CriteriaContext(org.sagebionetworks.bridge.models.CriteriaContext)

Example 29 with BadRequestException

use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.

the class OAuthProviderService method oauthSignIn.

/**
 * Authenticate a Bridge user via an external OAuth server that supports Open Connect ID (identified by the supplied
 * vendor ID; currently the only supported external authentication server is Synapse, but the same requirements are
 * fulfilled by Google, Facebook, etc.). This is the second contact of the OAuth server, after a client has sent a
 * user to authenticate on the OAuth server's web site and the OAuth server has redirected back to the Bridge client
 * with an authentication code. We now exchange it for an authentication token as well as the additional OCID
 * information to verify the identity of the caller (currently we ask for the user's Synapse ID from Synapse, but we
 * could also use email or phone number).
 *
 * @param authToken
 *         that was passed from the OAuth server back to the authenticating client
 * @return accountId if the exchange is successful, the accountId will contain an identifying credential that should
 *         be usable to retrieve an account
 *
 * @throws BadRequestException
 */
public AccountId oauthSignIn(OAuthAuthorizationToken authToken) {
    checkNotNull(authToken);
    if (authToken.getVendorId() == null) {
        throw new BadRequestException("Vendor ID required");
    }
    if (authToken.getAppId() == null) {
        throw new BadRequestException("App ID required");
    }
    if (authToken.getAuthToken() == null) {
        throw new BadRequestException("Authorization token required");
    }
    OAuthProvider provider = null;
    if (SYNAPSE_OAUTH_VENDOR_ID.equals(authToken.getVendorId())) {
        // Synapse configuration is globally available and not stored in providers table.
        provider = new OAuthProvider(this.synapseClientID, this.synapseClientSecret, this.synapseOauthURL, authToken.getCallbackUrl(), null);
    } else {
        // Is this vendor ID mapped to another provider for this app?
        App app = appService.getApp(authToken.getAppId());
        provider = app.getOAuthProviders().get(authToken.getVendorId());
    }
    if (provider == null) {
        throw new BadRequestException("Vendor not supported: " + authToken.getVendorId());
    }
    HttpPost client = createOAuthProviderPost(provider, provider.getEndpoint());
    List<NameValuePair> pairs = new ArrayList<>();
    pairs.add(new BasicNameValuePair(GRANT_TYPE_PROP_NAME, AUTHORIZATION_CODE_VALUE));
    pairs.add(new BasicNameValuePair(CODE_PROP_NAME, authToken.getAuthToken()));
    pairs.add(new BasicNameValuePair(REDIRECT_URI_PROP_NAME, authToken.getCallbackUrl()));
    client.setEntity(formEntity(pairs));
    Response response = executeGrantRequest(client);
    if (response.getStatusCode() < 200 || response.getStatusCode() > 299) {
        throw new BadRequestException(response.getBody().get(SYNAPSE_ERROR_KEY).textValue());
    }
    JwtParser parser = getJwtParser();
    parser.setSigningKey(getRSAPublicKey());
    parser.setAllowedClockSkewSeconds(5);
    String idTokenBlock = response.getBody().get(SYNAPSE_ID_TOKEN_KEY).textValue();
    Jws<Claims> jwt = parser.parseClaimsJws(idTokenBlock);
    String synapseUserId = jwt.getBody().get(SYNAPSE_USERID_KEY, String.class);
    if (synapseUserId != null) {
        return AccountId.forSynapseUserId(authToken.getAppId(), synapseUserId);
    }
    return null;
}
Also used : App(org.sagebionetworks.bridge.models.apps.App) HttpPost(org.apache.http.client.methods.HttpPost) NameValuePair(org.apache.http.NameValuePair) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) Claims(io.jsonwebtoken.Claims) ArrayList(java.util.ArrayList) OAuthProvider(org.sagebionetworks.bridge.models.apps.OAuthProvider) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) JwtParser(io.jsonwebtoken.JwtParser) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) BadRequestException(org.sagebionetworks.bridge.exceptions.BadRequestException)

Example 30 with BadRequestException

use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.

the class ReportService method getStudyReportV4.

/**
 * Return set of study report records based on the provided datetime range. Study memberships are enforced.
 */
public ForwardCursorPagedResourceList<ReportData> getStudyReportV4(final String appId, final String identifier, final DateTime startTime, final DateTime endTime, final String offsetKey, final int pageSize) {
    if (pageSize < API_MINIMUM_PAGE_SIZE || pageSize > API_MAXIMUM_PAGE_SIZE) {
        throw new BadRequestException(BridgeConstants.PAGE_SIZE_ERROR);
    }
    RangeTuple<DateTime> finalTimes = validateDateTimeRange(startTime, endTime);
    ReportDataKey key = new ReportDataKey.Builder().withReportType(ReportType.STUDY).withIdentifier(identifier).withAppId(appId).build();
    Validate.entityThrowingException(ReportDataKeyValidator.INSTANCE, key);
    ReportIndex index = reportIndexDao.getIndex(key);
    checkStudyReportAccess(index);
    return reportDataDao.getReportDataV4(key, finalTimes.getStart(), finalTimes.getEnd(), offsetKey, pageSize);
}
Also used : ReportIndex(org.sagebionetworks.bridge.models.reports.ReportIndex) ReportDataKey(org.sagebionetworks.bridge.models.reports.ReportDataKey) BadRequestException(org.sagebionetworks.bridge.exceptions.BadRequestException) DateTime(org.joda.time.DateTime)

Aggregations

BadRequestException (org.sagebionetworks.bridge.exceptions.BadRequestException)104 EntityNotFoundException (org.sagebionetworks.bridge.exceptions.EntityNotFoundException)23 Test (org.testng.annotations.Test)19 UserSession (org.sagebionetworks.bridge.models.accounts.UserSession)17 App (org.sagebionetworks.bridge.models.apps.App)17 DateTime (org.joda.time.DateTime)13 StudyParticipant (org.sagebionetworks.bridge.models.accounts.StudyParticipant)10 Study (org.sagebionetworks.bridge.models.studies.Study)10 ArrayList (java.util.ArrayList)9 Account (org.sagebionetworks.bridge.models.accounts.Account)9 StudyActivityEvent (org.sagebionetworks.bridge.models.activities.StudyActivityEvent)9 PostMapping (org.springframework.web.bind.annotation.PostMapping)9 UploadSchema (org.sagebionetworks.bridge.models.upload.UploadSchema)8 CacheKey (org.sagebionetworks.bridge.cache.CacheKey)7 AccountId (org.sagebionetworks.bridge.models.accounts.AccountId)7 ScheduleContext (org.sagebionetworks.bridge.models.schedules.ScheduleContext)7 List (java.util.List)5 Survey (org.sagebionetworks.bridge.models.surveys.Survey)5 GetMapping (org.springframework.web.bind.annotation.GetMapping)5 Map (java.util.Map)4