diff --git a/smp-angular/src/app/login/login.component.ts b/smp-angular/src/app/login/login.component.ts index 1fc24581a74e5bef5162b4fce29cefcf9b71ca73..89dbdd050ce150741c7470d4d3bc117eb23b241a 100644 --- a/smp-angular/src/app/login/login.component.ts +++ b/smp-angular/src/app/login/login.component.ts @@ -54,20 +54,19 @@ export class LoginComponent implements OnInit, OnDestroy { const HTTP_NOTFOUND = 404; const HTTP_GATEWAY_TIMEOUT = 504; const USER_INACTIVE = 'Inactive'; - const USER_SUSPENDED = 'Suspended'; switch (error.status) { case HTTP_UNAUTHORIZED: + message =error.error.errorDescription; + this.model.password = ''; + break; case HTTP_FORBIDDEN: const forbiddenCode = error.message; switch (forbiddenCode) { case USER_INACTIVE: message = 'The user is inactive. Please contact your administrator.'; break; - case USER_SUSPENDED: - message = 'The user is suspended. Please try again later or contact your administrator.'; - break; default: - message = 'The username/password combination you provided are not valid. Please try again or contact your administrator.'; + message = error.status + ' The username/password combination you provided are not valid. Please try again or contact your administrator.'; // clear the password this.model.password = ''; break; diff --git a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html index e94bdf35d04587be74db60faaf75b1f6e0011ba1..4750a3c659fbb82e93aa63513c38725ea0ce1c7b 100644 --- a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html +++ b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html @@ -64,7 +64,7 @@ </mat-expansion-panel-header> <mat-selection-list #usersSelected [disabled]="!securityService.isCurrentUserSMPAdmin()" - [compareWith]="compareTableItemById" + [compareWith]="compareUserByUserId" [formControl]="dialogForm.controls['users']" style="height: 200px; overflow-y: scroll; overflow-x: auto;"> <!-- // if username is null then there must be an cerificate id! --> diff --git a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts index 3e85e6702d0e230308360bfab5c35495c4bb4a75..1c18a51a82c174926b864f6525dc59b423f38214 100644 --- a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts +++ b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts @@ -228,12 +228,12 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { } - compareTableItemById(item1, item2): boolean { - return item1.id === item2.id; + compareUserByUserId(item1, item2): boolean { + return item1.userId === item2.userId; } compareDomain(domain: DomainRo, serviceGroupDomain: ServiceGroupDomainEditRo): boolean { - return domain.id === serviceGroupDomain.domainId; + return domain.domainCode === serviceGroupDomain.domainCode; } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java index ebffa082cab5a8b697a77c27141645f742bd0b7a..99d9eaf09c6c1efae4ca283cd61d0c388fe7cfa8 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java @@ -33,7 +33,7 @@ import java.util.Objects; }) @NamedNativeQueries({ @NamedNativeQuery(name = "DBUserDeleteValidation.validateUsersForOwnership", - resultSetMapping="DBUserDeleteValidationMapping", + resultSetMapping = "DBUserDeleteValidationMapping", query = "SELECT S.ID as ID, S.USERNAME as USERNAME, " + " C.CERTIFICATE_ID as certificateId, COUNT(S.ID) as ownedCount FROM " + " SMP_USER S LEFT JOIN SMP_CERTIFICATE C ON (S.ID=C.ID) " + @@ -41,19 +41,19 @@ import java.util.Objects; " WHERE S.ID IN (:idList)" + " GROUP BY S.ID, S.USERNAME, C.CERTIFICATE_ID"), }) -@SqlResultSetMapping(name="DBUserDeleteValidationMapping", classes = { +@SqlResultSetMapping(name = "DBUserDeleteValidationMapping", classes = { @ConstructorResult(targetClass = DBUserDeleteValidation.class, - columns = {@ColumnResult(name="id" , type=Long.class), - @ColumnResult(name="username",type=String.class), - @ColumnResult(name="certificateId",type=String.class), - @ColumnResult(name="ownedCount",type=Integer.class)}) + columns = {@ColumnResult(name = "id", type = Long.class), + @ColumnResult(name = "username", type = String.class), + @ColumnResult(name = "certificateId", type = String.class), + @ColumnResult(name = "ownedCount", type = Integer.class)}) }) public class DBUser extends BaseEntity { @Id - @SequenceGenerator(name = "usr_generator", sequenceName = "SMP_USER_SEQ",allocationSize = 1 ) - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usr_generator" ) + @SequenceGenerator(name = "usr_generator", sequenceName = "SMP_USER_SEQ", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usr_generator") @Column(name = "ID") @ColumnDescription(comment = "Unique user id") Long id; @@ -62,7 +62,7 @@ public class DBUser extends BaseEntity { @ColumnDescription(comment = "User email") private String emailAddress; // username - @Column(name = "USERNAME", length = CommonColumnsLengths.MAX_USERNAME_LENGTH, unique = true, nullable = false) + @Column(name = "USERNAME", length = CommonColumnsLengths.MAX_USERNAME_LENGTH, unique = true, nullable = false) @ColumnDescription(comment = "Unique username identifier. The Username must not be null") private String username; @Column(name = "PASSWORD", length = CommonColumnsLengths.MAX_PASSWORD_LENGTH) @@ -71,12 +71,17 @@ public class DBUser extends BaseEntity { @Column(name = "PASSWORD_CHANGED") @ColumnDescription(comment = "Last date when password was changed") LocalDateTime passwordChanged; - @Column(name = "PASSWORD_EXPIRE_ON") @ColumnDescription(comment = "Date when password will expire") LocalDateTime passwordExpireOn; - - // Personal access token + @Column(name = "LOGIN_FAILURE_COUNT") + @ColumnDescription(comment = "Sequential login failure count") + Integer sequentialLoginFailureCount; + @Column(name = "LAST_FAILED_LOGIN_ON") + @ColumnDescription(comment = "Last failed login attempt") + LocalDateTime lastFailedLoginAttempt; + + // Personal access token @Column(name = "ACCESS_TOKEN_ID", length = CommonColumnsLengths.MAX_USERNAME_LENGTH, unique = true) @ColumnDescription(comment = "Personal access token id") private String accessTokenIdentifier; @@ -86,12 +91,15 @@ public class DBUser extends BaseEntity { @Column(name = "ACCESS_TOKEN_GENERATED_ON") @ColumnDescription(comment = "Date when personal access token was generated") LocalDateTime accessTokenGeneratedOn; - @Column(name = "ACCESS_TOKEN_EXPIRE_ON") @ColumnDescription(comment = "Date when personal access token will expire") LocalDateTime accessTokenExpireOn; - - + @Column(name = "AT_LOGIN_FAILURE_COUNT") + @ColumnDescription(comment = "Sequential token login failure count") + Integer sequentialTokenLoginFailureCount; + @Column(name = "AT_LAST_FAILED_LOGIN_ON") + @ColumnDescription(comment = "Last failed token login attempt") + LocalDateTime lastTokenFailedLoginAttempt; @Column(name = "ACTIVE", nullable = false) @ColumnDescription(comment = "Is user active") @@ -105,7 +113,7 @@ public class DBUser extends BaseEntity { orphanRemoval = true) private DBCertificate certificate; - @Column(name = "CREATED_ON" , nullable = false) + @Column(name = "CREATED_ON", nullable = false) LocalDateTime createdOn; @Column(name = "LAST_UPDATED_ON", nullable = false) LocalDateTime lastUpdatedOn; @@ -146,6 +154,22 @@ public class DBUser extends BaseEntity { this.active = active; } + public LocalDateTime getLastFailedLoginAttempt() { + return lastFailedLoginAttempt; + } + + public void setLastFailedLoginAttempt(LocalDateTime lastFailedLoginAttempt) { + this.lastFailedLoginAttempt = lastFailedLoginAttempt; + } + + public LocalDateTime getLastTokenFailedLoginAttempt() { + return lastTokenFailedLoginAttempt; + } + + public void setLastTokenFailedLoginAttempt(LocalDateTime lastTokenFailedLoginAttempt) { + this.lastTokenFailedLoginAttempt = lastTokenFailedLoginAttempt; + } + public String getAccessTokenIdentifier() { return accessTokenIdentifier; } @@ -186,6 +210,22 @@ public class DBUser extends BaseEntity { this.accessTokenExpireOn = accessTokenExpireOn; } + public Integer getSequentialLoginFailureCount() { + return sequentialLoginFailureCount; + } + + public void setSequentialLoginFailureCount(Integer sequentialLoginFailureCount) { + this.sequentialLoginFailureCount = sequentialLoginFailureCount; + } + + public Integer getSequentialTokenLoginFailureCount() { + return sequentialTokenLoginFailureCount; + } + + public void setSequentialTokenLoginFailureCount(Integer sequentialTokenLoginFailureCount) { + this.sequentialTokenLoginFailureCount = sequentialTokenLoginFailureCount; + } + public String getRole() { return role; } @@ -203,14 +243,15 @@ public class DBUser extends BaseEntity { if (this.certificate != null) { this.certificate.setDbUser(null); } - } - else { + } else { certificate.setDbUser(this); } this.certificate = certificate; } - public String getEmailAddress() { return emailAddress; } + public String getEmailAddress() { + return emailAddress; + } public void setEmailAddress(String email) { this.emailAddress = email; @@ -245,7 +286,7 @@ public class DBUser extends BaseEntity { @PrePersist public void prePersist() { - if(createdOn == null) { + if (createdOn == null) { createdOn = LocalDateTime.now(); } lastUpdatedOn = LocalDateTime.now(); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DeleteEntityValidation.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DeleteEntityValidation.java index a73ba49aaddeb95984589aac7f43721d1acd0f4e..916bdec64808d77589ffcc1de308cb63436ae208 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DeleteEntityValidation.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DeleteEntityValidation.java @@ -11,8 +11,8 @@ public class DeleteEntityValidation implements Serializable { boolean validOperation; String stringMessage; - List<Long> listIds= new ArrayList<>(); - List<Long> listDeleteNotPermitedIds = new ArrayList<>(); + List<String> listIds= new ArrayList<>(); + List<String> listDeleteNotPermitedIds = new ArrayList<>(); public boolean isValidOperation() { return validOperation; @@ -30,12 +30,12 @@ public class DeleteEntityValidation implements Serializable { this.stringMessage = stringMessage; } - public List<Long> getListIds() { + public List<String> getListIds() { return listIds; } - public List<Long> getListDeleteNotPermitedIds() { + public List<String> getListDeleteNotPermitedIds() { return listDeleteNotPermitedIds; } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java index 167216dcb50bd9b244dbc85393274f17fa6c255e..aa62a783d400dbeca9c6e10fa57fb1a3e52c9c1d 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java @@ -65,12 +65,20 @@ public enum SMPPropertyEnum { "The error message shown to the user in case the password does not follow the regex put in the domibus.passwordPolicy.pattern property", false, false,false, STRING), PASSWORD_POLICY_VALID_DAYS("smp.passwordPolicy.validDays","90", "Number of days password is valid", false, false,false, INTEGER), + USER_MAX_FAILED_ATTEMPTS("smp.user.login.maximum.attempt","5", + "Number of console login attempt before the user is deactivated", false, false,false, INTEGER), + USER_SUSPENSION_TIME("smp.user.login.suspension.time","3600", + "Time in seconds for a suspended user to be reactivated. (if 0 the user will not be reactivated)", false, false,false, INTEGER), ACCESS_TOKEN_POLICY_VALID_DAYS("smp.accessToken.validDays","60", "Number of days access token is valid is valid", false, false,false, INTEGER), + ACCESS_TOKEN_MAX_FAILED_ATTEMPTS("smp.accessToken.login.maximum.attempt","10", + "Number of accessToken login attempt before the accessToken is deactivated", false, false,false, INTEGER), + ACCESS_TOKEN_SUSPENSION_TIME("smp.accessToken.login.suspension.time","3600", + "Time in seconds for a suspended accessToken to be reactivated. (if 0 the user will not be reactivated)", false, false,false, INTEGER), - // authentication + // authentication UI_AUTHENTICATION_TYPES("smp.ui.authentication.types", "PASSWORD", "Set list of '|' separated authentication types: PASSWORD|SSO.", false, false, false, LIST_STRING), AUTOMATION_AUTHENTICATION_TYPES("smp.automation.authentication.types", "PASSWORD|CERTIFICATE", "Set list of '|' separated application-automation authentication types (Web-Service integration). Currently supported PASSWORD, CERT: ex. PASSWORD|CERT", false, false, false, LIST_STRING), // SSO configuration diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/logging/SMPMessageCode.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/logging/SMPMessageCode.java index 5fff0ed1b1f5f1f0565b31394bf6ee7c613f4d38..0bf2341c134360e784fae906bf8665a1975d2160 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/logging/SMPMessageCode.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/logging/SMPMessageCode.java @@ -46,9 +46,11 @@ public enum SMPMessageCode implements MessageCode { SEC_USER_AUTHENTICATED("SEC-002", "User {} is authenticated with role {}."), SEC_USER_NOT_EXISTS("SEC-003", "User {} not exists."), SEC_INVALID_PASSWORD("SEC-004", "User {} has invalid password."), - SEC_USER_NOT_AUTHENTICATED("SEC-007", "User {}. Reason: {}."), SEC_USER_CERT_NOT_EXISTS("SEC-005", "User certificate {} not exists."), SEC_USER_CERT_INVALID("SEC-006", "User certificate {} is invalid: {}."), + SEC_USER_NOT_AUTHENTICATED("SEC-007", "User {}. Reason: {}."), + SEC_USER_SUSPENDED("SEC-008", "User {} is temporarily suspended."), + ; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java index 6d8cc577ced60c2af9c9d109e9d0b910cb15f8be..e614b714b93b7c5adfe70c4d50cf0aca1772e634 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java @@ -87,6 +87,22 @@ public class ConfigurationService { return (Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_POLICY_VALID_DAYS); } + + public Integer getLoginMaxAttempts() { + return (Integer) configurationDAO.getCachedPropertyValue(USER_MAX_FAILED_ATTEMPTS); + } + public Integer getLoginSuspensionTimeInSeconds() { + return (Integer) configurationDAO.getCachedPropertyValue(USER_SUSPENSION_TIME); + } + + + public Integer getAccessTokenLoginMaxAttempts() { + return (Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_MAX_FAILED_ATTEMPTS); + } + public Integer getAccessTokenLoginSuspensionTimeInSeconds() { + return (Integer) configurationDAO.getCachedPropertyValue(ACCESS_TOKEN_SUSPENSION_TIME); + } + public Integer getHttpHeaderHstsMaxAge() { return (Integer) configurationDAO.getCachedPropertyValue(HTTP_HSTS_MAX_AGE); } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainService.java index f645aaf1e84f4ba17bf8a037cd567c5f23e62ca0..e87f64ed1444a8c0330b4985aba475a0fafee7f9 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainService.java @@ -12,6 +12,7 @@ import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.sml.SmlConnector; +import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.StringWriter; import java.time.LocalDateTime; import java.util.List; +import java.util.stream.Collectors; @Service public class UIDomainService extends UIServiceBase<DBDomain, DomainRO> { @@ -80,13 +82,14 @@ public class UIDomainService extends UIServiceBase<DBDomain, DomainRO> { } public DeleteEntityValidation validateDeleteRequest(DeleteEntityValidation dev) { - List<DBDomainDeleteValidation> lstMessages = domainDao.validateDomainsForDelete(dev.getListIds()); + List<Long> idList = dev.getListIds().stream().map(encId-> Long.parseLong(encId)).collect(Collectors.toList()); + List<DBDomainDeleteValidation> lstMessages = domainDao.validateDomainsForDelete(idList); dev.setValidOperation(lstMessages.isEmpty()); if (!dev.isValidOperation()) { StringWriter sw = new StringWriter(); sw.write("Could not delete domains used by Service groups! "); lstMessages.forEach(msg -> { - dev.getListDeleteNotPermitedIds().add(msg.getId()); + dev.getListDeleteNotPermitedIds().add(msg.getId()+""); sw.write("Domain: "); sw.write(msg.getDomainCode()); sw.write(" ("); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java index 697363e34be439c2af513f6b155514d2652b8de5..26cce3e8f62f383c11e52ec063da25c153766e18 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java @@ -16,6 +16,7 @@ import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.services.SMLIntegrationService; import eu.europa.ec.edelivery.smp.services.ui.filters.ServiceGroupFilter; +import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils; import eu.europa.ec.smp.api.exceptions.XmlInvalidAgainstSchemaException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -38,9 +39,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import static eu.europa.ec.edelivery.smp.data.ui.ServiceGroupValidationRO.ERROR_CODE_INVALID_EXTENSION; -import static eu.europa.ec.edelivery.smp.data.ui.ServiceGroupValidationRO.ERROR_CODE_OK; -import static eu.europa.ec.edelivery.smp.data.ui.ServiceGroupValidationRO.ERROR_CODE_SERVICE_GROUP_EXISTS; +import static eu.europa.ec.edelivery.smp.data.ui.ServiceGroupValidationRO.*; import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.*; @Service @@ -466,28 +465,6 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service return participantSMLRecordList; } - /** - * Method validates if domain list in consistent - code and sml subdomain are used only oncet - * - * @param serviceGroupRO - * @return - * - protected List<ServiceGroupDomainRO> validateDomainList(ServiceGroupRO serviceGroupRO) { - List<ServiceGroupDomainRO> serviceGroupDomainROList = serviceGroupRO.getServiceGroupDomains(); - // validate (if domains are added only once) and create domain list for service group. - serviceGroupDomainROList.forEach(dro -> { - List<ServiceGroupDomainRO> result = serviceGroupDomainROList.stream() - .filter(domainToAdd -> Objects.equals(domainToAdd.getDomainCode(), dro.getDomainCode()) - || Objects.equals(domainToAdd.getSmlSubdomain(), dro.getSmlSubdomain())) - .collect(Collectors.toList()); - if (result.size() != 1) { - throw new SMPRuntimeException(DUPLICATE_DOMAIN_FOR_SG, serviceGroupRO.getParticipantIdentifier(), - serviceGroupRO.getParticipantScheme(), dro.getDomainCode(), dro.getSmlSubdomain()); - } - }); - return serviceGroupDomainROList; - }*/ - /** * Update users on service group. Method is OK for update and add new domain * @@ -499,7 +476,8 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service dbServiceGroup.getUsers().clear(); List<UserRO> lstUsers = serviceGroupRO.getUsers(); for (UserRO userRO : lstUsers) { - Optional<DBUser> optUser = userDao.findUserByUsername(userRO.getUsername()); + Long userid = SessionSecurityUtils.decryptEntityId(userRO.getUserId()); + Optional<DBUser> optUser = userDao.findUser(userid); if (!optUser.isPresent()) { throw new SMPRuntimeException(INTERNAL_ERROR, "Database changed", "User "+userRO.getUsername()+ " not exists! (Refresh data)"); @@ -586,14 +564,10 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service //also add domain to service group serviceGroupRo.getServiceGroupDomains().add(servGrpDomain); }); - // add users + // add users add just encrypted ID dbServiceGroup.getUsers().forEach(usr -> { UserRO userRO = new UserRO(); - userRO.setUserId(usr.getId()+""); - userRO.setUsername(usr.getUsername()); - userRO.setActive(usr.isActive()); - userRO.setEmailAddress(usr.getEmailAddress()); - userRO.setRole(usr.getRole()); + userRO.setUserId(SessionSecurityUtils.encryptedEntityId(usr.getId())); serviceGroupRo.getUsers().add(userRO); }); // do not add service extension to gain performance. diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java index 836a768a44f2f660b43163604693004537c31320..2d8bfd74820bce8f43799145cf1163b5e5d2c853 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java @@ -14,6 +14,7 @@ import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.services.ConfigurationService; import eu.europa.ec.edelivery.smp.utils.BCryptPasswordHash; import eu.europa.ec.edelivery.smp.utils.SecurityUtils; +import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils; import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -36,6 +37,7 @@ import java.util.Base64; import java.util.List; import java.util.Optional; import java.util.regex.Pattern; +import java.util.stream.Collectors; @Service public class UIUserService extends UIServiceBase<DBUser, UserRO> { @@ -268,12 +270,13 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> { public DeleteEntityValidation validateDeleteRequest(DeleteEntityValidation dev) { - List<DBUserDeleteValidation> lstMessages = userDao.validateUsersForDelete(dev.getListIds()); + List<Long> idList = dev.getListIds().stream().map(encId->SessionSecurityUtils.decryptEntityId(encId)).collect(Collectors.toList()); + List<DBUserDeleteValidation> lstMessages = userDao.validateUsersForDelete(idList); dev.setValidOperation(lstMessages.isEmpty()); StringWriter sw = new StringWriter(); sw.write("Could not delete user with ownerships! "); lstMessages.forEach(msg -> { - dev.getListDeleteNotPermitedIds().add(msg.getId()); + dev.getListDeleteNotPermitedIds().add(SessionSecurityUtils.encryptedEntityId(msg.getId())); sw.write("User: "); sw.write(StringUtils.isBlank(msg.getUsername()) ? msg.getCertificateId() : msg.getUsername()); sw.write(" owns SG count: "); diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainServiceIntegrationTest.java index aaeaf9919ff3f405129103cb84fe0ba01b58c3a2..8db8c2f1bccc99a9b09e4758c8630a05b34c7d46 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainServiceIntegrationTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIDomainServiceIntegrationTest.java @@ -83,12 +83,9 @@ public class UIDomainServiceIntegrationTest extends AbstractServiceIntegrationTe public void validateDeleteRequest(){ DeleteEntityValidation dev= new DeleteEntityValidation(); - dev.getListIds().add((long)10); - + dev.getListIds().add("10"); DeleteEntityValidation res = testInstance.validateDeleteRequest(dev); - assertEquals(true, res.isValidOperation()); - } @Test @@ -106,15 +103,15 @@ public class UIDomainServiceIntegrationTest extends AbstractServiceIntegrationTe // when DeleteEntityValidation dev= new DeleteEntityValidation(); - dev.getListIds().add(d.getId()); - dev.getListIds().add(d2.getId()); + dev.getListIds().add(d.getId()+""); + dev.getListIds().add(d2.getId()+""); DeleteEntityValidation res = testInstance.validateDeleteRequest(dev); // then assertEquals(false, res.isValidOperation()); assertEquals(1, res.getListDeleteNotPermitedIds().size()); - assertEquals(d.getId(), res.getListDeleteNotPermitedIds().get(0)); + assertEquals(d.getId()+"", res.getListDeleteNotPermitedIds().get(0)); assertEquals("Could not delete domains used by Service groups! Domain: domain (domain ) uses by:1 SG.", res.getStringMessage()); } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java index 6751b3582d4049468acbb18e5f1595a7b89c00ab..527742a1a3c7e7fbfe212b86d72e93976903c0a6 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProvider.java @@ -7,6 +7,7 @@ import eu.europa.ec.edelivery.smp.data.dao.UserDao; import eu.europa.ec.edelivery.smp.data.model.DBCertificate; import eu.europa.ec.edelivery.smp.data.model.DBUser; import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; +import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.logging.SMPMessageCode; @@ -30,22 +31,23 @@ import java.security.cert.CertificateRevokedException; import java.security.cert.X509Certificate; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.*; import static java.util.Locale.US; /** - * Authentication provider for the Accounts supporting automated application functionalities. The account are used in SMP for - * webservice access as application to application integration with SMP. Authentication provider supports following + * An AuthenticationProvider is an abstraction for fetching user information from a specific repository + * (like a database, LDAP, custom third party source, etc. ). It uses the fetched user information to validate the supplied credentials. + * The current Authentication provider is intented for the accounts supporting automated application functionalities . + * The account are used in SMP for webservice access as application to application integration with SMP. Authentication provider supports following * {@link org.springframework.security.core.Authentication} implementation: * - {@link org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken} implementation using * - * - * * @author Joze Rihtarsic * @since 4.1 */ -@Import({SmpAppConfig.class}) @Component public class SMPAuthenticationProvider implements AuthenticationProvider { @@ -200,6 +202,45 @@ public class SMPAuthenticationProvider implements AuthenticationProvider { } + /** + * Method tests if user account Suspended + * + * @param user + */ + public void validateIfTokenIsSuspended(DBUser user) { + if (user.getSequentialTokenLoginFailureCount() == null + || user.getSequentialTokenLoginFailureCount() < 0) { + LOG.trace("User has no previous failed attempts"); + return; + } + if (configurationService.getAccessTokenLoginMaxAttempts() == null + || configurationService.getAccessTokenLoginMaxAttempts() < 0) { + LOG.warn("Max login attempts [{}] is not set", SMPPropertyEnum.ACCESS_TOKEN_MAX_FAILED_ATTEMPTS.getProperty()); + return; + } + + if (user.getLastFailedLoginAttempt() == null) { + LOG.warn("Access token [{}] has failed attempts [{}] but null last Failed login attempt!", user.getUsername(), user.getLastFailedLoginAttempt()); + return; + } + // check if the last failed attempt is already expired. If yes just clear the attepmts + if (configurationService.getAccessTokenLoginSuspensionTimeInSeconds() !=null && configurationService.getAccessTokenLoginSuspensionTimeInSeconds() > 0 + && ChronoUnit.SECONDS.between(LocalDateTime.now(), user.getLastTokenFailedLoginAttempt()) > configurationService.getAccessTokenLoginSuspensionTimeInSeconds()){ + LOG.warn("User [{}] suspension is expired! Clear failed login attempts and last failed login attempt", user.getUsername()); + user.setLastTokenFailedLoginAttempt(null); + user.setSequentialTokenLoginFailureCount(0); + mUserDao.update(user); + return; + } + + if (user.getSequentialTokenLoginFailureCount() < configurationService.getAccessTokenLoginMaxAttempts()) { + LOG.warn("User [{}] failed login attempt [{}]! did not reach the max failed attempts [{}]", user.getUsername(), user.getSequentialTokenLoginFailureCount() , configurationService.getAccessTokenLoginMaxAttempts()); + return; + } + LOG.securityWarn(SMPMessageCode.SEC_USER_SUSPENDED, user.getUsername()); + throw new BadCredentialsException("The user is suspended. Please try again later or contact your administrator."); + } + public Authentication authenticateByUsernameToken(UsernamePasswordAuthenticationToken auth) throws AuthenticationException { @@ -209,8 +250,7 @@ public class SMPAuthenticationProvider implements AuthenticationProvider { DBUser user; try { Optional<DBUser> oUsr = mUserDao.findUserByAuthenticationToken(authenticationTokenId); - - if (!oUsr.isPresent()) { + if (!oUsr.isPresent() || !oUsr.get().isActive()) { LOG.securityWarn(SMPMessageCode.SEC_USER_NOT_EXISTS, authenticationTokenId); //run validation on dummy password to achieve similar response time // as it would be if the password is invalid @@ -220,7 +260,6 @@ public class SMPAuthenticationProvider implements AuthenticationProvider { // Do not reveal the status of an existing account. Not to use UsernameNotFoundException throw new BadCredentialsException("Login failed; Invalid userID or password"); } - user = oUsr.get(); } catch (AuthenticationException ex) { LOG.securityWarn(SMPMessageCode.SEC_USER_NOT_AUTHENTICATED, authenticationTokenId, ExceptionUtils.getRootCause(ex), ex); @@ -229,10 +268,15 @@ public class SMPAuthenticationProvider implements AuthenticationProvider { } catch (RuntimeException ex) { LOG.securityWarn(SMPMessageCode.SEC_USER_NOT_AUTHENTICATED, authenticationTokenId, ExceptionUtils.getRootCause(ex), ex); throw new AuthenticationServiceException("Internal server error occurred while user authentication!"); - } + + validateIfTokenIsSuspended(user); + try { if (!BCrypt.checkpw(authenticationTokenValue, user.getAccessToken())) { + user.setSequentialTokenLoginFailureCount(user.getSequentialTokenLoginFailureCount()!=null?user.getSequentialTokenLoginFailureCount()+1:1); + user.setLastTokenFailedLoginAttempt(LocalDateTime.now()); + mUserDao.update(user); LOG.securityWarn(SMPMessageCode.SEC_INVALID_PASSWORD, authenticationTokenId); throw new BadCredentialsException("Login failed; Invalid userID or password"); } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java index 16f1e3e18b4193c9e8bdf92dd2485e38b2a59efb..b7845dcb7b97349e74433c99110f37ccb57db37c 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationProviderForUI.java @@ -1,38 +1,32 @@ package eu.europa.ec.edelivery.smp.auth; -import eu.europa.ec.edelivery.security.PreAuthenticatedCertificatePrincipal; -import eu.europa.ec.edelivery.security.cert.CertificateValidator; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.data.dao.UserDao; -import eu.europa.ec.edelivery.smp.data.model.DBCertificate; import eu.europa.ec.edelivery.smp.data.model.DBUser; import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; +import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.logging.SMPMessageCode; import eu.europa.ec.edelivery.smp.services.CRLVerifierService; import eu.europa.ec.edelivery.smp.services.ConfigurationService; import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Import; -import org.springframework.security.authentication.*; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCrypt; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.stereotype.Component; -import java.security.KeyStore; -import java.security.cert.CertificateException; -import java.security.cert.CertificateRevokedException; -import java.security.cert.X509Certificate; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; - -import static java.util.Locale.US; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Collections; +import java.util.Optional; /** * Authentication provider for the UI authentication. @@ -40,7 +34,6 @@ import static java.util.Locale.US; * @author Joze Rihtarsic * @since 4.2 */ -@Import({SmpAppConfig.class}) @Component public class SMPAuthenticationProviderForUI implements AuthenticationProvider { @@ -96,13 +89,20 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider { throw new AuthenticationServiceException("Internal server error occurred while user authentication!"); } + + validateIfUserAccountIsSuspended(user); + String role = user.getRole(); SMPAuthenticationToken smpAuthenticationToken = new SMPAuthenticationToken(username, userCredentialToken, Collections.singletonList(new SMPAuthority(role)), user); try { if (!BCrypt.checkpw(userCredentialToken, user.getPassword())) { + user.setSequentialLoginFailureCount(user.getSequentialLoginFailureCount() != null ? user.getSequentialLoginFailureCount() + 1 : 1); + user.setLastFailedLoginAttempt(LocalDateTime.now()); + mUserDao.update(user); LOG.securityWarn(SMPMessageCode.SEC_INVALID_PASSWORD, username); throw new BadCredentialsException("Login failed; Invalid userID or password"); } + user.setSequentialLoginFailureCount(0); } catch (IllegalArgumentException ex) { // password is not hashed; LOG.securityWarn(SMPMessageCode.SEC_INVALID_PASSWORD, ex, username); @@ -112,6 +112,46 @@ public class SMPAuthenticationProviderForUI implements AuthenticationProvider { return smpAuthenticationToken; } + + /** + * Method tests if user account Suspended + * + * @param user + */ + public void validateIfUserAccountIsSuspended(DBUser user) { + if (user.getSequentialLoginFailureCount() == null + || user.getSequentialLoginFailureCount() < 0) { + LOG.trace("User has no previous failed attempts"); + return; + } + if (configurationService.getLoginMaxAttempts() == null + || configurationService.getLoginMaxAttempts() < 0) { + LOG.warn("Max login attempts [{}] is not set", SMPPropertyEnum.USER_MAX_FAILED_ATTEMPTS.getProperty()); + return; + } + + if (user.getLastFailedLoginAttempt() == null) { + LOG.warn("User [{}] has failed attempts [{}] but null last Failed login attempt!", user.getUsername(), user.getLastFailedLoginAttempt()); + return; + } + // check if the last failed attempt is already expired. If yes just clear the attepmts + if (configurationService.getLoginSuspensionTimeInSeconds() !=null && configurationService.getLoginSuspensionTimeInSeconds() > 0 + && ChronoUnit.SECONDS.between(LocalDateTime.now(), user.getLastFailedLoginAttempt()) > configurationService.getLoginSuspensionTimeInSeconds()){ + LOG.warn("User [{}] suspension is expired! Clear failed login attempts and last failed login attempt", user.getUsername()); + user.setLastFailedLoginAttempt(null); + user.setSequentialLoginFailureCount(0); + mUserDao.update(user); + return; + } + + if (user.getSequentialLoginFailureCount() < configurationService.getLoginMaxAttempts()) { + LOG.warn("User [{}] failed login attempt [{}]! did not reach the max failed attempts [{}]", user.getUsername(), user.getSequentialLoginFailureCount() , configurationService.getLoginMaxAttempts()); + return; + } + LOG.securityWarn(SMPMessageCode.SEC_USER_SUSPENDED, user.getUsername()); + throw new BadCredentialsException("The user is suspended. Please try again later or contact your administrator."); + } + @Override public boolean supports(Class<?> auth) { LOG.info("Support authentication: " + auth); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java index 9f9f476fd197fa40f57a40866386a57161357ce8..b9505571785159a6e6a432cd3430524d95ef9a64 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationService.java @@ -20,7 +20,7 @@ public class SMPAuthenticationService { private static final SMPLogger LOG = SMPLoggerFactory.getLogger(SMPAuthenticationService.class); @Autowired - @Qualifier(SMPSecurityConstants.SMP_AUTHENTICATION_MANAGER_BEAN) + @Qualifier(SMPSecurityConstants.SMP_UI_AUTHENTICATION_MANAGER_BEAN) private AuthenticationManager authenticationManager; @Transactional(noRollbackFor = AuthenticationException.class) diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPSecurityConstants.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPSecurityConstants.java index 70d5c0029a50bcc0de7286898091ee6ee58c162c..e03cbaa4e36d7921d4b9d5e98edc0acc555bf2f0 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPSecurityConstants.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPSecurityConstants.java @@ -11,6 +11,7 @@ import eu.europa.ec.edelivery.smp.ui.ResourceConstants; public class SMPSecurityConstants { public static final String SMP_AUTHENTICATION_MANAGER_BEAN = "smpAuthenticationManager"; + public static final String SMP_UI_AUTHENTICATION_MANAGER_BEAN = "smpUIAuthenticationManager"; // must be "forwardedHeaderTransformer" see the documentation for the ForwardedHeaderTransformer public static final String SMP_FORWARDED_HEADER_TRANSFORMER_BEAN = "forwardedHeaderTransformer"; // CAS BEANS diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SpringSecurityConfig.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/UISecurityConfigurerAdapter.java similarity index 76% rename from smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SpringSecurityConfig.java rename to smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/UISecurityConfigurerAdapter.java index e412ff515606f830195868d13fb889215c3ea981..d53de11ffd7413f5502d88578ef2882e1f636b2d 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SpringSecurityConfig.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/UISecurityConfigurerAdapter.java @@ -1,18 +1,6 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ - package eu.europa.ec.edelivery.smp.config; + import eu.europa.ec.edelivery.security.ClientCertAuthenticationFilter; import eu.europa.ec.edelivery.security.EDeliveryX509AuthenticationFilter; import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationProvider; @@ -31,6 +19,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Lazy; +import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.cas.authentication.CasAuthenticationProvider; @@ -45,6 +34,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.csrf.CookieCsrfTokenRepository; import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.security.web.firewall.DefaultHttpFirewall; @@ -57,24 +47,22 @@ import org.springframework.web.server.adapter.ForwardedHeaderTransformer; import static eu.europa.ec.edelivery.smp.config.SMPSecurityConstants.*; - /** - * SMP Security configuration - * @author gutowpa - * @since 3.0 + * SMP UI Security configuration + * @author Joze Rihtarsic + * @since 4.1 */ + @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) +@Order(1) @ComponentScan("eu.europa.ec.edelivery.smp.auth") -public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { - private static final Logger LOG = LoggerFactory.getLogger(SpringSecurityConfig.class); +public class UISecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(UISecurityConfigurerAdapter.class); - SMPAuthenticationProvider smpAuthenticationProvider; SMPAuthenticationProviderForUI smpAuthenticationProviderForUI; CasAuthenticationProvider casAuthenticationProvider; - // Accounts supporting automated application functionalities - ClientCertAuthenticationFilter clientCertAuthenticationFilter; - EDeliveryX509AuthenticationFilter x509AuthenticationFilter; MDCLogRequestFilter mdcLogRequestFilter; // User account CasAuthenticationFilter casAuthenticationFilter; @@ -85,17 +73,9 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { RequestMatcher csrfURLMatcher; ConfigurationService configurationService; - @Value("${authentication.blueCoat.enabled:false}") - boolean clientCertEnabled; - @Value("${encodedSlashesAllowedInUrl:true}") - boolean encodedSlashesAllowedInUrl; - @Autowired - public SpringSecurityConfig(SMPAuthenticationProvider smpAuthenticationProvider, - SMPAuthenticationProviderForUI smpAuthenticationProviderForUI, + public UISecurityConfigurerAdapter(SMPAuthenticationProviderForUI smpAuthenticationProviderForUI, ConfigurationService configurationService, - @Lazy ClientCertAuthenticationFilter clientCertAuthenticationFilter, - @Lazy EDeliveryX509AuthenticationFilter x509AuthenticationFilter, @Lazy MDCLogRequestFilter mdcLogRequestFilter, @Lazy CsrfTokenRepository csrfTokenRepository, @Lazy RequestMatcher csrfURLMatcher, @@ -107,11 +87,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { ) { super(false); this.configurationService = configurationService; - this.smpAuthenticationProvider = smpAuthenticationProvider; this.smpAuthenticationProviderForUI = smpAuthenticationProviderForUI; this.casAuthenticationProvider = casAuthenticationProvider; - this.clientCertAuthenticationFilter = clientCertAuthenticationFilter; - this.x509AuthenticationFilter = x509AuthenticationFilter; this.casAuthenticationFilter = casAuthenticationFilter; this.mdcLogRequestFilter = mdcLogRequestFilter; this.casAuthenticationEntryPoint = casAuthenticationEntryPoint; @@ -122,7 +99,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { - + httpSecurity = httpSecurity.antMatcher("/ui/**"); configureSecurityHeaders(httpSecurity); ExceptionHandlingConfigurer<HttpSecurity> exceptionHandlingConfigurer = httpSecurity.exceptionHandling(); @@ -150,32 +127,24 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { httpSecurity - .addFilterAfter(mdcLogRequestFilter, EDeliveryX509AuthenticationFilter.class) - .addFilter(clientCertAuthenticationFilter) - .addFilter(x509AuthenticationFilter) + .addFilterAfter(mdcLogRequestFilter, BasicAuthenticationFilter.class) .httpBasic().authenticationEntryPoint(smpSecurityExceptionHandler).and() // username .anonymous().authorities(SMPAuthority.S_AUTHORITY_ANONYMOUS.getAuthority()).and() .authorizeRequests() - .antMatchers(HttpMethod.DELETE, SMP_SECURITY_PATH_AUTHENTICATE).permitAll() - .antMatchers(HttpMethod.POST, SMP_SECURITY_PATH_AUTHENTICATE).permitAll() .antMatchers(HttpMethod.GET, SMP_SECURITY_PATH_CAS_AUTHENTICATE).authenticated() .and() .authorizeRequests() .antMatchers(HttpMethod.DELETE).hasAnyAuthority( - SMPAuthority.S_AUTHORITY_TOKEN_WS_SERVICE_GROUP_ADMIN, - SMPAuthority.S_AUTHORITY_TOKEN_WS_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority(), SMPAuthority.S_AUTHORITY_SERVICE_GROUP.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()) .antMatchers(HttpMethod.PUT).hasAnyAuthority( - SMPAuthority.S_AUTHORITY_TOKEN_WS_SERVICE_GROUP_ADMIN, - SMPAuthority.S_AUTHORITY_TOKEN_WS_SMP_ADMIN, SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority(), SMPAuthority.S_AUTHORITY_SERVICE_GROUP.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()) .antMatchers(HttpMethod.GET).permitAll().and() .authorizeRequests() - .antMatchers(HttpMethod.GET, "/ui/").hasAnyAuthority( + .antMatchers(HttpMethod.GET, "/ui/**").hasAnyAuthority( SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority(), SMPAuthority.S_AUTHORITY_SERVICE_GROUP.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()) @@ -237,46 +206,20 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { } // add UI authentication provider auth.authenticationProvider(smpAuthenticationProviderForUI); - // fallback automation user token authentication - auth.authenticationProvider(smpAuthenticationProvider); - - } @Override - @Bean(name = {BeanIds.AUTHENTICATION_MANAGER, SMP_AUTHENTICATION_MANAGER_BEAN}) + @Bean(name = {SMP_UI_AUTHENTICATION_MANAGER_BEAN}) public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } - @Bean - public HttpFirewall smpHttpFirewall() { - DefaultHttpFirewall firewall = new DefaultHttpFirewall(); - firewall.setAllowUrlEncodedSlash(encodedSlashesAllowedInUrl); - return firewall; - } - - @Bean - public ClientCertAuthenticationFilter getClientCertAuthenticationFilter(@Qualifier(SMP_AUTHENTICATION_MANAGER_BEAN) AuthenticationManager authenticationManager) { - ClientCertAuthenticationFilter ClientCertAuthenticationFilter = new ClientCertAuthenticationFilter(); - ClientCertAuthenticationFilter.setAuthenticationManager(authenticationManager); - ClientCertAuthenticationFilter.setClientCertAuthenticationEnabled(clientCertEnabled); - return ClientCertAuthenticationFilter; - } - @Bean public MDCLogRequestFilter getMDCLogRequestFilter() { MDCLogRequestFilter filter= new MDCLogRequestFilter(); return filter; } - @Bean - public EDeliveryX509AuthenticationFilter getEDeliveryX509AuthenticationFilter(@Qualifier(SMP_AUTHENTICATION_MANAGER_BEAN) AuthenticationManager authenticationManager) { - EDeliveryX509AuthenticationFilter x509AuthenticationFilter = new EDeliveryX509AuthenticationFilter(); - x509AuthenticationFilter.setAuthenticationManager(authenticationManager); - return x509AuthenticationFilter; - } - @Bean public CsrfTokenRepository tokenRepository() { CookieCsrfTokenRepository repository = CookieCsrfTokenRepository.withHttpOnlyFalse(); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/WSSecurityConfigurerAdapter.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/WSSecurityConfigurerAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..a1be863a0ef8c25cb6817c544ff34fd5c1367f22 --- /dev/null +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/WSSecurityConfigurerAdapter.java @@ -0,0 +1,221 @@ +/* + * Copyright 2017 European Commission | CEF eDelivery + * + * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and limitations under the Licence. + */ + +package eu.europa.ec.edelivery.smp.config; + +import eu.europa.ec.edelivery.security.ClientCertAuthenticationFilter; +import eu.europa.ec.edelivery.security.EDeliveryX509AuthenticationFilter; +import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationProvider; +import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; +import eu.europa.ec.edelivery.smp.error.SMPSecurityExceptionHandler; +import eu.europa.ec.edelivery.smp.services.ConfigurationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.BeanIds; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.csrf.CsrfTokenRepository; +import org.springframework.security.web.firewall.DefaultHttpFirewall; +import org.springframework.security.web.firewall.HttpFirewall; +import org.springframework.security.web.util.matcher.AnyRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; + +import static eu.europa.ec.edelivery.smp.config.SMPSecurityConstants.*; + + +/** + * SMP Security configuration + * @author gutowpa + * @since 3.0 + */ +@Order(2) +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) +public class WSSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + private static final Logger LOG = LoggerFactory.getLogger(WSSecurityConfigurerAdapter.class); + + SMPAuthenticationProvider smpAuthenticationProvider; + // Accounts supporting automated application functionalities + ClientCertAuthenticationFilter clientCertAuthenticationFilter; + EDeliveryX509AuthenticationFilter x509AuthenticationFilter; + MDCLogRequestFilter mdcLogRequestFilter; + + CsrfTokenRepository csrfTokenRepository; + HttpFirewall httpFirewall; + RequestMatcher csrfURLMatcher; + ConfigurationService configurationService; + + @Value("${authentication.blueCoat.enabled:false}") + boolean clientCertEnabled; + @Value("${encodedSlashesAllowedInUrl:true}") + boolean encodedSlashesAllowedInUrl; + + @Autowired + public WSSecurityConfigurerAdapter(SMPAuthenticationProvider smpAuthenticationProvider, + ConfigurationService configurationService, + @Lazy ClientCertAuthenticationFilter clientCertAuthenticationFilter, + @Lazy EDeliveryX509AuthenticationFilter x509AuthenticationFilter, + @Lazy MDCLogRequestFilter mdcLogRequestFilter, + @Lazy CsrfTokenRepository csrfTokenRepository, + @Lazy RequestMatcher csrfURLMatcher, + @Lazy HttpFirewall httpFirewall + ) { + super(false); + this.configurationService = configurationService; + this.smpAuthenticationProvider = smpAuthenticationProvider; + this.clientCertAuthenticationFilter = clientCertAuthenticationFilter; + this.x509AuthenticationFilter = x509AuthenticationFilter; + this.mdcLogRequestFilter = mdcLogRequestFilter; + this.csrfTokenRepository = csrfTokenRepository; + this.csrfURLMatcher = csrfURLMatcher; + this.httpFirewall = httpFirewall; + } + + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + + configureSecurityHeaders(httpSecurity); + + ExceptionHandlingConfigurer<HttpSecurity> exceptionHandlingConfigurer = httpSecurity.exceptionHandling(); + + SMPSecurityExceptionHandler smpSecurityExceptionHandler = new SMPSecurityExceptionHandler(); + + exceptionHandlingConfigurer.authenticationEntryPoint(smpSecurityExceptionHandler); + httpSecurity = exceptionHandlingConfigurer + .accessDeniedHandler(smpSecurityExceptionHandler) + .and() + .headers().frameOptions().deny() + .contentTypeOptions().and() + .xssProtection().xssProtectionEnabled(true).and() + .and(); + + httpSecurity + .addFilterAfter(mdcLogRequestFilter, EDeliveryX509AuthenticationFilter.class) + .addFilter(clientCertAuthenticationFilter) + .addFilter(x509AuthenticationFilter) + .httpBasic().authenticationEntryPoint(smpSecurityExceptionHandler).and() // username + .anonymous().authorities(SMPAuthority.S_AUTHORITY_ANONYMOUS.getAuthority()).and() + .authorizeRequests() + .antMatchers(HttpMethod.DELETE, SMP_SECURITY_PATH_AUTHENTICATE).permitAll() + .antMatchers(HttpMethod.POST, SMP_SECURITY_PATH_AUTHENTICATE).permitAll() + .antMatchers(HttpMethod.GET, SMP_SECURITY_PATH_CAS_AUTHENTICATE).authenticated() + .and() + .authorizeRequests() + .antMatchers(HttpMethod.DELETE).hasAnyAuthority( + SMPAuthority.S_AUTHORITY_TOKEN_WS_SERVICE_GROUP_ADMIN, + SMPAuthority.S_AUTHORITY_TOKEN_WS_SMP_ADMIN) + .antMatchers(HttpMethod.PUT).hasAnyAuthority( + SMPAuthority.S_AUTHORITY_TOKEN_WS_SERVICE_GROUP_ADMIN, + SMPAuthority.S_AUTHORITY_TOKEN_WS_SMP_ADMIN) + .antMatchers(HttpMethod.GET).permitAll().and() + ; + } + + protected void configureSecurityHeaders(HttpSecurity httpSecurity) throws Exception { + // configure session and csrf headers + httpSecurity + .csrf().csrfTokenRepository(csrfTokenRepository).requireCsrfProtectionMatcher(csrfURLMatcher).and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + //on authentication, a new HTTP Session is created, the old one is invalidated and the attributes from the old session are copied over. + .sessionFixation().migrateSession() + //In order to force only one concurrent sessions for the same user, + .maximumSessions(1).and() + .and(); + + // set HstsMAxAge + Integer maxAge = configurationService.getHttpHeaderHstsMaxAge(); + if (maxAge == null || maxAge < 0) { + LOG.info("The httpStrictTransportSecurity (HSTS) policy is set for HTTPS/1Y!"); + httpSecurity = httpSecurity.headers() + .httpStrictTransportSecurity() + .includeSubDomains(true) + .preload(false) + .maxAgeInSeconds(31536000).and().and(); + } else if (maxAge == 0) { + LOG.warn("The httpStrictTransportSecurity (HSTS) policy is disabled!"); + httpSecurity = httpSecurity.headers().httpStrictTransportSecurity().disable().and(); + } else { + LOG.info("The httpStrictTransportSecurity (HSTS) policy is set to [{}] for http and https!", maxAge); + httpSecurity = httpSecurity.headers() + .httpStrictTransportSecurity() + .includeSubDomains(true) + .preload(false) + .maxAgeInSeconds(maxAge) + .requestMatcher(AnyRequestMatcher.INSTANCE).and().and(); + } +/* + String contentSecurityPolicy = configurationService.getHttpHeaderContentSecurityPolicy(); + if (StringUtils.isNotBlank(contentSecurityPolicy)) { + httpSecurity = httpSecurity.headers().contentSecurityPolicy(contentSecurityPolicy).and().and(); + }*/ + } + + @Override + public void configure(WebSecurity web) throws Exception { + super.configure(web); + web.httpFirewall(httpFirewall); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) { + LOG.info("configureAuthenticationManagerBuilder, set SMP provider "); + // fallback automation user token authentication + auth.authenticationProvider(smpAuthenticationProvider); + } + + @Override + @Bean(name = {BeanIds.AUTHENTICATION_MANAGER, SMP_AUTHENTICATION_MANAGER_BEAN}) + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Bean + public HttpFirewall smpHttpFirewall() { + DefaultHttpFirewall firewall = new DefaultHttpFirewall(); + firewall.setAllowUrlEncodedSlash(encodedSlashesAllowedInUrl); + return firewall; + } + + @Bean + public ClientCertAuthenticationFilter getClientCertAuthenticationFilter(@Qualifier(SMP_AUTHENTICATION_MANAGER_BEAN) AuthenticationManager authenticationManager) { + ClientCertAuthenticationFilter ClientCertAuthenticationFilter = new ClientCertAuthenticationFilter(); + ClientCertAuthenticationFilter.setAuthenticationManager(authenticationManager); + ClientCertAuthenticationFilter.setClientCertAuthenticationEnabled(clientCertEnabled); + return ClientCertAuthenticationFilter; + } + + @Bean + public EDeliveryX509AuthenticationFilter getEDeliveryX509AuthenticationFilter(@Qualifier(SMP_AUTHENTICATION_MANAGER_BEAN) AuthenticationManager authenticationManager) { + EDeliveryX509AuthenticationFilter x509AuthenticationFilter = new EDeliveryX509AuthenticationFilter(); + x509AuthenticationFilter.setAuthenticationManager(authenticationManager); + return x509AuthenticationFilter; + } + + +} diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/AbstractErrorControllerAdvice.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/AbstractErrorControllerAdvice.java index d786ca4ec01773d4ed4edd9124401dfa0a08ef71..6d63882e10e9f96898bb366684fe17bd47c0ade6 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/AbstractErrorControllerAdvice.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/AbstractErrorControllerAdvice.java @@ -9,6 +9,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.AuthenticationException; import static eu.europa.ec.edelivery.smp.exceptions.ErrorBusinessCode.TECHNICAL; @@ -30,6 +31,9 @@ abstract class AbstractErrorControllerAdvice { } else if (runtimeException instanceof AuthenticationException ){ AuthenticationException ex = (AuthenticationException)runtimeException; response = buildAndLog(UNAUTHORIZED, ErrorBusinessCode.UNAUTHORIZED, ex.getMessage(), ex); + }else if (runtimeException instanceof AccessDeniedException){ + AuthenticationException ex = (AuthenticationException)runtimeException; + response = buildAndLog(UNAUTHORIZED, ErrorBusinessCode.UNAUTHORIZED, ex.getMessage(), ex); } else { response = buildAndLog(INTERNAL_SERVER_ERROR, TECHNICAL, "Unexpected technical error occurred.", runtimeException); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/UIErrorControllerAdvice.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/UIErrorControllerAdvice.java index 1e23a2330b1e9e6108604dfc5b1dc9e3a157c5d7..91d8cf815d02b4c6dfb83b1c18675e008b5b261a 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/UIErrorControllerAdvice.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/UIErrorControllerAdvice.java @@ -51,8 +51,7 @@ public class UIErrorControllerAdvice extends AbstractErrorControllerAdvice { .buildJSon(); String errorUniqueId = ((ErrorResponseRO) response.getBody()).getErrorUniqueId(); - String logMsg = format("Error unique ID: %s", errorUniqueId); - + String logMsg = format("UI Error unique ID: %s", errorUniqueId); LOG.warn(logMsg, exception); return response; } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResource.java index 4c49c7a7e23469bfa6cd616baf5f4945270cb976..788c498b040799ed990961cb25d85bf552571d67 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResource.java @@ -78,7 +78,7 @@ public class DomainAdminResource { @Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN}) @PutMapping(value = "validate-delete", produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public DeleteEntityValidation validateDeleteDomain(@RequestBody List<Long> listOfDomainIds) { + public DeleteEntityValidation validateDeleteDomain(@RequestBody List<String> listOfDomainIds) { DeleteEntityValidation dres = new DeleteEntityValidation(); dres.getListIds().addAll(listOfDomainIds); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java index 888bde7220da9bf8ce79360b196392cb79bc8cea..259c012a1a5ea506d936dc23bffcbf3931eb31e7 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/internal/UserAdminResource.java @@ -3,23 +3,17 @@ package eu.europa.ec.edelivery.smp.ui.internal; import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken; import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService; import eu.europa.ec.edelivery.smp.data.model.DBUser; -import eu.europa.ec.edelivery.smp.data.ui.CertificateRO; import eu.europa.ec.edelivery.smp.data.ui.DeleteEntityValidation; import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.data.ui.UserRO; import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; -import eu.europa.ec.edelivery.smp.exceptions.ErrorCode; -import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.services.ui.UITruststoreService; import eu.europa.ec.edelivery.smp.services.ui.UIUserService; import eu.europa.ec.edelivery.smp.services.ui.filters.UserFilter; -import eu.europa.ec.edelivery.smp.utils.SecurityUtils; import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.MimeTypeUtils; @@ -87,7 +81,7 @@ public class UserAdminResource { dres.setStringMessage("Could not delete logged user!"); return dres; } - dres.getListIds().addAll(query); + dres.getListIds().addAll(query.stream().map(id -> SessionSecurityUtils.encryptedEntityId(id)).collect(Collectors.toList())); return uiUserService.validateDeleteRequest(dres); } diff --git a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl index dc0553b8ba3f8664eb109218f1a1c3c4079d3917..9dbdc002f43c767676f4dc8554c7ab4cb0abff7e 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl @@ -239,11 +239,15 @@ ACTIVE bit not null comment 'Is user active', CREATED_ON datetime not null, EMAIL varchar(256) CHARACTER SET utf8 COLLATE utf8_bin comment 'User email', + LAST_FAILED_LOGIN_ON datetime comment 'Last failed login attempt', + AT_LAST_FAILED_LOGIN_ON datetime comment 'Last failed token login attempt', LAST_UPDATED_ON datetime not null, PASSWORD varchar(256) CHARACTER SET utf8 COLLATE utf8_bin comment 'BCrypted password for username/password login', PASSWORD_CHANGED datetime comment 'Last date when password was changed', PASSWORD_EXPIRE_ON datetime comment 'Date when password will expire', ROLE varchar(256) CHARACTER SET utf8 COLLATE utf8_bin comment 'User role', + LOGIN_FAILURE_COUNT integer comment 'Sequential login failure count', + AT_LOGIN_FAILURE_COUNT integer comment 'Sequential token login failure count', USERNAME varchar(256) CHARACTER SET utf8 COLLATE utf8_bin not null comment 'Unique username identifier. The Username must not be null', primary key (ID) ) comment='SMP can handle multiple domains. This table contains domain specific data' ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -259,11 +263,15 @@ ACTIVE bit, CREATED_ON datetime, EMAIL varchar(256) CHARACTER SET utf8 COLLATE utf8_bin, + LAST_FAILED_LOGIN_ON datetime, + AT_LAST_FAILED_LOGIN_ON datetime, LAST_UPDATED_ON datetime, PASSWORD varchar(256) CHARACTER SET utf8 COLLATE utf8_bin, PASSWORD_CHANGED datetime, PASSWORD_EXPIRE_ON datetime, ROLE varchar(256) CHARACTER SET utf8 COLLATE utf8_bin, + LOGIN_FAILURE_COUNT integer, + AT_LOGIN_FAILURE_COUNT integer, USERNAME varchar(256) CHARACTER SET utf8 COLLATE utf8_bin, primary key (ID, REV) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl index 190d4ee1343e01b65e9d465229d957b551e8dca6..e16911b8252a225ff040b1c7f41b40b97b2144be 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl @@ -320,11 +320,15 @@ create sequence SMP_USER_SEQ start with 1 increment by 1; ACTIVE number(1,0) not null, CREATED_ON timestamp not null, EMAIL varchar2(256 char), + LAST_FAILED_LOGIN_ON timestamp, + AT_LAST_FAILED_LOGIN_ON timestamp, LAST_UPDATED_ON timestamp not null, PASSWORD varchar2(256 char), PASSWORD_CHANGED timestamp, PASSWORD_EXPIRE_ON timestamp, ROLE varchar2(256 char), + LOGIN_FAILURE_COUNT number(10,0), + AT_LOGIN_FAILURE_COUNT number(10,0), USERNAME varchar2(256 char) not null, primary key (ID) ); @@ -353,6 +357,12 @@ create sequence SMP_USER_SEQ start with 1 increment by 1; comment on column SMP_USER.EMAIL is 'User email'; + comment on column SMP_USER.LAST_FAILED_LOGIN_ON is + 'Last failed login attempt'; + + comment on column SMP_USER.AT_LAST_FAILED_LOGIN_ON is + 'Last failed token login attempt'; + comment on column SMP_USER.PASSWORD is 'BCrypted password for username/password login'; @@ -365,6 +375,12 @@ create sequence SMP_USER_SEQ start with 1 increment by 1; comment on column SMP_USER.ROLE is 'User role'; + comment on column SMP_USER.LOGIN_FAILURE_COUNT is + 'Sequential login failure count'; + + comment on column SMP_USER.AT_LOGIN_FAILURE_COUNT is + 'Sequential token login failure count'; + comment on column SMP_USER.USERNAME is 'Unique username identifier. The Username must not be null'; @@ -379,11 +395,15 @@ create sequence SMP_USER_SEQ start with 1 increment by 1; ACTIVE number(1,0), CREATED_ON timestamp, EMAIL varchar2(256 char), + LAST_FAILED_LOGIN_ON timestamp, + AT_LAST_FAILED_LOGIN_ON timestamp, LAST_UPDATED_ON timestamp, PASSWORD varchar2(256 char), PASSWORD_CHANGED timestamp, PASSWORD_EXPIRE_ON timestamp, ROLE varchar2(256 char), + LOGIN_FAILURE_COUNT number(10,0), + AT_LOGIN_FAILURE_COUNT number(10,0), USERNAME varchar2(256 char), primary key (ID, REV) ); diff --git a/smp-webapp/src/main/webapp/WEB-INF/web.xml b/smp-webapp/src/main/webapp/WEB-INF/web.xml index d6de0998890ee38573851bdc2e4b063c190f3e83..a2fffa74a2eba2499f159099aa19255f5d72da65 100644 --- a/smp-webapp/src/main/webapp/WEB-INF/web.xml +++ b/smp-webapp/src/main/webapp/WEB-INF/web.xml @@ -64,7 +64,8 @@ <context-param> <param-name>contextConfigLocation</param-name> <param-value> - eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; + eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; + eu.europa.ec.edelivery.smp.config.UISecurityConfigurerAdapter; eu.europa.ec.edelivery.smp.config.SmpAppConfig; eu.europa.ec.edelivery.smp.config.PropertiesConfig </param-value> diff --git a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java index ce5cf0afeb74cd03c3ed015c8bfd9dac23047e16..93474f5b977dec468da56ca0fc0d5b92a749b800 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java @@ -54,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. SmpAppConfig.class, SmpWebAppConfig.class, DatabaseConfig.class, - SpringSecurityConfig.class, + WSSecurityConfigurerAdapter.class, SpringSecurityTestConfig.class }) @WebAppConfiguration diff --git a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java index 4a279b284c7703ead6211b932adc2fb445822cb0..1af07ca29e9657bc12b57cacb8263b4b0f7ca108 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java @@ -45,8 +45,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. SmpAppConfig.class, SmpWebAppConfig.class, DatabaseConfig.class, - SpringSecurityConfig.class, - SpringSecurityTestConfig.class, + WSSecurityConfigurerAdapter.class, }) @WebAppConfiguration @Sql("classpath:/cleanup-database.sql") diff --git a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java index a58ef9a104252daa5b42303b7df4b2c63d9600d4..963ed4ebc13adafa2cc91c6fd7a9f91f71c83427 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SignatureValidatorTest.java @@ -18,11 +18,9 @@ import eu.europa.ec.edelivery.security.PreAuthenticatedCertificatePrincipal; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; -import eu.europa.ec.edelivery.smp.services.ui.UIKeystoreService; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.time.DateUtils; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,7 +29,6 @@ import org.springframework.mock.web.MockServletContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -39,7 +36,6 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.RequestPostProcessor; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.WebApplicationContext; import org.w3c.dom.Document; @@ -75,7 +71,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class + WSSecurityConfigurerAdapter.class }) @WebAppConfiguration @Sql(scripts = {"classpath:cleanup-database.sql", diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/config/PropertiesTestConfig.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/config/PropertiesTestConfig.java index 77a8fb28d37346349839cc7374a7ad05429ca810..51abb82986cfe6c601b2e2ec2dd234c156425701 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/config/PropertiesTestConfig.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/config/PropertiesTestConfig.java @@ -13,10 +13,7 @@ package eu.europa.ec.edelivery.smp.config; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.context.annotation.PropertySources; +import org.springframework.context.annotation.*; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import java.util.Properties; @@ -31,6 +28,7 @@ import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.*; @PropertySource(value = "classpath:config.properties", ignoreResourceNotFound = true), @PropertySource(value = "classpath:application.properties", ignoreResourceNotFound = true) }) +@ComponentScan(basePackages = "eu.europa.ec.edelivery.smp") public class PropertiesTestConfig { @Bean diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerSingleDomainTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerSingleDomainTest.java index 592ad8bb22ee8e38ea145b4d354594562c58d552..5e06b17fb3825678e6929665eac4ff265c254d25 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerSingleDomainTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerSingleDomainTest.java @@ -13,22 +13,21 @@ package eu.europa.ec.edelivery.smp.controllers; -import eu.europa.ec.edelivery.smp.AbstractTest; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.services.ui.UIKeystoreService; import eu.europa.ec.edelivery.smp.testutils.X509CertificateTestUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; import org.springframework.mock.web.MockServletContext; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; -import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; @@ -60,7 +59,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class, + WSSecurityConfigurerAdapter.class, UIKeystoreService.class }) @WebAppConfiguration diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java index 67b1cf3b324056d0751b50002e02f341da0ed8b4..3fc79a94401224abd245fba25c26c6aa30ee8f30 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/controllers/ServiceGroupControllerTest.java @@ -17,7 +17,6 @@ import eu.europa.ec.edelivery.smp.config.*; import eu.europa.ec.edelivery.smp.services.ui.UIKeystoreService; import eu.europa.ec.edelivery.smp.testutils.X509CertificateTestUtils; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -58,7 +57,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class, + WSSecurityConfigurerAdapter.class, UIKeystoreService.class, ForwardedHeaderTransformer.class }) diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java index 6360cbfd1bbc3d9309d212a73c9ef3b234c44d0c..1cf01a6adfdd02e4b2b17f2db22679d67723a621 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/monitor/MonitorResourceTest.java @@ -3,9 +3,8 @@ package eu.europa.ec.edelivery.smp.monitor; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.exceptions.SMPTestIsALiveException; -import eu.europa.ec.edelivery.smp.monitor.MonitorResource; import eu.europa.ec.edelivery.smp.testutils.X509CertificateTestUtils; import org.junit.Before; import org.junit.Rule; @@ -45,7 +44,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @Sql("classpath:/cleanup-database.sql") @Sql("classpath:/webapp_integration_test_data.sql") diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java index df1be54540ac154dd23dab5fd92147ad2fc12b3c..8286374e34656ec9bce92ac365566e4e78fbd89a 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResourceTest.java @@ -1,9 +1,6 @@ package eu.europa.ec.edelivery.smp.ui; -import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; -import eu.europa.ec.edelivery.smp.config.SmpAppConfig; -import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.*; import eu.europa.ec.edelivery.smp.error.ServiceErrorControllerAdvice; import eu.europa.ec.edelivery.smp.error.UIErrorControllerAdvice; import org.junit.Before; @@ -39,7 +36,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class, + UISecurityConfigurerAdapter.class, UIErrorControllerAdvice.class, ServiceErrorControllerAdvice.class}) @WebAppConfiguration @@ -62,8 +59,6 @@ public class AuthenticationResourceTest { mvc = MockMvcBuilders.webAppContextSetup(webAppContext) .apply(SecurityMockMvcConfigurers.springSecurity()) .build(); - - initServletContext(); } @@ -92,7 +87,6 @@ public class AuthenticationResourceTest { @Test @Ignore public void authenticateInvalidPasswordTest() throws Exception { - // given when then mvc.perform(post(PATH) .header("Content-Type", "application/json") diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java index 2076b331fd9df78f8df93c349b4c3072ab488222..99b1c79031965d8524ce3d56c323f4f65ed95e70 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.dao.ServiceGroupDao; import eu.europa.ec.edelivery.smp.data.model.DBServiceGroup; import eu.europa.ec.edelivery.smp.data.ui.ServiceGroupRO; @@ -32,7 +32,6 @@ import org.springframework.web.context.WebApplicationContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import javax.xml.ws.spi.WebServiceFeatureAnnotation; import java.io.IOException; @@ -52,7 +51,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @Sql("classpath:/cleanup-database.sql") @Sql("classpath:/webapp_integration_test_data.sql") @@ -135,7 +134,7 @@ public class ServiceGroupResourceTest { assertNotNull(sgro.getParticipantScheme()); assertNotNull(sgro.getParticipantIdentifier()); assertEquals(1, sgro.getUsers().size()); - assertEquals("sg_admin", sgro.getUsers().get(0).getUsername()); + assertNotNull(sgro.getUsers().get(0).getUserId()); }); } @@ -156,7 +155,7 @@ public class ServiceGroupResourceTest { assertEquals(PARTICIPANT_IDENTIFIER, res.getParticipantIdentifier()); assertEquals(PARTICIPANT_SCHEME, res.getParticipantScheme()); assertEquals(1, res.getUsers().size()); - assertEquals("test_user_hashed_pass", res.getUsers().get(0).getUsername()); + assertNotNull(res.getUsers().get(0).getUserId()); assertEquals(1, res.getServiceGroupDomains().size()); assertEquals(1, res.getServiceMetadata().size()); diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java index 8df1d88ea30f613ae0ab355b7d972f346457d083..6c5e75b75e8f051d75c48816101127acadd88f95 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java @@ -4,17 +4,17 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.ui.CertificateRO; import eu.europa.ec.edelivery.smp.data.ui.DeleteEntityValidation; import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.data.ui.UserRO; -import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockServletContext; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; @@ -36,9 +36,10 @@ import javax.ws.rs.core.MediaType; import java.util.Arrays; import java.util.UUID; +import static eu.europa.ec.edelivery.smp.ui.ResourceConstants.CONTEXT_PATH_INTERNAL_USER; +import static eu.europa.ec.edelivery.smp.ui.ResourceConstants.CONTEXT_PATH_PUBLIC_SECURITY; import static org.junit.Assert.*; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -51,32 +52,36 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class + }) @WebAppConfiguration @Sql("classpath:/cleanup-database.sql") @Sql("classpath:/webapp_integration_test_data.sql") @SqlConfig(encoding = "UTF-8") public class UserResourceTest { - private static final String PATH_INTERNAL = ResourceConstants.CONTEXT_PATH_INTERNAL_USER; private static final String PATH_PUBLIC = ResourceConstants.CONTEXT_PATH_PUBLIC_USER; - private static final String PATH_AUTHENTICATION = ResourceConstants.CONTEXT_PATH_PUBLIC_SECURITY + "/authentication"; - + private static final String PATH_AUTHENTICATION = CONTEXT_PATH_PUBLIC_SECURITY + "/authentication"; @Autowired private WebApplicationContext webAppContext; private MockMvc mvc; - private static final RequestPostProcessor ADMIN_CREDENTIALS = httpBasic("smp_admin", "test123"); - private static final RequestPostProcessor SYSTEM_CREDENTIALS = httpBasic("sys_admin", "test123"); - private static final RequestPostProcessor SG_ADMIN_CREDENTIALS = httpBasic("sg_admin", "test123"); + private static final String SMP_ADMIN_USERNAME="smp_admin"; + private static final String SMP_ADMIN_PASSWD="test123"; + private static final String SYS_ADMIN_USERNAME="sys_admin"; + private static final String SYS_ADMIN_PASSWD="test123"; + private static final String SG_ADMIN_USERNAME="sg_admin"; + private static final String SG_ADMIN_PASSWD="test123"; + + + ObjectMapper mapper = new ObjectMapper(); @Before public void setup() { mvc = MockMvcBuilders.webAppContextSetup(webAppContext) .apply(SecurityMockMvcConfigurers.springSecurity()) .build(); - initServletContext(); } @@ -88,17 +93,14 @@ public class UserResourceTest { @Test public void getUserList() throws Exception { - // given when - MvcResult result = mvc.perform(get(PATH_INTERNAL) - .with(ADMIN_CREDENTIALS) + + MockHttpSession session = loginWithCredentials(SYS_ADMIN_USERNAME, SYS_ADMIN_PASSWD); + MvcResult result = mvc.perform(get(CONTEXT_PATH_INTERNAL_USER) + .session(session) .with(csrf())) .andExpect(status().isOk()).andReturn(); - - //them - ObjectMapper mapper = new ObjectMapper(); ServiceResult res = mapper.readValue(result.getResponse().getContentAsString(), ServiceResult.class); - - + // then assertNotNull(res); assertEquals(10, res.getServiceEntities().size()); res.getServiceEntities().forEach(sgMap -> { @@ -110,31 +112,18 @@ public class UserResourceTest { } @Test - @Ignore public void testUpdateCurrentUserOK() throws Exception { - - // given when - log as SMP admin - MvcResult result = mvc.perform(post(PATH_AUTHENTICATION) - .header("Content-Type", "application/json") - .content("{\"username\":\"smp_admin\",\"password\":\"test123\"}")) - .andExpect(status().isOk()).andReturn(); - ObjectMapper mapper = new ObjectMapper(); - UserRO userRO = mapper.readValue(result.getResponse().getContentAsString(), UserRO.class); - assertNotNull(userRO); - - MockHttpSession session = (MockHttpSession) result.getRequest().getSession(); - - // when + // login + MockHttpSession session = loginWithCredentials(SMP_ADMIN_USERNAME, SMP_ADMIN_PASSWD); + // when update data + UserRO userRO = getLoggedUserData(session); userRO.setActive(!userRO.isActive()); userRO.setEmailAddress("test@mail.com"); - userRO.setPassword(UUID.randomUUID().toString()); if (userRO.getCertificate() == null) { userRO.setCertificate(new CertificateRO()); } userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); - mvc.perform(put(PATH_PUBLIC + "/" + userRO.getUserId()) - .with(ADMIN_CREDENTIALS) .with(csrf()) .session(session) .contentType(MediaType.APPLICATION_JSON) @@ -147,25 +136,19 @@ public class UserResourceTest { // given when - log as SMP admin // then change values and list uses for changed value - MvcResult result = mvc.perform(post(PATH_AUTHENTICATION) - .header("Content-Type", "application/json") - .content("{\"username\":\"smp_admin\",\"password\":\"test123\"}")) - .andExpect(status().isOk()).andReturn(); - ObjectMapper mapper = new ObjectMapper(); - UserRO userRO = mapper.readValue(result.getResponse().getContentAsString(), UserRO.class); + MockHttpSession session = loginWithCredentials(SMP_ADMIN_USERNAME, SMP_ADMIN_PASSWD); + UserRO userRO = getLoggedUserData(session); assertNotNull(userRO); - // when userRO.setActive(!userRO.isActive()); userRO.setEmailAddress("test@mail.com"); - userRO.setPassword(UUID.randomUUID().toString()); if (userRO.getCertificate() == null) { userRO.setCertificate(new CertificateRO()); } userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); mvc.perform(put(PATH_PUBLIC + "/" + userRO.getUserId()) - .with(SYSTEM_CREDENTIALS) + .with(httpBasic(SYS_ADMIN_USERNAME, SYS_ADMIN_PASSWD)) .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(userRO)) @@ -175,11 +158,11 @@ public class UserResourceTest { @Test public void testUpdateUserList() throws Exception { // given when - MvcResult result = mvc.perform(get(PATH_INTERNAL) - .with(SYSTEM_CREDENTIALS) + MockHttpSession session = loginWithCredentials(SYS_ADMIN_USERNAME, SYS_ADMIN_PASSWD); + MvcResult result = mvc.perform(get(CONTEXT_PATH_INTERNAL_USER) + .session(session) .with(csrf())) .andExpect(status().isOk()).andReturn(); - ObjectMapper mapper = new ObjectMapper(); ServiceResult res = mapper.readValue(result.getResponse().getContentAsString(), ServiceResult.class); assertNotNull(res); assertFalse(res.getServiceEntities().isEmpty()); @@ -193,8 +176,8 @@ public class UserResourceTest { } userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); - mvc.perform(put(PATH_INTERNAL) - .with(SYSTEM_CREDENTIALS) + mvc.perform(put(CONTEXT_PATH_INTERNAL_USER) + .session(session) .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) @@ -204,11 +187,11 @@ public class UserResourceTest { @Test public void testUpdateUserListWrongAuthentication() throws Exception { // given when - MvcResult result = mvc.perform(get(PATH_INTERNAL) - .with(SYSTEM_CREDENTIALS) + MockHttpSession session = loginWithCredentials(SYS_ADMIN_USERNAME, SYS_ADMIN_PASSWD); + MvcResult result = mvc.perform(get(CONTEXT_PATH_INTERNAL_USER) + .session(session) .with(csrf())) .andExpect(status().isOk()).andReturn(); - ObjectMapper mapper = new ObjectMapper(); ServiceResult res = mapper.readValue(result.getResponse().getContentAsString(), ServiceResult.class); assertNotNull(res); assertFalse(res.getServiceEntities().isEmpty()); @@ -222,21 +205,23 @@ public class UserResourceTest { } userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); // anonymous - mvc.perform(put(PATH_INTERNAL) + mvc.perform(put(CONTEXT_PATH_INTERNAL_USER) .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) ).andExpect(status().isUnauthorized()); - mvc.perform(put(PATH_INTERNAL) - .with(ADMIN_CREDENTIALS) + MockHttpSession sessionSMPAdmin = loginWithCredentials(SMP_ADMIN_USERNAME, SMP_ADMIN_PASSWD); + mvc.perform(put(CONTEXT_PATH_INTERNAL_USER) + .session(sessionSMPAdmin) .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) ).andExpect(status().isUnauthorized()); - mvc.perform(put(PATH_INTERNAL) - .with(SG_ADMIN_CREDENTIALS) + MockHttpSession sessionSGAdmin = loginWithCredentials(SG_ADMIN_USERNAME, SG_ADMIN_PASSWD); + mvc.perform(put(CONTEXT_PATH_INTERNAL_USER) + .session(sessionSGAdmin) .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) @@ -244,41 +229,92 @@ public class UserResourceTest { } @Test - @Ignore public void testValidateDeleteUserOK() throws Exception { - MvcResult result = mvc.perform(put(PATH_INTERNAL + "/validate-delete") - .with(SYSTEM_CREDENTIALS) + + // login + MockHttpSession session = loginWithCredentials(SYS_ADMIN_USERNAME, SYS_ADMIN_PASSWD); + // get list + MvcResult result = mvc.perform(get(CONTEXT_PATH_INTERNAL_USER) .with(csrf()) - .contentType(org.springframework.http.MediaType.APPLICATION_JSON) - .content("[" + SessionSecurityUtils.encryptedEntityId(5L) + "]")) + .session(session)) + .andExpect(status().isOk()).andReturn(); + ServiceResult res = mapper.readValue(result.getResponse().getContentAsString(), ServiceResult.class); + assertNotNull(res); + assertFalse(res.getServiceEntities().isEmpty()); + UserRO userRO = mapper.convertValue(res.getServiceEntities().get(0), UserRO.class); + + MvcResult resultDelete = mvc.perform(post(CONTEXT_PATH_INTERNAL_USER + "/validate-delete") + .with(csrf()) + .session(session) + .contentType(MediaType.APPLICATION_JSON) + .content("[\"" + userRO.getUserId() + "\"]")) .andExpect(status().isOk()).andReturn(); - ObjectMapper mapper = new ObjectMapper(); - DeleteEntityValidation res = mapper.readValue(result.getResponse().getContentAsString(), DeleteEntityValidation.class); + DeleteEntityValidation dev = mapper.readValue(resultDelete.getResponse().getContentAsString(), DeleteEntityValidation.class); - assertFalse(res.getListIds().isEmpty()); - assertTrue(res.getListDeleteNotPermitedIds().isEmpty()); - assertEquals(5, res.getListIds().get(0).intValue()); + assertFalse(dev.getListIds().isEmpty()); + assertTrue(dev.getListDeleteNotPermitedIds().isEmpty()); + assertEquals(userRO.getUserId(), dev.getListIds().get(0)); } @Test - @Ignore - public void testValidateDeleteUserNotOK() throws Exception { + public void testValidateDeleteLoggedUserNotOK() throws Exception { + + // login + MockHttpSession session = loginWithCredentials(SYS_ADMIN_USERNAME, SYS_ADMIN_PASSWD); + // get list + MvcResult result = mvc.perform(get(CONTEXT_PATH_INTERNAL_USER) + .with(csrf()) + .session(session)) + .andExpect(status().isOk()).andReturn(); + UserRO userRO = getLoggedUserData(session); + // note system credential has id 3! - MvcResult result = mvc.perform(post(PATH_INTERNAL + "/validate-delete") - .with(SYSTEM_CREDENTIALS) + MvcResult resultDelete = mvc.perform(post(CONTEXT_PATH_INTERNAL_USER + "/validate-delete") .with(csrf()) + .session(session) .contentType(org.springframework.http.MediaType.APPLICATION_JSON) - .content("[3]")) + .content("[\""+userRO.getUserId()+"\"]")) .andExpect(status().isOk()) .andReturn(); - ObjectMapper mapper = new ObjectMapper(); - DeleteEntityValidation res = mapper.readValue(result.getResponse().getContentAsString(), DeleteEntityValidation.class); + DeleteEntityValidation res = mapper.readValue(resultDelete.getResponse().getContentAsString(), DeleteEntityValidation.class); assertTrue(res.getListIds().isEmpty()); assertEquals("Could not delete logged user!", res.getStringMessage()); + } + + + /** + * Login with the username and data + * @param username + * @param password + * @return + * @throws Exception + */ + public MockHttpSession loginWithCredentials(String username, String password) throws Exception { + MvcResult result = mvc.perform(post(PATH_AUTHENTICATION) + .header(HttpHeaders.CONTENT_TYPE, org.springframework.http.MediaType.APPLICATION_JSON_VALUE) + .content("{\"username\":\""+username+"\",\"password\":\""+password+"\"}")) + .andExpect(status().isOk()).andReturn(); + // assert successful login + UserRO userRO = mapper.readValue(result.getResponse().getContentAsString(), UserRO.class); + assertNotNull(userRO); + return (MockHttpSession) result.getRequest().getSession(); + } + /** + * Return currently logged in data for the session + * @param session + * @return + * @throws Exception + */ + public UserRO getLoggedUserData(MockHttpSession session) throws Exception { + MvcResult result = mvc.perform(get(CONTEXT_PATH_PUBLIC_SECURITY+"/user") + .session(session) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); + return mapper.readValue(result.getResponse().getContentAsString(), UserRO.class); } } \ No newline at end of file diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResourceTest.java index 4e6a4d1d0d55691ea505fbc418340069c7c96ffc..68f6ce54e03b12ca4ec851e018489a56fe492b44 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResourceTest.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.ui.SmpInfoRO; import eu.europa.ec.edelivery.smp.ui.ResourceConstants; import org.junit.Before; @@ -28,7 +28,6 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import static org.junit.Assert.assertEquals; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -38,7 +37,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @SqlConfig(encoding = "UTF-8") @Sql(scripts = {"classpath:cleanup-database.sql", diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceTest.java index 61858cb3d11a9a4523efcf83c46ea2a3e8de1242..9ea0d2fe6d34b5a9819cc8e0f293d40e59c18b67 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/DomainResourceTest.java @@ -3,7 +3,6 @@ package eu.europa.ec.edelivery.smp.ui.external; import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.*; import eu.europa.ec.edelivery.smp.data.dao.DomainDao; -import eu.europa.ec.edelivery.smp.data.ui.DeleteEntityValidation; import eu.europa.ec.edelivery.smp.data.ui.DomainRO; import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.ui.ResourceConstants; @@ -14,14 +13,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockServletContext; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.RequestPostProcessor; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.WebApplicationContext; @@ -32,11 +29,9 @@ import javax.servlet.ServletContextListener; import static org.hamcrest.Matchers.stringContainsInOrder; import static org.junit.Assert.*; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -45,7 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @Sql("classpath:/cleanup-database.sql") @Sql("classpath:/webapp_integration_test_data.sql") diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/SearchResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/SearchResourceTest.java index 7997213e400270e3bc02c18fe27dcdf2ff0c8c57..979d888bdccf770d60c19432ce341160d062b43d 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/SearchResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/external/SearchResourceTest.java @@ -4,10 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; -import eu.europa.ec.edelivery.smp.data.ui.ServiceGroupRO; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; -import eu.europa.ec.edelivery.smp.ui.ResourceConstants; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -21,7 +19,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.RequestPostProcessor; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.WebApplicationContext; @@ -31,7 +28,6 @@ import javax.servlet.ServletContextListener; import static eu.europa.ec.edelivery.smp.ui.ResourceConstants.CONTEXT_PATH_PUBLIC_SEARCH_PARTICIPANT; import static org.junit.Assert.*; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -45,7 +41,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @Sql("classpath:/cleanup-database.sql") @Sql("classpath:/webapp_integration_test_data.sql") diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/ApplicationAdminResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/ApplicationAdminResourceTest.java index fb067c09c5e73c45404554ab15a9b10769adad34..1d0486bab74eb91aacd9f96ab55e358809519a22 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/ApplicationAdminResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/ApplicationAdminResourceTest.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.ui.SmpConfigRO; import eu.europa.ec.edelivery.smp.ui.ResourceConstants; import org.junit.Before; @@ -40,7 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @SqlConfig(encoding = "UTF-8") @Sql(scripts = {"classpath:cleanup-database.sql", diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResourceTest.java index aa6de7444cca5751d4b214d444c292bc4df267b9..3eb5f77d1d35d572da493f4c03e0b9aa2e511489 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/DomainAdminResourceTest.java @@ -4,11 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.dao.DomainDao; import eu.europa.ec.edelivery.smp.data.ui.DeleteEntityValidation; -import eu.europa.ec.edelivery.smp.data.ui.DomainRO; -import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.ui.ResourceConstants; import org.junit.Before; import org.junit.Test; @@ -17,7 +15,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockServletContext; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -46,7 +43,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @Sql("classpath:/cleanup-database.sql") @Sql("classpath:/webapp_integration_test_data.sql") diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/KeystoreResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/KeystoreResourceTest.java index 6f1d23f9eb47b6b450584f86f92122892d500add..04fc5143fa0da712c500c4f4e0840220685d0200 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/KeystoreResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/KeystoreResourceTest.java @@ -5,11 +5,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.ui.*; import eu.europa.ec.edelivery.smp.services.ui.UIKeystoreService; import eu.europa.ec.edelivery.smp.testutils.X509CertificateTestUtils; -import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockServletContext; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -33,11 +31,9 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import static eu.europa.ec.edelivery.smp.ui.ResourceConstants.CONTEXT_PATH_INTERNAL_KEYSTORE; import static org.junit.Assert.assertEquals; @@ -56,7 +52,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class}) + WSSecurityConfigurerAdapter.class}) @WebAppConfiguration @SqlConfig(encoding = "UTF-8") @Sql(scripts = {"classpath:cleanup-database.sql", diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceTest.java index 2bc6e27fba62563868003d49e33cacbc0f41ebf4..f4950ee3eace7f35a6677ad73e6047fd5fcea171 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/internal/TruststoreAdminResourceTest.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.edelivery.smp.config.PropertiesTestConfig; import eu.europa.ec.edelivery.smp.config.SmpAppConfig; import eu.europa.ec.edelivery.smp.config.SmpWebAppConfig; -import eu.europa.ec.edelivery.smp.config.SpringSecurityConfig; +import eu.europa.ec.edelivery.smp.config.WSSecurityConfigurerAdapter; import eu.europa.ec.edelivery.smp.data.ui.CertificateRO; import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.error.UIErrorControllerAdvice; @@ -15,7 +15,6 @@ import eu.europa.ec.edelivery.smp.ui.UserResourceTest; import org.apache.commons.io.IOUtils; import org.hamcrest.CoreMatchers; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -55,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. PropertiesTestConfig.class, SmpAppConfig.class, SmpWebAppConfig.class, - SpringSecurityConfig.class, + WSSecurityConfigurerAdapter.class, UIErrorControllerAdvice.class}) @WebAppConfiguration @SqlConfig(encoding = "UTF-8")