Add fine graned role and permission for user management (#1670)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-02-29 12:01:35 +02:00
committed by GitHub
parent a0db5ff70e
commit 57450bf31b
6 changed files with 28 additions and 198 deletions

View File

@@ -78,7 +78,7 @@ public class InMemoryUserManagementAutoConfiguration extends GlobalAuthenticatio
tenantAwareUserProperties.getUsers().forEach((username, user) -> {
final TenantAwareUser userPrincipal = new TenantAwareUser(
username, password(user.getPassword(), passwordEncoder),
createAuthorities(user.getRoles(), Collections::emptyList),
createAuthorities(user.getRoles(), user.getPermissions(), Collections::emptyList),
ObjectUtils.isEmpty(user.getTenant()) ? DEFAULT_TENANT : user.getTenant());
userPrincipals.add(userPrincipal);
});
@@ -91,7 +91,8 @@ public class InMemoryUserManagementAutoConfiguration extends GlobalAuthenticatio
securityProperties.getUser().getName(),
password(securityProperties.getUser().getPassword(), passwordEncoder),
createAuthorities(
securityProperties.getUser().getRoles(), PermissionUtils::createAllAuthorityList),
securityProperties.getUser().getRoles(), Collections.emptyList(),
PermissionUtils::createAllAuthorityList),
DEFAULT_TENANT));
} else if (securityProperties != null && securityProperties.getUser() != null &&
!securityProperties.getUser().isPasswordGenerated()) {
@@ -102,7 +103,8 @@ public class InMemoryUserManagementAutoConfiguration extends GlobalAuthenticatio
securityProperties.getUser().getName(),
password(securityProperties.getUser().getPassword(), passwordEncoder),
createAuthorities(
securityProperties.getUser().getRoles(), PermissionUtils::createAllAuthorityList)));
securityProperties.getUser().getRoles(), Collections.emptyList(),
PermissionUtils::createAllAuthorityList)));
}
return new FixedInMemoryTenantAwareUserDetailsService(userPrincipals);
@@ -114,21 +116,27 @@ public class InMemoryUserManagementAutoConfiguration extends GlobalAuthenticatio
}
private static List<GrantedAuthority> createAuthorities(
final List<String> userPermissions, final Supplier<List<GrantedAuthority>> defaultRolesSupplier) {
if (ObjectUtils.isEmpty(userPermissions)) {
final List<String> userRoles, final List<String> userPermissions,
final Supplier<List<GrantedAuthority>> defaultRolesSupplier) {
if (ObjectUtils.isEmpty(userRoles) && ObjectUtils.isEmpty(userPermissions)) {
return defaultRolesSupplier.get();
}
final List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
if (userRoles != null) {
for (final String role : userRoles) {
grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + role));
}
}
// Allows ALL as a shorthand for all permissions
if (userPermissions.size() == 1 && "ALL".equals(userPermissions.get(0))) {
return PermissionUtils.createAllAuthorityList();
grantedAuthorityList.addAll(PermissionUtils.createAllAuthorityList());
} else {
for (final String permission : userPermissions) {
grantedAuthorityList.add(new SimpleGrantedAuthority(permission));
}
}
final List<GrantedAuthority> grantedAuthorityList = new ArrayList<>(userPermissions.size());
for (final String permission : userPermissions) {
grantedAuthorityList.add(new SimpleGrantedAuthority(permission));
grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + permission));
}
return grantedAuthorityList;
}

View File

@@ -35,6 +35,7 @@ public class TenantAwareUserProperties {
@ToString.Exclude
private String password;
private List<String> roles = new ArrayList<>();
private List<String> permissions = new ArrayList<>();
private String tenant;
}
}

View File

@@ -15,309 +15,134 @@ package org.eclipse.hawkbit.exception;
public enum SpServerError {
/**
*
*/
SP_REPO_GENERIC_ERROR("hawkbit.server.error.repo.genericError", "unknown error occurred"),
/**
*
*/
SP_REPO_GENERIC_ERROR("hawkbit.server.error.repo.genericError", "unknown error occurred"),
SP_REPO_ENTITY_ALREADY_EXISTS("hawkbit.server.error.repo.entitiyAlreayExists",
"The given entity already exists in database"),
/**
*
*/
SP_REPO_AUTO_CONFIRMATION_ALREADY_ACTIVE("hawkbit.server.error.repo.autoConfAlreadyActive",
"Auto confirmation is already active"),
/**
*
*/
SP_CONFIRMATION_FEEDBACK_INVALID("hawkbit.server.confirmation.feedback.invalid",
"Confirmation feedback is not valid"),
/**
*
*/
SP_REPO_CONSTRAINT_VIOLATION("hawkbit.server.error.repo.constraintViolation",
"The given entity cannot be saved due to Constraint Violation"),
/**
*
*/
SP_REPO_INVALID_TARGET_ADDRESS("hawkbit.server.error.repo.invalidTargetAddress",
"The target address is not well formed"),
/**
*
*/
SP_REPO_ENTITY_NOT_EXISTS("hawkbit.server.error.repo.entitiyNotFound",
"The given entity does not exist in the repository"),
/**
*
*/
SP_REPO_CONCURRENT_MODIFICATION("hawkbit.server.error.repo.concurrentModification",
"The given entity has been changed by another user/session"),
/**
*
*/
SP_TARGET_ATTRIBUTES_INVALID("hawkbit.server.error.repo.invalidTargetAttributes",
"The given target attributes are invalid"),
/**
*
*/
SP_REST_SORT_PARAM_SYNTAX("hawkbit.server.error.rest.param.sortParamSyntax",
"The given sort parameter is not well formed"),
/**
*
*/
SP_REST_RSQL_SEARCH_PARAM_SYNTAX("hawkbit.server.error.rest.param.rsqlParamSyntax",
"The given search parameter is not well formed"),
/**
*
*/
SP_REST_RSQL_PARAM_INVALID_FIELD("hawkbit.server.error.rest.param.rsqlInvalidField",
"The given search parameter field does not exist"),
/**
*
*/
SP_REST_SORT_PARAM_INVALID_FIELD("hawkbit.server.error.rest.param.invalidField",
"The given sort parameter field does not exist"),
/**
*
*/
SP_REST_SORT_PARAM_INVALID_DIRECTION("hawkbit.server.error.rest.param.invalidDirection",
"The given sort parameter direction does not exist"),
/**
*
*/
SP_REST_BODY_NOT_READABLE("hawkbit.server.error.rest.body.notReadable",
"The given request body is not well formed"),
/**
*
*/
SP_ARTIFACT_UPLOAD_FAILED("hawkbit.server.error.artifact.uploadFailed",
"Upload of artifact failed with internal server error."),
/**
*
*/
SP_ARTIFACT_ENCRYPTION_NOT_SUPPORTED("hawkbit.server.error.artifact.encryptionNotSupported",
"Artifact encryption is not supported."),
/**
*
*/
SP_ARTIFACT_ENCRYPTION_FAILED("hawkbit.server.error.artifact.encryptionFailed",
"Artifact encryption operation failed."),
/**
*
*/
SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH("hawkbit.server.error.artifact.uploadFailed.checksum.md5.match",
"Upload of artifact failed as the provided MD5 checksum did not match with the provided artifact."),
/**
*
*/
SP_ARTIFACT_UPLOAD_FAILED_SHA1_MATCH("hawkbit.server.error.artifact.uploadFailed.checksum.sha1.match",
"Upload of artifact failed as the provided SHA1 checksum did not match with the provided artifact."),
/**
*
*/
SP_ARTIFACT_UPLOAD_FAILED_SHA256_MATCH("hawkbit.server.error.artifact.uploadFailed.checksum.sha256.match",
"Upload of artifact failed as the provided SHA256 checksum did not match with the provided artifact."),
/**
*
*/
SP_DS_CREATION_FAILED_MISSING_MODULE("hawkbit.server.error.distributionset.creationFailed.missingModule",
"Creation if Distribution Set failed as module is missing that is configured as mandatory."),
/**
*
*/
SP_INSUFFICIENT_PERMISSION("hawkbit.server.error.insufficientpermission", "Insufficient Permission"),
/**
*
*/
SP_ARTIFACT_DELETE_FAILED("hawkbit.server.error.artifact.deleteFailed",
"Deletion of artifact failed with internal server error."),
/**
*
*/
SP_ARTIFACT_LOAD_FAILED("hawkbit.server.error.artifact.loadFailed",
"Load of artifact failed with internal server error."),
/**
*
*/
SP_ARTIFACT_BINARY_DELETED("hawkbit.server.error.artifact.binaryDeleted",
"The artifact binary does not exist anymore."),
/**
*
*/
SP_QUOTA_EXCEEDED("hawkbit.server.error.quota.tooManyEntries", "Too many entries have been inserted."),
/**
* error that describes that size of uploaded file exceeds size quota
*/
SP_FILE_SIZE_QUOTA_EXCEEDED("hawkbit.server.error.quota.fileSizeExceeded", "File exceeds size quota."),
/**
* error that describes that size of uploaded file exceeds storage quota
*/
SP_STORAGE_QUOTA_EXCEEDED("hawkbit.server.error.quota.storageExceeded",
"Storage quota will be exceeded if file is uploaded."),
/**
* error message, which describes that the action can not be canceled cause
* the action is inactive.
*/
SP_ACTION_NOT_CANCELABLE("hawkbit.server.error.action.notcancelable",
"Only active actions which are in status pending are cancelable."),
/**
* error message, which describes that the action can not be force quit
* cause the action is inactive.
*/
SP_ACTION_NOT_FORCE_QUITABLE("hawkbit.server.error.action.notforcequitable",
"Only active actions which are in status pending can be force quit."),
/**
*
*/
SP_DS_INCOMPLETE("hawkbit.server.error.distributionset.incomplete",
"Distribution set is assigned/locked to a target that is incomplete (i.e. mandatory modules are missing)"),
/**
* error message, which describes that an entity is locked and can't be functionally modified
*/
SP_LOCKED("hawkbit.server.error.locked", "Entry is locked. Could not be functionally modified"),
/**
* error message, which describes that an entity is locked and can't be functionally modified
*/
SP_DELETED("hawkbit.server.error.deleted", "Entry is soft deleted"),
/**
*
*/
SP_DS_INVALID("hawkbit.server.error.distributionset.invalid", "Invalid distribution set is assigned to a target"),
/**
*
*/
SP_DS_TYPE_UNDEFINED("hawkbit.server.error.distributionset.type.undefined",
"Distribution set type is not yet defined. Modules cannot be added until definition."),
/**
*
*/
SP_DS_MODULE_UNSUPPORTED("hawkbit.server.error.distributionset.modules.unsupported",
"Distribution set type does not contain the given module, i.e. is incompatible."),
/**
*
*/
SP_REPO_TENANT_NOT_EXISTS("hawkbit.server.error.repo.tenantNotExists",
"The entity cannot be inserted due the tenant does not exists"),
/**
*
*/
SP_ENTITY_LOCKED("hawkbit.server.error.entitiylocked", "The given entity is locked by the server."),
/**
*
*/
SP_REPO_ENTITY_READ_ONLY("hawkbit.server.error.entityreadonly",
"The given entity is read only and the change cannot be completed."),
/**
*
*/
SP_CONFIGURATION_VALUE_INVALID("hawkbit.server.error.configValueInvalid",
"The given configuration value is invalid."),
/**
*
*/
SP_CONFIGURATION_KEY_INVALID("hawkbit.server.error.configKeyInvalid", "The given configuration key is invalid."),
/**
*
*/
SP_ROLLOUT_ILLEGAL_STATE("hawkbit.server.error.rollout.illegalstate",
"The rollout is in the wrong state for the requested operation"),
/**
*
*/
SP_ROLLOUT_VERIFICATION_FAILED("hawkbit.server.error.rollout.verificationFailed",
"The rollout configuration could not be verified successfully"),
/**
*
*/
SP_REPO_OPERATION_NOT_SUPPORTED("hawkbit.server.error.operation.notSupported",
"Operation or method is (no longer) supported by service."),
/**
* Error message informing that the maintenance schedule is invalid.
*/
SP_MAINTENANCE_SCHEDULE_INVALID("hawkbit.server.error.maintenanceScheduleInvalid",
"Information for schedule, duration or timezone is missing; or there is no valid maintenance window available in future."),
/**
* Error message informing that the action type for auto-assignment is
* invalid.
*/
SP_AUTO_ASSIGN_ACTION_TYPE_INVALID("hawkbit.server.error.repo.invalidAutoAssignActionType",
"The given action type for auto-assignment is invalid: allowed values are ['forced', 'soft', 'downloadonly']"),
/**
* Error message informing the user that the requested tenant configuration
* change is not allowed.
*/
SP_CONFIGURATION_VALUE_CHANGE_NOT_ALLOWED("hawkbit.server.error.repo.tenantConfigurationValueChangeNotAllowed",
"The requested tenant configuration value modification is not allowed."),
/**
*
*/
SP_MULTIASSIGNMENT_NOT_ENABLED("hawkbit.server.error.multiassignmentNotEnabled",
"The requested operation requires multi assignments to be enabled."),
/**
*
*/
SP_NO_WEIGHT_PROVIDED_IN_MULTIASSIGNMENT_MODE("hawkbit.server.error.noWeightProvidedInMultiAssignmentMode",
"The requested operation requires a weight to be specified when multi assignments is enabled."),
SP_TARGET_TYPE_IN_USE("hawkbit.server.error.target.type.used", "Target type is still in use by a target."),
SP_TARGET_TYPE_INCOMPATIBLE("hawkbit.server.error.target.type.incompatible",
"Target type of target is not compatible with distribution set."),
SP_TARGET_TYPE_KEY_OR_NAME_REQUIRED("hawkbit.server.error.target.type.keyOrNameRequired",
"Target type key or name is required."),
SP_STOP_ROLLOUT_FAILED("hawkbit.server.error.stopRolloutFailed", "Stopping the rollout failed.");
private final String key;

View File

@@ -12,19 +12,15 @@ package org.eclipse.hawkbit.rest.exception;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import java.io.Serial;
/**
* Exception which is thrown in case an request body is not well formaned and
* Exception which is thrown in case an request body is not well formatted and
* cannot be parsed.
*
*
*
*
*/
public class MessageNotReadableException extends AbstractServerRtException {
/**
*
*/
@Serial
private static final long serialVersionUID = 1L;
/**
@@ -34,4 +30,4 @@ public class MessageNotReadableException extends AbstractServerRtException {
public MessageNotReadableException() {
super(SpServerError.SP_REST_BODY_NOT_READABLE);
}
}
}

View File

@@ -36,7 +36,7 @@ spring.rabbitmq.port=5672
# Define own (my_user) users instead together default "admin" (system-wide) user:
#hawkbit.security.user.my_user.password={noop}isAwesome!
#hawkbit.security.user.my_user.roles=ALL
#hawkbit.security.user.my_user.permissions=ALL
#hawkbit.security.user.my_user.tenant=DEFAULT
# Enable CORS and specify the allowed origins:

View File

@@ -37,7 +37,7 @@ spring.rabbitmq.port=5672
# Define own (my_user) users instead together default "admin" (system-wide) user:
#hawkbit.security.user.my_user.password={noop}isAwesome!
#hawkbit.security.user.my_user.roles=ALL
#hawkbit.security.user.my_user.permissions=ALL
#hawkbit.security.user.my_user.tenant=DEFAULT
# Enable CORS and specify the allowed origins: