Code development platform for open source projects from the European Union institutions

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

Pull request #131: [EDELIVERY-13956] UI: event table filter is not working

Merge in EDELIVERY/smp from bugfix/EDELIVERY-13956-event-filter-not-working-ok to development

* commit '36a7b89a':
  [EDELIVERY-13956] UI: event table filter is not working
  [EDELIVERY-13882] rollback change
  [EDELIVERY-13882] fix user password reset for uses with no password
  [EDELIVERY-13882] fix user password reset for uses with no password
  [EDELIVERY-13882] fix user password reset for uses with no password
  [EDELIVERY-13882] fix user password reset for uses with no password
parents f12022af 36a7b89a
No related branches found
No related tags found
No related merge requests found
Pipeline #207585 failed
......@@ -34,7 +34,9 @@ import {
import {MatSort} from "@angular/material/sort";
import {MatDialog} from "@angular/material/dialog";
import {MatPaginator} from "@angular/material/paginator";
import {DocumentVersionEventRo} from "../../model/document-version-event-ro.model";
import {
DocumentVersionEventRo
} from "../../model/document-version-event-ro.model";
import {
BeforeLeaveGuard
} from "../../../window/sidenav/navigation-on-leave-guard";
......@@ -60,7 +62,7 @@ import {GlobalLookups} from "../../global-lookups";
export class DocumentEventsPanelComponent implements AfterViewInit, BeforeLeaveGuard, ControlValueAccessor {
displayedColumns: string[] = [ 'date', 'eventType', 'username', 'eventSource'];
displayedColumns: string[] = ['date', 'eventType', 'username', 'eventSource'];
private onChangeCallback: (_: any) => void = () => {
};
eventDataSource: MatTableDataSource<DocumentVersionEventRo> = new MatTableDataSource();
......@@ -72,8 +74,8 @@ export class DocumentEventsPanelComponent implements AfterViewInit, BeforeLeaveG
constructor(
private globalLookups: GlobalLookups,
public dialog: MatDialog,
private controlContainer: ControlContainer) {
public dialog: MatDialog,
private controlContainer: ControlContainer) {
}
get dateTimeFormat(): string {
......@@ -103,6 +105,13 @@ export class DocumentEventsPanelComponent implements AfterViewInit, BeforeLeaveG
ngAfterViewInit() {
this.eventDataSource.paginator = this.paginator;
this.eventDataSource.sort = this.sort;
// add custom filter to exclude filtering on event description
this.eventDataSource.filterPredicate = (data: DocumentVersionEventRo, filter: string) => {
return data.eventType?.toLowerCase().includes(filter)
|| data.username?.toLowerCase().includes(filter)
|| data.eventSourceType?.toLowerCase().includes(filter)
|| data.eventOn?.toLocaleString().toLowerCase().includes(filter);
};
}
applyFilter(event: Event) {
......
......@@ -151,74 +151,81 @@ export class AdminUserComponent implements AfterViewInit, BeforeLeaveGuard {
}
updateUserData(user: UserRo) {
// capture this to variable because of async call 'this' inside targets the wrong object
const thatAdminUserComponent = this;
// change only allowed data
this.adminUserService.updateManagedUser(user).subscribe({
async next(user: UserRo) {
if (user) {
this.selected = null;
this.managedUserData = null;
this.loadTableData(user.username);
this.alertService.success(await lastValueFrom(this.translateService.get("admin.user.success.update", {username: user.username})));
thatAdminUserComponent.selected = null;
thatAdminUserComponent.managedUserData = null;
thatAdminUserComponent.loadTableData(user.username);
thatAdminUserComponent.alertService.success(await lastValueFrom(thatAdminUserComponent.translateService.get("admin.user.success.update", {username: user.username})));
}
}, error(error) {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
if (thatAdminUserComponent.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
this.alertService.error(error.error?.errorDescription)
thatAdminUserComponent.alertService.error(error.error?.errorDescription)
}
});
}
createUserData(user: UserRo) {
// change only allowed data
// capture this to variable because of async call 'this' inside targets the wrong object
const thatAdminUserComponent = this;
this.adminUserService.createManagedUser(user).subscribe({
async next(user: UserRo) {
if (user) {
this.selected = null;
this.managedUserData = null;
this.loadTableData(user.username);
this.alertService.success(await lastValueFrom(this.translateService.get("admin.user.success.create", {username: user.username})));
thatAdminUserComponent.selected = null;
thatAdminUserComponent.managedUserData = null;
thatAdminUserComponent.loadTableData(user.username);
thatAdminUserComponent.alertService.success(await lastValueFrom(thatAdminUserComponent.translateService.get("admin.user.success.create", {username: user.username})));
}
}, error(error) {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
if (thatAdminUserComponent.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
this.alertService.error(error.error?.errorDescription)
thatAdminUserComponent.alertService.error(error.error?.errorDescription)
}
});
}
async onDeleteSelectedUserClicked() {
// capture this to variable because of async call 'this' inside targets the wrong object
const thatAdminUserComponent = this;
this.dialog.open(ConfirmationDialogComponent, {
data: {
title: await lastValueFrom(this.translateService.get("admin.user.delete.confirmation.dialog.title", {username: this.managedUserData?.username})),
description: await lastValueFrom(this.translateService.get("admin.user.delete.confirmation.dialog.description"))
title: await lastValueFrom(thatAdminUserComponent.translateService.get("admin.user.delete.confirmation.dialog.title", {username: this.managedUserData?.username})),
description: await lastValueFrom(thatAdminUserComponent.translateService.get("admin.user.delete.confirmation.dialog.description"))
}
}).afterClosed().subscribe(result => {
if (result) {
this.deleteUser(this.managedUserData);
this.deleteUser(thatAdminUserComponent.managedUserData);
}
});
}
deleteUser(user: UserRo) {
// capture this to variable because of async call 'this' inside targets the wrong object
const thatAdminUserComponent = this;
// change only allowed data
this.adminUserService.deleteManagedUser(user).subscribe({
async next(user: UserRo) {
if (user) {
this.selected = null;
this.managedUserData = null;
this.loadTableData();
this.alertService.success(await lastValueFrom(this.translateService.get("admin.user.success.delete", {username: user.username})));
thatAdminUserComponent.selected = null;
thatAdminUserComponent.managedUserData = null;
thatAdminUserComponent.loadTableData();
thatAdminUserComponent.alertService.success(await lastValueFrom(thatAdminUserComponent.translateService.get("admin.user.success.delete", {username: user.username})));
}
}, error(error) {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
if (thatAdminUserComponent.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
this.alertService.error(error.error?.errorDescription)
thatAdminUserComponent.alertService.error(error.error?.errorDescription)
}
});
......@@ -235,7 +242,7 @@ export class AdminUserComponent implements AfterViewInit, BeforeLeaveGuard {
if (result) {
this.selected = null;
this.managedUserData = null;
this.loadTableData();
this.loadTableData(user.username);
this.alertService.success(await lastValueFrom(this.translateService.get("admin.user.success.password.updated")));
}
});
......
......@@ -32,7 +32,7 @@ public enum ErrorCode {
UNAUTHORIZED(401, "SMP:003",ErrorBusinessCode.UNAUTHORIZED, "User not authorized!"),
UNAUTHORIZED_INVALID_USER_IDENTIFIER(401, "SMP:004",ErrorBusinessCode.UNAUTHORIZED, "Invalid user identifier! User not authorized."),
UNAUTHORIZED_INVALID_IDENTIFIER(401, "SMP:005",ErrorBusinessCode.UNAUTHORIZED, "Invalid entity identifier! User not authorized to access the entity data"),
UNAUTHORIZED_INVALID_RESET_TOKEN(401, "SMP:006",ErrorBusinessCode.UNAUTHORIZED, "Reset token; Invalid or not active reset token!"),
UNAUTHORIZED_INVALID_RESET_TOKEN(401, "SMP:006",ErrorBusinessCode.UNAUTHORIZED, "The reset token it is invalid or not active any more. Please try to reset your password again."),
INVALID_ENCODING (500, "SMP:100",ErrorBusinessCode.TECHNICAL, "Unsupported or invalid encoding for %s!"),
SML_INVALID_IDENTIFIER (400,"SMP:101",ErrorBusinessCode.FORMAT_ERROR,"Malformed identifier, scheme and id should be delimited by double colon: %s "),
......
......@@ -26,6 +26,7 @@ import eu.europa.ec.edelivery.smp.auth.UILoginAuthenticationToken;
import eu.europa.ec.edelivery.smp.config.SMPEnvironmentProperties;
import eu.europa.ec.edelivery.smp.data.dao.CredentialDao;
import eu.europa.ec.edelivery.smp.data.dao.UserDao;
import eu.europa.ec.edelivery.smp.data.enums.CredentialTargetType;
import eu.europa.ec.edelivery.smp.data.enums.CredentialType;
import eu.europa.ec.edelivery.smp.data.model.user.DBCertificate;
import eu.europa.ec.edelivery.smp.data.model.user.DBCredential;
......@@ -76,6 +77,8 @@ public class CredentialService {
protected static final BadCredentialsException SUSPENDED_CREDENTIALS_EXCEPTION = new BadCredentialsException(ErrorCode.UNAUTHORIZED_CREDENTIAL_SUSPENDED.getMessage());
protected static final int RESET_TOKEN_LENGTH = 64;
private static final String USER_ID_REQUEST_TYPE = "UserId";
final UserDao userDao;
final CredentialDao credentialDao;
final ConversionService conversionService;
......@@ -341,7 +344,7 @@ public class CredentialService {
// retrieve user Optional credentials by username
Optional<DBCredential> optCredential = getActiveCredentialsForUsernameToReset(username, true);
if (!optCredential.isPresent()) {
LOG.info("Skip generating reset token for username [{}]!", username);
LOG.info("Skip generating reset token for username [{}]. User is not active!", username);
return;
}
DBCredential dbCredential = optCredential.get();
......@@ -407,13 +410,24 @@ public class CredentialService {
* @return Optional of DBCredential: if the user has active credentials and active else empty is returned
*/
private Optional<DBCredential> getActiveCredentialsForUsernameToReset(String username, boolean toGenerateResetToken) {
// retrieve user Optional credentials by username
Optional<DBCredential> optCredential = credentialDao.findUsernamePasswordCredentialForUsernameAndUI(username);
DBCredential dbCredential;
if (!optCredential.isPresent()) {
LOG.warn("There is not credentials for User [{}]!", username);
return optCredential;
DBUser user = userDao.findUserByUsername(username).orElseThrow(() -> {
LOG.warn("There is no user with username [{}]!", username);
throw new SMPRuntimeException(ErrorCode.UNAUTHORIZED_INVALID_USERNAME_PASSWORD, "User not found!");
});
LOG.info("User [{}] does not have username/password credentials. Create new credentials!", username);
dbCredential = createCredentialsForUser(user.getId(),
CredentialType.USERNAME_PASSWORD,
CredentialTargetType.UI);
// persist new credential
credentialDao.persist(dbCredential);
optCredential = Optional.of(dbCredential);
} else {
dbCredential = optCredential.get();
}
DBCredential dbCredential = optCredential.get();
if (!dbCredential.getUser().isActive() || !dbCredential.isActive()) {
LOG.info("User [{}] or credentials are not active. Skip reset password request!", username);
......@@ -434,6 +448,31 @@ public class CredentialService {
return optCredential;
}
/**
* Method creates Username/passwords credentials for the user with given userId.
* The method must be called inside active transactions.
*
* @param userID to change/create username-password credentials
* @param credentialType the credential type
* @param credentialTargetType the credential target
*/
public DBCredential createCredentialsForUser(Long userID, CredentialType credentialType, CredentialTargetType credentialTargetType) {
DBUser dbUserToUpdate = userDao.find(userID);
if (dbUserToUpdate == null) {
LOG.error("Can not create user password credentials, because user [{}] does not exist!", userID);
throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, USER_ID_REQUEST_TYPE, "Can not find user id to update!");
}
DBCredential credential = new DBCredential();
credential.setUser(dbUserToUpdate);
credential.setName(dbUserToUpdate.getUsername());
credential.setCredentialType(credentialType);
credential.setCredentialTarget(credentialTargetType);
return credential;
}
public void validatePasswordResetToken(String resetToken){
Optional<DBCredential> optCredential = credentialDao.findUCredentialForUsernamePasswordTypeAndResetToken(resetToken);
if (!optCredential.isPresent()) {
......@@ -478,8 +517,9 @@ public class CredentialService {
* Method validates if the certificate contains one of allowed Certificate policy. At the moment it does not validates
* the whole chain. Because in some configuration cases does not use the truststore
*
* @param certificateId
* @throws CertificateException
* @param certificateId certificate id to be validated
* @param certPolicyList certificate policy list
* @throws AuthenticationServiceException
*/
protected void validateCertificatePolicyMatchLegacy(String certificateId, List<String> certPolicyList) throws AuthenticationServiceException {
......
......@@ -39,6 +39,7 @@ 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.ConfigurationService;
import eu.europa.ec.edelivery.smp.services.CredentialService;
import eu.europa.ec.edelivery.smp.services.CredentialsAlertService;
import eu.europa.ec.edelivery.smp.utils.BCryptPasswordHash;
import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils;
......@@ -70,6 +71,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
private static final String USER_ID_REQUEST_TYPE = "UserId";
private final UserDao userDao;
private final CredentialService credentialService;
CredentialDao credentialDao;
private final ConfigurationService configurationService;
private final ConversionService conversionService;
......@@ -81,13 +83,15 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
ConfigurationService configurationService,
ConversionService conversionService,
UITruststoreService truststoreService,
CredentialsAlertService alertService) {
CredentialsAlertService alertService,
CredentialService credentialService) {
this.userDao = userDao;
this.credentialDao = credentialDao;
this.configurationService = configurationService;
this.conversionService = conversionService;
this.truststoreService = truststoreService;
this.alertService = alertService;
this.credentialService = credentialService;
}
@Override
......@@ -242,7 +246,7 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
protected DBUser updateUsernamePasswordForUser(Long userID, String password, boolean adminUpdate) {
Optional<DBCredential> optCredential = credentialDao.findUsernamePasswordCredentialForUserIdAndUI(userID);
DBCredential dbCredential = optCredential.orElse(createCredentialsForUser(userID,
DBCredential dbCredential = optCredential.orElse(credentialService.createCredentialsForUser(userID,
CredentialType.USERNAME_PASSWORD,
CredentialTargetType.UI));
......@@ -277,31 +281,6 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
return dbCredential.getUser();
}
/**
* Method creates Username/passwords credentials for the user with given userId.
* The method must be called inside active transactions.
*
* @param userID to change/create username-password credentials
* @param credentialType the credential type
* @param credentialTargetType the credential target
*/
protected DBCredential createCredentialsForUser(Long userID, CredentialType credentialType, CredentialTargetType credentialTargetType) {
DBUser dbUserToUpdate = userDao.find(userID);
if (dbUserToUpdate == null) {
LOG.error("Can not update user password because user,[{}] does not exist!", userID);
throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, USER_ID_REQUEST_TYPE, "Can not find user id to update!");
}
DBCredential credential = new DBCredential();
credential.setUser(dbUserToUpdate);
credential.setName(dbUserToUpdate.getUsername());
credential.setCredentialType(credentialType);
credential.setCredentialTarget(credentialTargetType);
return credential;
}
/**
* Method updates the user password
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment