FINERACT-1971 Improve Request Validation
This commit is contained in:
+23
-3
@@ -127,10 +127,14 @@ final class UsersApiResourceSwagger {
|
||||
@Schema(example = "1")
|
||||
public Long staffId;
|
||||
@Schema(example = "[2,3]")
|
||||
public List<String> roles;
|
||||
public List<Long> roles;
|
||||
@Schema(example = "[2,3]")
|
||||
public List<Long> clients;
|
||||
@Schema(example = "true")
|
||||
public Boolean sendPasswordToEmail;
|
||||
@Schema(example = "true")
|
||||
public Boolean passwordNeverExpires;
|
||||
@Schema(example = "true")
|
||||
public Boolean isSelfServiceUser;
|
||||
}
|
||||
|
||||
@@ -156,10 +160,26 @@ final class UsersApiResourceSwagger {
|
||||
|
||||
@Schema(example = "Test")
|
||||
public String firstname;
|
||||
@Schema(example = "window75")
|
||||
@Schema(example = "User")
|
||||
public String lastname;
|
||||
@Schema(example = "whatever@mifos.org")
|
||||
public String email;
|
||||
@Schema(example = "1")
|
||||
public Long officeId;
|
||||
@Schema(example = "1")
|
||||
public Long staffId;
|
||||
@Schema(example = "[2,3]")
|
||||
public List<Long> roles;
|
||||
@Schema(example = "[2,3]")
|
||||
public List<Long> clients;
|
||||
@Schema(example = "password")
|
||||
public String password;
|
||||
@Schema(example = "window75")
|
||||
@Schema(example = "repeatPassword")
|
||||
public String repeatPassword;
|
||||
@Schema(example = "true")
|
||||
public Boolean sendPasswordToEmail;
|
||||
@Schema(example = "true")
|
||||
public Boolean isSelfServiceUser;
|
||||
}
|
||||
|
||||
@Schema(description = "PutUsersUserIdResponse")
|
||||
|
||||
+7
-5
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.fineract.useradministration.service;
|
||||
|
||||
import static org.apache.fineract.useradministration.service.AppUserConstants.CLIENTS;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import jakarta.persistence.PersistenceException;
|
||||
@@ -112,8 +114,8 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
|
||||
Collection<Client> clients;
|
||||
if (command.hasParameter(AppUserConstants.IS_SELF_SERVICE_USER)
|
||||
&& command.booleanPrimitiveValueOfParameterNamed(AppUserConstants.IS_SELF_SERVICE_USER)
|
||||
&& command.hasParameter(AppUserConstants.CLIENTS)) {
|
||||
JsonArray clientsArray = command.arrayOfParameterNamed(AppUserConstants.CLIENTS);
|
||||
&& command.hasParameter(CLIENTS)) {
|
||||
JsonArray clientsArray = command.arrayOfParameterNamed(CLIENTS);
|
||||
Collection<Long> clientIds = new HashSet<>();
|
||||
for (JsonElement clientElement : clientsArray) {
|
||||
clientIds.add(clientElement.getAsLong());
|
||||
@@ -159,7 +161,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
|
||||
try {
|
||||
this.context.authenticatedUser(new CommandWrapperBuilder().updateUser(null).build());
|
||||
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json(), this.context.authenticatedUser());
|
||||
|
||||
final AppUser userToUpdate = this.appUserRepository.findById(userId).orElseThrow(() -> new UserNotFoundException(userId));
|
||||
|
||||
@@ -171,8 +173,8 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
|
||||
isSelfServiceUser = command.booleanPrimitiveValueOfParameterNamed(AppUserConstants.IS_SELF_SERVICE_USER);
|
||||
}
|
||||
|
||||
if (isSelfServiceUser && command.hasParameter(AppUserConstants.CLIENTS)) {
|
||||
JsonArray clientsArray = command.arrayOfParameterNamed(AppUserConstants.CLIENTS);
|
||||
if (isSelfServiceUser && command.hasParameter(CLIENTS)) {
|
||||
JsonArray clientsArray = command.arrayOfParameterNamed(CLIENTS);
|
||||
Collection<Long> clientIds = new HashSet<>();
|
||||
for (JsonElement clientElement : clientsArray) {
|
||||
clientIds.add(clientElement.getAsLong());
|
||||
|
||||
+45
-14
@@ -18,8 +18,11 @@
|
||||
*/
|
||||
package org.apache.fineract.useradministration.service;
|
||||
|
||||
import static org.apache.fineract.useradministration.service.AppUserConstants.CLIENTS;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
@@ -34,6 +37,7 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.apache.fineract.useradministration.domain.PasswordValidationPolicy;
|
||||
import org.apache.fineract.useradministration.domain.PasswordValidationPolicyRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -57,9 +61,9 @@ public final class UserDataValidator {
|
||||
/**
|
||||
* The parameters supported for this command.
|
||||
*/
|
||||
private static final Set<String> SUPPORTED_PARAMETERS = new HashSet<>(Arrays.asList(USERNAME, FIRSTNAME, LASTNAME, PASSWORD,
|
||||
REPEAT_PASSWORD, EMAIL, OFFICE_ID, NOT_SELECTED_ROLES, ROLES, SEND_PASSWORD_TO_EMAIL, STAFF_ID, PASSWORD_NEVER_EXPIRES,
|
||||
AppUserConstants.IS_SELF_SERVICE_USER, AppUserConstants.CLIENTS));
|
||||
private static final Set<String> SUPPORTED_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList(USERNAME, FIRSTNAME, LASTNAME, PASSWORD, REPEAT_PASSWORD, EMAIL, OFFICE_ID, NOT_SELECTED_ROLES, ROLES,
|
||||
SEND_PASSWORD_TO_EMAIL, STAFF_ID, PASSWORD_NEVER_EXPIRES, AppUserConstants.IS_SELF_SERVICE_USER, CLIENTS));
|
||||
public static final String PASSWORD_NEVER_EXPIRE = "passwordNeverExpire";
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
@@ -139,17 +143,17 @@ public final class UserDataValidator {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(AppUserConstants.CLIENTS, element)) {
|
||||
if (this.fromApiJsonHelper.parameterExists(CLIENTS, element)) {
|
||||
if (isSelfServiceUser == null || !isSelfServiceUser) {
|
||||
baseDataValidator.reset().parameter(AppUserConstants.CLIENTS).failWithCode("not.supported.when.isSelfServiceUser.is.false",
|
||||
baseDataValidator.reset().parameter(CLIENTS).failWithCode("not.supported.when.isSelfServiceUser.is.false",
|
||||
"clients parameter is not supported when isSelfServiceUser parameter is false");
|
||||
} else {
|
||||
final JsonArray clientsArray = this.fromApiJsonHelper.extractJsonArrayNamed(AppUserConstants.CLIENTS, element);
|
||||
baseDataValidator.reset().parameter(AppUserConstants.CLIENTS).value(clientsArray).jsonArrayNotEmpty();
|
||||
final JsonArray clientsArray = this.fromApiJsonHelper.extractJsonArrayNamed(CLIENTS, element);
|
||||
baseDataValidator.reset().parameter(CLIENTS).value(clientsArray).jsonArrayNotEmpty();
|
||||
|
||||
for (JsonElement client : clientsArray) {
|
||||
Long clientId = client.getAsLong();
|
||||
baseDataValidator.reset().parameter(AppUserConstants.CLIENTS).value(clientId).longGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(CLIENTS).value(clientId).longGreaterThanZero();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,7 +170,33 @@ public final class UserDataValidator {
|
||||
}
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
private Set<String> getParamNamesFromRequest(final String json) {
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
if (element.isJsonObject()) {
|
||||
return ((JsonObject) element).keySet();
|
||||
}
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
void validateFieldLevelACL(final String json, AppUser authenticatedUser) {
|
||||
if (!authenticatedUser.hasAnyPermission("ALL_FUNCTIONS", "UPDATE_USER")) {
|
||||
Set<String> paramNamesFromRequest = getParamNamesFromRequest(json);
|
||||
if (authenticatedUser.isSelfServiceUser()) {
|
||||
// selfService user can change the clients and the password
|
||||
paramNamesFromRequest.removeAll(Set.of(CLIENTS, PASSWORD, REPEAT_PASSWORD));
|
||||
} else {
|
||||
// user without permission can only change the password
|
||||
paramNamesFromRequest.removeAll(Set.of(PASSWORD, REPEAT_PASSWORD));
|
||||
}
|
||||
if (paramNamesFromRequest.size() > 0) {
|
||||
throw new PlatformApiDataValidationException(
|
||||
List.of(ApiParameterError.parameterError("not.enough.permission.to.update.fields",
|
||||
"Current user has no permission to update fields", String.join(",", paramNamesFromRequest))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json, AppUser authenticatedUser) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
@@ -243,21 +273,22 @@ public final class UserDataValidator {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(AppUserConstants.CLIENTS, element)) {
|
||||
if (this.fromApiJsonHelper.parameterExists(CLIENTS, element)) {
|
||||
if (isSelfServiceUser != null && !isSelfServiceUser) {
|
||||
baseDataValidator.reset().parameter(AppUserConstants.CLIENTS).failWithCode("not.supported.when.isSelfServiceUser.is.false",
|
||||
baseDataValidator.reset().parameter(CLIENTS).failWithCode("not.supported.when.isSelfServiceUser.is.false",
|
||||
"clients parameter is not supported when isSelfServiceUser parameter is false");
|
||||
} else {
|
||||
final JsonArray clientsArray = this.fromApiJsonHelper.extractJsonArrayNamed(AppUserConstants.CLIENTS, element);
|
||||
baseDataValidator.reset().parameter(AppUserConstants.CLIENTS).value(clientsArray).jsonArrayNotEmpty();
|
||||
final JsonArray clientsArray = this.fromApiJsonHelper.extractJsonArrayNamed(CLIENTS, element);
|
||||
baseDataValidator.reset().parameter(CLIENTS).value(clientsArray).jsonArrayNotEmpty();
|
||||
|
||||
for (JsonElement client : clientsArray) {
|
||||
Long clientId = client.getAsLong();
|
||||
baseDataValidator.reset().parameter(AppUserConstants.CLIENTS).value(clientId).longGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(CLIENTS).value(clientId).longGreaterThanZero();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
validateFieldLevelACL(json, authenticatedUser);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user