diff --git a/domismp-tests/domismp-tests-ui/src/main/java/utils/XMLUtils.java b/domismp-tests/domismp-tests-ui/src/main/java/utils/XMLUtils.java index dbde54e4118cda60663bbec67efe721515d78556..aa258fb15134ad32f990e4f56c5045759ac803d3 100644 --- a/domismp-tests/domismp-tests-ui/src/main/java/utils/XMLUtils.java +++ b/domismp-tests/domismp-tests-ui/src/main/java/utils/XMLUtils.java @@ -26,8 +26,8 @@ public class XMLUtils { public XMLUtils(String xmlStr) throws ParserConfigurationException { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + dbFactory.setNamespaceAware(true); + dbFactory.setValidating(true); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); try { doc = dBuilder.parse(new InputSource(new StringReader(xmlStr))); diff --git a/smp-angular/src/app/app.module.ts b/smp-angular/src/app/app.module.ts index 6cfd77b7f3648d372ae50c02ed5a7c0176a98699..d649da40fd94addffeddbdb6883f6165a1d69ac1 100644 --- a/smp-angular/src/app/app.module.ts +++ b/smp-angular/src/app/app.module.ts @@ -45,7 +45,7 @@ import {FlexLayoutModule} from '@angular/flex-layout'; import {FooterComponent} from './window/footer/footer.component'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {GlobalLookups} from './common/global-lookups'; -import {HttpClient, HttpClientModule, HttpClientXsrfModule} from '@angular/common/http'; +import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule, HttpClientXsrfModule} from '@angular/common/http'; import {HttpEventService} from './http/http-event.service'; import {InformationDialogComponent} from "./common/dialogs/information-dialog/information-dialog.component"; import {IsAuthorized} from './security/is-authorized.directive'; @@ -154,6 +154,10 @@ import { PropertyDetailsDialogComponent } from "./common/dialogs/property-details-dialog/property-details-dialog.component"; import {ResourceFilterOptionsService} from "./common/services/resource-filter-options.service"; +import {HttpSessionInterceptor} from "./http/http-session-interceptor"; +import { + SessionExpirationDialogComponent +} from "./common/dialogs/session-expiration-dialog/session-expiration-dialog.component"; @NgModule({ @@ -241,6 +245,7 @@ import {ResourceFilterOptionsService} from "./common/services/resource-filter-op UserCertificatesComponent, UserProfileComponent, UserProfilePanelComponent, + SessionExpirationDialogComponent, ], imports: [ BrowserAnimationsModule, @@ -323,6 +328,7 @@ import {ResourceFilterOptionsService} from "./common/services/resource-filter-op {provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS}, {provide: NgxMatDateAdapter, useClass: NgxMatMomentAdapter, deps: [MAT_DATE_LOCALE, NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS]}, {provide: NGX_MAT_DATE_FORMATS, useValue: NGX_MAT_MOMENT_FORMATS}, + {provide: HTTP_INTERCEPTORS, useClass: HttpSessionInterceptor, multi: true}, ], bootstrap: [AppComponent] }) diff --git a/smp-angular/src/app/common/dialogs/session-expiration-dialog/session-expiration-dialog.component.html b/smp-angular/src/app/common/dialogs/session-expiration-dialog/session-expiration-dialog.component.html new file mode 100644 index 0000000000000000000000000000000000000000..589c43d317c75e2d8c8a76b78bffd67b99a4dd0c --- /dev/null +++ b/smp-angular/src/app/common/dialogs/session-expiration-dialog/session-expiration-dialog.component.html @@ -0,0 +1,12 @@ +<h2 mat-dialog-title>Extend session</h2> +<mat-dialog-content>Your session is about to expire in <b>{{data.timeLeft}}</b> seconds!<br />Would you like to logout now or extend it for another <b>{{data.timeout}}</b> seconds?</mat-dialog-content> +<mat-dialog-actions> + <button mat-raised-button mat-dialog-close (click)="onLogoutClicked()" tabindex="-1"> + <mat-icon>power_settings_new</mat-icon> + <mat-label>Logout</mat-label> + </button> + <button mat-raised-button mat-dialog-close color="primary" (click)="onExtendSessionClicked()"> + <mat-icon>autorenew</mat-icon> + <mat-label>Extend</mat-label> + </button> +</mat-dialog-actions> diff --git a/smp-angular/src/app/common/dialogs/session-expiration-dialog/session-expiration-dialog.component.ts b/smp-angular/src/app/common/dialogs/session-expiration-dialog/session-expiration-dialog.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..8d459600e665165cdc997b5cdb03b64116044382 --- /dev/null +++ b/smp-angular/src/app/common/dialogs/session-expiration-dialog/session-expiration-dialog.component.ts @@ -0,0 +1,26 @@ +import {Component, Inject} from '@angular/core'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; +import {SecurityService} from "../../../security/security.service"; + +@Component({ + templateUrl: './session-expiration-dialog.component.html', +}) +export class SessionExpirationDialogComponent { + + constructor(@Inject(MAT_DIALOG_DATA) public data: any, + public dialogRef: MatDialogRef<SessionExpirationDialogComponent>, + public securityService: SecurityService) { + } + + public onExtendSessionClicked() { + // just make another simple call to the backend which cancels out the current inactivity + this.securityService.isAuthenticated(true); + this.dialogRef.close(); + } + + onLogoutClicked() { + this.securityService.logout(); + this.dialogRef.close(); + } +} + diff --git a/smp-angular/src/app/http/http-session-interceptor.ts b/smp-angular/src/app/http/http-session-interceptor.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b5a3b9f1f4a7868742ab021d19a1c69336763e6 --- /dev/null +++ b/smp-angular/src/app/http/http-session-interceptor.ts @@ -0,0 +1,49 @@ +import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http"; +import {Observable} from "rxjs"; +import {Injectable} from "@angular/core"; +import {SecurityService} from "../security/security.service"; +import {AlertMessageService} from "../common/alert-message/alert-message.service"; +import {MatDialog} from "@angular/material/dialog"; +import { + SessionExpirationDialogComponent +} from "../common/dialogs/session-expiration-dialog/session-expiration-dialog.component"; + +/* + * A custom interceptor that handles session expiration before it happens. + * + * Users are prompted 60 seconds before their HTTP sessions are about to expire + * and asked whether they would like to logout or extend the session time again. + */ +@Injectable({ + providedIn: 'root' +}) +export class HttpSessionInterceptor implements HttpInterceptor { + + private readonly TIME_BEFORE_EXPIRATION_IN_SECONDS = 60; + + private timerId: number; + + constructor(public securityService: SecurityService, + public alertMessageService: AlertMessageService, + private dialog: MatDialog) { + } + + public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { + clearTimeout(this.timerId); + let user = this.securityService.getCurrentUser(); + if (user && user.sessionMaxIntervalTimeoutInSeconds && user.sessionMaxIntervalTimeoutInSeconds > this.TIME_BEFORE_EXPIRATION_IN_SECONDS) { + let timeout = (user.sessionMaxIntervalTimeoutInSeconds - this.TIME_BEFORE_EXPIRATION_IN_SECONDS) * 1000; + this.timerId = setTimeout(() => this.sessionExpiringSoon(user.sessionMaxIntervalTimeoutInSeconds), timeout); + } + return next.handle(req); + } + + private sessionExpiringSoon(timeout) { + this.dialog.open(SessionExpirationDialogComponent, { + data: { + timeLeft: this.TIME_BEFORE_EXPIRATION_IN_SECONDS, + timeout + } + }); + } +} diff --git a/smp-angular/src/app/security/user.model.ts b/smp-angular/src/app/security/user.model.ts index de4c26e2395ccec8bdb78c21c348bada60051860..5f8a033aaf22a27551b7dc5b374cdb736ade7248 100644 --- a/smp-angular/src/app/security/user.model.ts +++ b/smp-angular/src/app/security/user.model.ts @@ -9,9 +9,6 @@ export interface User { smpTheme?: string; smpLocale?: string; - - - accessTokenId?: string; accessTokenExpireOn?: Date; sequentialTokenLoginFailureCount?:number; @@ -26,6 +23,7 @@ export interface User { sequentialLoginFailureCount?:number; lastFailedLoginAttempt?:Date; suspendedUtil?:Date; + sessionMaxIntervalTimeoutInSeconds?: number; casUserDataUrl?: string; } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java index 60c05f24f38420a4ffe39dee0c59341cc1d03444..b1efe4b44d13b99e1ed32179a6e60c5c0ee1e48e 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/UserRO.java @@ -57,6 +57,7 @@ public class UserRO extends BaseRO { private boolean passwordExpired = false; private boolean showPasswordExpirationWarning = false; private boolean forceChangeExpiredPassword = false; + private int sessionMaxIntervalTimeoutInSeconds; /** * Get DB user hash value. It can be used as unique ID for the user. Use hash value for the webservice/ui and do not @@ -225,4 +226,12 @@ public class UserRO extends BaseRO { public void setSuspendedUtil(OffsetDateTime suspendedUtil) { this.suspendedUtil = suspendedUtil; } + + public void setSessionMaxIntervalTimeoutInSeconds(int sessionMaxIntervalTimeoutInSeconds) { + this.sessionMaxIntervalTimeoutInSeconds = sessionMaxIntervalTimeoutInSeconds; + } + + public int getSessionMaxIntervalTimeoutInSeconds() { + return sessionMaxIntervalTimeoutInSeconds; + } } 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 4e2f10c832a84a4d3c5bde749bfa018a22ed4f90..171153ac5bee1ee4261be2f65c561c3f5aaed04b 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 @@ -22,18 +22,21 @@ import eu.europa.ec.edelivery.smp.auth.enums.SMPUserAuthenticationTypes; import eu.europa.ec.edelivery.smp.config.enums.SMPDomainPropertyEnum; import eu.europa.ec.edelivery.smp.config.enums.SMPPropertyEnum; import eu.europa.ec.edelivery.smp.data.dao.ConfigurationDao; +import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; import eu.europa.ec.edelivery.smp.data.ui.enums.AlertLevelEnum; import eu.europa.ec.edelivery.smp.data.ui.enums.AlertSuspensionMomentEnum; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service; import java.io.File; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; @@ -316,6 +319,16 @@ public class ConfigurationService { return configurationDAO.getCachedPropertyValue(UI_COOKIE_SESSION_PATH); } + public int getSessionTimeoutForRoles(Collection<? extends GrantedAuthority> authorities) { + boolean hasAdminRole = false; + if (authorities != null) { + hasAdminRole = authorities.stream().anyMatch(grantedAuthority -> + StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority())); + } + LOG.debug("Has admin role [{}]", hasAdminRole); + return hasAdminRole ? getSessionIdleTimeoutForAdmin(): getSessionIdleTimeoutForUser(); + } + public Integer getSessionIdleTimeoutForAdmin() { return configurationDAO.getCachedPropertyValue(UI_COOKIE_SESSION_IDLE_TIMEOUT_ADMIN); } @@ -612,6 +625,4 @@ public class ConfigurationService { public <T> T getDefaultDomainConfigurationValue(SMPDomainPropertyEnum property) { return configurationDAO.getCachedPropertyValue(property.getPropertyEnum()); } - - } diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceTest.java index 7d11c60fc7de0e5a391bc2519117502fb4ccb847..a58aefe7b519385e938f925df0b022058038b5dc 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ConfigurationServiceTest.java @@ -19,22 +19,32 @@ package eu.europa.ec.edelivery.smp.services; import eu.europa.ec.edelivery.smp.data.dao.ConfigurationDao; +import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.security.core.GrantedAuthority; import java.net.MalformedURLException; import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import static eu.europa.ec.edelivery.smp.config.enums.SMPPropertyEnum.SSO_CAS_SMP_USER_DATA_URL_PATH; import static eu.europa.ec.edelivery.smp.config.enums.SMPPropertyEnum.SSO_CAS_URL; import static org.junit.jupiter.api.Assertions.*; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.*; class ConfigurationServiceTest { ConfigurationDao configurationDaoMock = mock(ConfigurationDao.class); - ConfigurationService testInstance = new ConfigurationService(configurationDaoMock); + ConfigurationService testInstance = spy(new ConfigurationService(configurationDaoMock)); + + @BeforeEach + public void setUp() { + Mockito.clearInvocations(testInstance); + } @Test void testGetCasUserDataURL() throws MalformedURLException { @@ -48,4 +58,58 @@ class ConfigurationServiceTest { // expected - the same server but different context path assertEquals("http://test:123/" + casUserDataPath, result.toString()); } + + @Test + void getSessionTimeoutForRolesSMPAdmin() { + // Given + Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_USER); + // when then + assertTimeoutForAuthorities(authorities, false); + } + + @Test + void getSessionTimeoutForRolesSystemAdmin() { + // Given + Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN); + // when then + assertTimeoutForAuthorities(authorities, true); + } + + @Test + void getSessionTimeoutForRolesUser() { + // Given + Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_USER); + // when then + assertTimeoutForAuthorities(authorities, false); + } + + @Test + void getSessionTimeoutForRolesUserAndSystem() { + // Given + Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_USER, SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN); + // when then + assertTimeoutForAuthorities(authorities, true); + } + + @Test + void getSessionTimeoutForRolesUserAndSMP() { + // Given + Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_USER); + // when then + assertTimeoutForAuthorities(authorities, false); + } + + public void assertTimeoutForAuthorities(Collection<? extends GrantedAuthority> authorities, boolean isAdmin) { + // Given + int secondsToTimeoutAdmin = 111; + int secondsToTimeoutUser = 555; + int expected = isAdmin ? secondsToTimeoutAdmin : secondsToTimeoutUser; + // idle for admin + Mockito.doReturn(secondsToTimeoutAdmin).when(testInstance).getSessionIdleTimeoutForAdmin(); + Mockito.doReturn(secondsToTimeoutUser).when(testInstance).getSessionIdleTimeoutForUser(); + // when + int result = testInstance.getSessionTimeoutForRoles(authorities); + //then + assertEquals(expected, result); + } } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java index aa713ece49ced79d17c6a713c9c087408d8cda3c..e3716c839d524907402a2a3fd27220def016f315 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListener.java @@ -18,11 +18,9 @@ */ package eu.europa.ec.edelivery.smp.auth; -import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.services.ConfigurationService; -import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.security.authentication.event.AuthenticationSuccessEvent; @@ -62,12 +60,11 @@ public class SMPAuthenticationEventListener implements ApplicationListener<Authe */ @Override public void onApplicationEvent(AuthenticationSuccessEvent event) { - ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attr != null) { Collection<? extends GrantedAuthority> authorities = event.getAuthentication().getAuthorities(); HttpSession session = attr.getRequest().getSession(); - int idleTimeout = getSessionTimeoutForRoles(authorities); + int idleTimeout = configurationService.getSessionTimeoutForRoles(authorities); LOG.debug("Set session idle timeout [{}] for user [{}] with roles [{}]", idleTimeout, event.getAuthentication().getName(), authorities.stream().map(GrantedAuthority::getAuthority).toArray()); @@ -77,14 +74,5 @@ public class SMPAuthenticationEventListener implements ApplicationListener<Authe } } - public int getSessionTimeoutForRoles(Collection<? extends GrantedAuthority> authorities) { - boolean hasAdminRole = authorities.stream().anyMatch(grantedAuthority -> - StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()) - ); - LOG.debug("has admin role [{}]", hasAdminRole); - LOG.debug("configurationService [{}]", configurationService); - return hasAdminRole ? configurationService.getSessionIdleTimeoutForAdmin() : - configurationService.getSessionIdleTimeoutForUser(); - } } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java index b7f32e5c765224990b8b5aff1ef7fbb7a2c87000..a93941668f529b9659d3d7e5881579041083619a 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationService.java @@ -37,12 +37,14 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.core.convert.ConversionService; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.session.SessionAuthenticationException; import org.springframework.stereotype.Service; import java.net.URL; import java.time.OffsetDateTime; +import java.util.Collection; import java.util.Collections; import java.util.stream.Collectors; @@ -211,14 +213,14 @@ public class SMPAuthorizationService { userDetails.getUser().getUsername()); return null; } - UserRO userRO = getUserData(dbUser); + UserRO userRO = getUserData(dbUser, userDetails.getAuthorities()); userRO.setCasAuthenticated(userDetails.isCasAuthenticated()); return userRO; } - public UserRO getUserData(DBUser user) { + public UserRO getUserData(DBUser user, Collection<? extends GrantedAuthority> authorities) { UserRO userRO = conversionService.convert(user, UserRO.class); - return userRO == null ? null : getUpdatedUserData(userRO); + return userRO == null ? null : getUpdatedUserData(userRO, authorities); } /** @@ -228,7 +230,7 @@ public class SMPAuthorizationService { * @param userRO * @return updated user data according to SMP configuration */ - public UserRO getUpdatedUserData(UserRO userRO) { + public UserRO getUpdatedUserData(UserRO userRO, Collection<? extends GrantedAuthority> authorities) { userRO.setShowPasswordExpirationWarning(userRO.getPasswordExpireOn() != null && OffsetDateTime.now().plusDays(configurationService.getPasswordPolicyUIWarningDaysBeforeExpire()) .isAfter(userRO.getPasswordExpireOn())); @@ -240,6 +242,9 @@ public class SMPAuthorizationService { userRO.setCasUserDataUrl(casUrlData != null ? casUrlData.toString() : null); } + int sessionTimeoutForRoles = configurationService.getSessionTimeoutForRoles(authorities); + userRO.setSessionMaxIntervalTimeoutInSeconds(sessionTimeoutForRoles); + return sanitize(userRO); } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationController.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationController.java index 51230f587d03573942eeae48160d33b3df826979..30624687921ff44265270682a92c6579d70a3642 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationController.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationController.java @@ -100,8 +100,7 @@ public class AuthenticationController { loginRO.getPassword()); SMPUserDetails user = authentication.getUserDetails(); - - return authorizationService.getUserData(user.getUser()); + return authorizationService.getUserData(user.getUser(), authentication.getAuthorities()); } /** diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/UserController.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/UserController.java index f5094e3c624b4f59ae8ced7b784c33c23301458b..3a69adc5265442a1a100be8ff2c744787fb2f889 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/UserController.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/UserController.java @@ -104,7 +104,7 @@ public class UserController { // refresh user from DB UserRO userRO = uiUserService.getUserById(entityId); // return clean user to UI - return authorizationService.getUpdatedUserData(userRO); + return authorizationService.getUpdatedUserData(userRO, userRO.getAuthorities()); } /** diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java deleted file mode 100644 index c5e4f888159e196806acaf28304845b26edc558a..0000000000000000000000000000000000000000 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthenticationEventListenerTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * #START_LICENSE# - * smp-webapp - * %% - * Copyright (C) 2017 - 2024 European Commission | eDelivery | DomiSMP - * %% - * 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 at: - * - * [PROJECT_HOME]\license\eupl-1.2\license.txt or https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * 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. - * #END_LICENSE# - */ -package eu.europa.ec.edelivery.smp.auth; - -import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; -import eu.europa.ec.edelivery.smp.services.ConfigurationService; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.security.core.GrantedAuthority; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; - -import static org.junit.jupiter.api.Assertions.*; - -class SMPAuthenticationEventListenerTest { - - ConfigurationService configurationService = Mockito.mock(ConfigurationService.class); - // test instance - SMPAuthenticationEventListener testInstance = new SMPAuthenticationEventListener(configurationService); - - - @Test - void getSessionTimeoutForRolesSMPAdmin() { - // Given - Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_USER); - // when then - assertTimeoutForAuthorities(authorities, false); - } - - @Test - void getSessionTimeoutForRolesSystemAdmin() { - // Given - Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN); - // when then - assertTimeoutForAuthorities(authorities, true); - } - - @Test - void getSessionTimeoutForRolesUser() { - // Given - Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_USER); - // when then - assertTimeoutForAuthorities(authorities, false); - } - - @Test - void getSessionTimeoutForRolesUserAndSystem() { - // Given - Collection<? extends GrantedAuthority> authorities = Arrays.asList(SMPAuthority.S_AUTHORITY_USER, SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN); - // when then - assertTimeoutForAuthorities(authorities, true); - } - - @Test - void getSessionTimeoutForRolesUserAndSMP() { - // Given - Collection<? extends GrantedAuthority> authorities = Collections.singletonList(SMPAuthority.S_AUTHORITY_USER); - // when then - assertTimeoutForAuthorities(authorities, false); - } - - public void assertTimeoutForAuthorities(Collection<? extends GrantedAuthority> authorities, boolean isAdmin) { - // Given - int secondsToTimeoutAdmin = 111; - int secondsToTimeoutUser = 555; - int expected = isAdmin ? secondsToTimeoutAdmin : secondsToTimeoutUser; - // idle for admin - Mockito.doReturn(secondsToTimeoutAdmin).when(configurationService).getSessionIdleTimeoutForAdmin(); - Mockito.doReturn(secondsToTimeoutUser).when(configurationService).getSessionIdleTimeoutForUser(); - // when - int result = testInstance.getSessionTimeoutForRoles(authorities); - //then - assertEquals(expected, result); - } -} diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java index ac8fe3e3a692d95b77d01acc2daa06e4c7d2dd40..b8c2d52c42efaeae82b324084b379cf190a473e9 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/auth/SMPAuthorizationServiceTest.java @@ -134,7 +134,7 @@ class SMPAuthorizationServiceTest { Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire(); Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired(); - user = testInstance.getUpdatedUserData(user); + user = testInstance.getUpdatedUserData(user, null); assertTrue(user.isShowPasswordExpirationWarning()); assertFalse(user.isForceChangeExpiredPassword()); @@ -149,7 +149,7 @@ class SMPAuthorizationServiceTest { Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire(); Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired(); - user = testInstance.getUpdatedUserData(user); + user = testInstance.getUpdatedUserData(user, null); assertFalse(user.isShowPasswordExpirationWarning()); assertFalse(user.isForceChangeExpiredPassword()); @@ -164,7 +164,7 @@ class SMPAuthorizationServiceTest { Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire(); Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired(); - user = testInstance.getUpdatedUserData(user); + user = testInstance.getUpdatedUserData(user, null); assertTrue(user.isShowPasswordExpirationWarning()); assertFalse(user.isForceChangeExpiredPassword()); @@ -179,7 +179,7 @@ class SMPAuthorizationServiceTest { Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire(); Mockito.doReturn(true).when(configurationService).getPasswordPolicyForceChangeIfExpired(); - user = testInstance.getUpdatedUserData(user); + user = testInstance.getUpdatedUserData(user, null); assertTrue(user.isForceChangeExpiredPassword()); assertTrue(user.isPasswordExpired()); @@ -193,7 +193,7 @@ class SMPAuthorizationServiceTest { Mockito.doReturn(10).when(configurationService).getPasswordPolicyUIWarningDaysBeforeExpire(); Mockito.doReturn(false).when(configurationService).getPasswordPolicyForceChangeIfExpired(); - user = testInstance.getUpdatedUserData(user); + user = testInstance.getUpdatedUserData(user, null); assertFalse(user.isForceChangeExpiredPassword()); assertTrue(user.isPasswordExpired());