Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit 119394ea authored by Joze RIHTARSIC's avatar Joze RIHTARSIC
Browse files

[EDELIVERY-13839] fix redirection on invalid reset password

parent a2002feb
Branches bugfix/EDELIVERY-13839-rest-error-fix-redirection
No related tags found
No related merge requests found
Pipeline #208277 failed
Showing
with 71 additions and 28 deletions
/**
* The used SMP error codes in the application. The SMP can send different error codes in the repponse,
* but the application only uses a subset of them.
*
* @since 5.1
* @author Joze RIHTARSIC
*/
export enum SmpErrorCode {
ERROR_CODE_INVALID_NEW_PASSWORD = 'SMP:010',
}
......@@ -15,6 +15,7 @@ import {MatDialog} from "@angular/material/dialog";
import {Router} from "@angular/router";
import {TranslateService} from "@ngx-translate/core";
import {WindowSpinnerService} from "../common/services/window-spinner.service";
import {SmpErrorCode} from "../common/enums/smp-error-code.enum";
@Injectable()
export class SecurityService {
......@@ -122,7 +123,11 @@ export class SecurityService {
}, // completeHandler
error: (error: any) => {
this.windowSpinnerService.showSpinner = false;
this.router.navigate(['/login']);
// if the error is not related to the password, we redirect to the login page
console
if (error.error?.errorCode !== SmpErrorCode.ERROR_CODE_INVALID_NEW_PASSWORD) {
this.router.navigate(['/login']);
}
this.alertService.error(error);
}, // errorHandler
next: async () => {
......@@ -194,13 +199,15 @@ export class SecurityService {
let subject = new ReplaySubject<boolean>();
if (callServer) {
//we get the username from the server to trigger the redirection to the login screen in case the user is not authenticated
this.getCurrentUsernameFromServer().subscribe((user: User) => {
if (!user) {
this.clearLocalStorage();
this.getCurrentUsernameFromServer().subscribe({
next: (user: User) => {
if (!user) {
this.clearLocalStorage();
}
subject.next(user !== null);
}, error: (user: any) => {
subject.next(false);
}
subject.next(user !== null);
}, (user: string) => {
subject.next(false);
});
} else {
......
......@@ -28,6 +28,7 @@ import java.util.Objects;
*/
public class ErrorResponseRO {
protected String businessCode;
protected String errorCode;
protected String errorDescription;
protected String errorUniqueId;
......@@ -67,6 +68,13 @@ public class ErrorResponseRO {
this.errorDescription = value;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorUniqueId() {
return errorUniqueId;
......
......@@ -34,6 +34,9 @@ public enum ErrorCode {
UNAUTHORIZED_INVALID_IDENTIFIER(401, "SMP:005",ErrorBusinessCode.UNAUTHORIZED, "Invalid entity identifier! User not authorized to access the entity data"),
UNAUTHORIZED_INVALID_RESET_TOKEN(401, "SMP:006",ErrorBusinessCode.UNAUTHORIZED, "The reset token it is invalid or not active any more. Please try to reset your password again."),
USER_CHANGE_INVALID_NEW_CREDENTIAL(400, "SMP:010",ErrorBusinessCode.INVALID_INPUT_DATA, "Password change failed. %s"),
INVALID_ENCODING (500, "SMP:100",ErrorBusinessCode.TECHNICAL, "Unsupported or invalid encoding for %s!"),
SML_INVALID_IDENTIFIER (400,"SMP:101",ErrorBusinessCode.FORMAT_ERROR,"Malformed identifier, scheme and id should be delimited by double colon: %s "),
......@@ -78,6 +81,7 @@ public enum ErrorCode {
// SML integration
SML_INTEGRATION_EXCEPTION (500,"SMP:150",ErrorBusinessCode.TECHNICAL,"SML integration error! Error: %s "),
XML_SIGNING_EXCEPTION (500,"SMP:500",ErrorBusinessCode.TECHNICAL,"Error occurred while signing response!"),
INTERNAL_ERROR_GENERIC (500,"SMP:501",ErrorBusinessCode.TECHNICAL, "Internal error!"),
JAXB_INITIALIZATION (500,"SMP:511",ErrorBusinessCode.TECHNICAL, "Could not create Unmarshaller for class [%s]!"),
XML_PARSE_EXCEPTION (500,"SMP:512",ErrorBusinessCode.TECHNICAL, "Error occurred while parsing input stream for [%s]. Error: %s!"),
INVALID_REQUEST(400,"SMP:513",ErrorBusinessCode.TECHNICAL, "Invalid request [%s]. Error: %s!"),
......
......@@ -366,23 +366,24 @@ public class CredentialService {
// retrieve user Optional credentials by username
Optional<DBCredential> optCredential = getActiveCredentialsForUsernameToReset(username, false);
if (!optCredential.isPresent()) {
LOG.warn("User [{}] does not have active reset token!", username);
throw UNAUTHORIZED_INVALID_RESET_TOKEN;
}
DBCredential dbCredential = optCredential.get();
if (!resetToken.equals(dbCredential.getResetToken())) {
LOG.warn("User [{}] reset token does not match the active reset token! The request is ignored", username);
return;
LOG.warn("User [{}] reset token does not match the active reset token!", username);
throw UNAUTHORIZED_INVALID_RESET_TOKEN;
}
Pattern pattern = configurationService.getPasswordPolicyRexExp();
if (pattern != null && !pattern.matcher(newPassword).matches()) {
LOG.info(SMPLogger.SECURITY_MARKER, "Change/set password failed because it does not match password policy!: [{}]", username);
throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "PasswordChange", configurationService.getPasswordPolicyValidationMessage());
throw new SMPRuntimeException(ErrorCode.USER_CHANGE_INVALID_NEW_CREDENTIAL, configurationService.getPasswordPolicyValidationMessage());
}
if (StringUtils.isNotBlank(dbCredential.getValue()) && BCrypt.checkpw(newPassword, dbCredential.getValue())) {
LOG.info(SMPLogger.SECURITY_MARKER, "Change/set password failed because 'new' password match the old password for user: [{}]", username);
throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "PasswordChange", configurationService.getPasswordPolicyValidationMessage());
throw new SMPRuntimeException(ErrorCode.USER_CHANGE_INVALID_NEW_CREDENTIAL, configurationService.getPasswordPolicyValidationMessage());
}
OffsetDateTime now = OffsetDateTime.now();
......
......@@ -114,7 +114,6 @@ public class SMPAuthenticationService {
credentialService.delayResponse(CredentialType.USERNAME_PASSWORD, startTime);
throw e;
}
credentialService.validatePasswordResetToken(resetToken);
}
public void logout(HttpServletRequest request, HttpServletResponse response) {
......
......@@ -21,9 +21,9 @@ package eu.europa.ec.edelivery.smp.error;
import eu.europa.ec.dynamicdiscovery.exception.MalformedIdentifierException;
import eu.europa.ec.edelivery.smp.data.ui.exceptions.ErrorResponseRO;
import eu.europa.ec.edelivery.smp.error.exceptions.SMPResponseStatusException;
import eu.europa.ec.edelivery.smp.exceptions.BadRequestException;
import eu.europa.ec.edelivery.smp.exceptions.ErrorBusinessCode;
import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -43,10 +43,7 @@ abstract class AbstractErrorControllerAdvice {
ResponseEntity response;
if (runtimeException instanceof SMPRuntimeException) {
SMPRuntimeException ex = (SMPRuntimeException)runtimeException;
response = buildAndLog(HttpStatus.resolve(ex.getErrorCode().getHttpCode()), ex.getErrorCode().getErrorBusinessCode(), ex.getMessage(), ex);
} else if (runtimeException instanceof SMPResponseStatusException ){
SMPResponseStatusException ex = (SMPResponseStatusException)runtimeException;
response = buildAndLog(ex.getStatus(), ex.getErrorBusinessCode(), ex.getMessage(), ex);
response = buildAndLog(HttpStatus.resolve(ex.getErrorCode().getHttpCode()), ex.getErrorCode(), ex.getMessage(), ex);
} else if (runtimeException instanceof AuthenticationException ){
AuthenticationException ex = (AuthenticationException)runtimeException;
response = buildAndLog(UNAUTHORIZED, ErrorBusinessCode.UNAUTHORIZED, ex.getMessage(), ex);
......@@ -66,7 +63,7 @@ abstract class AbstractErrorControllerAdvice {
}
String errorCodeId = response.getBody() instanceof ErrorResponseRO?
String errorCodeId = response.getBody()!=null && response.getBody() instanceof ErrorResponseRO?
((ErrorResponseRO) response.getBody()).getErrorUniqueId(): null;
......@@ -74,5 +71,16 @@ abstract class AbstractErrorControllerAdvice {
return response;
}
abstract ResponseEntity buildAndLog(HttpStatus status, ErrorBusinessCode businessCode, String msg, Exception exception);
ResponseEntity buildAndLog(HttpStatus status, ErrorBusinessCode businessCode, String msg, Exception exception) {
return buildAndLog(status, ErrorCode.INTERNAL_ERROR_GENERIC, businessCode, msg, exception);
}
ResponseEntity buildAndLog(HttpStatus status, ErrorCode errorCode, String msg, Exception exception) {
return buildAndLog(status, errorCode, errorCode.getErrorBusinessCode(), msg, exception);
}
abstract ResponseEntity buildAndLog(HttpStatus status, ErrorCode errorCode,
ErrorBusinessCode businessCode,
String msg, Exception exception);
}
......@@ -24,6 +24,7 @@ package eu.europa.ec.edelivery.smp.error;
import eu.europa.ec.edelivery.smp.data.ui.exceptions.ErrorResponseRO;
import eu.europa.ec.edelivery.smp.error.xml.ErrorResponse;
import eu.europa.ec.edelivery.smp.exceptions.ErrorBusinessCode;
import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
......@@ -42,11 +43,10 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
*/
public class ErrorResponseBuilder {
private static final Logger LOG = LoggerFactory.getLogger(ErrorResponseBuilder.class);
public static final MediaType CONTENT_TYPE_TEXT_XML_UTF8 = MediaType.valueOf("text/xml; charset=UTF-8");
private HttpStatus status = INTERNAL_SERVER_ERROR;
private ErrorBusinessCode errorBusinessCode = TECHNICAL;
private ErrorCode errorCode = ErrorCode.INTERNAL_ERROR_GENERIC;
private String strErrorDescription = "Unexpected technical error occurred.";
private static String getErrorUniqueId() {
......@@ -78,6 +78,7 @@ public class ErrorResponseBuilder {
public ErrorResponseRO buildJSonBody() {
ErrorResponseRO err = new ErrorResponseRO();
err.setBusinessCode(errorBusinessCode.name());
err.setErrorCode(errorCode.getErrorCode());
err.setErrorDescription(strErrorDescription);
err.setErrorUniqueId(getErrorUniqueId());
return err;
......@@ -88,6 +89,11 @@ public class ErrorResponseBuilder {
return this;
}
public ErrorResponseBuilder errorCode(ErrorCode errorCode) {
this.errorCode = errorCode;
return this;
}
public ErrorResponseBuilder errorDescription(String newErrorDescription) {
this.strErrorDescription = newErrorDescription;
return this;
......
......@@ -19,10 +19,10 @@
package eu.europa.ec.edelivery.smp.error;
import eu.europa.ec.edelivery.smp.error.exceptions.SMPResponseStatusException;
import eu.europa.ec.edelivery.smp.error.xml.ErrorResponse;
import eu.europa.ec.edelivery.smp.exceptions.BadRequestException;
import eu.europa.ec.edelivery.smp.exceptions.ErrorBusinessCode;
import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
......@@ -44,7 +44,7 @@ import static org.springframework.http.HttpStatus.UNAUTHORIZED;
public class ServiceErrorControllerAdvice extends AbstractErrorControllerAdvice {
@Override
@ExceptionHandler({RuntimeException.class, SMPRuntimeException.class, SMPResponseStatusException.class, AuthenticationException.class,})
@ExceptionHandler({RuntimeException.class, SMPRuntimeException.class, AuthenticationException.class,})
public ResponseEntity handleRuntimeException(RuntimeException ex) {
return super.handleRuntimeException(ex);
}
......@@ -64,16 +64,16 @@ public class ServiceErrorControllerAdvice extends AbstractErrorControllerAdvice
return buildAndLog(UNAUTHORIZED, ErrorBusinessCode.UNAUTHORIZED, ex.getMessage() + " - Only SMP Admin or owner of given ServiceGroup is allowed to perform this action", ex);
}
ResponseEntity buildAndLog(HttpStatus status, ErrorBusinessCode businessCode, String msg, Exception exception) {
ResponseEntity buildAndLog(HttpStatus status, ErrorCode errorCode, ErrorBusinessCode businessCode, String msg, Exception exception) {
ResponseEntity response = ErrorResponseBuilder.status(status)
.businessCode(businessCode)
.errorCode(errorCode)
.errorDescription(msg)
.build();
String errorUniqueId = ((ErrorResponse) response.getBody()).getErrorUniqueId();
String logMsg = errorUniqueId == null ? "Null Error ID" : format("UI Error unique ID: %s", errorUniqueId);
LOG.warn(logMsg, exception);
return response;
}
......
......@@ -19,9 +19,9 @@
package eu.europa.ec.edelivery.smp.error;
import eu.europa.ec.edelivery.smp.data.ui.exceptions.ErrorResponseRO;
import eu.europa.ec.edelivery.smp.error.exceptions.SMPResponseStatusException;
import eu.europa.ec.edelivery.smp.exceptions.BadRequestException;
import eu.europa.ec.edelivery.smp.exceptions.ErrorBusinessCode;
import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
......@@ -47,17 +47,17 @@ public class UIErrorControllerAdvice extends AbstractErrorControllerAdvice {
@ExceptionHandler({BadCredentialsException.class,
RuntimeException.class,
SMPRuntimeException.class,
SMPResponseStatusException.class,
AuthenticationException.class,
BadRequestException.class})
public ResponseEntity handleRuntimeException(RuntimeException ex) {
return super.handleRuntimeException(ex);
}
ResponseEntity buildAndLog(HttpStatus status, ErrorBusinessCode businessCode, String msg, Exception exception) {
protected ResponseEntity buildAndLog(HttpStatus status, ErrorCode errorCode, ErrorBusinessCode businessCode, String msg, Exception exception) {
ResponseEntity response = ErrorResponseBuilder.status(status)
.businessCode(businessCode)
.errorCode(errorCode)
.errorDescription(msg)
.buildJSon();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment