[Major] Privilege refactorings, remove unused services and actions

This commit is contained in:
Robert von Burg 2023-10-05 13:43:46 +02:00
parent 6f729554c8
commit 6b6a61ab62
Signed by: eitch
GPG Key ID: 75DB9C85C74331F7
22 changed files with 392 additions and 1336 deletions

View File

@ -32,11 +32,12 @@ public class PrivilegeElementFromJsonVisitor {
String name = nameE == null ? null : nameE.getAsString().trim();
List<PrivilegeRep> privileges = new ArrayList<>();
Map<String, PrivilegeRep> privileges = new HashMap<>();
if (privilegesE != null) {
JsonArray privilegesArr = privilegesE.getAsJsonArray();
for (JsonElement privilegeE : privilegesArr) {
privileges.add(privilegeRepFromJson(privilegeE.getAsJsonObject()));
PrivilegeRep privilegeRep = privilegeRepFromJson(privilegeE.getAsJsonObject());
privileges.put(privilegeRep.getName(), privilegeRep);
}
}

View File

@ -53,7 +53,7 @@ public class PrivilegeElementToJsonVisitor implements PrivilegeElementVisitor<Js
jsonObject.addProperty("name", roleRep.getName());
JsonArray privilegesJ = new JsonArray();
roleRep.getPrivileges().forEach(p -> privilegesJ.add(p.accept(this)));
roleRep.getPrivileges().values().forEach(p -> privilegesJ.add(p.accept(this)));
jsonObject.add("privileges", privilegesJ);
return jsonObject;

View File

@ -240,15 +240,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
}
@Override
public UserRep replaceUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException {
public UserRep updateUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException {
return this.lockingHandler.lockedExecuteWithResult(userRep.getUsername(),
() -> crudHandler.replaceUser(certificate, userRep, password));
}
@Override
public UserRep updateUser(Certificate certificate, UserRep userRep) throws PrivilegeException {
return this.lockingHandler.lockedExecuteWithResult(userRep.getUsername(),
() -> crudHandler.updateUser(certificate, userRep));
() -> crudHandler.updateUser(certificate, userRep, password));
}
@Override
@ -257,18 +251,6 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
() -> crudHandler.removeUser(certificate, username));
}
@Override
public UserRep addRoleToUser(Certificate certificate, String username, String roleName) {
return this.lockingHandler.lockedExecuteWithResult(username,
() -> crudHandler.addRoleToUser(certificate, username, roleName));
}
@Override
public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) {
return this.lockingHandler.lockedExecuteWithResult(username,
() -> crudHandler.removeRoleFromUser(certificate, username, roleName));
}
@Override
public UserRep setUserLocale(Certificate certificate, String username, Locale locale) {
return this.lockingHandler.lockedExecuteWithResult(username,
@ -309,18 +291,6 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
() -> crudHandler.removeRole(certificate, roleName));
}
@Override
public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) {
return this.lockingHandler.lockedExecuteWithResult(roleName,
() -> crudHandler.addOrReplacePrivilegeOnRole(certificate, roleName, privilegeRep));
}
@Override
public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) {
return this.lockingHandler.lockedExecuteWithResult(roleName,
() -> crudHandler.removePrivilegeFromRole(certificate, roleName, privilegeName));
}
void invalidSessionsFor(User user) {
List<PrivilegeContext> contexts = new ArrayList<>(this.privilegeContextMap.values());
for (PrivilegeContext ctx : contexts) {

View File

@ -10,7 +10,6 @@ import li.strolch.privilege.model.internal.User;
import li.strolch.privilege.model.internal.UserHistory;
import li.strolch.privilege.policy.PrivilegePolicy;
import li.strolch.utils.collections.Tuple;
import li.strolch.utils.helper.StringHelper;
import java.text.MessageFormat;
import java.time.ZonedDateTime;
@ -19,6 +18,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.text.MessageFormat.format;
import static li.strolch.utils.helper.StringHelper.*;
public class PrivilegeCrudHandler {
@ -146,16 +146,16 @@ public class PrivilegeCrudHandler {
boolean propertySelected;
// userId
userIdSelected = StringHelper.isEmpty(selUserId) || selUserId.equals(user.getUserId());
userIdSelected = isEmpty(selUserId) || selUserId.equals(user.getUserId());
// username
usernameSelected = StringHelper.isEmpty(selUsername) || selUsername.equals(user.getUsername());
usernameSelected = isEmpty(selUsername) || selUsername.equals(user.getUsername());
// firstname
firstNameSelected = StringHelper.isEmpty(selFirstName) || selFirstName.equals(user.getFirstname());
firstNameSelected = isEmpty(selFirstName) || selFirstName.equals(user.getFirstname());
// lastname
lastNameSelected = StringHelper.isEmpty(selLastName) || selLastName.equals(user.getLastname());
lastNameSelected = isEmpty(selLastName) || selLastName.equals(user.getLastname());
// user state
userStateSelected = selUserState == null || selUserState.equals(user.getUserState());
@ -248,13 +248,13 @@ public class PrivilegeCrudHandler {
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_ADD_USER);
// make sure userId is not set
if (StringHelper.isNotEmpty(userRepParam.getUserId()))
if (isNotEmpty(userRepParam.getUserId()))
throw new PrivilegeModelException("UserId can not be set when adding a new user!");
UserRep userRep = userRepParam.getCopy();
// set userId
userRep.setUserId(StringHelper.getUniqueId());
userRep.setUserId(getUniqueId());
// first validate user
userRep.validate();
@ -327,11 +327,11 @@ public class PrivilegeCrudHandler {
// add user
// make sure userId is not set
if (StringHelper.isNotEmpty(userRep.getUserId()))
if (isNotEmpty(userRep.getUserId()))
throw new PrivilegeModelException("UserId can not be set when adding a new user!");
// set userId
userRep.setUserId(StringHelper.getUniqueId());
userRep.setUserId(getUniqueId());
// first validate user
userRep.validate();
@ -383,80 +383,15 @@ public class PrivilegeCrudHandler {
DefaultPrivilegeHandler.logger.info("Updated " + toUpdate.size() + " users");
}
public UserRep replaceUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException {
try {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = privilegeHandler.validate(certificate);
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_USER);
// first validate user
userRep.validate();
validateGroupsExist(userRep);
validateRolesExist(userRep);
// validate user exists
User existingUser = this.persistenceHandler.getUser(userRep.getUsername());
if (existingUser == null) {
String msg = "User {0} can not be replaced as it does not exist!";
throw new PrivilegeModelException(MessageFormat.format(msg, userRep.getUsername()));
}
// validate same userId
if (!existingUser.getUserId().equals(userRep.getUserId())) {
String msg = "UserId of existing user {0} does not match userRep {1}";
msg = MessageFormat.format(msg, existingUser.getUserId(), userRep.getUserId());
throw new PrivilegeModelException(MessageFormat.format(msg, userRep.getUsername()));
}
UserHistory history = existingUser.getHistory();
PasswordCrypt passwordCrypt = null;
if (password != null) {
// validate password meets basic requirements
privilegeHandler.validatePassword(certificate.getLocale(), password);
// get new salt for user
byte[] salt = privilegeHandler.getEncryptionHandler().nextSalt();
// hash password
passwordCrypt = privilegeHandler.getEncryptionHandler().hashPassword(password, salt);
history = history.withLastPasswordChange(ZonedDateTime.now());
}
User newUser = createUser(userRep, history, passwordCrypt, existingUser.isPasswordChangeRequested());
// detect privilege conflicts
assertNoPrivilegeConflict(newUser);
// validate this user may modify this user
prvCtx.validateAction(new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_USER,
new Tuple(existingUser, newUser)));
// delegate to persistence handler
this.persistenceHandler.replaceUser(newUser);
this.privilegeHandler.persistModelAsync();
DefaultPrivilegeHandler.logger.info("Replaced user " + newUser.getUsername());
return newUser.asUserRep();
} finally {
clearPassword(password);
}
}
private void assertNoPrivilegeConflict(User user) {
if (this.privilegeConflictResolution.isStrict()) {
Map<String, String> privilegeNames = new HashMap<>();
List<String> conflicts = detectPrivilegeConflicts(privilegeNames, user);
if (!conflicts.isEmpty()) {
String msg = String.join("\n", conflicts);
throw new PrivilegeModelException(msg);
}
}
if (!this.privilegeConflictResolution.isStrict())
return;
Map<String, String> privilegeNames = new HashMap<>();
List<String> conflicts = detectPrivilegeConflicts(privilegeNames, user);
if (conflicts.isEmpty())
return;
String msg = String.join("\n", conflicts);
throw new PrivilegeModelException(msg);
}
private void assertNoPrivilegeConflict(Role role) {
@ -507,7 +442,7 @@ public class PrivilegeCrudHandler {
private void validateGroupsExist(UserRep userRep) {
for (String group : userRep.getGroups()) {
if (this.persistenceHandler.getGroup(group) == null) {
String msg = "Can not add user {0} as group {1} does not exist!";
String msg = "Can not add/update user {0} as group {1} does not exist!";
msg = MessageFormat.format(msg, userRep.getUsername(), group);
throw new PrivilegeModelException(msg);
}
@ -517,7 +452,7 @@ public class PrivilegeCrudHandler {
private void validateRolesExist(UserRep userRep) {
for (String role : userRep.getRoles()) {
if (this.persistenceHandler.getRole(role) == null) {
String msg = "Can not add user {0} as role {1} does not exist!";
String msg = "Can not add/update user {0} as role {1} does not exist!";
msg = MessageFormat.format(msg, userRep.getUsername(), role);
throw new PrivilegeModelException(msg);
}
@ -539,72 +474,71 @@ public class PrivilegeCrudHandler {
passwordChangeRequested, history);
}
public UserRep updateUser(Certificate certificate, UserRep userRep) throws PrivilegeException {
public UserRep updateUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException {
try {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = privilegeHandler.validate(certificate);
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_USER);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = this.privilegeHandler.validate(certificate);
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_USER);
// get existing user
User existingUser = this.persistenceHandler.getUser(userRep.getUsername());
if (existingUser == null)
throw new PrivilegeModelException(MessageFormat.format("User {0} does not exist!", userRep.getUsername()));
// first validate user
userRep.validate();
// if nothing to do, then stop
if (StringHelper.isEmpty(userRep.getFirstname()) && StringHelper.isEmpty(userRep.getLastname()) &&
userRep.getLocale() == null && (userRep.getProperties() == null || userRep.getProperties().isEmpty())) {
throw new PrivilegeModelException(
MessageFormat.format("All updateable fields are empty for update of user {0}",
userRep.getUsername()));
validateGroupsExist(userRep);
validateRolesExist(userRep);
// validate user exists
User existingUser = this.persistenceHandler.getUser(userRep.getUsername());
if (existingUser == null) {
String msg = "User {0} does not exist!";
throw new PrivilegeModelException(MessageFormat.format(msg, userRep.getUsername()));
}
// validate same userId
if (!existingUser.getUserId().equals(userRep.getUserId())) {
String msg = "UserId of existing user {0} does not match userRep {1}";
msg = MessageFormat.format(msg, existingUser.getUserId(), userRep.getUserId());
throw new PrivilegeModelException(MessageFormat.format(msg, userRep.getUsername()));
}
UserHistory history = existingUser.getHistory();
PasswordCrypt passwordCrypt;
if (password == null) {
passwordCrypt = existingUser.getPasswordCrypt();
} else {
// validate password meets basic requirements
privilegeHandler.validatePassword(certificate.getLocale(), password);
// get new salt for user
byte[] salt = privilegeHandler.getEncryptionHandler().nextSalt();
// hash password
passwordCrypt = privilegeHandler.getEncryptionHandler().hashPassword(password, salt);
history = history.withLastPasswordChange(ZonedDateTime.now());
}
User newUser = createUser(userRep, history, passwordCrypt, existingUser.isPasswordChangeRequested());
// detect privilege conflicts
assertNoPrivilegeConflict(newUser);
// validate this user may modify this user
prvCtx.validateAction(new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_USER,
new Tuple(existingUser, newUser)));
// delegate to persistence handler
this.persistenceHandler.replaceUser(newUser);
this.privilegeHandler.persistModelAsync();
DefaultPrivilegeHandler.logger.info("Replaced user " + newUser.getUsername());
return newUser.asUserRep();
} finally {
clearPassword(password);
}
String userId = existingUser.getUserId();
String username = existingUser.getUsername();
PasswordCrypt passwordCrypt = existingUser.getPasswordCrypt();
String firstName = existingUser.getFirstname();
String lastName = existingUser.getLastname();
UserState userState = existingUser.getUserState();
Set<String> groups = existingUser.getGroups();
Set<String> roles = existingUser.getRoles();
Locale locale = existingUser.getLocale();
Map<String, String> propertyMap = existingUser.getProperties();
// get updated fields
if (StringHelper.isNotEmpty(userRep.getFirstname()))
firstName = userRep.getFirstname();
if (StringHelper.isNotEmpty(userRep.getLastname()))
lastName = userRep.getLastname();
if (userRep.getProperties() != null && !userRep.getProperties().isEmpty())
propertyMap = userRep.getProperties();
if (userRep.getLocale() != null)
locale = userRep.getLocale();
if (userRep.getUserState() != null)
userState = userRep.getUserState();
if (userRep.getRoles() != null && !userRep.getRoles().equals(roles))
roles = userRep.getRoles();
// create new user
User newUser = new User(userId, username, passwordCrypt, firstName, lastName, userState, groups, roles, locale,
propertyMap, existingUser.isPasswordChangeRequested(), existingUser.getHistory());
// detect privilege conflicts
assertNoPrivilegeConflict(newUser);
// validate this user may modify this user
prvCtx.validateAction(new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_USER,
new Tuple(existingUser, newUser)));
// delegate to persistence handler
this.persistenceHandler.replaceUser(newUser);
this.privilegeHandler.persistModelAsync();
DefaultPrivilegeHandler.logger.info("Updated user " + newUser.getUsername());
// update any existing sessions for this user
this.privilegeHandler.updateExistingSessionsForUser(newUser);
return newUser.asUserRep();
}
public UserRep removeUser(Certificate certificate, String username) {
@ -634,100 +568,6 @@ public class PrivilegeCrudHandler {
return existingUser.asUserRep();
}
public UserRep addRoleToUser(Certificate certificate, String username, String roleName) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = privilegeHandler.validate(certificate);
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER);
// get user
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null)
throw new PrivilegeModelException(MessageFormat.format("User {0} does not exist!", username));
// validate that this user may add this role to this user
prvCtx.validateAction(new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER,
new Tuple(existingUser, roleName)));
// check that user not already has role
Set<String> currentRoles = existingUser.getRoles();
if (currentRoles.contains(roleName)) {
String msg = MessageFormat.format("User {0} already has role {1}", username, roleName);
throw new PrivilegeModelException(msg);
}
// validate that the role exists
if (this.persistenceHandler.getRole(roleName) == null) {
String msg = MessageFormat.format("Role {0} does not exist!", roleName);
throw new PrivilegeModelException(msg);
}
// create new user
Set<String> newRoles = new HashSet<>(currentRoles);
newRoles.add(roleName);
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPasswordCrypt(),
existingUser.getFirstname(), existingUser.getLastname(), existingUser.getUserState(),
existingUser.getGroups(), newRoles, existingUser.getLocale(), existingUser.getProperties(),
existingUser.isPasswordChangeRequested(), existingUser.getHistory());
// detect privilege conflicts
assertNoPrivilegeConflict(newUser);
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);
this.privilegeHandler.persistModelAsync();
DefaultPrivilegeHandler.logger.info("Added role " + roleName + " to " + newUser.getUsername());
// update any existing sessions for this user
this.privilegeHandler.updateExistingSessionsForUser(newUser);
return newUser.asUserRep();
}
public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = privilegeHandler.validate(certificate);
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER);
// get User
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null)
throw new PrivilegeModelException(MessageFormat.format("User {0} does not exist!", username));
// validate that this user may remove this role from this user
prvCtx.validateAction(new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER,
new Tuple(existingUser, roleName)));
// ignore if user does not have role
Set<String> currentRoles = existingUser.getRoles();
if (!currentRoles.contains(roleName)) {
String msg = MessageFormat.format("User {0} does not have role {1}", existingUser.getUsername(), roleName);
throw new PrivilegeModelException(msg);
}
// create new user
Set<String> newRoles = new HashSet<>(currentRoles);
newRoles.remove(roleName);
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPasswordCrypt(),
existingUser.getFirstname(), existingUser.getLastname(), existingUser.getUserState(),
existingUser.getGroups(), newRoles, existingUser.getLocale(), existingUser.getProperties(),
existingUser.isPasswordChangeRequested(), existingUser.getHistory());
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);
this.privilegeHandler.persistModelAsync();
DefaultPrivilegeHandler.logger.info("Removed role " + roleName + " from " + newUser.getUsername());
// update any existing sessions for this user
this.privilegeHandler.updateExistingSessionsForUser(newUser);
return newUser.asUserRep();
}
public UserRep setUserLocale(Certificate certificate, String username, Locale locale) {
// validate user actually has this type of privilege
@ -792,7 +632,7 @@ public class PrivilegeCrudHandler {
public void setUserPassword(Certificate certificate, String username, char[] password) {
// we don't want the user to worry about whitespace
username = StringHelper.trimOrEmpty(username);
username = trimOrEmpty(username);
try {
@ -994,112 +834,6 @@ public class PrivilegeCrudHandler {
return existingRole.asRoleRep();
}
public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = privilegeHandler.validate(certificate);
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_ROLE);
// validate PrivilegeRep
privilegeRep.validate();
// get role
Role existingRole = this.persistenceHandler.getRole(roleName);
if (existingRole == null) {
String msg = MessageFormat.format("Role {0} does not exist!", roleName);
throw new PrivilegeModelException(msg);
}
// validate that policy exists if needed
String policy = privilegeRep.getPolicy();
if (policy != null && !this.policyMap.containsKey(policy)) {
String msg = "Policy {0} for Privilege {1} does not exist";
msg = MessageFormat.format(msg, policy, privilegeRep.getName());
throw new PrivilegeModelException(msg);
}
// create new role with the additional privilege
Privilege newPrivilege = Privilege.of(privilegeRep);
// copy existing privileges
Set<String> existingPrivilegeNames = existingRole.getPrivilegeNames();
Map<String, Privilege> privilegeMap = new HashMap<>(existingPrivilegeNames.size() + 1);
for (String name : existingPrivilegeNames) {
Privilege privilege = existingRole.getPrivilege(name);
privilegeMap.put(name, privilege);
}
// add new one
privilegeMap.put(newPrivilege.getName(), newPrivilege);
// create new role
Role newRole = new Role(existingRole.getName(), privilegeMap);
// detect privilege conflicts
assertNoPrivilegeConflict(newRole);
// validate that this user may modify this role
prvCtx.validateAction(new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_ROLE,
new Tuple(existingRole, newRole)));
// delegate role replacement to persistence handler
this.persistenceHandler.replaceRole(newRole);
this.privilegeHandler.persistModelAsync();
DefaultPrivilegeHandler.logger.info("Added/replaced privilege " + privilegeRep.getName() + " to " + roleName);
// update any existing certificates with new role
this.privilegeHandler.updateExistingSessionsWithNewRole(newRole);
return newRole.asRoleRep();
}
public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = privilegeHandler.validate(certificate);
prvCtx.assertHasPrivilege(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_ROLE);
// get role
Role existingRole = this.persistenceHandler.getRole(roleName);
if (existingRole == null) {
throw new PrivilegeModelException(MessageFormat.format("Role {0} does not exist!", roleName));
}
// ignore if role does not have privilege
if (!existingRole.hasPrivilege(privilegeName)) {
String msg = MessageFormat.format("Role {0} does not have Privilege {1}", roleName, privilegeName);
throw new PrivilegeModelException(msg);
}
// create new set of privileges with out the to removed privilege
Set<String> privilegeNames = existingRole.getPrivilegeNames();
Map<String, Privilege> newPrivileges = new HashMap<>(privilegeNames.size() - 1);
for (String name : privilegeNames) {
Privilege privilege = existingRole.getPrivilege(name);
if (!privilege.getName().equals(privilegeName))
newPrivileges.put(privilege.getName(), privilege);
}
// create new role
Role newRole = new Role(existingRole.getName(), newPrivileges);
// validate that this user may modify this role
prvCtx.validateAction(new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_MODIFY_ROLE,
new Tuple(existingRole, newRole)));
// delegate user replacement to persistence handler
this.persistenceHandler.replaceRole(newRole);
this.privilegeHandler.persistModelAsync();
DefaultPrivilegeHandler.logger.info("Removed privilege " + privilegeName + " from " + roleName);
// update any existing certificates with new role
this.privilegeHandler.updateExistingSessionsWithNewRole(newRole);
return newRole.asRoleRep();
}
/**
* Validates that the policies which are not null on the privileges of the role exist
*

View File

@ -15,16 +15,16 @@
*/
package li.strolch.privilege.handler;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import li.strolch.privilege.base.*;
import li.strolch.privilege.model.*;
import li.strolch.privilege.model.internal.Role;
import li.strolch.privilege.model.internal.User;
import li.strolch.privilege.policy.PrivilegePolicy;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* The {@link PrivilegeHandler} is the centrally exposed API for accessing the privilege library. It exposes all needed
* methods to access Privilege data model objects, modify them and validate if users or roles have privileges to perform
@ -212,10 +212,8 @@ public interface PrivilegeHandler {
/**
* Returns a {@link UserRep} for the given username
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the name of the {@link UserRep} to return
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param username the name of the {@link UserRep} to return
*
* @return the {@link UserRep} for the given username, or null if it was not found
*/
@ -224,10 +222,8 @@ public interface PrivilegeHandler {
/**
* Returns a {@link RoleRep} for the given roleName
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName
* the name of the {@link RoleRep} to return
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName the name of the {@link RoleRep} to return
*
* @return the {@link RoleRep} for the given roleName, or null if it was not found
*/
@ -236,8 +232,7 @@ public interface PrivilegeHandler {
/**
* Returns the map of {@link PrivilegePolicy} definitions
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
*
* @return the map of {@link PrivilegePolicy} definitions
*/
@ -246,8 +241,7 @@ public interface PrivilegeHandler {
/**
* Returns the list of {@link Certificate Certificates}
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
*
* @return the list of {@link Certificate Certificates}
*/
@ -256,8 +250,7 @@ public interface PrivilegeHandler {
/**
* Returns all {@link RoleRep RoleReps}
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
*
* @return the list of {@link RoleRep RoleReps}
*/
@ -266,8 +259,7 @@ public interface PrivilegeHandler {
/**
* Returns all {@link UserRep UserReps}
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
*
* @return the list of {@link UserRep UserReps}
*/
@ -277,10 +269,8 @@ public interface PrivilegeHandler {
* Method to query {@link UserRep} which meet the criteria set in the given {@link UserRep}. Null fields mean the
* fields are irrelevant.
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param selectorRep
* the {@link UserRep} to use as criteria selection
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param selectorRep the {@link UserRep} to use as criteria selection
*
* @return a list of {@link UserRep}s which fit the given criteria
*/
@ -289,72 +279,30 @@ public interface PrivilegeHandler {
/**
* Removes the user with the given username
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the username of the user to remove
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param username the username of the user to remove
*
* @return the {@link UserRep} of the user removed, or null if the user did not exist
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate
*/
UserRep removeUser(Certificate certificate, String username) throws PrivilegeException;
/**
* Removes the role with the given roleName from the user with the given username
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the username of the user from which the role is to be removed
* @param roleName
* the roleName of the role to remove from the user
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate
*/
UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) throws PrivilegeException;
/**
* Removes the role with the given roleName
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName
* the roleName of the role to remove
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName the roleName of the role to remove
*
* @return the {@link RoleRep} of the role removed, or null if the role did not exist
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or the role is still in use by a user
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate or the role is still in use by a
* user
*/
RoleRep removeRole(Certificate certificate, String roleName) throws PrivilegeException;
/**
* Removes the privilege with the given privilegeName from the role with the given roleName
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName
* the roleName of the role from which the privilege is to be removed
* @param privilegeName
* the privilegeName of the privilege to remove from the role
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate
*/
RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName)
throws PrivilegeException;
/**
* <p>
* Adds a new user with the information from this {@link UserRep}
@ -365,18 +313,14 @@ public interface PrivilegeHandler {
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(Locale, char[])}
* </p>
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep
* the {@link UserRep} containing the information to create the new {@link User}
* @param password
* the password of the new user. If the password is null, then this is accepted but the user can not login,
* otherwise the password must be validated against {@link PrivilegeHandler#validatePassword(Locale, char[])}
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep the {@link UserRep} containing the information to create the new {@link User}
* @param password the password of the new user. If the password is null, then this is accepted but the user can
* not login, otherwise the password must be validated against
* {@link PrivilegeHandler#validatePassword(Locale, char[])}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or the user already exists
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate or the user already exists
*/
UserRep addUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException;
@ -384,10 +328,8 @@ public interface PrivilegeHandler {
* Allows the bulk adding or updating of users. If the user exists, the user's history and password is kept,
* otherwise the user is created without a password
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param userReps
* the list of users to add or update
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param userReps the list of users to add or update
*/
void addOrUpdateUsers(Certificate certificate, List<UserRep> userReps) throws PrivilegeException;
@ -410,108 +352,39 @@ public interface PrivilegeHandler {
* Any other fields will be ignored
* </p>
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep
* the {@link UserRep} with the fields set to their new values
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep the {@link UserRep} with the fields set to their new values
* @param password the password of the new user. If the password is null, then this is accepted but the user can
* not login, otherwise the password must be validated against
* {@link PrivilegeHandler#validatePassword(Locale, char[])}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or if the user does not exist
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate or if the user does not exist
*/
UserRep updateUser(Certificate certificate, UserRep userRep) throws PrivilegeException;
/**
* <p>
* Replaces the existing user with the information from this {@link UserRep} if the user already exists
* </p>
*
* <p>
* If the password given is null, then the user is created, but can not not login! Otherwise the password must meet
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(Locale, char[])}
* </p>
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep
* the {@link UserRep} containing the information to replace the existing {@link User}
* @param password
* the password of the new user. If the password is null, then this is accepted but the user can not login,
* otherwise the password must be validated against {@link PrivilegeHandler#validatePassword(Locale, char[])}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or if the user does not exist
*/
UserRep replaceUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException;
UserRep updateUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException;
/**
* Adds a new role with the information from this {@link RoleRep}
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param roleRep
* the {@link RoleRep} containing the information to create the new {@link Role}
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param roleRep the {@link RoleRep} containing the information to create the new {@link Role}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or if the role already exists
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate or if the role already exists
*/
RoleRep addRole(Certificate certificate, RoleRep roleRep) throws PrivilegeException;
/**
* Replaces the existing role with the information from this {@link RoleRep}
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param roleRep
* the {@link RoleRep} containing the information to replace the existing {@link Role}
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param roleRep the {@link RoleRep} containing the information to replace the existing {@link Role}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or if the role does not exist
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate or if the role does not exist
*/
RoleRep replaceRole(Certificate certificate, RoleRep roleRep) throws PrivilegeException;
/**
* Adds the role with the given roleName to the {@link User} with the given username
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the username of the {@link User} to which the role should be added
* @param roleName
* the roleName of the {@link Role} which should be added to the {@link User}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or if the role does not exist
*/
UserRep addRoleToUser(Certificate certificate, String username, String roleName) throws PrivilegeException;
/**
* Adds the {@link PrivilegeRep} to the {@link Role} with the given roleName or replaces it, if it already exists
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName
* the roleName of the {@link Role} to which the privilege should be added
* @param privilegeRep
* the representation of the {@link Privilege} which should be added or replaced on the {@link Role}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate or the role does not exist
*/
RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep)
throws PrivilegeException;
/**
* <p>
* Changes the password for the {@link User} with the given username. If the password is null, then the {@link User}
@ -523,19 +396,14 @@ public interface PrivilegeHandler {
* It should be possible for a user to change their own password
* </p>
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the username of the {@link User} for which the password is to be changed
* @param password
* the new password for this user. If the password is null, then the {@link User} can not login anymore. Otherwise
* the password must meet the requirements of the implementation under
* {@link PrivilegeHandler#validatePassword(Locale, char[])}
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param username the username of the {@link User} for which the password is to be changed
* @param password the new password for this user. If the password is null, then the {@link User} can not login
* anymore. Otherwise the password must meet the requirements of the implementation under
* {@link PrivilegeHandler#validatePassword(Locale, char[])}
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate
*/
void setUserPassword(Certificate certificate, String username, char[] password) throws PrivilegeException;
@ -544,105 +412,79 @@ public interface PrivilegeHandler {
* Requires the given user to change their password after next login
* </p>
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the username of the {@link User} for which the password change is requested
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param username the username of the {@link User} for which the password change is requested
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate
*/
void requirePasswordChange(Certificate certificate, String username) throws PrivilegeException;
/**
* Changes the {@link UserState} of the user
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the username of the {@link User} for which the {@link UserState} is to be changed
* @param state
* the new state for the user
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param username the username of the {@link User} for which the {@link UserState} is to be changed
* @param state the new state for the user
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate
*/
UserRep setUserState(Certificate certificate, String username, UserState state) throws PrivilegeException;
/**
* Changes the {@link Locale} of the user
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param username
* the username of the {@link User} for which the {@link Locale} is to be changed
* @param locale
* the new {@link Locale} for the user
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param username the username of the {@link User} for which the {@link Locale} is to be changed
* @param locale the new {@link Locale} for the user
*
* @throws AccessDeniedException
* if the user for this certificate may not perform the action
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws AccessDeniedException if the user for this certificate may not perform the action
* @throws PrivilegeException if there is anything wrong with this certificate
*/
UserRep setUserLocale(Certificate certificate, String username, Locale locale) throws PrivilegeException;
/**
* Initiate a password reset challenge for the given username
*
* @param usage
* the usage for which the challenge is requested
* @param username
* the username of the user to initiate the challenge for
* @param usage the usage for which the challenge is requested
* @param username the username of the user to initiate the challenge for
*/
void initiateChallengeFor(Usage usage, String username);
/**
* Initiate a password reset challenge for the given username
*
* @param usage
* the usage for which the challenge is requested
* @param username
* the username of the user to initiate the challenge for
* @param source
* the source of the challenge
* @param usage the usage for which the challenge is requested
* @param username the username of the user to initiate the challenge for
* @param source the source of the challenge
*/
void initiateChallengeFor(Usage usage, String username, String source);
/**
* Validate the response of a challenge for the given username
*
* @param username
* the username of the user for which the challenge is to be validated
* @param challenge
* the challenge from the user
* @param username the username of the user for which the challenge is to be validated
* @param challenge the challenge from the user
*
* @return certificate with which the user can access the system with the {@link Usage} set to the value from the
* initiated challenge
*
* @throws PrivilegeException
* if anything goes wrong
* @throws PrivilegeException if anything goes wrong
*/
Certificate validateChallenge(String username, String challenge) throws PrivilegeException;
/**
* Validate the response of a challenge for the given username
*
* @param username
* the username of the user for which the challenge is to be validated
* @param challenge
* the challenge from the user
* @param source
* the source of the challenge validation
* @param username the username of the user for which the challenge is to be validated
* @param challenge the challenge from the user
* @param source the source of the challenge validation
*
* @return certificate with which the user can access the system with the {@link Usage} set to the value from the
* initiated challenge
*
* @throws PrivilegeException
* if anything goes wrong
* @throws PrivilegeException if anything goes wrong
*/
Certificate validateChallenge(String username, String challenge, String source) throws PrivilegeException;
@ -650,18 +492,14 @@ public interface PrivilegeHandler {
* Authenticates a user by validating that a {@link User} for the given username and password exist and then returns
* a {@link Certificate} with which this user may then perform actions
*
* @param username
* the username of the {@link User} which is registered in the {@link PersistenceHandler}
* @param password
* the password with which this user is to be authenticated. Null passwords are not accepted and they must meet
* the requirements of the {@link #validatePassword(Locale, char[])}-method
* @param keepAlive
* should this session be kept alive
* @param username the username of the {@link User} which is registered in the {@link PersistenceHandler}
* @param password the password with which this user is to be authenticated. Null passwords are not accepted and
* they must meet the requirements of the {@link #validatePassword(Locale, char[])}-method
* @param keepAlive should this session be kept alive
*
* @return a {@link Certificate} with which this user may then perform actions
*
* @throws AccessDeniedException
* if the user credentials are not valid
* @throws AccessDeniedException if the user credentials are not valid
*/
Certificate authenticate(String username, char[] password, boolean keepAlive) throws AccessDeniedException;
@ -669,22 +507,16 @@ public interface PrivilegeHandler {
* Authenticates a user by validating that a {@link User} for the given username and password exist and then returns
* a {@link Certificate} with which this user may then perform actions
*
* @param username
* the username of the {@link User} which is registered in the {@link PersistenceHandler}
* @param password
* the password with which this user is to be authenticated. Null passwords are not accepted and they must meet
* the requirements of the {@link #validatePassword(Locale, char[])}-method
* @param source
* the source of the authentication request, i.e. remote IP
* @param usage
* the usage type for this authentication
* @param keepAlive
* should this session be kept alive
* @param username the username of the {@link User} which is registered in the {@link PersistenceHandler}
* @param password the password with which this user is to be authenticated. Null passwords are not accepted and
* they must meet the requirements of the {@link #validatePassword(Locale, char[])}-method
* @param source the source of the authentication request, i.e. remote IP
* @param usage the usage type for this authentication
* @param keepAlive should this session be kept alive
*
* @return a {@link Certificate} with which this user may then perform actions
*
* @throws AccessDeniedException
* if the user credentials are not valid
* @throws AccessDeniedException if the user credentials are not valid
*/
Certificate authenticate(String username, char[] password, String source, Usage usage, boolean keepAlive)
throws AccessDeniedException;
@ -692,47 +524,37 @@ public interface PrivilegeHandler {
/**
* Authenticates a user on a remote Single Sign On service. This is implemented by the
*
* @param data
* the data to perform the SSO
* @param keepAlive
* should this session be kept alive
* @param data the data to perform the SSO
* @param keepAlive should this session be kept alive
*
* @return the {@link Certificate} for the user
*
* @throws PrivilegeException
* if something goes wrong with the SSO
* @throws PrivilegeException if something goes wrong with the SSO
*/
Certificate authenticateSingleSignOn(Object data, boolean keepAlive) throws PrivilegeException;
/**
* Authenticates a user on a remote Single Sign On service. This is implemented by the
*
* @param data
* the data to perform the SSO
* @param source
* the source of the SSO authentication
* @param keepAlive
* may the certificate be kept alive
* @param data the data to perform the SSO
* @param source the source of the SSO authentication
* @param keepAlive may the certificate be kept alive
*
* @return the {@link Certificate} for the user
*
* @throws PrivilegeException
* if something goes wrong with the SSO
* @throws PrivilegeException if something goes wrong with the SSO
*/
Certificate authenticateSingleSignOn(Object data, String source, boolean keepAlive) throws PrivilegeException;
/**
* Refreshes the given certificate's session with a new session, i.e. a new certificate
*
* @param certificate
* the certificate for which to perform a refresh
* @param source
* the source of the refresh request
* @param certificate the certificate for which to perform a refresh
* @param source the source of the refresh request
*
* @return a {@link Certificate} with which this user may then perform actions
*
* @throws AccessDeniedException
* if the certificate is now valid, or refreshing is not allowed
* @throws AccessDeniedException if the certificate is now valid, or refreshing is not allowed
*/
Certificate refresh(Certificate certificate, String source) throws AccessDeniedException;
@ -754,8 +576,7 @@ public interface PrivilegeHandler {
* Invalidates the session for the given {@link Certificate}, effectively logging out the user who was authenticated
* with the credentials associated to the given {@link Certificate}
*
* @param certificate
* the {@link Certificate} for which the session is to be invalidated
* @param certificate the {@link Certificate} for which the session is to be invalidated
*
* @return true if the session was still valid and is now invalidated, false otherwise
*/
@ -769,15 +590,12 @@ public interface PrivilegeHandler {
* encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their
* actions and do not need to access the {@link PrivilegeHandler} anymore
*
* @param certificate
* the {@link Certificate} to check
* @param certificate the {@link Certificate} to check
*
* @return the {@link PrivilegeContext} for the given {@link Certificate}
*
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws NotAuthenticatedException
* if the certificate has expired
* @throws PrivilegeException if there is anything wrong with this certificate
* @throws NotAuthenticatedException if the certificate has expired
*/
PrivilegeContext validate(Certificate certificate) throws PrivilegeException;
@ -786,13 +604,10 @@ public interface PrivilegeHandler {
* system user session and that the user exists for the certificate. This method checks if the {@link Certificate}
* has been tampered with
*
* @param ctx
* the {@link PrivilegeContext} to check
* @param ctx the {@link PrivilegeContext} to check
*
* @throws PrivilegeException
* if there is anything wrong with this privilege context
* @throws NotAuthenticatedException
* if the privilege context has expired
* @throws PrivilegeException if there is anything wrong with this privilege context
* @throws NotAuthenticatedException if the privilege context has expired
*/
void validateSystemSession(PrivilegeContext ctx) throws PrivilegeException;
@ -804,17 +619,13 @@ public interface PrivilegeHandler {
* encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their
* actions and do not need to access the {@link PrivilegeHandler} anymore
*
* @param certificate
* the {@link Certificate} to check
* @param source
* the source, e.g. remote IP for this validation request
* @param certificate the {@link Certificate} to check
* @param source the source, e.g. remote IP for this validation request
*
* @return the {@link PrivilegeContext} for the given {@link Certificate}
*
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws NotAuthenticatedException
* if the certificate has expired
* @throws PrivilegeException if there is anything wrong with this certificate
* @throws NotAuthenticatedException if the certificate has expired
*/
PrivilegeContext validate(Certificate certificate, String source) throws PrivilegeException;
@ -840,15 +651,13 @@ public interface PrivilegeHandler {
*
* <b>Note:</b> It depends on the underlying {@link PersistenceHandler} implementation if data really is read
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param source
* the source of the request
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param source the source of the request
*
* @return true if the reload was successful, false if something went wrong
*
* @throws AccessDeniedException
* if the users of the given certificate does not have the privilege to perform this action
* @throws AccessDeniedException if the users of the given certificate does not have the privilege to perform this
* action
*/
boolean reload(Certificate certificate, String source);
@ -856,28 +665,25 @@ public interface PrivilegeHandler {
* Persists any changes to the privilege data model. Changes are thus not persisted immediately, but must be
* actively performed
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
*
* @return true if changes were persisted, false if no changes were persisted
*
* @throws AccessDeniedException
* if the users of the given certificate does not have the privilege to perform this action
* @throws AccessDeniedException if the users of the given certificate does not have the privilege to perform this
* action
*/
boolean persist(Certificate certificate) throws AccessDeniedException;
/**
* Persists all currently active sessions
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
* @param source
* the source of the request
* @param certificate the {@link Certificate} of the user which has the privilege to perform this action
* @param source the source of the request
*
* @return true if changes were persisted, false if not (i.e. not enabled)
*
* @throws AccessDeniedException
* if the users of the given certificate does not have the privilege to perform this action
* @throws AccessDeniedException if the users of the given certificate does not have the privilege to perform this
* action
*/
boolean persistSessions(Certificate certificate, String source) throws AccessDeniedException;
@ -886,15 +692,11 @@ public interface PrivilegeHandler {
* has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation
* of the given {@link SystemAction} instance
*
* @param systemUsername
* the username of the system user to perform the action as
* @param action
* the action to be performed as the system user
* @param systemUsername the username of the system user to perform the action as
* @param action the action to be performed as the system user
*
* @throws PrivilegeException
* if the user does not exist, or the system action is not allowed
* @throws Exception
* if anything else goes wrong during execution
* @throws PrivilegeException if the user does not exist, or the system action is not allowed
* @throws Exception if anything else goes wrong during execution
*/
void runAs(String systemUsername, SystemAction action) throws PrivilegeException, Exception;
@ -903,17 +705,13 @@ public interface PrivilegeHandler {
* has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation
* of the given {@link SystemAction} instance
*
* @param systemUsername
* the username of the system user to perform the action as
* @param action
* the action to be performed as the system user
* @param systemUsername the username of the system user to perform the action as
* @param action the action to be performed as the system user
*
* @return the action
*
* @throws PrivilegeException
* if the user does not exist, or the system action is not allowed
* @throws Exception
* if anything else goes wrong during execution
* @throws PrivilegeException if the user does not exist, or the system action is not allowed
* @throws Exception if anything else goes wrong during execution
*/
<T> T runWithResult(String systemUsername, SystemActionWithResult<T> action) throws PrivilegeException, Exception;
@ -923,13 +721,11 @@ public interface PrivilegeHandler {
* {@link PrivilegeContext} should be open for a longer period of time, or where opening many
* {@link PrivilegeContext} is resource intensive e.g. on low power devices.
*
* @param systemUsername
* the username of the system user to perform the action as
* @param systemUsername the username of the system user to perform the action as
*
* @return the action
*
* @throws PrivilegeException
* if the user does not exist, or the system action is not allowed
* @throws PrivilegeException if the user does not exist, or the system action is not allowed
*/
PrivilegeContext openSystemUserContext(String systemUsername) throws PrivilegeException;

View File

@ -22,7 +22,6 @@ import li.strolch.privilege.policy.PrivilegePolicy;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import static li.strolch.utils.helper.StringHelper.isEmpty;
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
@ -42,6 +41,8 @@ public class PrivilegeRep {
private Set<String> denyList;
private Set<String> allowList;
private boolean readOnly;
/**
* Default constructor
*
@ -57,8 +58,26 @@ public class PrivilegeRep {
this.name = trimOrEmpty(name);
this.policy = trimOrEmpty(policy);
this.allAllowed = allAllowed;
this.denyList = denyList == null ? Set.of() : Set.copyOf(denyList);
this.allowList = allowList == null ? Set.of() : Set.copyOf(allowList);
setDenyList(denyList == null ? Set.of() : denyList);
setAllowList(allowList == null ? Set.of() : allowList);
}
public boolean isReadOnly() {
return readOnly;
}
public PrivilegeRep readOnly() {
if (this.readOnly)
return this;
this.readOnly = true;
this.denyList = Set.copyOf(this.denyList);
this.allowList = Set.copyOf(this.allowList);
return this;
}
protected void assertNotReadonly() {
if (this.readOnly)
throw new IllegalStateException("Privilege is currently readOnly, to modify get a copy!");
}
/**
@ -86,6 +105,7 @@ public class PrivilegeRep {
* @param name the name to set
*/
public void setName(String name) {
assertNotReadonly();
this.name = trimOrEmpty(name);
}
@ -100,6 +120,7 @@ public class PrivilegeRep {
* @param policy the policy to set
*/
public void setPolicy(String policy) {
assertNotReadonly();
this.policy = trimOrEmpty(policy);
}
@ -114,6 +135,7 @@ public class PrivilegeRep {
* @param allAllowed the allAllowed to set
*/
public void setAllAllowed(boolean allAllowed) {
assertNotReadonly();
this.allAllowed = allAllowed;
}
@ -128,7 +150,8 @@ public class PrivilegeRep {
* @param denyList the denyList to set
*/
public void setDenyList(Set<String> denyList) {
this.denyList = denyList.stream().map(String::trim).collect(Collectors.toSet());
assertNotReadonly();
this.denyList = denyList.stream().map(String::trim).collect(HashSet::new, HashSet::add, HashSet::addAll);
}
/**
@ -142,7 +165,8 @@ public class PrivilegeRep {
* @param allowList the allowList to set
*/
public void setAllowList(Set<String> allowList) {
this.allowList = allowList.stream().map(String::trim).collect(Collectors.toSet());
assertNotReadonly();
this.allowList = allowList.stream().map(String::trim).collect(HashSet::new, HashSet::add, HashSet::addAll);
}
/**
@ -178,6 +202,10 @@ public class PrivilegeRep {
return this.name.equals(other.name);
}
public PrivilegeRep getCopy() {
return new PrivilegeRep(this.name, this.policy, this.allAllowed, this.denyList, this.allowList);
}
public <T> T accept(PrivilegeElementVisitor<T> visitor) {
return visitor.visitPrivilegeRep(this);
}

View File

@ -20,7 +20,8 @@ import li.strolch.privilege.model.internal.Role;
import li.strolch.utils.dbc.DBC;
import java.text.MessageFormat;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import static li.strolch.utils.helper.StringHelper.isEmpty;
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
@ -35,7 +36,9 @@ import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
public class RoleRep {
private String name;
private List<PrivilegeRep> privileges;
private Map<String, PrivilegeRep> privileges;
private boolean readOnly;
/**
* Default constructor
@ -43,9 +46,26 @@ public class RoleRep {
* @param name the name of this role
* @param privileges the list of privileges granted to this role
*/
public RoleRep(String name, List<PrivilegeRep> privileges) {
public RoleRep(String name, Map<String, PrivilegeRep> privileges) {
this.name = trimOrEmpty(name);
this.privileges = privileges == null ? List.of() : List.copyOf(privileges);
setPrivileges(privileges == null ? Map.of() : privileges);
}
public boolean isReadOnly() {
return readOnly;
}
public RoleRep readOnly() {
if (this.readOnly)
return this;
this.readOnly = true;
this.privileges = Map.copyOf(this.privileges);
return this;
}
protected void assertNotReadonly() {
if (this.readOnly)
throw new IllegalStateException("Role is currently readOnly, to modify get a copy!");
}
/**
@ -55,7 +75,7 @@ public class RoleRep {
if (isEmpty(this.name))
throw new PrivilegeException("name is null");
for (PrivilegeRep privilege : this.privileges) {
for (PrivilegeRep privilege : this.privileges.values()) {
try {
privilege.validate();
} catch (Exception e) {
@ -77,26 +97,26 @@ public class RoleRep {
* @param name the name to set
*/
public void setName(String name) {
assertNotReadonly();
this.name = trimOrEmpty(name);
}
/**
* Returns the privileges assigned to this Role as a list
*
* @return the privileges assigned to this Role as a list
*/
public List<PrivilegeRep> getPrivileges() {
public Map<String, PrivilegeRep> getPrivileges() {
if (this.privileges == null)
return null;
return this.privileges;
}
/**
* Sets the privileges on this from a list
*
* @param privileges the list of privileges to assign to this role
*/
public void setPrivileges(List<PrivilegeRep> privileges) {
public void setPrivileges(Map<String, PrivilegeRep> privileges) {
assertNotReadonly();
DBC.PRE.assertNotNull("privileges must not be null!", privileges);
this.privileges = List.copyOf(privileges);
this.privileges = new HashMap<>(privileges);
}
public void addPrivilege(PrivilegeRep privilegeRep) {
DBC.PRE.assertFalse(() -> "Privilege " + privilegeRep.getName() + " already on role " + this.name,
privileges.containsKey(privilegeRep.getName()));
this.privileges.put(privilegeRep.getName(), privilegeRep);
}
/**
@ -131,6 +151,10 @@ public class RoleRep {
return this.name.equals(other.name);
}
public RoleRep getCopy() {
return new RoleRep(this.name, this.privileges);
}
public <T> T accept(PrivilegeElementVisitor<T> visitor) {
return visitor.visitRoleRep(this);
}

View File

@ -25,7 +25,6 @@ import li.strolch.utils.dbc.DBC;
import java.text.MessageFormat;
import java.util.*;
import static java.util.stream.Collectors.toSet;
import static li.strolch.privilege.base.PrivilegeConstants.*;
import static li.strolch.utils.helper.StringHelper.isEmpty;
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
@ -74,15 +73,11 @@ public class UserRep {
this.firstname = trimOrEmpty(firstname);
this.lastname = trimOrEmpty(lastname);
this.userState = userState;
this.groups = groups == null ? null : groups.stream().map(String::trim).collect(toSet());
this.roles = roles == null ? null : roles.stream().map(String::trim).collect(toSet());
this.locale = locale;
this.properties = new HashMap<>();
if (propertyMap != null)
propertyMap.forEach((key, value) -> this.properties.put(key.trim(), value.trim()));
this.history = history;
setGroups(groups == null ? Set.of() : groups);
setRoles(roles == null ? Set.of() : roles);
setProperties(properties == null ? Map.of() : properties);
this.history = history == null ? UserHistory.EMPTY : history;
}
@SuppressWarnings("unused")
@ -129,7 +124,8 @@ public class UserRep {
}
public UserRep readOnly() {
assertNotReadonly();
if (this.readOnly)
return this;
this.readOnly = true;
this.groups = Set.copyOf(this.groups);
this.roles = Set.copyOf(this.roles);
@ -232,17 +228,17 @@ public class UserRep {
}
public Set<String> getGroups() {
return groups;
return this.groups;
}
public void setGroups(Set<String> groups) {
DBC.PRE.assertNotNull("groups must not be null!", groups);
assertNotReadonly();
this.groups = groups.stream().map(String::trim).collect(toSet());
this.groups = groups.stream().map(String::trim).collect(HashSet::new, HashSet::add, HashSet::addAll);
}
public boolean hasGroup(String group) {
return this.groups != null && this.groups.contains(group);
return this.groups.contains(group);
}
/**
@ -258,11 +254,16 @@ public class UserRep {
public void setRoles(Set<String> roles) {
DBC.PRE.assertNotNull("roles must not be null!", roles);
assertNotReadonly();
this.roles = roles.stream().map(String::trim).collect(toSet());
this.roles = roles.stream().map(String::trim).collect(HashSet::new, HashSet::add, HashSet::addAll);
}
public void addRole(String role) {
assertNotReadonly();
this.roles.add(role);
}
public boolean hasRole(String role) {
return this.roles != null && this.roles.contains(role);
return this.roles.contains(role);
}
/**
@ -286,8 +287,6 @@ public class UserRep {
* @return the user history
*/
public UserHistory getHistory() {
if (this.history == null)
return UserHistory.EMPTY;
return this.history;
}
@ -329,7 +328,8 @@ public class UserRep {
public void setProperties(Map<String, String> properties) {
DBC.PRE.assertNotNull("properties must not be null!", properties);
assertNotReadonly();
this.properties = properties;
this.properties = new HashMap<>();
properties.forEach((key, value) -> this.properties.put(key.trim(), value.trim()));
}
/**
@ -338,9 +338,7 @@ public class UserRep {
* @return the {@link Set} of keys of all properties
*/
public Set<String> getPropertyKeySet() {
if (this.readOnly)
return this.properties.keySet();
return new HashSet<>(this.properties.keySet());
return this.properties.keySet();
}
/**
@ -349,9 +347,7 @@ public class UserRep {
* @return the map of properties
*/
public Map<String, String> getProperties() {
if (this.readOnly)
return this.properties;
return new HashMap<>(this.properties);
return this.properties;
}
/**
@ -417,13 +413,8 @@ public class UserRep {
}
public UserRep getCopy() {
Set<String> groups = this.groups == null ? null : new HashSet<>(this.groups);
Set<String> roles = this.roles == null ? null : new HashSet<>(this.roles);
Map<String, String> propertyMap = new HashMap<>(this.properties);
return new UserRep(this.userId, this.username, this.firstname, this.lastname, this.userState, groups, roles,
this.locale, propertyMap, this.history == null ? UserHistory.EMPTY : this.history);
return new UserRep(this.userId, this.username, this.firstname, this.lastname, this.userState, this.groups,
this.roles, this.locale, this.properties, this.history);
}
public <T> T accept(PrivilegeElementVisitor<T> visitor) {

View File

@ -21,8 +21,9 @@ import li.strolch.privilege.model.PrivilegeRep;
import li.strolch.privilege.model.RoleRep;
import li.strolch.utils.dbc.DBC;
import java.util.*;
import java.util.Map.Entry;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import static li.strolch.utils.helper.StringHelper.isEmpty;
@ -62,9 +63,7 @@ public record Role(String name, Map<String, Privilege> privilegeMap) {
// build privileges from rep
Map<String, Privilege> privilegeMap = new HashMap<>(roleRep.getPrivileges().size());
for (PrivilegeRep privilege : roleRep.getPrivileges()) {
privilegeMap.put(privilege.getName(), Privilege.of(privilege));
}
roleRep.getPrivileges().values().forEach(p -> privilegeMap.put(p.getName(), Privilege.of(p)));
return new Role(name, privilegeMap);
}
@ -109,10 +108,8 @@ public record Role(String name, Map<String, Privilege> privilegeMap) {
* @return a {@link RoleRep} which is a representation of this object used to serialize and view on clients
*/
public RoleRep asRoleRep() {
List<PrivilegeRep> privileges = new ArrayList<>();
for (Entry<String, Privilege> entry : this.privilegeMap.entrySet()) {
privileges.add(entry.getValue().asPrivilegeRep());
}
Map<String, PrivilegeRep> privileges = new HashMap<>();
this.privilegeMap.values().forEach(p -> privileges.put(p.getName(), p.asPrivilegeRep()));
return new RoleRep(this.name, privileges);
}

View File

@ -137,7 +137,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
try {
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
RoleRep roleRep = new RoleRep(ROLE_TEMP, new ArrayList<>());
RoleRep roleRep = new RoleRep(ROLE_TEMP, Map.of());
Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addRole(certificate, roleRep);
@ -253,9 +253,12 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
assertNotEquals("The", user.getFirstname());
assertNotEquals("Admin", user.getLastname());
// let's add a new user bob
UserRep userRep = new UserRep(null, ADMIN, "The", "Admin", null, null, null, null, null, null);
this.privilegeHandler.updateUser(certificate, userRep);
// set new name
user.setFirstname("The");
user.setLastname("Admin");
// update user
this.privilegeHandler.updateUser(certificate, user, null);
user = this.privilegeHandler.getUser(certificate, ADMIN);
assertEquals("The", user.getFirstname());
@ -275,8 +278,9 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
Certificate certificate = this.ctx.getCertificate();
// let's add a new user bob
UserRep userRep = new UserRep(null, BOB, null, null, null, null, null, null, null, null);
this.privilegeHandler.updateUser(certificate, userRep);
UserRep userRep = new UserRep(BOB, BOB, "Bob", "Anderson", UserState.ENABLED,
Set.of("AppUserLocationA"), null, null, null, null);
this.privilegeHandler.updateUser(certificate, userRep, null);
} finally {
logout();
}
@ -284,25 +288,6 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
MatcherAssert.assertThat(exception.getMessage(), containsString("User bob does not exist"));
}
@Test
public void shouldFailUpdateAdminNoChanges() {
PrivilegeException exception = assertThrows(PrivilegeException.class, () -> {
try {
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
Certificate certificate = this.ctx.getCertificate();
// let's add a new user bob
UserRep userRep = new UserRep(null, ADMIN, null, null, null, null, null, null, null, null);
this.privilegeHandler.updateUser(certificate, userRep);
} finally {
logout();
}
});
MatcherAssert.assertThat(exception.getMessage(),
containsString("All updateable fields are empty for update of user admin"));
}
@Test
public void shouldQueryUsers() {
try {
@ -379,8 +364,10 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
Certificate certificate = this.ctx.getCertificate();
PrivilegeRep privilegeRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_ACTION, "DefaultPrivilege",
true, Collections.emptySet(), Collections.emptySet());
this.privilegeHandler.addOrReplacePrivilegeOnRole(certificate, ROLE_APP_USER, privilegeRep);
true, Set.of(), Set.of());
RoleRep role = this.privilegeHandler.getRole(certificate, ROLE_APP_USER);
role.addPrivilege(privilegeRep);
this.privilegeHandler.replaceRole(certificate, role);
} finally {
logout();
}
@ -394,8 +381,10 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
try {
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addRoleToUser(certificate, ADMIN, ROLE_MY);
this.privilegeHandler.addRoleToUser(certificate, ADMIN, ROLE_MY2);
UserRep user = this.privilegeHandler.getUser(certificate, ADMIN);
user.addRole(ROLE_MY);
user.addRole(ROLE_MY2);
this.privilegeHandler.updateUser(certificate, user, null);
} finally {
logout();
}
@ -559,15 +548,21 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
PrivilegeRep passwordRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_SET_USER_PASSWORD,
PRIVILEGE_USER_ACCESS, false, Collections.emptySet(), Collections.emptySet());
PRIVILEGE_USER_ACCESS, false, Set.of(), Set.of());
PrivilegeRep localeRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_SET_USER_LOCALE, PRIVILEGE_USER_ACCESS,
false, Collections.emptySet(), Collections.emptySet());
false, Set.of(), Set.of());
RoleRep roleRep = new RoleRep(ROLE_CHANGE_PW, Arrays.asList(passwordRep, localeRep));
Map<String, PrivilegeRep> privileges = new HashMap<>();
privileges.put(passwordRep.getName(), passwordRep);
privileges.put(localeRep.getName(), localeRep);
RoleRep roleRep = new RoleRep(ROLE_CHANGE_PW, privileges);
Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addRole(certificate, roleRep);
this.privilegeHandler.addRoleToUser(certificate, TED, ROLE_CHANGE_PW);
UserRep ted = this.privilegeHandler.getUser(certificate, TED);
ted.addRole(ROLE_CHANGE_PW);
this.privilegeHandler.updateUser(certificate, ted, null);
logger.info("Added " + ROLE_CHANGE_PW + " to " + TED);
this.privilegeHandler.persist(certificate);
} finally {
@ -593,7 +588,9 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
// testAddAppRoleToBob
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addRoleToUser(certificate, BOB, ROLE_APP_USER);
UserRep bob = this.privilegeHandler.getUser(certificate, BOB);
bob.addRole(ROLE_APP_USER);
this.privilegeHandler.updateUser(certificate, bob, null);
logger.info("Added " + ROLE_APP_USER + " to " + BOB);
this.privilegeHandler.persist(certificate);
} finally {
@ -694,7 +691,9 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
// testAddAdminRoleToBob
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addRoleToUser(certificate, BOB, ROLE_PRIVILEGE_ADMIN);
UserRep bob = this.privilegeHandler.getUser(certificate, BOB);
bob.addRole(ROLE_PRIVILEGE_ADMIN);
this.privilegeHandler.updateUser(certificate, bob, null);
logger.info("Added " + ROLE_PRIVILEGE_ADMIN + " to " + ADMIN);
this.privilegeHandler.persist(certificate);
} finally {
@ -739,7 +738,9 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
// testAddRoleUserToBob
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addRoleToUser(certificate, BOB, ROLE_USER);
UserRep bob = this.privilegeHandler.getUser(certificate, BOB);
bob.addRole(ROLE_USER);
this.privilegeHandler.updateUser(certificate, bob, null);
this.privilegeHandler.persist(certificate);
logout();
} finally {
@ -751,7 +752,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
try {
// add role user
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
RoleRep roleRep = new RoleRep(ROLE_USER, new ArrayList<>());
RoleRep roleRep = new RoleRep(ROLE_USER, Map.of());
Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addRole(certificate, roleRep);
this.privilegeHandler.persist(certificate);

View File

@ -254,7 +254,7 @@ public class XmlTest {
Map<String, Group> groups = xmlHandler.getGroups();
assertNotNull(groups);
assertEquals(1, groups.size());
assertEquals(2, groups.size());
// group AppUserLocationA
Group group = groups.get("AppUserLocationA");
@ -263,6 +263,12 @@ public class XmlTest {
Map<String, String> properties = group.getProperties();
assertEquals(new HashSet<>(List.of("location")), properties.keySet());
assertEquals("LocationA", properties.get("location"));
group = groups.get("GroupA");
assertEquals("GroupA", group.name());
properties = group.getProperties();
assertTrue(properties.isEmpty());
assertTrue(group.roles().isEmpty());
}
@Test

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Groups>
<Group name="GroupA"/>
<Group name="AppUserLocationA">
<Roles>
<Role>AppUser</Role>

View File

@ -1,24 +0,0 @@
/*
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.service.privilege.roles;
import li.strolch.privilege.model.PrivilegeRep;
import li.strolch.service.api.ServiceArgument;
public class PrivilegeAddOrReplacePrivilegeOnRoleArgument extends ServiceArgument {
public String roleName;
public PrivilegeRep privilegeRep;
}

View File

@ -1,64 +0,0 @@
/*
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.service.privilege.roles;
import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.model.RoleRep;
import li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants;
import li.strolch.service.api.AbstractService;
import li.strolch.service.api.ServiceResultState;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PrivilegeAddOrReplacePrivilegeOnRoleService
extends AbstractService<PrivilegeAddOrReplacePrivilegeOnRoleArgument, PrivilegeRoleResult> {
@Override
protected PrivilegeRoleResult getResultInstance() {
return new PrivilegeRoleResult(ServiceResultState.FAILED);
}
@Override
public PrivilegeAddOrReplacePrivilegeOnRoleArgument getArgumentInstance() {
return new PrivilegeAddOrReplacePrivilegeOnRoleArgument();
}
@Override
protected PrivilegeRoleResult internalDoService(PrivilegeAddOrReplacePrivilegeOnRoleArgument arg) {
li.strolch.runtime.privilege.PrivilegeHandler strolchPrivilegeHandler = getContainer().getPrivilegeHandler();
PrivilegeHandler privilegeHandler = strolchPrivilegeHandler.getPrivilegeHandler();
RoleRep role;
try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_MODIFY_ROLE)) {
tx.setSuppressAudits(true);
role = privilegeHandler.addOrReplacePrivilegeOnRole(getCertificate(), arg.roleName, arg.privilegeRep);
privilegeHandler.persist(getCertificate());
Audit audit = tx
.auditFrom(AccessType.UPDATE, StrolchPrivilegeConstants.PRIVILEGE, StrolchPrivilegeConstants.ROLE,
role.getName());
tx.getAuditTrail().add(tx, audit);
}
return new PrivilegeRoleResult(role);
}
}

View File

@ -1,23 +0,0 @@
/*
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.service.privilege.roles;
import li.strolch.service.api.ServiceArgument;
public class PrivilegeRemovePrivilegeFromRoleArgument extends ServiceArgument {
public String roleName;
public String privilegeName;
}

View File

@ -1,64 +0,0 @@
/*
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.service.privilege.roles;
import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.model.RoleRep;
import li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants;
import li.strolch.service.api.AbstractService;
import li.strolch.service.api.ServiceResultState;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PrivilegeRemovePrivilegeFromRoleService
extends AbstractService<PrivilegeRemovePrivilegeFromRoleArgument, PrivilegeRoleResult> {
@Override
protected PrivilegeRoleResult getResultInstance() {
return new PrivilegeRoleResult(ServiceResultState.FAILED);
}
@Override
public PrivilegeRemovePrivilegeFromRoleArgument getArgumentInstance() {
return new PrivilegeRemovePrivilegeFromRoleArgument();
}
@Override
protected PrivilegeRoleResult internalDoService(PrivilegeRemovePrivilegeFromRoleArgument arg) {
li.strolch.runtime.privilege.PrivilegeHandler strolchPrivilegeHandler = getContainer().getPrivilegeHandler();
PrivilegeHandler privilegeHandler = strolchPrivilegeHandler.getPrivilegeHandler();
RoleRep role;
try (StrolchTransaction tx = openArgOrUserTx(arg, StrolchPrivilegeConstants.PRIVILEGE_MODIFY_ROLE)) {
tx.setSuppressAudits(true);
role = privilegeHandler.removePrivilegeFromRole(getCertificate(), arg.roleName, arg.privilegeName);
privilegeHandler.persist(getCertificate());
Audit audit = tx
.auditFrom(AccessType.UPDATE, StrolchPrivilegeConstants.PRIVILEGE, StrolchPrivilegeConstants.ROLE,
role.getName());
tx.getAuditTrail().add(tx, audit);
}
return new PrivilegeRoleResult(role);
}
}

View File

@ -1,64 +0,0 @@
/*
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.service.privilege.users;
import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.model.UserRep;
import li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants;
import li.strolch.service.api.AbstractService;
import li.strolch.service.api.ServiceResultState;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PrivilegeAddRoleToUserService
extends AbstractService<PrivilegeRoleUserNamesArgument, PrivilegeUserResult> {
@Override
protected PrivilegeUserResult getResultInstance() {
return new PrivilegeUserResult(ServiceResultState.FAILED);
}
@Override
public PrivilegeRoleUserNamesArgument getArgumentInstance() {
return new PrivilegeRoleUserNamesArgument();
}
@Override
protected PrivilegeUserResult internalDoService(PrivilegeRoleUserNamesArgument arg) {
li.strolch.runtime.privilege.PrivilegeHandler strolchPrivilegeHandler = getContainer().getPrivilegeHandler();
PrivilegeHandler privilegeHandler = strolchPrivilegeHandler.getPrivilegeHandler();
UserRep user;
try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER)) {
tx.setSuppressAudits(true);
user = privilegeHandler.addRoleToUser(getCertificate(), arg.username, arg.rolename);
if (privilegeHandler.isPersistOnUserDataChanged())
privilegeHandler.persist(getCertificate());
Audit audit = tx.auditFrom(AccessType.UPDATE, StrolchPrivilegeConstants.PRIVILEGE,
StrolchPrivilegeConstants.USER, user.getUsername());
tx.getAuditTrail().add(tx, audit);
}
return new PrivilegeUserResult(user);
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.service.privilege.users;
import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.model.UserRep;
import li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants;
import li.strolch.service.api.AbstractService;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PrivilegeRemoveRoleFromUserService
extends AbstractService<PrivilegeRoleUserNamesArgument, PrivilegeUserResult> {
@Override
protected PrivilegeUserResult getResultInstance() {
return new PrivilegeUserResult();
}
@Override
public PrivilegeRoleUserNamesArgument getArgumentInstance() {
return new PrivilegeRoleUserNamesArgument();
}
@Override
protected PrivilegeUserResult internalDoService(PrivilegeRoleUserNamesArgument arg) {
li.strolch.runtime.privilege.PrivilegeHandler strolchPrivilegeHandler = getContainer().getPrivilegeHandler();
PrivilegeHandler privilegeHandler = strolchPrivilegeHandler.getPrivilegeHandler();
UserRep user;
try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER)) {
tx.setSuppressAudits(true);
user = privilegeHandler.removeRoleFromUser(getCertificate(), arg.username, arg.rolename);
if (privilegeHandler.isPersistOnUserDataChanged())
privilegeHandler.persist(getCertificate());
Audit audit = tx.auditFrom(AccessType.UPDATE, StrolchPrivilegeConstants.PRIVILEGE,
StrolchPrivilegeConstants.USER, user.getUsername());
tx.getAuditTrail().add(tx, audit);
}
return new PrivilegeUserResult(user);
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.service.privilege.users;
import java.util.HashSet;
import java.util.Set;
import com.google.gson.JsonArray;
import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.model.UserRep;
import li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants;
import li.strolch.service.JsonServiceArgument;
import li.strolch.service.api.AbstractService;
import li.strolch.service.api.ServiceResultState;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PrivilegeUpdateUserRolesService extends AbstractService<JsonServiceArgument, PrivilegeUserResult> {
@Override
protected PrivilegeUserResult getResultInstance() {
return new PrivilegeUserResult(ServiceResultState.FAILED);
}
@Override
public JsonServiceArgument getArgumentInstance() {
return new JsonServiceArgument();
}
@Override
protected PrivilegeUserResult internalDoService(JsonServiceArgument arg) {
li.strolch.runtime.privilege.PrivilegeHandler strolchPrivilegeHandler = getContainer().getPrivilegeHandler();
PrivilegeHandler privilegeHandler = strolchPrivilegeHandler.getPrivilegeHandler();
JsonArray rolesE = arg.jsonElement.getAsJsonArray();
Set<String> roles = new HashSet<>();
rolesE.forEach(e -> roles.add(e.getAsString()));
String username = arg.objectId;
UserRep user;
try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER)) {
tx.setSuppressAudits(true);
user = privilegeHandler.getUser(getCertificate(), username);
// first add new roles
boolean changed = false;
for (String role : roles) {
if (!user.hasRole(role)) {
user = privilegeHandler.addRoleToUser(getCertificate(), username, role);
changed = true;
}
}
// handle removed roles
for (String role : user.getRoles()) {
if (!roles.contains(role)) {
user = privilegeHandler.removeRoleFromUser(getCertificate(), username, role);
changed = true;
}
}
if (changed) {
if (privilegeHandler.isPersistOnUserDataChanged())
privilegeHandler.persist(getCertificate());
Audit audit = tx.auditFrom(AccessType.UPDATE, StrolchPrivilegeConstants.PRIVILEGE,
StrolchPrivilegeConstants.USER, user.getUsername());
tx.getAuditTrail().add(tx, audit);
}
}
return new PrivilegeUserResult(user);
}
}

View File

@ -49,7 +49,7 @@ public class PrivilegeUpdateUserService extends AbstractService<PrivilegeUserArg
try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_MODIFY_USER)) {
tx.setSuppressAudits(true);
user = privilegeHandler.updateUser(getCertificate(), arg.user);
user = privilegeHandler.updateUser(getCertificate(), arg.user, null);
if (privilegeHandler.isPersistOnUserDataChanged())
privilegeHandler.persist(getCertificate());

View File

@ -15,23 +15,18 @@
*/
package li.strolch.rest.endpoint;
import static java.util.Comparator.comparing;
import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_GET_ROLE;
import com.google.gson.JsonArray;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import com.google.gson.JsonArray;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.model.json.PrivilegeElementFromJsonVisitor;
import li.strolch.model.json.PrivilegeElementToJsonVisitor;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.PrivilegeRep;
import li.strolch.privilege.model.RoleRep;
import li.strolch.rest.RestfulStrolchComponent;
import li.strolch.rest.StrolchRestfulConstants;
@ -39,6 +34,9 @@ import li.strolch.rest.helper.ResponseUtil;
import li.strolch.service.api.ServiceHandler;
import li.strolch.service.privilege.roles.*;
import static java.util.Comparator.comparing;
import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_GET_ROLE;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
@ -147,50 +145,11 @@ public class PrivilegeRolesService {
return handleServiceResult(svcResult);
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{roleName}/privileges")
public Response addOrReplacePrivilegeOnRole(@Context HttpServletRequest request,
@PathParam("roleName") String roleName, String data) {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
PrivilegeRep privilegeRep = new PrivilegeElementFromJsonVisitor().privilegeRepFromJson(data);
ServiceHandler svcHandler = RestfulStrolchComponent.getInstance().getComponent(ServiceHandler.class);
PrivilegeAddOrReplacePrivilegeOnRoleService svc = new PrivilegeAddOrReplacePrivilegeOnRoleService();
PrivilegeAddOrReplacePrivilegeOnRoleArgument arg = new PrivilegeAddOrReplacePrivilegeOnRoleArgument();
arg.roleName = roleName;
arg.privilegeRep = privilegeRep;
PrivilegeRoleResult svcResult = svcHandler.doService(cert, svc, arg);
return handleServiceResult(svcResult);
}
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{roleName}/privileges/{privilege}")
public Response removePrivilegeFromRole(@Context HttpServletRequest request, @PathParam("roleName") String roleName,
@PathParam("privilege") String privilege) {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
ServiceHandler svcHandler = RestfulStrolchComponent.getInstance().getComponent(ServiceHandler.class);
PrivilegeRemovePrivilegeFromRoleService svc = new PrivilegeRemovePrivilegeFromRoleService();
PrivilegeRemovePrivilegeFromRoleArgument arg = new PrivilegeRemovePrivilegeFromRoleArgument();
arg.roleName = roleName;
arg.privilegeName = privilege;
PrivilegeRoleResult svcResult = svcHandler.doService(cert, svc, arg);
return handleServiceResult(svcResult);
}
private Response handleServiceResult(PrivilegeRoleResult svcResult) {
if (svcResult.isOk()) {
RoleRep roleRep = svcResult.getRole();
return Response
.ok(roleRep.accept(new PrivilegeElementToJsonVisitor()).toString(), MediaType.APPLICATION_JSON)
.build();
return Response.ok(roleRep.accept(new PrivilegeElementToJsonVisitor()).toString(),
MediaType.APPLICATION_JSON).build();
}
return ResponseUtil.toResponse(svcResult);
}

View File

@ -15,19 +15,6 @@
*/
package li.strolch.rest.endpoint;
import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE;
import static java.util.Comparator.comparing;
import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_GET_USER;
import static li.strolch.rest.helper.ResponseUtil.toResponse;
import static li.strolch.rest.helper.RestfulHelper.toJson;
import static li.strolch.search.SearchBuilder.buildSimpleValueSearch;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Locale;
import com.google.gson.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.*;
@ -50,7 +37,6 @@ import li.strolch.rest.StrolchSessionHandler;
import li.strolch.rest.model.QueryData;
import li.strolch.search.SearchResult;
import li.strolch.search.ValueSearch;
import li.strolch.service.JsonServiceArgument;
import li.strolch.service.StringMapArgument;
import li.strolch.service.api.ServiceHandler;
import li.strolch.service.api.ServiceResult;
@ -58,6 +44,19 @@ import li.strolch.service.privilege.users.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Locale;
import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE;
import static java.util.Comparator.comparing;
import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_GET_USER;
import static li.strolch.rest.helper.ResponseUtil.toResponse;
import static li.strolch.rest.helper.RestfulHelper.toJson;
import static li.strolch.search.SearchBuilder.buildSimpleValueSearch;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
@ -191,60 +190,6 @@ public class PrivilegeUsersService {
return handleServiceResult(svcResult);
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{username}/roles")
public Response updateRolesOnUser(@PathParam("username") String username, String data,
@Context HttpServletRequest request) {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
ServiceHandler svcHandler = RestfulStrolchComponent.getInstance().getComponent(ServiceHandler.class);
PrivilegeUpdateUserRolesService svc = new PrivilegeUpdateUserRolesService();
JsonServiceArgument arg = svc.getArgumentInstance();
arg.objectId = username;
arg.jsonElement = JsonParser.parseString(data);
PrivilegeUserResult svcResult = svcHandler.doService(cert, svc, arg);
return handleServiceResult(svcResult);
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{username}/roles/{rolename}")
public Response addRoleToUser(@PathParam("username") String username, @PathParam("rolename") String rolename,
@Context HttpServletRequest request) {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
ServiceHandler svcHandler = RestfulStrolchComponent.getInstance().getComponent(ServiceHandler.class);
PrivilegeAddRoleToUserService svc = new PrivilegeAddRoleToUserService();
PrivilegeRoleUserNamesArgument arg = new PrivilegeRoleUserNamesArgument();
arg.username = username;
arg.rolename = rolename;
PrivilegeUserResult svcResult = svcHandler.doService(cert, svc, arg);
return handleServiceResult(svcResult);
}
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{username}/roles/{rolename}")
public Response removeRoleFromUser(@PathParam("username") String username, @PathParam("rolename") String rolename,
@Context HttpServletRequest request) {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
ServiceHandler svcHandler = RestfulStrolchComponent.getInstance().getComponent(ServiceHandler.class);
PrivilegeRemoveRoleFromUserService svc = new PrivilegeRemoveRoleFromUserService();
PrivilegeRoleUserNamesArgument arg = new PrivilegeRoleUserNamesArgument();
arg.username = username;
arg.rolename = rolename;
PrivilegeUserResult svcResult = svcHandler.doService(cert, svc, arg);
return handleServiceResult(svcResult);
}
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Path("{username}/state/{state}")
@ -279,7 +224,7 @@ public class PrivilegeUsersService {
Locale locale;
try {
locale = new Locale(localeS);
locale = Locale.forLanguageTag(localeS);
} catch (Exception e) {
String msg = MessageFormat.format("Locale {0} is not valid!", localeS);
return toResponse(msg);