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");
}
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());
}
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;
}
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());
}
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;
}
Aggregations