Search in sources :

Example 1 with Phone

use of org.sagebionetworks.bridge.models.accounts.Phone in project BridgeServer2 by Sage-Bionetworks.

the class SignInValidatorTest method reauthWithInvalidPhoneInvalid.

@Test
public void reauthWithInvalidPhoneInvalid() {
    SignIn signIn = new SignIn.Builder().withPhone(new Phone("xxxxxxxxxx", "US")).build();
    assertValidatorMessage(SignInValidator.REAUTH_SIGNIN, signIn, "phone", "does not appear to be a phone number");
}
Also used : Phone(org.sagebionetworks.bridge.models.accounts.Phone) SignIn(org.sagebionetworks.bridge.models.accounts.SignIn) Test(org.testng.annotations.Test)

Example 2 with Phone

use of org.sagebionetworks.bridge.models.accounts.Phone in project BridgeServer2 by Sage-Bionetworks.

the class AccountWorkflowService method resetPassword.

/**
 * Use a supplied password reset token to change the password on an account. If the supplied
 * token is not valid, this method throws an exception. If the token is valid but the account
 * does not exist, an exception is also thrown (this would be unusual).
 */
public void resetPassword(PasswordReset passwordReset) {
    checkNotNull(passwordReset);
    // This pathway is unusual as the token may have been sent via email or phone, so test for both.
    CacheKey emailCacheKey = CacheKey.passwordResetForEmail(passwordReset.getSptoken(), passwordReset.getAppId());
    CacheKey phoneCacheKey = CacheKey.passwordResetForPhone(passwordReset.getSptoken(), passwordReset.getAppId());
    String email = cacheProvider.getObject(emailCacheKey, String.class);
    Phone phone = cacheProvider.getObject(phoneCacheKey, Phone.class);
    if (email == null && phone == null) {
        throw new BadRequestException(PASSWORD_RESET_TOKEN_EXPIRED);
    }
    cacheProvider.removeObject(emailCacheKey);
    cacheProvider.removeObject(phoneCacheKey);
    App app = appService.getApp(passwordReset.getAppId());
    ChannelType channelType = null;
    AccountId accountId = null;
    if (email != null) {
        accountId = AccountId.forEmail(app.getIdentifier(), email);
        channelType = ChannelType.EMAIL;
    } else if (phone != null) {
        accountId = AccountId.forPhone(app.getIdentifier(), phone);
        channelType = ChannelType.PHONE;
    } else {
        throw new BridgeServiceException("Could not reset password");
    }
    Account account = accountService.getAccount(accountId).orElseThrow(() -> new EntityNotFoundException(Account.class));
    accountService.changePassword(account, channelType, passwordReset.getPassword());
}
Also used : App(org.sagebionetworks.bridge.models.apps.App) Account(org.sagebionetworks.bridge.models.accounts.Account) AccountId(org.sagebionetworks.bridge.models.accounts.AccountId) Phone(org.sagebionetworks.bridge.models.accounts.Phone) BridgeServiceException(org.sagebionetworks.bridge.exceptions.BridgeServiceException) BadRequestException(org.sagebionetworks.bridge.exceptions.BadRequestException) EntityNotFoundException(org.sagebionetworks.bridge.exceptions.EntityNotFoundException) ChannelType(org.sagebionetworks.bridge.services.AuthenticationService.ChannelType) CacheKey(org.sagebionetworks.bridge.cache.CacheKey)

Example 3 with Phone

use of org.sagebionetworks.bridge.models.accounts.Phone in project BridgeServer2 by Sage-Bionetworks.

the class IntentService method registerIntentToParticipate.

public boolean registerIntentToParticipate(App app, Account account) {
    Phone phone = account.getPhone();
    String email = account.getEmail();
    // Somehow, this is being called but the user has no phone number.
    if (phone == null && email == null) {
        return false;
    }
    boolean consentsUpdated = false;
    StudyParticipant participant = null;
    List<Subpopulation> subpops = subpopService.getSubpopulations(app.getIdentifier(), false);
    for (Subpopulation subpop : subpops) {
        CacheKey cacheKey = (phone == null) ? CacheKey.itp(subpop.getGuid(), app.getIdentifier(), email) : CacheKey.itp(subpop.getGuid(), app.getIdentifier(), phone);
        IntentToParticipate intent = cacheProvider.getObject(cacheKey, IntentToParticipate.class);
        if (intent != null) {
            if (participant == null) {
                participant = participantService.getParticipant(app, account.getId(), true);
            }
            consentService.consentToResearch(app, subpop.getGuid(), participant, intent.getConsentSignature(), intent.getScope(), true);
            cacheProvider.removeObject(cacheKey);
            consentsUpdated = true;
        }
    }
    return consentsUpdated;
}
Also used : Phone(org.sagebionetworks.bridge.models.accounts.Phone) Subpopulation(org.sagebionetworks.bridge.models.subpopulations.Subpopulation) IntentToParticipate(org.sagebionetworks.bridge.models.itp.IntentToParticipate) StudyParticipant(org.sagebionetworks.bridge.models.accounts.StudyParticipant) CacheKey(org.sagebionetworks.bridge.cache.CacheKey)

Example 4 with Phone

use of org.sagebionetworks.bridge.models.accounts.Phone in project BridgeServer2 by Sage-Bionetworks.

the class ParticipantService method createParticipant.

/**
 * Create a study participant. A password must be provided, even if it is added on behalf of a user before
 * triggering a reset password request.
 */
public IdentifierHolder createParticipant(App app, StudyParticipant participant, boolean shouldSendVerification) {
    checkNotNull(app);
    checkNotNull(participant);
    if (app.getAccountLimit() > 0) {
        throwExceptionIfLimitMetOrExceeded(app);
    }
    StudyParticipantValidator validator = new StudyParticipantValidator(studyService, organizationService, app, true);
    Validate.entityThrowingException(validator, participant);
    // Set basic params from inputs.
    Account account = getAccount();
    account.setId(generateGUID());
    account.setAppId(app.getIdentifier());
    account.setEmail(participant.getEmail());
    account.setPhone(participant.getPhone());
    account.setEmailVerified(FALSE);
    account.setPhoneVerified(FALSE);
    account.setHealthCode(generateGUID());
    account.setStatus(UNVERIFIED);
    // Otherwise this field is ignored on create.
    if (CAN_EDIT_MEMBERS.check(ORG_ID, participant.getOrgMembership())) {
        account.setOrgMembership(participant.getOrgMembership());
    }
    // Hash password if it has been supplied.
    if (participant.getPassword() != null) {
        try {
            PasswordAlgorithm passwordAlgorithm = DEFAULT_PASSWORD_ALGORITHM;
            String passwordHash = passwordAlgorithm.generateHash(participant.getPassword());
            account.setPasswordAlgorithm(passwordAlgorithm);
            account.setPasswordHash(passwordHash);
        } catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException ex) {
            throw new BridgeServiceException("Error creating password: " + ex.getMessage(), ex);
        }
    }
    updateAccountAndRoles(app, account, participant, true);
    // enabled unless we need any kind of verification
    boolean sendEmailVerification = shouldSendVerification && app.isEmailVerificationEnabled();
    if (participant.getEmail() != null && !sendEmailVerification) {
        // not verifying, so consider it verified
        account.setEmailVerified(true);
    }
    if (participant.getPhone() != null && !shouldSendVerification) {
        // not verifying, so consider it verified
        account.setPhoneVerified(true);
    }
    account.setSynapseUserId(participant.getSynapseUserId());
    // not save if the account is inaccessible after construction.
    if (BridgeUtils.hasValidIdentifier(account)) {
        accountService.createAccount(app, account);
    }
    // send verify email
    if (sendEmailVerification && !app.isAutoVerificationEmailSuppressed()) {
        accountWorkflowService.sendEmailVerificationToken(app, account.getId(), account.getEmail());
    }
    // If you create an account with a phone number, this opts the phone number in to receiving SMS. We do this
    // _before_ phone verification / sign-in, because we need to opt the user in to SMS in order to send phone
    // verification / sign-in.
    Phone phone = account.getPhone();
    if (phone != null) {
        // Note that there is no object with both accountId and phone, so we need to pass them in separately.
        smsService.optInPhoneNumber(account.getId(), phone);
    }
    // send verify phone number
    if (shouldSendVerification && !app.isAutoVerificationPhoneSuppressed()) {
        accountWorkflowService.sendPhoneVerificationToken(app, account.getId(), phone);
    }
    return new IdentifierHolder(account.getId());
}
Also used : Account(org.sagebionetworks.bridge.models.accounts.Account) IdentifierHolder(org.sagebionetworks.bridge.models.accounts.IdentifierHolder) PasswordAlgorithm(org.sagebionetworks.bridge.models.accounts.PasswordAlgorithm) Phone(org.sagebionetworks.bridge.models.accounts.Phone) BridgeServiceException(org.sagebionetworks.bridge.exceptions.BridgeServiceException) StudyParticipantValidator(org.sagebionetworks.bridge.validators.StudyParticipantValidator) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException)

Example 5 with Phone

use of org.sagebionetworks.bridge.models.accounts.Phone in project BridgeServer2 by Sage-Bionetworks.

the class ParticipantController method sendInstallLink.

@PostMapping("/v3/participants/{userId}/sendInstallLink")
@ResponseStatus(HttpStatus.ACCEPTED)
public StatusMessage sendInstallLink(@PathVariable String userId, @RequestParam(required = false) String osName) {
    UserSession session = getAdministrativeSession();
    CAN_EDIT_PARTICIPANTS.checkAndThrow(USER_ID, userId);
    AccountId accountId = BridgeUtils.parseAccountId(session.getAppId(), userId);
    Account account = accountService.getAccount(accountId).orElseThrow(() -> new EntityNotFoundException(Account.class));
    App app = appService.getApp(session.getAppId());
    String email = TRUE.equals(account.getEmailVerified()) ? account.getEmail() : null;
    Phone phone = TRUE.equals(account.getPhoneVerified()) ? account.getPhone() : null;
    participantService.sendInstallLinkMessage(app, PROMOTIONAL, account.getHealthCode(), email, phone, osName);
    return INSTALL_LINK_SEND_MSG;
}
Also used : App(org.sagebionetworks.bridge.models.apps.App) Account(org.sagebionetworks.bridge.models.accounts.Account) AccountId(org.sagebionetworks.bridge.models.accounts.AccountId) Phone(org.sagebionetworks.bridge.models.accounts.Phone) UserSession(org.sagebionetworks.bridge.models.accounts.UserSession) EntityNotFoundException(org.sagebionetworks.bridge.exceptions.EntityNotFoundException) PostMapping(org.springframework.web.bind.annotation.PostMapping) ResponseStatus(org.springframework.web.bind.annotation.ResponseStatus)

Aggregations

Phone (org.sagebionetworks.bridge.models.accounts.Phone)25 Test (org.testng.annotations.Test)14 SignIn (org.sagebionetworks.bridge.models.accounts.SignIn)7 IdentifierUpdate (org.sagebionetworks.bridge.models.accounts.IdentifierUpdate)5 Account (org.sagebionetworks.bridge.models.accounts.Account)4 StudyParticipant (org.sagebionetworks.bridge.models.accounts.StudyParticipant)4 App (org.sagebionetworks.bridge.models.apps.App)4 CacheKey (org.sagebionetworks.bridge.cache.CacheKey)3 BridgeServiceException (org.sagebionetworks.bridge.exceptions.BridgeServiceException)3 DateTimeException (java.time.DateTimeException)2 EntityNotFoundException (org.sagebionetworks.bridge.exceptions.EntityNotFoundException)2 AccountId (org.sagebionetworks.bridge.models.accounts.AccountId)2 UserSession (org.sagebionetworks.bridge.models.accounts.UserSession)2 IntentToParticipate (org.sagebionetworks.bridge.models.itp.IntentToParticipate)2 Contact (org.sagebionetworks.bridge.models.studies.Contact)2 Study (org.sagebionetworks.bridge.models.studies.Study)2 PostMapping (org.springframework.web.bind.annotation.PostMapping)2 ResponseStatus (org.springframework.web.bind.annotation.ResponseStatus)2 PublishResult (com.amazonaws.services.sns.model.PublishResult)1 JsonNode (com.fasterxml.jackson.databind.JsonNode)1