FINERACT-2185: User management improvement
This commit is contained in:
committed by
Adam Saghy
parent
8d83b5547c
commit
79c006774e
+14
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.commands.domain;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -41,8 +42,21 @@ public enum CommandProcessingResultType {
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
@NotNull
|
||||
public static CommandProcessingResultType fromInt(final Integer value) {
|
||||
CommandProcessingResultType transactionType = BY_ID.get(value);
|
||||
return transactionType == null ? INVALID : transactionType;
|
||||
}
|
||||
|
||||
public boolean isProcessed() {
|
||||
return this == PROCESSED;
|
||||
}
|
||||
|
||||
public boolean isAwaitingApproval() {
|
||||
return this == AWAITING_APPROVAL;
|
||||
}
|
||||
|
||||
public boolean isRejected() {
|
||||
return this == REJECTED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.OffsetDateTime;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -136,9 +137,11 @@ public class CommandSource extends AbstractPersistableCustom<Long> {
|
||||
@Column(name = "loan_external_id", length = 100)
|
||||
private ExternalId loanExternalId;
|
||||
|
||||
public static CommandSource fullEntryFrom(final CommandWrapper wrapper, final JsonCommand command, final AppUser maker,
|
||||
String idempotencyKey, Integer status) {
|
||||
@Column(name = "is_sanitized", nullable = false)
|
||||
private boolean sanitized;
|
||||
|
||||
public static CommandSource fullEntryFrom(final CommandWrapper wrapper, final JsonCommand command, final AppUser maker,
|
||||
String idempotencyKey, Integer status, boolean sanitized) {
|
||||
return CommandSource.builder() //
|
||||
.actionName(wrapper.actionName()) //
|
||||
.entityName(wrapper.entityName()) //
|
||||
@@ -159,31 +162,52 @@ public class CommandSource extends AbstractPersistableCustom<Long> {
|
||||
.transactionId(command.getTransactionId()) //
|
||||
.creditBureauId(command.getCreditBureauId()) //
|
||||
.organisationCreditBureauId(command.getOrganisationCreditBureauId()) //
|
||||
.loanExternalId(command.getLoanExternalId()).build(); //
|
||||
.loanExternalId(command.getLoanExternalId()).sanitized(sanitized).build(); //
|
||||
}
|
||||
|
||||
public String getPermissionCode() {
|
||||
return this.actionName + "_" + this.entityName;
|
||||
}
|
||||
|
||||
public void markAsAwaitingApproval() {
|
||||
this.status = CommandProcessingResultType.AWAITING_APPROVAL.getValue();
|
||||
@NotNull
|
||||
public CommandProcessingResultType getStatusEnum() {
|
||||
return CommandProcessingResultType.fromInt(status);
|
||||
}
|
||||
|
||||
public boolean isMarkedAsAwaitingApproval() {
|
||||
return this.status.equals(CommandProcessingResultType.AWAITING_APPROVAL.getValue());
|
||||
public void setStatus(@NotNull CommandProcessingResultType status) {
|
||||
this.status = status.getValue();
|
||||
}
|
||||
|
||||
public void markAsAwaitingApproval() {
|
||||
setStatus(CommandProcessingResultType.AWAITING_APPROVAL);
|
||||
}
|
||||
|
||||
public boolean isAwaitingApproval() {
|
||||
return getStatusEnum().isAwaitingApproval();
|
||||
}
|
||||
|
||||
public boolean isProcessed() {
|
||||
return getStatusEnum().isProcessed();
|
||||
}
|
||||
|
||||
public void markAsChecked(final AppUser checker) {
|
||||
this.checker = checker;
|
||||
this.checkedOnDate = DateUtils.getAuditOffsetDateTime();
|
||||
this.status = CommandProcessingResultType.PROCESSED.getValue();
|
||||
setStatus(CommandProcessingResultType.PROCESSED);
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checker != null && isProcessed();
|
||||
}
|
||||
|
||||
public void markAsRejected(final AppUser checker) {
|
||||
this.checker = checker;
|
||||
this.checkedOnDate = DateUtils.getAuditOffsetDateTime();
|
||||
this.status = CommandProcessingResultType.REJECTED.getValue();
|
||||
setStatus(CommandProcessingResultType.REJECTED);
|
||||
}
|
||||
|
||||
public boolean isRejected() {
|
||||
return checker != null && isRejected();
|
||||
}
|
||||
|
||||
public void updateForAudit(final CommandProcessingResult result) {
|
||||
|
||||
+19
-9
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.commands.domain;
|
||||
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.useradministration.api.PasswordPreferencesApiConstants;
|
||||
@@ -45,6 +46,7 @@ public class CommandWrapper {
|
||||
private final Long organisationCreditBureauId;
|
||||
private final String jobName;
|
||||
private final ExternalId loanExternalId;
|
||||
private final Set<String> sanitizeJsonKeys;
|
||||
|
||||
private final String idempotencyKey;
|
||||
|
||||
@@ -67,7 +69,7 @@ public class CommandWrapper {
|
||||
final ExternalId loanExternalId) {
|
||||
return new CommandWrapper(commandId, actionName, entityName, resourceId, subresourceId, resourceGetUrl, productId, officeId,
|
||||
groupId, clientId, loanId, savingsId, transactionId, creditBureauId, organisationCreditBureauId, idempotencyKey,
|
||||
loanExternalId);
|
||||
loanExternalId, null);
|
||||
}
|
||||
|
||||
private CommandWrapper(final Long commandId, final String actionName, final String entityName, final Long resourceId,
|
||||
@@ -92,12 +94,14 @@ public class CommandWrapper {
|
||||
this.jobName = null;
|
||||
this.idempotencyKey = null;
|
||||
this.loanExternalId = null;
|
||||
this.sanitizeJsonKeys = null;
|
||||
}
|
||||
|
||||
public CommandWrapper(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId,
|
||||
final String actionName, final String entityName, final Long entityId, final Long subentityId, final String href,
|
||||
final String json, final String transactionId, final Long productId, final Long templateId, final Long creditBureauId,
|
||||
final Long organisationCreditBureauId, final String jobName, final String idempotencyKey, final ExternalId loanExternalId) {
|
||||
final Long organisationCreditBureauId, final String jobName, final String idempotencyKey, final ExternalId loanExternalId,
|
||||
final Set<String> sanitizeJsonKeys) {
|
||||
|
||||
this.commandId = null;
|
||||
this.officeId = officeId;
|
||||
@@ -120,12 +124,14 @@ public class CommandWrapper {
|
||||
this.jobName = jobName;
|
||||
this.idempotencyKey = idempotencyKey;
|
||||
this.loanExternalId = loanExternalId;
|
||||
this.sanitizeJsonKeys = sanitizeJsonKeys;
|
||||
}
|
||||
|
||||
private CommandWrapper(final Long commandId, final String actionName, final String entityName, final Long resourceId,
|
||||
final Long subresourceId, final String resourceGetUrl, final Long productId, final Long officeId, final Long groupId,
|
||||
final Long clientId, final Long loanId, final Long savingsId, final String transactionId, final Long creditBureauId,
|
||||
final Long organisationCreditBureauId, final String idempotencyKey, final ExternalId loanExternalId) {
|
||||
final Long organisationCreditBureauId, final String idempotencyKey, final ExternalId loanExternalId,
|
||||
final Set<String> sanitizeJsonKeys) {
|
||||
|
||||
this.commandId = commandId;
|
||||
this.officeId = officeId;
|
||||
@@ -147,6 +153,7 @@ public class CommandWrapper {
|
||||
this.jobName = null;
|
||||
this.idempotencyKey = idempotencyKey;
|
||||
this.loanExternalId = loanExternalId;
|
||||
this.sanitizeJsonKeys = sanitizeJsonKeys;
|
||||
}
|
||||
|
||||
public boolean isCreate() {
|
||||
@@ -200,21 +207,24 @@ public class CommandWrapper {
|
||||
return isnoteResource;
|
||||
}
|
||||
|
||||
public boolean isUpdateOfOwnUserDetails(final Long loggedInUserId) {
|
||||
return isUserResource() && isUpdate() && loggedInUserId.equals(this.entityId);
|
||||
public boolean isChangeOfOwnUserDetails(final Long loggedInUserId) {
|
||||
return isUserResource() && loggedInUserId.equals(this.entityId) && (isUpdate() || isChangePasswordOperation());
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
// permissions resource has special update which involves no resource.
|
||||
return (isPermissionResource() && isUpdateOperation()) || (isCurrencyResource() && isUpdateOperation())
|
||||
|| (isCacheResource() && isUpdateOperation()) || (isWorkingDaysResource() && isUpdateOperation())
|
||||
|| (isPasswordPreferencesResource() && isUpdateOperation()) || (isUpdateOperation() && (this.entityId != null));
|
||||
// some resources have special update which involves no resource identifier.
|
||||
return isUpdateOperation() && (this.entityId != null || isPermissionResource() || isCurrencyResource() || isCacheResource()
|
||||
|| isWorkingDaysResource() || isPasswordPreferencesResource());
|
||||
}
|
||||
|
||||
public boolean isCacheResource() {
|
||||
return this.entityName.equalsIgnoreCase("CACHE");
|
||||
}
|
||||
|
||||
public boolean isChangePasswordOperation() {
|
||||
return this.actionName.equalsIgnoreCase("CHANGEPWD");
|
||||
}
|
||||
|
||||
public boolean isUpdateOperation() {
|
||||
return this.actionName.equalsIgnoreCase("UPDATE");
|
||||
}
|
||||
|
||||
+56
-6
@@ -20,6 +20,9 @@ package org.apache.fineract.commands.service;
|
||||
|
||||
import static org.apache.fineract.commands.domain.CommandProcessingResultType.UNDER_PROCESSING;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.exception.ErrorInfo;
|
||||
import org.apache.fineract.commands.domain.CommandSource;
|
||||
@@ -28,10 +31,13 @@ import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.commands.exception.CommandNotFoundException;
|
||||
import org.apache.fineract.commands.exception.RollbackTransactionNotApprovedException;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
|
||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
@@ -49,8 +55,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@RequiredArgsConstructor
|
||||
public class CommandSourceService {
|
||||
|
||||
public static final String COMMAND_MASK_VALUE = "***";
|
||||
public static final String COMMAND_SANITIZE_ALL = "SANITIZE_ALL";
|
||||
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final CommandSourceRepository commandSourceRepository;
|
||||
private final ErrorHandler errorHandler;
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@NotNull
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ)
|
||||
@@ -110,7 +121,8 @@ public class CommandSourceService {
|
||||
|
||||
public CommandSource getInitialCommandSource(CommandWrapper wrapper, JsonCommand jsonCommand, AppUser maker, String idempotencyKey) {
|
||||
CommandSource commandSourceResult = CommandSource.fullEntryFrom(wrapper, jsonCommand, maker, idempotencyKey,
|
||||
UNDER_PROCESSING.getValue());
|
||||
UNDER_PROCESSING.getValue(), false);
|
||||
sanitizeJson(commandSourceResult, wrapper.getSanitizeJsonKeys());
|
||||
if (commandSourceResult.getCommandAsJson() == null) {
|
||||
commandSourceResult.setCommandAsJson("{}");
|
||||
}
|
||||
@@ -119,13 +131,51 @@ public class CommandSourceService {
|
||||
|
||||
@Transactional
|
||||
public CommandProcessingResult processCommand(NewCommandSourceHandler handler, JsonCommand command, CommandSource commandSource,
|
||||
AppUser user, boolean isApprovedByChecker, boolean isMakerChecker) {
|
||||
AppUser user, boolean isApprovedByChecker) {
|
||||
final CommandProcessingResult result = handler.processCommand(command);
|
||||
boolean isRollback = !isApprovedByChecker && !user.isCheckerSuperUser() && (isMakerChecker || result.isRollbackTransaction());
|
||||
if (isRollback) {
|
||||
commandSource.markAsAwaitingApproval();
|
||||
throw new RollbackTransactionNotApprovedException(commandSource.getId(), commandSource.getResourceId());
|
||||
|
||||
String permission = commandSource.getPermissionCode();
|
||||
boolean isMakerChecker = configurationDomainService.isMakerCheckerEnabledForTask(permission);
|
||||
if (isMakerChecker || result.isRollbackTransaction()) {
|
||||
if (isApprovedByChecker || user.isCheckerSuperUser()) {
|
||||
commandSource.markAsChecked(user);
|
||||
} else {
|
||||
if (commandSource.isSanitized()) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.invalid.sanitization",
|
||||
"Maker-checker command can not be sanitized, please change the permission configuration", permission);
|
||||
}
|
||||
commandSource.markAsAwaitingApproval();
|
||||
throw new RollbackTransactionNotApprovedException(commandSource.getId(), commandSource.getResourceId());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void sanitizeJson(@NotNull CommandSource commandSource, Set<String> sanitizeKeys) {
|
||||
if (sanitizeKeys == null || sanitizeKeys.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String commandAsJson = commandSource.getCommandAsJson();
|
||||
if (commandAsJson == null || commandAsJson.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandAsJson);
|
||||
if (!parsedCommand.isJsonObject()) {
|
||||
return;
|
||||
}
|
||||
String sanitizedJson;
|
||||
if (sanitizeKeys.contains(COMMAND_SANITIZE_ALL)) {
|
||||
sanitizedJson = "";
|
||||
} else {
|
||||
JsonObject jsonObject = parsedCommand.getAsJsonObject();
|
||||
for (String key : sanitizeKeys) {
|
||||
if (jsonObject.has(key)) {
|
||||
jsonObject.addProperty(key, COMMAND_MASK_VALUE);
|
||||
}
|
||||
}
|
||||
sanitizedJson = jsonObject.toString();
|
||||
}
|
||||
commandSource.setCommandAsJson(sanitizedJson);
|
||||
commandSource.setSanitized(true);
|
||||
}
|
||||
}
|
||||
|
||||
+22
-2
@@ -18,7 +18,13 @@
|
||||
*/
|
||||
package org.apache.fineract.commands.service;
|
||||
|
||||
import static org.apache.fineract.useradministration.service.AppUserConstants.PASSWORD;
|
||||
import static org.apache.fineract.useradministration.service.AppUserConstants.REPEAT_PASSWORD;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.infrastructure.accountnumberformat.service.AccountNumberFormatConstants;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
@@ -49,18 +55,21 @@ public class CommandWrapperBuilder {
|
||||
private String jobName;
|
||||
private String idempotencyKey;
|
||||
private ExternalId loanExternalId;
|
||||
private Set<String> sanitizeJsonKeys;
|
||||
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "TODO: fix this!")
|
||||
public CommandWrapper build() {
|
||||
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, this.entityName,
|
||||
this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, this.templateId,
|
||||
this.creditBureauId, this.organisationCreditBureauId, this.jobName, this.idempotencyKey, this.loanExternalId);
|
||||
this.creditBureauId, this.organisationCreditBureauId, this.jobName, this.idempotencyKey, this.loanExternalId,
|
||||
this.sanitizeJsonKeys);
|
||||
}
|
||||
|
||||
public CommandWrapper build(String idempotencyKey) {
|
||||
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, this.entityName,
|
||||
this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, this.templateId,
|
||||
this.creditBureauId, this.organisationCreditBureauId, this.jobName, idempotencyKey, this.loanExternalId);
|
||||
this.creditBureauId, this.organisationCreditBureauId, this.jobName, idempotencyKey, this.loanExternalId,
|
||||
this.sanitizeJsonKeys);
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateCreditBureau() {
|
||||
@@ -264,6 +273,16 @@ public class CommandWrapperBuilder {
|
||||
this.entityName = "USER";
|
||||
this.entityId = null;
|
||||
this.href = "/users/template";
|
||||
this.sanitizeJsonKeys = new HashSet<>(Arrays.asList(PASSWORD, REPEAT_PASSWORD));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder changeUserPassword(final Long userId) {
|
||||
this.actionName = "CHANGEPWD";
|
||||
this.entityName = "USER";
|
||||
this.entityId = userId;
|
||||
this.href = "/users/" + userId + "/pwd";
|
||||
this.sanitizeJsonKeys = new HashSet<>(Arrays.asList(PASSWORD, REPEAT_PASSWORD));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -272,6 +291,7 @@ public class CommandWrapperBuilder {
|
||||
this.entityName = "USER";
|
||||
this.entityId = userId;
|
||||
this.href = "/users/" + userId;
|
||||
this.sanitizeJsonKeys = new HashSet<>(Arrays.asList(PASSWORD, REPEAT_PASSWORD));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -55,7 +55,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
|
||||
boolean isApprovedByChecker = false;
|
||||
|
||||
// check if is update of own account details
|
||||
if (wrapper.isUpdateOfOwnUserDetails(this.context.authenticatedUser(wrapper).getId())) {
|
||||
if (wrapper.isChangeOfOwnUserDetails(this.context.authenticatedUser(wrapper).getId())) {
|
||||
// then allow this operation to proceed.
|
||||
// maker checker doesnt mean anything here.
|
||||
isApprovedByChecker = true; // set to true in case permissions have
|
||||
@@ -117,7 +117,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
|
||||
private CommandSource validateMakerCheckerTransaction(final Long makerCheckerId) {
|
||||
final CommandSource commandSource = this.commandSourceRepository.findById(makerCheckerId)
|
||||
.orElseThrow(() -> new CommandNotFoundException(makerCheckerId));
|
||||
if (!commandSource.isMarkedAsAwaitingApproval()) {
|
||||
if (!commandSource.isAwaitingApproval()) {
|
||||
throw new CommandNotAwaitingApprovalException(makerCheckerId);
|
||||
}
|
||||
AppUser appUser = this.context.authenticatedUser();
|
||||
|
||||
+3
-8
@@ -117,16 +117,11 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
storeCommandIdInContext(commandSource); // Store command id as a request attribute
|
||||
}
|
||||
|
||||
boolean isMakerChecker = configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName());
|
||||
if (isApprovedByChecker || (isMakerChecker && user.isCheckerSuperUser())) {
|
||||
commandSource.markAsChecked(user);
|
||||
}
|
||||
setIdempotencyKeyStoreFlag(true);
|
||||
|
||||
final CommandProcessingResult result;
|
||||
try {
|
||||
result = commandSourceService.processCommand(findCommandHandler(wrapper), command, commandSource, user, isApprovedByChecker,
|
||||
isMakerChecker);
|
||||
result = commandSourceService.processCommand(findCommandHandler(wrapper), command, commandSource, user, isApprovedByChecker);
|
||||
} catch (Throwable t) { // NOSONAR
|
||||
RuntimeException mappable = ErrorHandler.getMappable(t);
|
||||
ErrorInfo errorInfo = commandSourceService.generateErrorInfo(mappable);
|
||||
@@ -134,7 +129,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
commandSource.setResultStatusCode(statusCode);
|
||||
commandSource.setResult(errorInfo.getMessage());
|
||||
if (statusCode != SC_OK) {
|
||||
commandSource.setStatus(ERROR.getValue());
|
||||
commandSource.setStatus(ERROR);
|
||||
}
|
||||
if (!isEnclosingTransaction) { // TODO: temporary solution
|
||||
commandSource = commandSourceService.saveResultNewTransaction(commandSource);
|
||||
@@ -148,7 +143,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
commandSource.setResultStatusCode(SC_OK);
|
||||
commandSource.updateForAudit(result);
|
||||
commandSource.setResult(toApiResultJsonSerializer.serializeResult(result));
|
||||
commandSource.setStatus(PROCESSED.getValue());
|
||||
commandSource.setStatus(PROCESSED);
|
||||
commandSource = commandSourceService.saveResultSameTransaction(commandSource);
|
||||
storeCommandIdInContext(commandSource); // Store command id as a request attribute
|
||||
|
||||
|
||||
+23
-19
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.fineract.useradministration.domain;
|
||||
|
||||
import static org.apache.fineract.useradministration.service.AppUserConstants.PASSWORD;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -195,8 +197,27 @@ public class AppUser extends AbstractPersistableCustom<Long> implements Platform
|
||||
return organisationalRole;
|
||||
}
|
||||
|
||||
public Map<String, Object> changePassword(final JsonCommand command, final PlatformPasswordEncoder platformPasswordEncoder) {
|
||||
// unencoded password provided
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(1);
|
||||
updatePassword(command, platformPasswordEncoder, actualChanges);
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void updatePassword(JsonCommand command, PlatformPasswordEncoder platformPasswordEncoder, Map<String, Object> actualChanges) {
|
||||
final String passwordParamName = PASSWORD;
|
||||
if (command.hasParameter(passwordParamName)) {
|
||||
if (command.isChangeInPasswordParameterNamed(passwordParamName, this.password, platformPasswordEncoder, getId())) {
|
||||
final String passwordEncodedValue = command.passwordValueOfParameterNamed(passwordParamName, platformPasswordEncoder,
|
||||
getId());
|
||||
actualChanges.put(passwordParamName, true);
|
||||
updatePassword(passwordEncodedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePassword(final String encodePassword) {
|
||||
if (cannotChangePassword != null && cannotChangePassword == true) {
|
||||
if (Boolean.TRUE.equals(cannotChangePassword)) {
|
||||
throw new NoAuthorizationException("Password of this user may not be modified");
|
||||
}
|
||||
|
||||
@@ -223,27 +244,10 @@ public class AppUser extends AbstractPersistableCustom<Long> implements Platform
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command, final PlatformPasswordEncoder platformPasswordEncoder,
|
||||
final Collection<Client> clients) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
|
||||
|
||||
// unencoded password provided
|
||||
final String passwordParamName = "password";
|
||||
final String passwordEncodedParamName = "passwordEncoded";
|
||||
if (command.hasParameter(passwordParamName)) {
|
||||
if (command.isChangeInPasswordParameterNamed(passwordParamName, this.password, platformPasswordEncoder, getId())) {
|
||||
final String passwordEncodedValue = command.passwordValueOfParameterNamed(passwordParamName, platformPasswordEncoder,
|
||||
getId());
|
||||
updatePassword(passwordEncodedValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (command.hasParameter(passwordEncodedParamName)) {
|
||||
if (command.isChangeInStringParameterNamed(passwordEncodedParamName, this.password)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(passwordEncodedParamName);
|
||||
updatePassword(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
updatePassword(command, platformPasswordEncoder, actualChanges);
|
||||
final String officeIdParamName = "officeId";
|
||||
if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) {
|
||||
final Long newValue = command.longValueOfParameterNamed(officeIdParamName);
|
||||
|
||||
+2
@@ -24,6 +24,8 @@ public final class AppUserConstants {
|
||||
|
||||
}
|
||||
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String REPEAT_PASSWORD = "repeatPassword";
|
||||
public static final String PASSWORD_NEVER_EXPIRES = "passwordNeverExpires";
|
||||
public static final String IS_SELF_SERVICE_USER = "isSelfServiceUser";
|
||||
public static final String CLIENTS = "clients";
|
||||
|
||||
+2
-2
@@ -58,8 +58,8 @@ public class IdempotencyCommandProcessFailedExceptionTest {
|
||||
public void testInconsistentStatus() {
|
||||
IdempotentCommandExceptionMapper mapper = new IdempotentCommandExceptionMapper();
|
||||
CommandWrapper command = new CommandWrapper(null, null, null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null);
|
||||
CommandSource source = CommandSource.fullEntryFrom(command, JsonCommand.from("{}"), null, "dummy-key", null);
|
||||
null, null, null, null, null, null);
|
||||
CommandSource source = CommandSource.fullEntryFrom(command, JsonCommand.from("{}"), null, "dummy-key", null, false);
|
||||
IdempotentCommandProcessFailedException exception = new IdempotentCommandProcessFailedException(command, null, source);
|
||||
Response result = mapper.toResponse(exception);
|
||||
assertEquals(500, result.getStatus());
|
||||
|
||||
Reference in New Issue
Block a user