use of io.gravitee.am.gateway.handler.root.service.user.model.ForgotPasswordParameters in project gravitee-access-management by gravitee-io.
the class ForgotPasswordSubmissionEndpoint method handle.
@Override
public void handle(RoutingContext context) {
final String email = context.request().getParam(ConstantKeys.EMAIL_PARAM_KEY);
final String username = context.request().getParam(ConstantKeys.USERNAME_PARAM_KEY);
final Client client = context.get(ConstantKeys.CLIENT_CONTEXT_KEY);
MultiMap queryParams = RequestUtils.getCleanedQueryParams(context.request());
AccountSettings settings = AccountSettings.getInstance(domain, client);
final ForgotPasswordParameters parameters = new ForgotPasswordParameters(email, username, settings != null && settings.isResetPasswordCustomForm(), settings != null && settings.isResetPasswordConfirmIdentity());
userService.forgotPassword(parameters, client, getAuthenticatedUser(context)).subscribe(() -> {
queryParams.set(ConstantKeys.SUCCESS_PARAM_KEY, "forgot_password_completed");
redirectToPage(context, queryParams);
}, error -> {
// the actual error continue to be stored in the audit logs
if (error instanceof UserNotFoundException || error instanceof AccountStatusException) {
queryParams.set(ConstantKeys.SUCCESS_PARAM_KEY, "forgot_password_completed");
redirectToPage(context, queryParams);
} else if (error instanceof EnforceUserIdentityException) {
if (settings.isResetPasswordConfirmIdentity()) {
queryParams.set(ConstantKeys.WARNING_PARAM_KEY, FORGOT_PASSWORD_CONFIRM);
} else {
queryParams.set(ConstantKeys.SUCCESS_PARAM_KEY, "forgot_password_completed");
}
redirectToPage(context, queryParams);
} else {
queryParams.set(ConstantKeys.ERROR_PARAM_KEY, "forgot_password_failed");
redirectToPage(context, queryParams, error);
}
});
}
use of io.gravitee.am.gateway.handler.root.service.user.model.ForgotPasswordParameters in project gravitee-access-management by gravitee-io.
the class UserServiceTest method shouldForgotPassword_MultipleMatch_NoMultiFieldForm.
@Test
public void shouldForgotPassword_MultipleMatch_NoMultiFieldForm() {
Client client = mock(Client.class);
when(client.getId()).thenReturn("client-id");
User user = mock(User.class);
when(user.getUsername()).thenReturn("username");
when(user.isInactive()).thenReturn(false);
when(user.getEmail()).thenReturn("test@test.com");
UserProvider userProvider = mock(UserProvider.class);
when(domain.getId()).thenReturn("domain-id");
when(identityProviderManager.getUserProvider(user.getSource())).thenReturn(Maybe.just(userProvider));
when(commonUserService.findByDomainAndCriteria(eq(domain.getId()), any(FilterCriteria.class))).thenReturn(Single.just(Arrays.asList(user, user)));
when(commonUserService.update(any())).thenReturn(Single.just(user));
when(userProvider.findByUsername("username")).thenReturn(Maybe.just(new DefaultUser("username")));
TestObserver testObserver = userService.forgotPassword(new ForgotPasswordParameters(user.getEmail(), false, false), client, mock(io.gravitee.am.identityprovider.api.User.class)).test();
testObserver.assertComplete();
testObserver.assertNoErrors();
}
use of io.gravitee.am.gateway.handler.root.service.user.model.ForgotPasswordParameters in project gravitee-access-management by gravitee-io.
the class UserServiceTest method shouldNotForgotPassword_MultipleMatch_ConfirmIdentityForm.
@Test
public void shouldNotForgotPassword_MultipleMatch_ConfirmIdentityForm() {
Client client = mock(Client.class);
when(client.getId()).thenReturn("client-id");
User user = mock(User.class);
when(user.getEmail()).thenReturn("test@test.com");
when(domain.getId()).thenReturn("domain-id");
when(commonUserService.findByDomainAndCriteria(eq(domain.getId()), any(FilterCriteria.class))).thenReturn(Single.just(Arrays.asList(user, user)));
TestObserver testObserver = userService.forgotPassword(new ForgotPasswordParameters(user.getEmail(), true, true), client, mock(io.gravitee.am.identityprovider.api.User.class)).test();
testObserver.assertNotComplete();
testObserver.assertError(EnforceUserIdentityException.class);
}
use of io.gravitee.am.gateway.handler.root.service.user.model.ForgotPasswordParameters in project gravitee-access-management by gravitee-io.
the class UserServiceImpl method forgotPassword.
@Override
public Completable forgotPassword(ForgotPasswordParameters params, Client client, io.gravitee.am.identityprovider.api.User principal) {
final String email = params.getEmail();
if (email != null && !emailValidator.validate(email)) {
return Completable.error(new EmailFormatInvalidException(email));
}
return userService.findByDomainAndCriteria(domain.getId(), params.buildCriteria()).flatMap(users -> {
List<User> foundUsers = new ArrayList<>(users);
// narrow users
if (users.size() > 1) {
// filter by identity provider
if (client.getIdentityProviders() != null && !client.getIdentityProviders().isEmpty()) {
foundUsers = users.stream().flatMap(u -> client.getIdentityProviders().stream().map(appIdp -> entry(u, appIdp.getIdentity()))).filter(entry -> {
var user = entry.getKey();
var identity = entry.getValue();
return Objects.equals(user.getSource(), identity);
}).map(Entry::getKey).collect(toList());
}
if (foundUsers.size() > 1) {
// try to filter by latest application used
List<User> filteredSourceUsers = users.stream().filter(u -> u.getClient() == null || client.getId().equals(u.getClient())).collect(toList());
if (!filteredSourceUsers.isEmpty()) {
foundUsers = new ArrayList<>(filteredSourceUsers);
}
}
}
// If multiple results, check if ConfirmIdentity isn't required before returning the first User.
if (foundUsers.size() == 1 || (foundUsers.size() > 1 && !params.isConfirmIdentityEnabled())) {
User user = foundUsers.get(0);
// check if user can update its password according to its identity provider type
return identityProviderManager.getUserProvider(user.getSource()).switchIfEmpty(Single.error(new UserInvalidException("User [ " + user.getUsername() + " ] cannot be updated because its identity provider does not support user provisioning"))).flatMap(userProvider -> {
// if user registration is not completed and force registration option is disabled throw invalid account exception
if (user.isInactive() && !forceUserRegistration(domain, client)) {
return Single.error(new AccountInactiveException("User [ " + user.getUsername() + " ] needs to complete the activation process"));
}
// fetch latest information from the identity provider and return the user
return userProvider.findByUsername(user.getUsername()).map(Optional::ofNullable).defaultIfEmpty(Optional.empty()).flatMapSingle(optUser -> {
if (optUser.isEmpty()) {
return Single.just(user);
}
return userService.update(enhanceUser(user, optUser.get()));
});
});
}
if (foundUsers.size() > 1) {
throw new EnforceUserIdentityException();
}
// fallback to registered user providers if user has never been authenticated
if (client.getIdentityProviders() == null || client.getIdentityProviders().isEmpty()) {
return Single.error(new UserNotFoundException(email));
}
if (Strings.isNullOrEmpty(params.getEmail()) & StringUtils.isEmpty(params.getUsername())) {
// no user found using criteria. email & username are missing, unable to search the user through UserProvider
return Single.error(new UserNotFoundException(email));
}
// email used in priority for backward compatibility
return Observable.fromIterable(client.getIdentityProviders()).flatMapMaybe(authProvider -> identityProviderManager.getUserProvider(authProvider.getIdentity()).flatMap(userProvider -> {
final String username = params.getUsername();
final Maybe<io.gravitee.am.identityprovider.api.User> findQuery = Strings.isNullOrEmpty(email) ? userProvider.findByUsername(username) : userProvider.findByEmail(email);
return findQuery.map(user -> Optional.of(new UserAuthentication(user, authProvider.getIdentity()))).defaultIfEmpty(Optional.empty()).onErrorReturnItem(Optional.empty());
}).defaultIfEmpty(Optional.empty())).takeUntil((Predicate<? super Optional<UserAuthentication>>) Optional::isPresent).lastOrError().flatMap(optional -> {
// be sure to not duplicate an existing user
if (optional.isEmpty()) {
return Single.error(new UserNotFoundException());
}
final UserAuthentication idpUser = optional.get();
return userService.findByDomainAndUsernameAndSource(domain.getId(), idpUser.getUser().getUsername(), idpUser.getSource()).switchIfEmpty(Maybe.defer(() -> userService.findByDomainAndExternalIdAndSource(domain.getId(), idpUser.getUser().getId(), idpUser.getSource()))).map(Optional::ofNullable).defaultIfEmpty(Optional.empty()).flatMapSingle(optEndUser -> {
if (optEndUser.isEmpty()) {
return userService.create(convert(idpUser.getUser(), idpUser.getSource()));
}
return userService.update(enhanceUser(optEndUser.get(), idpUser.getUser()));
});
}).onErrorResumeNext(Single.error(new UserNotFoundException(email != null ? email : params.getUsername())));
}).doOnSuccess(user -> new Thread(() -> emailService.send(Template.RESET_PASSWORD, user, client)).start()).doOnSuccess(user1 -> {
// reload principal
io.gravitee.am.identityprovider.api.User principal1 = reloadPrincipal(principal, user1);
auditService.report(AuditBuilder.builder(UserAuditBuilder.class).domain(domain.getId()).client(client).principal(principal1).type(EventType.FORGOT_PASSWORD_REQUESTED));
}).doOnError(throwable -> auditService.report(AuditBuilder.builder(UserAuditBuilder.class).domain(domain.getId()).client(client).principal(principal).type(EventType.FORGOT_PASSWORD_REQUESTED).throwable(throwable))).ignoreElement();
}
Aggregations