[Fix] Allow user to retry password reset if failed password strength
This commit is contained in:
parent
cace8c5156
commit
9334136c25
|
@ -0,0 +1,7 @@
|
|||
package li.strolch.privilege.base;
|
||||
|
||||
public class PasswordStrengthException extends PrivilegeException {
|
||||
public PasswordStrengthException(String string) {
|
||||
super(string);
|
||||
}
|
||||
}
|
|
@ -1882,9 +1882,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void validatePassword(Locale locale, char[] password) throws PrivilegeException {
|
||||
public void validatePassword(Locale locale, char[] password) throws PasswordStrengthException {
|
||||
if (!this.passwordStrengthHandler.validateStrength(password))
|
||||
throw new PrivilegeException(this.passwordStrengthHandler.getDescription(locale));
|
||||
throw new PasswordStrengthException(this.passwordStrengthHandler.getDescription(locale));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,10 +19,7 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.NotAuthenticatedException;
|
||||
import li.strolch.privilege.base.PrivilegeConflictResolution;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.base.*;
|
||||
import li.strolch.privilege.model.*;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
|
@ -40,8 +37,8 @@ public interface PrivilegeHandler {
|
|||
///
|
||||
|
||||
/**
|
||||
* Privilege "PrivilegeAction" which is used for privileges which are not further categorized e.g. s {@link
|
||||
* #PRIVILEGE_ACTION_PERSIST} and {@link #PRIVILEGE_ACTION_GET_POLICIES}
|
||||
* Privilege "PrivilegeAction" which is used for privileges which are not further categorized e.g. s
|
||||
* {@link #PRIVILEGE_ACTION_PERSIST} and {@link #PRIVILEGE_ACTION_GET_POLICIES}
|
||||
*/
|
||||
String PRIVILEGE_ACTION = "PrivilegeAction";
|
||||
|
||||
|
@ -360,7 +357,7 @@ public interface PrivilegeHandler {
|
|||
*
|
||||
* <p>
|
||||
* If the password given is null, then the user is created, but can not not login! Otherwise the password must meet
|
||||
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(char[])}
|
||||
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(Locale, char[])}
|
||||
* </p>
|
||||
*
|
||||
* @param certificate
|
||||
|
@ -369,7 +366,7 @@ public interface PrivilegeHandler {
|
|||
* the {@link UserRep} containing the information to create the new {@link User}
|
||||
* @param password
|
||||
* the password of the new user. If the password is null, then this is accepted but the user can not login,
|
||||
* otherwise the password must be validated against {@link PrivilegeHandler#validatePassword(char[])}
|
||||
* otherwise the password must be validated against {@link PrivilegeHandler#validatePassword(Locale, char[])}
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
* if the user for this certificate may not perform the action
|
||||
|
@ -386,8 +383,6 @@ public interface PrivilegeHandler {
|
|||
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||
* @param userReps
|
||||
* the list of users to add or update
|
||||
*
|
||||
* @throws PrivilegeException
|
||||
*/
|
||||
void addOrUpdateUsers(Certificate certificate, List<UserRep> userReps) throws PrivilegeException;
|
||||
|
||||
|
@ -397,7 +392,7 @@ public interface PrivilegeHandler {
|
|||
* will be updated on the existing user. The username on the given {@link UserRep} must be set and correspond to an
|
||||
* existing user.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following fields are considered updateable:
|
||||
* <ul>
|
||||
* <li>{@link UserRep#getFirstname()}</li>
|
||||
|
@ -429,7 +424,7 @@ public interface PrivilegeHandler {
|
|||
*
|
||||
* <p>
|
||||
* If the password given is null, then the user is created, but can not not login! Otherwise the password must meet
|
||||
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(char[])}
|
||||
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(Locale, char[])}
|
||||
* </p>
|
||||
*
|
||||
* @param certificate
|
||||
|
@ -438,7 +433,7 @@ public interface PrivilegeHandler {
|
|||
* the {@link UserRep} containing the information to replace the existing {@link User}
|
||||
* @param password
|
||||
* the password of the new user. If the password is null, then this is accepted but the user can not login,
|
||||
* otherwise the password must be validated against {@link PrivilegeHandler#validatePassword(char[])}
|
||||
* otherwise the password must be validated against {@link PrivilegeHandler#validatePassword(Locale, char[])}
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
* if the user for this certificate may not perform the action
|
||||
|
@ -515,8 +510,8 @@ public interface PrivilegeHandler {
|
|||
/**
|
||||
* <p>
|
||||
* Changes the password for the {@link User} with the given username. If the password is null, then the {@link User}
|
||||
* can not login anymore. Otherwise the password must meet the requirements of the implementation under {@link
|
||||
* PrivilegeHandler#validatePassword(char[])}
|
||||
* can not login anymore. Otherwise the password must meet the requirements of the implementation under
|
||||
* {@link PrivilegeHandler#validatePassword(Locale, char[])}
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
|
@ -529,7 +524,8 @@ public interface PrivilegeHandler {
|
|||
* the username of the {@link User} for which the password is to be changed
|
||||
* @param password
|
||||
* the new password for this user. If the password is null, then the {@link User} can not login anymore. Otherwise
|
||||
* the password must meet the requirements of the implementation under {@link PrivilegeHandler#validatePassword(char[])}
|
||||
* the password must meet the requirements of the implementation under
|
||||
* {@link PrivilegeHandler#validatePassword(Locale, char[])}
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
* if the user for this certificate may not perform the action
|
||||
|
@ -653,7 +649,7 @@ public interface PrivilegeHandler {
|
|||
* the username of the {@link User} which is registered in the {@link PersistenceHandler}
|
||||
* @param password
|
||||
* the password with which this user is to be authenticated. Null passwords are not accepted and they must meet
|
||||
* the requirements of the {@link #validatePassword(char[])}-method
|
||||
* the requirements of the {@link #validatePassword(Locale, char[])}-method
|
||||
* @param keepAlive
|
||||
* should this session be kept alive
|
||||
*
|
||||
|
@ -672,7 +668,7 @@ public interface PrivilegeHandler {
|
|||
* the username of the {@link User} which is registered in the {@link PersistenceHandler}
|
||||
* @param password
|
||||
* the password with which this user is to be authenticated. Null passwords are not accepted and they must meet
|
||||
* the requirements of the {@link #validatePassword(char[])}-method
|
||||
* the requirements of the {@link #validatePassword(Locale, char[])}-method
|
||||
* @param source
|
||||
* the source of the authentication request, i.e. remote IP
|
||||
* @param usage
|
||||
|
@ -763,7 +759,7 @@ public interface PrivilegeHandler {
|
|||
/**
|
||||
* Checks if the given {@link Certificate} is valid. This means that the certificate is for a valid session and that
|
||||
* the user exists for the certificate. This method checks if the {@link Certificate} has been tampered with
|
||||
*
|
||||
* <p>
|
||||
* Returns the {@link PrivilegeContext} for the given {@link Certificate}. The {@link PrivilegeContext} is an
|
||||
* encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their
|
||||
* actions and do not need to access the {@link PrivilegeHandler} anymore
|
||||
|
@ -798,7 +794,7 @@ public interface PrivilegeHandler {
|
|||
/**
|
||||
* Checks if the given {@link Certificate} is valid. This means that the certificate is for a valid session and that
|
||||
* the user exists for the certificate. This method checks if the {@link Certificate} has been tampered with
|
||||
*
|
||||
* <p>
|
||||
* Returns the {@link PrivilegeContext} for the given {@link Certificate}. The {@link PrivilegeContext} is an
|
||||
* encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their
|
||||
* actions and do not need to access the {@link PrivilegeHandler} anymore
|
||||
|
@ -820,7 +816,7 @@ public interface PrivilegeHandler {
|
|||
/**
|
||||
* @see li.strolch.privilege.handler.PasswordStrengthHandler#validateStrength(char[])
|
||||
*/
|
||||
void validatePassword(Locale locale, char[] password) throws PrivilegeException;
|
||||
void validatePassword(Locale locale, char[] password) throws PasswordStrengthException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -908,9 +904,9 @@ public interface PrivilegeHandler {
|
|||
|
||||
/**
|
||||
* Special method to open a {@link PrivilegeContext} as a System user, meaning the given systemUsername corresponds
|
||||
* to an account which has the state {@link UserState#SYSTEM}. This is used in cases where a system user's {@link
|
||||
* PrivilegeContext} should be open for a longer period of time, or where opening many {@link PrivilegeContext} is
|
||||
* resource intensive e.g. on low power devices.
|
||||
* to an account which has the state {@link UserState#SYSTEM}. This is used in cases where a system user's
|
||||
* {@link PrivilegeContext} should be open for a longer period of time, or where opening many
|
||||
* {@link PrivilegeContext} is resource intensive e.g. on low power devices.
|
||||
*
|
||||
* @param systemUsername
|
||||
* the username of the system user to perform the action as
|
||||
|
|
|
@ -15,17 +15,13 @@
|
|||
*/
|
||||
package li.strolch.rest.endpoint;
|
||||
|
||||
import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE;
|
||||
import static java.util.Comparator.comparing;
|
||||
import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_GET_USER;
|
||||
import static li.strolch.rest.helper.ResponseUtil.toResponse;
|
||||
import static li.strolch.rest.helper.RestfulHelper.toJson;
|
||||
import static li.strolch.search.SearchBuilder.buildSimpleValueSearch;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
@ -33,11 +29,17 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
import com.google.gson.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.model.Tags;
|
||||
import li.strolch.model.json.PrivilegeElementFromJsonVisitor;
|
||||
import li.strolch.model.json.PrivilegeElementToJsonVisitor;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.privilege.base.PasswordStrengthException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.UserRep;
|
||||
|
@ -312,8 +314,11 @@ public class PrivilegeUsersService {
|
|||
arg.password = passwordString.toCharArray();
|
||||
|
||||
ServiceResult svcResult = svcHandler.doService(cert, svc, arg);
|
||||
if (svcResult.isNok())
|
||||
if (svcResult.isNok()) {
|
||||
if (svcResult.getRootCause() instanceof PasswordStrengthException)
|
||||
return toResponse(NOT_ACCEPTABLE, svcResult.getRootCause());
|
||||
return toResponse(svcResult);
|
||||
}
|
||||
|
||||
// if user changes their own password, then invalidate the session
|
||||
if (cert.getUsername().equals(username)) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import static li.strolch.rest.StrolchRestfulConstants.STROLCH_CERTIFICATE;
|
|||
import jakarta.ws.rs.container.ContainerRequestContext;
|
||||
import jakarta.ws.rs.container.ContainerResponseContext;
|
||||
import jakarta.ws.rs.container.ContainerResponseFilter;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
|
@ -47,8 +48,11 @@ public class AuthenticationResponseFilter implements ContainerResponseFilter {
|
|||
logger.info("Invalidating single usage certificate for " + cert.getUsername());
|
||||
RestfulStrolchComponent.getInstance().getSessionHandler().invalidate(cert);
|
||||
} else if (cert.getUsage().isSetPassword()) {
|
||||
logger.info("Invalidating SET_PASSWORD usage certificate for " + cert.getUsername());
|
||||
RestfulStrolchComponent.getInstance().getSessionHandler().invalidate(cert);
|
||||
// if not acceptable, then user can try again
|
||||
if (responseContext.getStatusInfo().toEnum() != Response.Status.NOT_ACCEPTABLE) {
|
||||
logger.info("Invalidating SET_PASSWORD usage certificate for " + cert.getUsername());
|
||||
RestfulStrolchComponent.getInstance().getSessionHandler().invalidate(cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue