[Major] Implemented groups in privilege. Refactored nearly everything
This commit is contained in:
parent
648553409c
commit
48d121882e
|
@ -19,7 +19,7 @@ import static java.lang.Boolean.parseBoolean;
|
|||
import static java.util.concurrent.TimeUnit.NANOSECONDS;
|
||||
import static li.strolch.privilege.handler.PrivilegeHandler.PARAM_PERSIST_SESSIONS;
|
||||
import static li.strolch.privilege.handler.PrivilegeHandler.PARAM_PERSIST_SESSIONS_PATH;
|
||||
import static li.strolch.privilege.helper.XmlConstants.XML_PARAM_BASE_PATH;
|
||||
import static li.strolch.privilege.helper.XmlConstants.PARAM_BASE_PATH;
|
||||
import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.*;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -126,7 +126,7 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements
|
|||
if (containerModel.getPersistenceHandlerClassName().equals(XmlPersistenceHandler.class.getName())) {
|
||||
Map<String, String> xmlParams = containerModel.getPersistenceHandlerParameterMap();
|
||||
File configPath = runtimeConfig.getConfigPath();
|
||||
xmlParams.put(XML_PARAM_BASE_PATH, configPath.getPath());
|
||||
xmlParams.put(PARAM_BASE_PATH, configPath.getPath());
|
||||
}
|
||||
|
||||
return new PrivilegeInitializer(getScheduledExecutor(getName())).initializeFromXml(containerModel);
|
||||
|
|
|
@ -9,7 +9,7 @@ import li.strolch.model.StrolchRootElement;
|
|||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
|
@ -20,10 +20,10 @@ public class ModelPrivilege implements PrivilegePolicy {
|
|||
/**
|
||||
* The value of {@link Restrictable#getPrivilegeValue()} is used to check if the {@link Role} has this privilege
|
||||
*
|
||||
* @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, IPrivilege, Restrictable)
|
||||
* @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, Privilege, Restrictable)
|
||||
*/
|
||||
@Override
|
||||
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public void validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException {
|
||||
validateAction(ctx, privilege, restrictable, true);
|
||||
}
|
||||
|
@ -31,15 +31,15 @@ public class ModelPrivilege implements PrivilegePolicy {
|
|||
/**
|
||||
* The value of {@link Restrictable#getPrivilegeValue()} is used to check if the {@link Role} has this privilege
|
||||
*
|
||||
* @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, IPrivilege, Restrictable)
|
||||
* @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, Privilege, Restrictable)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws PrivilegeException {
|
||||
return validateAction(ctx, privilege, restrictable, false);
|
||||
}
|
||||
|
||||
protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
protected boolean validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
boolean assertHasPrivilege) throws AccessDeniedException {
|
||||
|
||||
preValidate(privilege, restrictable);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package li.strolch.model.json;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -11,6 +9,8 @@ import li.strolch.privilege.model.RoleRep;
|
|||
import li.strolch.privilege.model.UserRep;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PrivilegeElementFromJsonVisitor {
|
||||
|
||||
public UserRep userRepFromJson(String string) {
|
||||
|
@ -82,6 +82,7 @@ public class PrivilegeElementFromJsonVisitor {
|
|||
JsonElement lastNameE = jsonObject.get("lastname");
|
||||
JsonElement userStateE = jsonObject.get("userState");
|
||||
JsonElement localeE = jsonObject.get("locale");
|
||||
JsonElement groupsE = jsonObject.get("groups");
|
||||
JsonElement rolesE = jsonObject.get("roles");
|
||||
JsonElement propertiesE = jsonObject.get("properties");
|
||||
|
||||
|
@ -90,16 +91,11 @@ public class PrivilegeElementFromJsonVisitor {
|
|||
String firstname = firstNameE == null ? null : firstNameE.getAsString().trim();
|
||||
String lastname = lastNameE == null ? null : lastNameE.getAsString().trim();
|
||||
UserState userState = userStateE == null ? null : UserState.valueOf(userStateE.getAsString().trim());
|
||||
Locale locale = localeE == null ? null : new Locale(localeE.getAsString().trim());
|
||||
Locale locale = localeE == null ? null : Locale.forLanguageTag(localeE.getAsString().trim());
|
||||
|
||||
Set<String> roles = null;
|
||||
if (rolesE != null) {
|
||||
roles = new HashSet<>();
|
||||
JsonArray rolesArr = rolesE.getAsJsonArray();
|
||||
for (JsonElement role : rolesArr) {
|
||||
roles.add(role.getAsString().trim());
|
||||
}
|
||||
}
|
||||
Set<String> groups = jsonArrayToSet(groupsE);
|
||||
|
||||
Set<String> roles = jsonArrayToSet(rolesE);
|
||||
|
||||
Map<String, String> properties = null;
|
||||
if (propertiesE != null) {
|
||||
|
@ -111,6 +107,19 @@ public class PrivilegeElementFromJsonVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
return new UserRep(userId, username, firstname, lastname, userState, roles, locale, properties, null);
|
||||
return new UserRep(userId, username, firstname, lastname, userState, groups, roles, locale, properties, null);
|
||||
}
|
||||
|
||||
private Set<String> jsonArrayToSet(JsonElement array) {
|
||||
if (array == null)
|
||||
return Set.of();
|
||||
|
||||
Set<String> result = new HashSet<>();
|
||||
JsonArray rolesArr = array.getAsJsonArray();
|
||||
for (JsonElement role : rolesArr) {
|
||||
result.add(role.getAsString().trim());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ public class PrivilegeConstants {
|
|||
public static final String PRIMARY_LOCATION = "primaryLocation";
|
||||
public static final String SECONDARY_LOCATIONS = "secondaryLocations";
|
||||
public static final String ROLES = "roles";
|
||||
public static final String GROUPS = "groups";
|
||||
public static final String EMAIL = "email";
|
||||
|
||||
public static final String ROLE_STROLCH_ADMIN = "StrolchAdmin";
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
package li.strolch.privilege.handler;
|
||||
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
|
@ -10,14 +18,6 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class BaseLdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(BaseLdapPrivilegeHandler.class);
|
||||
|
@ -135,12 +135,13 @@ public abstract class BaseLdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
|||
Set<String> ldapGroups = getLdapGroups(username, attrs);
|
||||
logger.info("User " + username + " is member of the following LDAP groups: ");
|
||||
ldapGroups.forEach(s -> logger.info("- " + s));
|
||||
Set<String> strolchGroups = mapToStrolchGroups(username, ldapGroups);
|
||||
Set<String> strolchRoles = mapToStrolchRoles(username, ldapGroups);
|
||||
|
||||
Map<String, String> properties = buildProperties(username, attrs, ldapGroups, strolchRoles);
|
||||
|
||||
return new User(username, username, null, firstName, lastName, UserState.REMOTE, strolchRoles, locale,
|
||||
properties, false, new UserHistory());
|
||||
return new User(username, username, null, firstName, lastName, UserState.REMOTE, strolchGroups, strolchRoles,
|
||||
locale, properties, false, UserHistory.EMPTY);
|
||||
}
|
||||
|
||||
protected abstract Map<String, String> buildProperties(String username, Attributes attrs, Set<String> ldapGroups,
|
||||
|
@ -168,5 +169,7 @@ public abstract class BaseLdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
|||
|
||||
protected abstract Set<String> getLdapGroups(String username, Attributes attrs) throws NamingException;
|
||||
|
||||
protected abstract Set<String> mapToStrolchGroups(String username, Set<String> ldapGroups);
|
||||
|
||||
protected abstract Set<String> mapToStrolchRoles(String username, Set<String> ldapGroups);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ import static li.strolch.privilege.helper.XmlConstants.*;
|
|||
* <p>
|
||||
* Required parameters:
|
||||
* <ul>
|
||||
* <li>{@link XmlConstants#XML_PARAM_HASH_ALGORITHM}</li>
|
||||
* <li>{@link XmlConstants#PARAM_HASH_ALGORITHM}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
|
@ -121,7 +121,7 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
|||
try {
|
||||
|
||||
MessageDigest digest = MessageDigest.getInstance(this.nonSaltAlgorithm);
|
||||
return new PasswordCrypt(digest.digest(new String(password).getBytes()), null);
|
||||
return PasswordCrypt.of(digest.digest(new String(password).getBytes()), null);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new PrivilegeException(MessageFormat.format("Algorithm {0} was not found!", nonSaltAlgorithm),
|
||||
|
@ -151,9 +151,8 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
|||
|
||||
@Override
|
||||
public boolean isPasswordCryptOutdated(PasswordCrypt passwordCrypt) {
|
||||
return passwordCrypt.getSalt() == null || passwordCrypt.getHashAlgorithm() == null ||
|
||||
passwordCrypt.getHashIterations() != this.iterations ||
|
||||
passwordCrypt.getHashKeyLength() != this.keyLength;
|
||||
return passwordCrypt.salt() == null || passwordCrypt.hashAlgorithm() == null ||
|
||||
passwordCrypt.hashIterations() != this.iterations || passwordCrypt.hashKeyLength() != this.keyLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,13 +162,13 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
|||
this.secureRandom = new SecureRandom();
|
||||
|
||||
// get hash algorithm parameters
|
||||
this.algorithm = parameterMap.getOrDefault(XML_PARAM_HASH_ALGORITHM, DEFAULT_ALGORITHM);
|
||||
this.nonSaltAlgorithm = parameterMap.getOrDefault(XML_PARAM_HASH_ALGORITHM_NON_SALT,
|
||||
this.algorithm = parameterMap.getOrDefault(PARAM_HASH_ALGORITHM, DEFAULT_ALGORITHM);
|
||||
this.nonSaltAlgorithm = parameterMap.getOrDefault(PARAM_HASH_ALGORITHM_NON_SALT,
|
||||
DEFAULT_ALGORITHM_NON_SALT);
|
||||
this.iterations = Integer.parseInt(
|
||||
parameterMap.getOrDefault(XML_PARAM_HASH_ITERATIONS, valueOf(DEFAULT_ITERATIONS)));
|
||||
parameterMap.getOrDefault(PARAM_HASH_ITERATIONS, valueOf(DEFAULT_ITERATIONS)));
|
||||
this.keyLength = Integer.parseInt(
|
||||
parameterMap.getOrDefault(XML_PARAM_HASH_KEY_LENGTH, valueOf(DEFAULT_KEY_LENGTH)));
|
||||
parameterMap.getOrDefault(PARAM_HASH_KEY_LENGTH, valueOf(DEFAULT_KEY_LENGTH)));
|
||||
|
||||
// test non-salt hash algorithm
|
||||
try {
|
||||
|
@ -178,7 +177,7 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
|||
MessageFormat.format("Using non-salt hashing algorithm {0}", this.nonSaltAlgorithm));
|
||||
} catch (Exception e) {
|
||||
String msg = "[{0}] Defined parameter {1} is invalid because of underlying exception: {2}";
|
||||
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), XML_PARAM_HASH_ALGORITHM_NON_SALT,
|
||||
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), PARAM_HASH_ALGORITHM_NON_SALT,
|
||||
e.getLocalizedMessage());
|
||||
throw new PrivilegeException(msg, e);
|
||||
}
|
||||
|
@ -189,7 +188,7 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
|||
DefaultEncryptionHandler.logger.info(MessageFormat.format("Using hashing algorithm {0}", this.algorithm));
|
||||
} catch (Exception e) {
|
||||
String msg = "[{0}] Defined parameter {1} is invalid because of underlying exception: {2}";
|
||||
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), XML_PARAM_HASH_ALGORITHM,
|
||||
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), PARAM_HASH_ALGORITHM,
|
||||
e.getLocalizedMessage());
|
||||
throw new PrivilegeException(msg, e);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,11 @@
|
|||
package li.strolch.privilege.handler;
|
||||
|
||||
import static java.lang.String.join;
|
||||
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.isNotEmpty;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import li.strolch.privilege.helper.LdapHelper;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
|
@ -13,12 +14,11 @@ import java.io.FileReader;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import li.strolch.privilege.helper.LdapHelper;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
import static java.lang.String.join;
|
||||
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.isNotEmpty;
|
||||
|
||||
public class JsonConfigLdapPrivilegeHandler extends BaseLdapPrivilegeHandler {
|
||||
|
||||
|
@ -147,17 +147,25 @@ public class JsonConfigLdapPrivilegeHandler extends BaseLdapPrivilegeHandler {
|
|||
return relevantLdapGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> mapToStrolchGroups(String username, Set<String> ldapGroups) {
|
||||
return mapLdapGroupToStrolch(ldapGroups, GROUPS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> mapToStrolchRoles(String username, Set<String> ldapGroups) {
|
||||
return mapLdapGroupToStrolch(ldapGroups, ROLES);
|
||||
}
|
||||
|
||||
Set<String> strolchRoles = new HashSet<>();
|
||||
|
||||
private Set<String> mapLdapGroupToStrolch(Set<String> ldapGroups, String type) {
|
||||
Set<String> mappedValues = new HashSet<>();
|
||||
for (String relevantLdapGroup : ldapGroups) {
|
||||
JsonObject mappingJ = this.ldapGroupConfigs.get(relevantLdapGroup).getAsJsonObject();
|
||||
mappingJ.get(ROLES).getAsJsonArray().forEach(e -> strolchRoles.add(e.getAsString()));
|
||||
if (mappingJ.has(type))
|
||||
mappingJ.get(type).getAsJsonArray().forEach(e -> mappedValues.add(e.getAsString()));
|
||||
}
|
||||
|
||||
return strolchRoles;
|
||||
return mappedValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,17 +15,17 @@
|
|||
*/
|
||||
package li.strolch.privilege.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.model.internal.Group;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -36,7 +36,7 @@ import javax.xml.stream.XMLStreamException;
|
|||
* <p>
|
||||
* The {@link PersistenceHandler} also serves the special {@link PrivilegePolicy} objects. These policies are special
|
||||
* objects which implement an algorithm to define if an action is allowed on a {@link Restrictable} by a {@link Role}
|
||||
* and {@link IPrivilege}
|
||||
* and {@link Privilege}
|
||||
* </p>
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
|
@ -50,6 +50,13 @@ public interface PersistenceHandler {
|
|||
*/
|
||||
List<User> getAllUsers();
|
||||
|
||||
/**
|
||||
* Returns all currently known {@link Group}s
|
||||
*
|
||||
* @return all currently known {@link Group}s
|
||||
*/
|
||||
List<Group> getAllGroups();
|
||||
|
||||
/**
|
||||
* Returns all currently known {@link Role}s
|
||||
*
|
||||
|
@ -60,18 +67,25 @@ public interface PersistenceHandler {
|
|||
/**
|
||||
* Returns a {@link User} object from the underlying database
|
||||
*
|
||||
* @param username
|
||||
* the name/id of the {@link User} object to return
|
||||
* @param username the name/id of the {@link User} object to return
|
||||
*
|
||||
* @return the {@link User} object, or null if it was not found
|
||||
*/
|
||||
User getUser(String username);
|
||||
|
||||
/**
|
||||
* Returns a {@link Group} object from the underlying database
|
||||
*
|
||||
* @param groupName the name/id of the {@link Group} object to return
|
||||
*
|
||||
* @return the {@link Group} object, or null if it was not found
|
||||
*/
|
||||
Group getGroup(String groupName);
|
||||
|
||||
/**
|
||||
* Returns a {@link Role} object from the underlying database
|
||||
*
|
||||
* @param roleName
|
||||
* the name/id of the {@link Role} object to return
|
||||
* @param roleName the name/id of the {@link Role} object to return
|
||||
*
|
||||
* @return the {@link Role} object, or null if it was not found
|
||||
*/
|
||||
|
@ -80,18 +94,25 @@ public interface PersistenceHandler {
|
|||
/**
|
||||
* Removes a {@link User} with the given name and returns the removed object if it existed
|
||||
*
|
||||
* @param username
|
||||
* the name of the {@link User} to remove
|
||||
* @param username the name of the {@link User} to remove
|
||||
*
|
||||
* @return the {@link User} removed, or null if it did not exist
|
||||
*/
|
||||
User removeUser(String username);
|
||||
|
||||
/**
|
||||
* Removes a {@link Group} with the given name and returns the removed object if it existed
|
||||
*
|
||||
* @param groupName the name of the {@link Group} to remove
|
||||
*
|
||||
* @return the {@link Group} removed, or null if it did not exist
|
||||
*/
|
||||
Group removeGroup(String groupName);
|
||||
|
||||
/**
|
||||
* Removes a {@link Role} with the given name and returns the removed object if it existed
|
||||
*
|
||||
* @param roleName
|
||||
* the name of the {@link Role} to remove
|
||||
* @param roleName the name of the {@link Role} to remove
|
||||
*
|
||||
* @return the {@link Role} removed, or null if it did not exist
|
||||
*/
|
||||
|
@ -100,35 +121,45 @@ public interface PersistenceHandler {
|
|||
/**
|
||||
* Adds a {@link User} object to the underlying database
|
||||
*
|
||||
* @param user
|
||||
* the {@link User} object to add
|
||||
* @param user the {@link User} object to add
|
||||
*/
|
||||
void addUser(User user);
|
||||
|
||||
/**
|
||||
* Replaces the existing {@link User} object in the underlying database
|
||||
*
|
||||
* @param user
|
||||
* the {@link User} object to add
|
||||
* @param user the {@link User} object to add
|
||||
*/
|
||||
void replaceUser(User user);
|
||||
|
||||
/**
|
||||
* Adds a {@link Role} object to the underlying database
|
||||
*
|
||||
* @param role
|
||||
* the {@link User} object to add
|
||||
* @param role the {@link Role} object to add
|
||||
*/
|
||||
void addRole(Role role);
|
||||
|
||||
/**
|
||||
* Replaces the {@link Role} object in the underlying database
|
||||
*
|
||||
* @param role
|
||||
* the {@link User} object to add
|
||||
* @param role the {@link User} object to add
|
||||
*/
|
||||
void replaceRole(Role role);
|
||||
|
||||
/**
|
||||
* Adds a {@link Group} object to the underlying database
|
||||
*
|
||||
* @param group the {@link Group} object to add
|
||||
*/
|
||||
void addGroup(Group group);
|
||||
|
||||
/**
|
||||
* Replaces the {@link Group} object in the underlying database
|
||||
*
|
||||
* @param group the {@link Group} object to add
|
||||
*/
|
||||
void replaceGroup(Group group);
|
||||
|
||||
/**
|
||||
* Informs this {@link PersistenceHandler} to persist any changes which need to be saved
|
||||
*
|
||||
|
@ -147,8 +178,7 @@ public interface PersistenceHandler {
|
|||
* Initialize the concrete {@link PersistenceHandler}. The passed parameter map contains any configuration the
|
||||
* concrete {@link PersistenceHandler} might need
|
||||
*
|
||||
* @param parameterMap
|
||||
* a map containing configuration properties
|
||||
* @param parameterMap a map containing configuration properties
|
||||
*/
|
||||
void initialize(Map<String, String> parameterMap);
|
||||
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
package li.strolch.privilege.handler;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeConflictResolution;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.base.PrivilegeModelException;
|
||||
import li.strolch.privilege.model.*;
|
||||
import li.strolch.privilege.model.internal.Group;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
|
||||
import static java.text.MessageFormat.format;
|
||||
import static java.util.stream.Collectors.toCollection;
|
||||
import static li.strolch.privilege.handler.DefaultPrivilegeHandler.streamAllRolesForUser;
|
||||
|
||||
public class PrivilegeContextBuilder {
|
||||
private static final Logger logger = LoggerFactory.getLogger(PrivilegeContextBuilder.class);
|
||||
|
||||
private final Map<String, Class<PrivilegePolicy>> policyMap;
|
||||
private final DefaultPrivilegeHandler privilegeHandler;
|
||||
private final PrivilegeConflictResolution conflictResolution;
|
||||
private final PersistenceHandler persistenceHandler;
|
||||
|
||||
private Set<String> userGroups;
|
||||
private Set<String> userRoles;
|
||||
private Map<String, String> userProperties;
|
||||
|
||||
public PrivilegeContextBuilder(DefaultPrivilegeHandler privilegeHandler) {
|
||||
this.privilegeHandler = privilegeHandler;
|
||||
this.persistenceHandler = privilegeHandler.persistenceHandler;
|
||||
this.policyMap = privilegeHandler.policyMap;
|
||||
this.conflictResolution = privilegeHandler.privilegeConflictResolution;
|
||||
}
|
||||
|
||||
public PrivilegeContext buildPrivilegeContext(Usage usage, User user, String source, ZonedDateTime loginTime,
|
||||
boolean keepAlive) {
|
||||
String authToken = this.privilegeHandler.getEncryptionHandler().nextToken();
|
||||
String sessionId = UUID.randomUUID().toString();
|
||||
return buildPrivilegeContext(usage, user, authToken, sessionId, source, loginTime, keepAlive);
|
||||
}
|
||||
|
||||
public PrivilegeContext buildPrivilegeContext(Usage usage, User user, String authToken, String sessionId,
|
||||
String source, ZonedDateTime loginTime, boolean keepAlive) {
|
||||
DBC.PRE.assertNotEmpty("source must not be empty!", source);
|
||||
|
||||
keepAlive = keepAlive && this.privilegeHandler.allowSessionRefresh;
|
||||
|
||||
prepare(user);
|
||||
|
||||
Map<String, Privilege> privileges = new HashMap<>();
|
||||
Map<String, PrivilegePolicy> policies = new HashMap<>();
|
||||
|
||||
// cache the privileges and policies for this user by role
|
||||
addPrivilegesForRoles(this.userRoles, user.getUsername(), privileges, policies);
|
||||
|
||||
UserRep userRep = user.asUserRep();
|
||||
userRep.setRoles(this.userRoles);
|
||||
userRep.setGroups(this.userGroups);
|
||||
userRep.setProperties(this.userProperties);
|
||||
userRep.readOnly();
|
||||
|
||||
Certificate certificate = new Certificate(usage, sessionId, user.getUsername(), user.getFirstname(),
|
||||
user.getLastname(), user.getUserState(), authToken, source, loginTime, keepAlive, user.getLocale(),
|
||||
this.userGroups, this.userRoles, this.userProperties);
|
||||
|
||||
return new PrivilegeContext(userRep, certificate, privileges, policies);
|
||||
}
|
||||
|
||||
private void prepare(User user) {
|
||||
this.userGroups = user.getGroups().stream().sorted().collect(toCollection(TreeSet::new));
|
||||
this.userRoles = streamAllRolesForUser(this.persistenceHandler, user).sorted()
|
||||
.collect(toCollection(TreeSet::new));
|
||||
this.userProperties = new HashMap<>(user.getProperties());
|
||||
|
||||
// copy properties from groups to user properties
|
||||
for (String groupName : this.userGroups) {
|
||||
Group group = this.persistenceHandler.getGroup(groupName);
|
||||
if (group == null) {
|
||||
logger.error("Group " + groupName + " does not exist!");
|
||||
continue;
|
||||
}
|
||||
Map<String, String> groupProperties = group.getProperties();
|
||||
for (String key : groupProperties.keySet()) {
|
||||
String replaced = this.userProperties.put(key, groupProperties.get(key));
|
||||
if (replaced != null)
|
||||
logger.error("Duplicate property {} for user {} from group {}", key, user.getUsername(), groupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addPrivilegesForRoles(Set<String> roles, String userName, Map<String, Privilege> privileges,
|
||||
Map<String, PrivilegePolicy> policies) {
|
||||
|
||||
for (String roleName : roles) {
|
||||
Role role = this.persistenceHandler.getRole(roleName);
|
||||
if (role == null) {
|
||||
logger.error("Role " + roleName + " does not exist for user " + userName);
|
||||
} else {
|
||||
addPrivilegesForRole(userName, role, privileges, policies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addPrivilegesForRole(String userName, Role role, Map<String, Privilege> privileges,
|
||||
Map<String, PrivilegePolicy> policies) {
|
||||
|
||||
for (Privilege privilege : role.privilegeMap().values()) {
|
||||
String privilegeName = privilege.name();
|
||||
|
||||
if (!privileges.containsKey(privilegeName)) {
|
||||
privileges.put(privilegeName, privilege);
|
||||
} else {
|
||||
handleDuplicatePrivilege(userName, role, privileges, privilege, privilegeName);
|
||||
}
|
||||
|
||||
// cache the policy for the privilege
|
||||
addPolicyForPrivilege(policies, privilege, privilegeName);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPolicyForPrivilege(Map<String, PrivilegePolicy> policies, Privilege privilege,
|
||||
String privilegeName) {
|
||||
String policyName = privilege.getPolicy();
|
||||
if (policies.containsKey(policyName))
|
||||
return;
|
||||
|
||||
PrivilegePolicy policy = getPolicy(policyName);
|
||||
if (policy == null) {
|
||||
logger.error(format("The Policy {0} does not exist for Privilege {1}", policyName, privilegeName));
|
||||
} else {
|
||||
policies.put(policyName, policy);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDuplicatePrivilege(String userName, Role role, Map<String, Privilege> privileges,
|
||||
Privilege additionalPrivilege, String privilegeName) {
|
||||
|
||||
// for strict, we have to throw an exception
|
||||
if (this.conflictResolution.isStrict())
|
||||
throw new PrivilegeModelException(
|
||||
format("User " + userName + " has conflicts for privilege {0} with role {1}", privilegeName,
|
||||
role.name()));
|
||||
|
||||
// merge privileges
|
||||
Privilege knownPrivilege = privileges.get(privilegeName);
|
||||
boolean allAllowed = knownPrivilege.isAllAllowed() || additionalPrivilege.isAllAllowed();
|
||||
Set<String> allowList;
|
||||
Set<String> denyList;
|
||||
if (allAllowed) {
|
||||
allowList = Set.of();
|
||||
denyList = Set.of();
|
||||
} else {
|
||||
allowList = new HashSet<>(knownPrivilege.getAllowList());
|
||||
allowList.addAll(additionalPrivilege.getAllowList());
|
||||
denyList = new HashSet<>(knownPrivilege.getDenyList());
|
||||
denyList.addAll(additionalPrivilege.getDenyList());
|
||||
}
|
||||
|
||||
String policy = knownPrivilege.getPolicy();
|
||||
privileges.put(privilegeName, new Privilege(knownPrivilege.getName(), policy, allAllowed, denyList, allowList));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This method instantiates a {@link PrivilegePolicy} object from the given policyName. The {@link PrivilegePolicy}
|
||||
* is not stored in a database. The privilege name is a class name and is then used to instantiate a new
|
||||
* {@link PrivilegePolicy} object
|
||||
* </p>
|
||||
*
|
||||
* @param policyName the class name of the {@link PrivilegePolicy} object to return
|
||||
*
|
||||
* @return the {@link PrivilegePolicy} object
|
||||
*
|
||||
* @throws PrivilegeException if the {@link PrivilegePolicy} object for the given policy name could not be
|
||||
* instantiated
|
||||
*/
|
||||
private PrivilegePolicy getPolicy(String policyName) {
|
||||
|
||||
// get the policies class
|
||||
Class<PrivilegePolicy> policyClazz = this.policyMap.get(policyName);
|
||||
if (policyClazz == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// instantiate the policy
|
||||
PrivilegePolicy policy;
|
||||
try {
|
||||
|
||||
policy = policyClazz.getConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
String msg = "The class for the policy with the name {0} does not exist!{1}";
|
||||
msg = format(msg, policyName, policyName);
|
||||
throw new PrivilegeModelException(msg, e);
|
||||
}
|
||||
|
||||
return policy;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -502,7 +502,7 @@ public interface PrivilegeHandler {
|
|||
* @param roleName
|
||||
* the roleName of the {@link Role} to which the privilege should be added
|
||||
* @param privilegeRep
|
||||
* the representation of the {@link IPrivilege} which should be added or replaced on the {@link Role}
|
||||
* 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
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
package li.strolch.privilege.handler;
|
||||
|
||||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import li.strolch.privilege.helper.LdapHelper;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SimpleLdapPrivilegeHandler extends BaseLdapPrivilegeHandler {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(SimpleLdapPrivilegeHandler.class);
|
||||
|
||||
private Locale defaultLocale;
|
||||
private String adminUsers;
|
||||
private Map<String, Set<String>> rolesForLdapGroups;
|
||||
private String organisation;
|
||||
private String location;
|
||||
private String realm;
|
||||
|
||||
@Override
|
||||
public void initialize(ScheduledExecutorService executorService, Map<String, String> parameterMap,
|
||||
EncryptionHandler encryptionHandler, PasswordStrengthHandler passwordStrengthHandler,
|
||||
PersistenceHandler persistenceHandler, UserChallengeHandler userChallengeHandler,
|
||||
SingleSignOnHandler ssoHandler, Map<String, Class<PrivilegePolicy>> policyMap) {
|
||||
|
||||
super.initialize(executorService, parameterMap, encryptionHandler, passwordStrengthHandler, persistenceHandler,
|
||||
userChallengeHandler, ssoHandler, policyMap);
|
||||
|
||||
this.organisation = parameterMap.getOrDefault(ORGANISATION, "");
|
||||
this.location = parameterMap.getOrDefault(LOCATION, "");
|
||||
this.realm = parameterMap.getOrDefault(REALM, "");
|
||||
|
||||
this.defaultLocale = parameterMap.containsKey("defaultLocale") ?
|
||||
Locale.forLanguageTag(parameterMap.get("defaultLocale")) : Locale.getDefault();
|
||||
|
||||
this.adminUsers = parameterMap.get("adminUsers");
|
||||
this.rolesForLdapGroups = getLdapGroupToRolesMappingFromConfig(parameterMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFirstName(String username, Attributes attrs) throws NamingException {
|
||||
String value = getLdapString(attrs, "givenName");
|
||||
return isEmpty(value) ? username : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLastName(String username, Attributes attrs) throws NamingException {
|
||||
String value = getLdapString(attrs, "sn");
|
||||
return isEmpty(value) ? username : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> buildProperties(String username, Attributes attrs, Set<String> ldapGroups,
|
||||
Set<String> strolchRoles) {
|
||||
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put(ORGANISATION, this.organisation);
|
||||
properties.put(LOCATION, this.location);
|
||||
properties.put(REALM, this.realm);
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Locale getLocale(Attributes attrs) {
|
||||
return this.defaultLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> getLdapGroups(String username, Attributes attrs) throws NamingException {
|
||||
Set<String> ldapGroups = LdapHelper.getLdapGroups(attrs);
|
||||
logger.info("User " + username + " has LDAP Groups: ");
|
||||
ldapGroups.forEach(s -> logger.info("- " + s));
|
||||
return ldapGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> mapToStrolchRoles(String username, Set<String> ldapGroups) {
|
||||
Set<String> strolchRoles = new HashSet<>();
|
||||
for (String ldapRole : ldapGroups) {
|
||||
Set<String> foundStrolchRoles = this.rolesForLdapGroups.get(ldapRole);
|
||||
if (foundStrolchRoles != null)
|
||||
strolchRoles.addAll(foundStrolchRoles);
|
||||
}
|
||||
|
||||
// see if this is an admin user
|
||||
if (this.adminUsers.contains(username))
|
||||
strolchRoles = this.rolesForLdapGroups.get("admin");
|
||||
|
||||
return strolchRoles;
|
||||
}
|
||||
|
||||
private Map<String, Set<String>> getLdapGroupToRolesMappingFromConfig(Map<String, String> params) {
|
||||
|
||||
String rolesForLdapGroups = params.get("rolesForLdapGroups");
|
||||
DBC.PRE.assertNotEmpty("No roles mapping for ldap directory groups defined (param: rolesForLdapGroups)",
|
||||
rolesForLdapGroups);
|
||||
|
||||
// rolesForLdapGroups = admin=StrolchAdmin,UserPrivileges;user=UserPrivileges
|
||||
|
||||
String[] ldapGroupRoles = rolesForLdapGroups.split(";");
|
||||
|
||||
Map<String, Set<String>> result = new HashMap<>();
|
||||
for (String ldapGroupRole : ldapGroupRoles) {
|
||||
ldapGroupRole = ldapGroupRole.trim();
|
||||
|
||||
String[] splitGroupRoles = ldapGroupRole.split("=");
|
||||
String ldapGroupName = splitGroupRoles[0];
|
||||
String[] strolchRoles = splitGroupRoles[1].split(",");
|
||||
Set<String> roleNames = new HashSet<>();
|
||||
for (String strolchRole : strolchRoles) {
|
||||
roleNames.add(strolchRole.trim());
|
||||
}
|
||||
|
||||
result.put(ldapGroupName, roleNames);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -17,12 +17,10 @@ package li.strolch.privilege.handler;
|
|||
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.helper.XmlConstants;
|
||||
import li.strolch.privilege.model.internal.Group;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.xml.PrivilegeRolesSaxReader;
|
||||
import li.strolch.privilege.xml.PrivilegeRolesSaxWriter;
|
||||
import li.strolch.privilege.xml.PrivilegeUsersSaxReader;
|
||||
import li.strolch.privilege.xml.PrivilegeUsersSaxWriter;
|
||||
import li.strolch.privilege.xml.*;
|
||||
import li.strolch.utils.helper.XmlHelper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -54,20 +52,24 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
protected static final Logger logger = LoggerFactory.getLogger(XmlPersistenceHandler.class);
|
||||
|
||||
private final Map<String, User> userMap;
|
||||
private final Map<String, Group> groupMap;
|
||||
private final Map<String, Role> roleMap;
|
||||
|
||||
private boolean userMapDirty;
|
||||
private boolean groupMapDirty;
|
||||
private boolean roleMapDirty;
|
||||
|
||||
private Map<String, String> parameterMap;
|
||||
|
||||
private File usersPath;
|
||||
private File groupsPath;
|
||||
private File rolesPath;
|
||||
|
||||
private boolean caseInsensitiveUsername;
|
||||
|
||||
public XmlPersistenceHandler() {
|
||||
this.roleMap = new ConcurrentHashMap<>();
|
||||
this.groupMap = new ConcurrentHashMap<>();
|
||||
this.userMap = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
|
@ -83,6 +85,13 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Group> getAllGroups() {
|
||||
synchronized (this.groupMap) {
|
||||
return new LinkedList<>(this.groupMap.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Role> getAllRoles() {
|
||||
synchronized (this.roleMap) {
|
||||
|
@ -95,6 +104,11 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
return this.userMap.get(this.caseInsensitiveUsername ? username.toLowerCase() : username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group getGroup(String groupName) {
|
||||
return this.groupMap.get(groupName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Role getRole(String roleName) {
|
||||
return this.roleMap.get(roleName);
|
||||
|
@ -107,6 +121,13 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group removeGroup(String groupName) {
|
||||
Group group = this.groupMap.remove(groupName);
|
||||
this.groupMapDirty = group != null;
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Role removeRole(String roleName) {
|
||||
Role role = this.roleMap.remove(roleName);
|
||||
|
@ -133,6 +154,23 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
this.userMapDirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(Group group) {
|
||||
if (this.groupMap.containsKey(group.name()))
|
||||
throw new IllegalStateException(format("The group {0} already exists!", group.name()));
|
||||
this.groupMap.put(group.name(), group);
|
||||
this.groupMapDirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceGroup(Group group) {
|
||||
if (!this.groupMap.containsKey(group.name()))
|
||||
throw new IllegalStateException(
|
||||
format("The group {0} can not be replaced as it does not exist!", group.name()));
|
||||
this.groupMap.put(group.name(), group);
|
||||
this.groupMapDirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRole(Role role) {
|
||||
if (this.roleMap.containsKey(role.getName()))
|
||||
|
@ -153,9 +191,10 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
/**
|
||||
* Initializes this {@link XmlPersistenceHandler} by reading the following parameters:
|
||||
* <ul>
|
||||
* <li>{@link XmlConstants#XML_PARAM_BASE_PATH}</li>
|
||||
* <li>{@link XmlConstants#XML_PARAM_USERS_FILE}</li>
|
||||
* <li>{@link XmlConstants#XML_PARAM_ROLES_FILE}</li>
|
||||
* <li>{@link XmlConstants#PARAM_BASE_PATH}</li>
|
||||
* <li>{@link XmlConstants#PARAM_USERS_FILE}</li>
|
||||
* <li>{@link XmlConstants#PARAM_GROUPS_FILE}</li>
|
||||
* <li>{@link XmlConstants#PARAM_ROLES_FILE}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
|
@ -163,22 +202,21 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
this.parameterMap = Map.copyOf(paramsMap);
|
||||
|
||||
// get and validate base bath
|
||||
String basePath = this.parameterMap.get(XML_PARAM_BASE_PATH);
|
||||
String basePath = this.parameterMap.get(PARAM_BASE_PATH);
|
||||
File basePathF = new File(basePath);
|
||||
if (!basePathF.exists() && !basePathF.isDirectory()) {
|
||||
String msg = "[{0}] Defined parameter {1} does not point to a valid path at {2}";
|
||||
msg = format(msg, PersistenceHandler.class.getName(), XML_PARAM_BASE_PATH, basePathF.getAbsolutePath());
|
||||
msg = format(msg, PersistenceHandler.class.getName(), PARAM_BASE_PATH, basePathF.getAbsolutePath());
|
||||
throw new PrivilegeException(msg);
|
||||
}
|
||||
|
||||
// get users file path
|
||||
File usersPath = getFile(basePath, XML_PARAM_USERS_FILE, XML_PARAM_USERS_FILE_DEF);
|
||||
|
||||
// get roles file path
|
||||
File rolesPath = getFile(basePath, XML_PARAM_ROLES_FILE, XML_PARAM_ROLES_FILE_DEF);
|
||||
File usersPath = getFile(basePath, PARAM_USERS_FILE, PARAM_USERS_FILE_DEF, true);
|
||||
File groupsPath = getFile(basePath, PARAM_GROUPS_FILE, PARAM_GROUPS_FILE_DEF, false);
|
||||
File rolesPath = getFile(basePath, PARAM_ROLES_FILE, PARAM_ROLES_FILE_DEF, true);
|
||||
|
||||
// save path to model
|
||||
this.usersPath = usersPath;
|
||||
this.groupsPath = groupsPath;
|
||||
this.rolesPath = rolesPath;
|
||||
|
||||
this.caseInsensitiveUsername = !this.parameterMap.containsKey(PARAM_CASE_INSENSITIVE_USERNAME) ||
|
||||
|
@ -188,7 +226,7 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
logger.info("Privilege Data loaded.");
|
||||
}
|
||||
|
||||
private File getFile(String basePath, String param, String defaultValue) {
|
||||
private File getFile(String basePath, String param, String defaultValue, boolean required) {
|
||||
String fileName = this.parameterMap.get(param);
|
||||
if (isEmpty(fileName)) {
|
||||
fileName = defaultValue;
|
||||
|
@ -199,7 +237,7 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
|
||||
String path = basePath + "/" + fileName;
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
if (required && !file.exists()) {
|
||||
String msg = "[{0}] Defined parameter {1} is invalid as file does not exist at path {2}";
|
||||
msg = format(msg, PersistenceHandler.class.getName(), param, file.getAbsolutePath());
|
||||
throw new PrivilegeException(msg);
|
||||
|
@ -221,6 +259,10 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
PrivilegeUsersSaxReader usersXmlHandler = new PrivilegeUsersSaxReader(this.caseInsensitiveUsername);
|
||||
XmlHelper.parseDocument(this.usersPath, usersXmlHandler);
|
||||
|
||||
PrivilegeGroupsSaxReader groupsXmlHandler = new PrivilegeGroupsSaxReader();
|
||||
if (this.groupsPath.exists())
|
||||
XmlHelper.parseDocument(this.groupsPath, groupsXmlHandler);
|
||||
|
||||
PrivilegeRolesSaxReader rolesXmlHandler = new PrivilegeRolesSaxReader();
|
||||
XmlHelper.parseDocument(this.rolesPath, rolesXmlHandler);
|
||||
|
||||
|
@ -230,6 +272,12 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
this.roleMap.putAll(rolesXmlHandler.getRoles());
|
||||
}
|
||||
|
||||
// GROUPS
|
||||
synchronized (this.groupMap) {
|
||||
this.groupMap.clear();
|
||||
this.groupMap.putAll(groupsXmlHandler.getGroups());
|
||||
}
|
||||
|
||||
// USERS
|
||||
synchronized (this.userMap) {
|
||||
this.userMap.clear();
|
||||
|
@ -237,21 +285,40 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
}
|
||||
|
||||
this.userMapDirty = false;
|
||||
this.groupMapDirty = false;
|
||||
this.roleMapDirty = false;
|
||||
|
||||
logger.info(format("Read {0} Users", this.userMap.size()));
|
||||
logger.info(format("Read {0} Groups", this.groupMap.size()));
|
||||
logger.info(format("Read {0} Roles", this.roleMap.size()));
|
||||
|
||||
// validate referenced roles exist
|
||||
// validate referenced elements exist
|
||||
for (User user : this.userMap.values()) {
|
||||
for (String roleName : user.getRoles()) {
|
||||
|
||||
// validate that role exists
|
||||
if (getRole(roleName) == null) {
|
||||
logger.error(
|
||||
format("Role {0} does not exist referenced by user {1}", roleName, user.getUsername()));
|
||||
}
|
||||
}
|
||||
|
||||
for (String groupName : user.getGroups()) {
|
||||
// validate that group exists
|
||||
if (getGroup(groupName) == null) {
|
||||
logger.error(
|
||||
format("Group {0} does not exist referenced by user {1}", groupName, user.getUsername()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validate referenced roles exist on groups
|
||||
for (Group group : this.groupMap.values()) {
|
||||
for (String roleName : group.roles()) {
|
||||
// validate that role exists
|
||||
if (getRole(roleName) == null) {
|
||||
logger.error(format("Role {0} does not exist referenced by group {1}", roleName, group.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -267,20 +334,21 @@ public class XmlPersistenceHandler implements PersistenceHandler {
|
|||
|
||||
// write users file
|
||||
if (this.userMapDirty) {
|
||||
// delegate writing
|
||||
PrivilegeUsersSaxWriter modelWriter = new PrivilegeUsersSaxWriter(getAllUsers(), this.usersPath);
|
||||
modelWriter.write();
|
||||
|
||||
new PrivilegeUsersSaxWriter(getAllUsers(), this.usersPath).write();
|
||||
this.userMapDirty = false;
|
||||
saved = true;
|
||||
}
|
||||
|
||||
// write groups file
|
||||
if (this.groupMapDirty) {
|
||||
new PrivilegeGroupsSaxWriter(getAllGroups(), this.groupsPath).write();
|
||||
this.groupMapDirty = false;
|
||||
saved = true;
|
||||
}
|
||||
|
||||
// write roles file
|
||||
if (this.roleMapDirty) {
|
||||
// delegate writing
|
||||
PrivilegeRolesSaxWriter modelWriter = new PrivilegeRolesSaxWriter(getAllRoles(), this.rolesPath);
|
||||
modelWriter.write();
|
||||
|
||||
new PrivilegeRolesSaxWriter(getAllRoles(), this.rolesPath).write();
|
||||
this.roleMapDirty = false;
|
||||
saved = true;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
import static li.strolch.privilege.model.internal.PasswordCrypt.buildPasswordString;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -111,9 +110,9 @@ public class PasswordCreator {
|
|||
}
|
||||
|
||||
Map<String, String> parameterMap = new HashMap<>();
|
||||
parameterMap.put(XmlConstants.XML_PARAM_HASH_ALGORITHM, hashAlgorithm);
|
||||
parameterMap.put(XmlConstants.XML_PARAM_HASH_ITERATIONS, String.valueOf(iterations));
|
||||
parameterMap.put(XmlConstants.XML_PARAM_HASH_KEY_LENGTH, String.valueOf(keyLength));
|
||||
parameterMap.put(XmlConstants.PARAM_HASH_ALGORITHM, hashAlgorithm);
|
||||
parameterMap.put(XmlConstants.PARAM_HASH_ITERATIONS, String.valueOf(iterations));
|
||||
parameterMap.put(XmlConstants.PARAM_HASH_KEY_LENGTH, String.valueOf(keyLength));
|
||||
|
||||
DefaultEncryptionHandler encryptionHandler = new DefaultEncryptionHandler();
|
||||
encryptionHandler.initialize(parameterMap);
|
||||
|
@ -136,15 +135,15 @@ public class PasswordCreator {
|
|||
byte[] salt = saltS.getBytes();
|
||||
|
||||
PasswordCrypt passwordCrypt = encryptionHandler.hashPassword(password, salt);
|
||||
String passwordHashS = StringHelper.toHexString(passwordCrypt.getPassword());
|
||||
String passwordHashS = StringHelper.toHexString(passwordCrypt.password());
|
||||
System.out.println("Hash is: " + passwordHashS);
|
||||
System.out.println("Salt is: " + saltS);
|
||||
System.out.println();
|
||||
|
||||
System.out.println(
|
||||
XmlConstants.XML_ATTR_PASSWORD + "=\"" + passwordHashS + "\" " + XmlConstants.XML_ATTR_SALT +
|
||||
"=\"" + saltS + "\"");
|
||||
System.out.println(XmlConstants.XML_ATTR_PASSWORD + "=\"" + passwordCrypt.buildPasswordString() + "\"");
|
||||
XmlConstants.ATTR_PASSWORD + "=\"" + passwordHashS + "\" " + XmlConstants.ATTR_SALT + "=\"" +
|
||||
saltS + "\"");
|
||||
System.out.println(XmlConstants.ATTR_PASSWORD + "=\"" + passwordCrypt.buildPasswordString() + "\"");
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,308 +23,69 @@ package li.strolch.privilege.helper;
|
|||
@SuppressWarnings("nls")
|
||||
public class XmlConstants {
|
||||
|
||||
/**
|
||||
* XML_ROOT_PRIVILEGE_CONTAINER = "PrivilegeContainer" :
|
||||
*/
|
||||
public static final String XML_ROOT_PRIVILEGE = "Privilege";
|
||||
|
||||
/**
|
||||
* XML_CONTAINER = "Container" :
|
||||
*/
|
||||
public static final String XML_CONTAINER = "Container";
|
||||
|
||||
/**
|
||||
* XML_POLICIES = "Policies" :
|
||||
*/
|
||||
public static final String XML_POLICIES = "Policies";
|
||||
|
||||
/**
|
||||
* XML_PRIVILEGES = "Privileges" :
|
||||
*/
|
||||
public static final String XML_PRIVILEGES = "Privileges";
|
||||
|
||||
/**
|
||||
* XML_ROOT_PRIVILEGE_USERS_AND_ROLES = "UsersAndRoles" :
|
||||
*/
|
||||
public static final String XML_ROOT_PRIVILEGE_USERS_AND_ROLES = "UsersAndRoles";
|
||||
|
||||
/**
|
||||
* XML_ROOT_CERTIFICATES = "Certificates" :
|
||||
*/
|
||||
public static final String XML_ROOT_CERTIFICATES = "Certificates";
|
||||
|
||||
/**
|
||||
* XML_HANDLER_USER_CHALLENGE = "UserChallengeHandler" :
|
||||
*/
|
||||
public static final String XML_HANDLER_USER_CHALLENGE = "UserChallengeHandler";
|
||||
|
||||
/**
|
||||
* XML_HANDLER_PERSISTENCE = "PersistenceHandler" :
|
||||
*/
|
||||
public static final String XML_HANDLER_PERSISTENCE = "PersistenceHandler";
|
||||
|
||||
/**
|
||||
* XML_HANDLER_ENCRYPTION = "EncryptionHandler" :
|
||||
*/
|
||||
public static final String XML_HANDLER_ENCRYPTION = "EncryptionHandler";
|
||||
|
||||
/**
|
||||
* XML_HANDLER_ENCRYPTION = "PasswordStrengthHandler" :
|
||||
*/
|
||||
public static final String XML_HANDLER_PASSWORD_STRENGTH = "PasswordStrengthHandler";
|
||||
|
||||
/**
|
||||
* XML_HANDLER_ENCRYPTION = "SsoHandler" :
|
||||
*/
|
||||
public static final String XML_HANDLER_SSO = "SsoHandler";
|
||||
|
||||
/**
|
||||
* XML_HANDLER_PRIVILEGE = "PrivilegeHandler" :
|
||||
*/
|
||||
public static final String XML_HANDLER_PRIVILEGE = "PrivilegeHandler";
|
||||
|
||||
/**
|
||||
* XML_ROLES = "Roles" :
|
||||
*/
|
||||
public static final String XML_ROLES = "Roles";
|
||||
|
||||
/**
|
||||
* XML_ROLE = "Role" :
|
||||
*/
|
||||
public static final String XML_ROLE = "Role";
|
||||
|
||||
/**
|
||||
* XML_USERS = "Users" :
|
||||
*/
|
||||
public static final String XML_USERS = "Users";
|
||||
|
||||
/**
|
||||
* XML_CERTIFICATE = "Certificate" :
|
||||
*/
|
||||
public static final String XML_CERTIFICATE = "Certificate";
|
||||
|
||||
/**
|
||||
* XML_SESSION_DATA = "SessionData" :
|
||||
*/
|
||||
public static final String XML_SESSION_DATA = "SessionData";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_USER = "User";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_HISTORY = "History";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_FIRST_LOGIN = "FirstLogin";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_LAST_LOGIN = "LastLogin";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_LAST_PASSWORD_CHANGE = "LastPasswordChange";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_PASSWORD_CHANGE_REQUESTED = "PasswordChangeRequested";
|
||||
|
||||
/**
|
||||
* XML_PRIVILEGE = "Privilege" :
|
||||
*/
|
||||
public static final String XML_PRIVILEGE = "Privilege";
|
||||
|
||||
/**
|
||||
* XML_POLICY = "Policy" :
|
||||
*/
|
||||
public static final String XML_POLICY = "Policy";
|
||||
|
||||
/**
|
||||
* XML_PARAMETERS = "Parameters" :
|
||||
*/
|
||||
public static final String XML_PARAMETERS = "Parameters";
|
||||
|
||||
/**
|
||||
* XML_PARAMETER = "Parameter" :
|
||||
*/
|
||||
public static final String XML_PARAMETER = "Parameter";
|
||||
|
||||
/**
|
||||
* XML_PROPERTIES = "Properties" :
|
||||
*/
|
||||
public static final String XML_PROPERTIES = "Properties";
|
||||
|
||||
/**
|
||||
* XML_PROPERTY = "Property" :
|
||||
*/
|
||||
public static final String XML_PROPERTY = "Property";
|
||||
|
||||
/**
|
||||
* XML_ALL_ALLOWED = "AllAllowed" :
|
||||
*/
|
||||
public static final String XML_ALL_ALLOWED = "AllAllowed";
|
||||
|
||||
/**
|
||||
* XML_DENY = "Deny" :
|
||||
*/
|
||||
public static final String XML_DENY = "Deny";
|
||||
|
||||
/**
|
||||
* XML_ALLOW = "Allow" :
|
||||
*/
|
||||
public static final String XML_ALLOW = "Allow";
|
||||
|
||||
/**
|
||||
* XML_FIRSTNAME = "Firstname" :
|
||||
*/
|
||||
public static final String XML_FIRSTNAME = "Firstname";
|
||||
|
||||
/**
|
||||
* XML_LASTNAME = "Lastname" :
|
||||
*/
|
||||
public static final String XML_LASTNAME = "Lastname";
|
||||
|
||||
/**
|
||||
* XML_STATE = "State" :
|
||||
*/
|
||||
public static final String XML_STATE = "State";
|
||||
|
||||
/**
|
||||
* XML_LOCALE = "Locale" :
|
||||
*/
|
||||
public static final String XML_LOCALE = "Locale";
|
||||
|
||||
/**
|
||||
* XML_ATTR_CLASS = "class" :
|
||||
*/
|
||||
public static final String XML_ATTR_CLASS = "class";
|
||||
|
||||
/**
|
||||
* XML_ATTR_LOGIN_TIME = "loginTime" :
|
||||
*/
|
||||
public static final String XML_ATTR_LOGIN_TIME = "loginTime";
|
||||
|
||||
/**
|
||||
* XML_ATTR_KEEP_ALIVE = "keepAlive" :
|
||||
*/
|
||||
public static final String XML_ATTR_KEEP_ALIVE = "keepAlive";
|
||||
|
||||
/**
|
||||
* XML_ATTR_LAST_ACCESS = "lastAccess" :
|
||||
*/
|
||||
public static final String XML_ATTR_LAST_ACCESS = "lastAccess";
|
||||
|
||||
/**
|
||||
* XML_ATTR_NAME = "name" :
|
||||
*/
|
||||
public static final String XML_ATTR_NAME = "name";
|
||||
|
||||
/**
|
||||
* XML_ATTR_VALUE = "value" :
|
||||
*/
|
||||
public static final String XML_ATTR_VALUE = "value";
|
||||
|
||||
/**
|
||||
* XML_ATTR_POLICY = "policy" :
|
||||
*/
|
||||
public static final String XML_ATTR_POLICY = "policy";
|
||||
|
||||
/**
|
||||
* XML_ATTR_USER_ID = "userId" :
|
||||
*/
|
||||
public static final String XML_ATTR_USER_ID = "userId";
|
||||
|
||||
/**
|
||||
* XML_ATTR_SESSION_ID = "sessionId" :
|
||||
*/
|
||||
public static final String XML_ATTR_SESSION_ID = "sessionId";
|
||||
|
||||
/**
|
||||
* XML_ATTR_SESSION_ID = "usage" :
|
||||
*/
|
||||
public static final String XML_ATTR_USAGE = "usage";
|
||||
|
||||
/**
|
||||
* XML_ATTR_USERNAME = "username" :
|
||||
*/
|
||||
public static final String XML_ATTR_USERNAME = "username";
|
||||
|
||||
/**
|
||||
* XML_ATTR_AUTH_TOKEN = "authToken" :
|
||||
*/
|
||||
public static final String XML_ATTR_AUTH_TOKEN = "authToken";
|
||||
|
||||
/**
|
||||
* XML_ATTR_SOURCE = "source" :
|
||||
*/
|
||||
public static final String XML_ATTR_SOURCE = "source";
|
||||
|
||||
/**
|
||||
* XML_ATTR_LOCALE = "locale" :
|
||||
*/
|
||||
public static final String XML_ATTR_LOCALE = "locale";
|
||||
|
||||
/**
|
||||
* XML_ATTR_PASSWORD = "password" :
|
||||
*/
|
||||
public static final String XML_ATTR_PASSWORD = "password";
|
||||
|
||||
/**
|
||||
* XML_ATTR_SALT = "salt" :
|
||||
*/
|
||||
public static final String XML_ATTR_SALT = "salt";
|
||||
|
||||
/**
|
||||
* XML_PARAM_HASH_ALGORITHM = "hashAlgorithm" :
|
||||
*/
|
||||
public static final String XML_PARAM_HASH_ALGORITHM = "hashAlgorithm";
|
||||
|
||||
/**
|
||||
* XML_PARAM_HASH_ALGORITHM_NON_SALT = "hashAlgorithmNonSalt" :
|
||||
*/
|
||||
public static final String XML_PARAM_HASH_ALGORITHM_NON_SALT = "hashAlgorithmNonSalt";
|
||||
|
||||
/**
|
||||
* XML_PARAM_HASH_ALGORITHM = "hashAlgorithm" :
|
||||
*/
|
||||
public static final String XML_PARAM_HASH_ITERATIONS = "hashIterations";
|
||||
|
||||
/**
|
||||
* XML_PARAM_HASH_ALGORITHM = "hashAlgorithm" :
|
||||
*/
|
||||
public static final String XML_PARAM_HASH_KEY_LENGTH = "hashKeyLength";
|
||||
|
||||
/**
|
||||
* XML_PARAM_USERS_FILE = "usersXmlFile" :
|
||||
*/
|
||||
public static final String XML_PARAM_USERS_FILE = "usersXmlFile";
|
||||
|
||||
/**
|
||||
* XML_PARAM_USERS_FILE_DEF = "PrivilegeUsers.xml" :
|
||||
*/
|
||||
public static final String XML_PARAM_USERS_FILE_DEF = "PrivilegeUsers.xml";
|
||||
|
||||
/**
|
||||
* XML_PARAM_ROLES_FILE = "rolesXmlFile" :
|
||||
*/
|
||||
public static final String XML_PARAM_ROLES_FILE = "rolesXmlFile";
|
||||
|
||||
/**
|
||||
* XML_PARAM_ROLES_FILE_DEF = "PrivilegeRoles.xml" :
|
||||
*/
|
||||
public static final String XML_PARAM_ROLES_FILE_DEF = "PrivilegeRoles.xml";
|
||||
|
||||
/**
|
||||
* XML_PARAM_BASE_PATH = "basePath" :
|
||||
*/
|
||||
public static final String XML_PARAM_BASE_PATH = "basePath";
|
||||
public static final String ROOT_PRIVILEGE = "Privilege";
|
||||
public static final String CONTAINER = "Container";
|
||||
public static final String POLICIES = "Policies";
|
||||
public static final String PRIVILEGES = "Privileges";
|
||||
public static final String ROOT_PRIVILEGE_USERS_AND_ROLES = "UsersAndRoles";
|
||||
public static final String ROOT_CERTIFICATES = "Certificates";
|
||||
public static final String HANDLER_USER_CHALLENGE = "UserChallengeHandler";
|
||||
public static final String HANDLER_PERSISTENCE = "PersistenceHandler";
|
||||
public static final String HANDLER_ENCRYPTION = "EncryptionHandler";
|
||||
public static final String HANDLER_PASSWORD_STRENGTH = "PasswordStrengthHandler";
|
||||
public static final String HANDLER_SSO = "SsoHandler";
|
||||
public static final String HANDLER_PRIVILEGE = "PrivilegeHandler";
|
||||
public static final String ROLES = "Roles";
|
||||
public static final String ROLE = "Role";
|
||||
public static final String USERS = "Users";
|
||||
public static final String GROUPS = "Groups";
|
||||
public static final String GROUP = "Group";
|
||||
public static final String CERTIFICATE = "Certificate";
|
||||
public static final String SESSION_DATA = "SessionData";
|
||||
public static final String USER = "User";
|
||||
public static final String HISTORY = "History";
|
||||
public static final String FIRST_LOGIN = "FirstLogin";
|
||||
public static final String LAST_LOGIN = "LastLogin";
|
||||
public static final String LAST_PASSWORD_CHANGE = "LastPasswordChange";
|
||||
public static final String PASSWORD_CHANGE_REQUESTED = "PasswordChangeRequested";
|
||||
public static final String PRIVILEGE = "Privilege";
|
||||
public static final String POLICY = "Policy";
|
||||
public static final String PARAMETERS = "Parameters";
|
||||
public static final String PARAMETER = "Parameter";
|
||||
public static final String PROPERTIES = "Properties";
|
||||
public static final String PROPERTY = "Property";
|
||||
public static final String ALL_ALLOWED = "AllAllowed";
|
||||
public static final String DENY = "Deny";
|
||||
public static final String ALLOW = "Allow";
|
||||
public static final String FIRSTNAME = "Firstname";
|
||||
public static final String LASTNAME = "Lastname";
|
||||
public static final String STATE = "State";
|
||||
public static final String LOCALE = "Locale";
|
||||
public static final String ATTR_CLASS = "class";
|
||||
public static final String ATTR_LOGIN_TIME = "loginTime";
|
||||
public static final String ATTR_KEEP_ALIVE = "keepAlive";
|
||||
public static final String ATTR_LAST_ACCESS = "lastAccess";
|
||||
public static final String ATTR_NAME = "name";
|
||||
public static final String ATTR_VALUE = "value";
|
||||
public static final String ATTR_POLICY = "policy";
|
||||
public static final String ATTR_USER_ID = "userId";
|
||||
public static final String ATTR_SESSION_ID = "sessionId";
|
||||
public static final String ATTR_USAGE = "usage";
|
||||
public static final String ATTR_USERNAME = "username";
|
||||
public static final String ATTR_AUTH_TOKEN = "authToken";
|
||||
public static final String ATTR_SOURCE = "source";
|
||||
public static final String ATTR_LOCALE = "locale";
|
||||
public static final String ATTR_PASSWORD = "password";
|
||||
public static final String ATTR_SALT = "salt";
|
||||
public static final String PARAM_HASH_ALGORITHM = "hashAlgorithm";
|
||||
public static final String PARAM_HASH_ALGORITHM_NON_SALT = "hashAlgorithmNonSalt";
|
||||
public static final String PARAM_HASH_ITERATIONS = "hashIterations";
|
||||
public static final String PARAM_HASH_KEY_LENGTH = "hashKeyLength";
|
||||
public static final String PARAM_USERS_FILE = "usersXmlFile";
|
||||
public static final String PARAM_USERS_FILE_DEF = "PrivilegeUsers.xml";
|
||||
public static final String PARAM_GROUPS_FILE = "groupsXmlFile";
|
||||
public static final String PARAM_GROUPS_FILE_DEF = "PrivilegeGroups.xml";
|
||||
public static final String PARAM_ROLES_FILE = "rolesXmlFile";
|
||||
public static final String PARAM_ROLES_FILE_DEF = "PrivilegeRoles.xml";
|
||||
public static final String PARAM_BASE_PATH = "basePath";
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public class XmlHelper {
|
|||
|
||||
public static void writeStringMapElement(XMLStreamWriter xmlWriter, Map<String, String> parameterMap,
|
||||
String elementName, String valueElementName) throws XMLStreamException {
|
||||
writeStringMapElement(xmlWriter, parameterMap, elementName, valueElementName, XML_ATTR_VALUE);
|
||||
writeStringMapElement(xmlWriter, parameterMap, elementName, valueElementName, ATTR_VALUE);
|
||||
}
|
||||
|
||||
public static void writeStringMapElement(XMLStreamWriter xmlWriter, Map<String, String> parameterMap,
|
||||
|
@ -32,7 +32,7 @@ public class XmlHelper {
|
|||
propertyKeys.sort(null);
|
||||
for (String propertyKey : propertyKeys) {
|
||||
xmlWriter.writeEmptyElement(valueElementName);
|
||||
xmlWriter.writeAttribute(XML_ATTR_NAME, propertyKey);
|
||||
xmlWriter.writeAttribute(ATTR_NAME, propertyKey);
|
||||
xmlWriter.writeAttribute(valueAttrName, parameterMap.get(propertyKey));
|
||||
}
|
||||
|
||||
|
|
|
@ -15,20 +15,18 @@
|
|||
*/
|
||||
package li.strolch.privilege.model;
|
||||
|
||||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
import li.strolch.privilege.base.PrivilegeConstants;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeConstants;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
import static li.strolch.utils.helper.StringHelper.isNotEmpty;
|
||||
|
||||
/**
|
||||
* The {@link Certificate} is the object a client keeps when accessing a Privilege enabled system. This object is the
|
||||
|
@ -37,7 +35,7 @@ import li.strolch.utils.helper.StringHelper;
|
|||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public final class Certificate implements Serializable {
|
||||
public final class Certificate {
|
||||
|
||||
private final Usage usage;
|
||||
private final String sessionId;
|
||||
|
@ -50,6 +48,7 @@ public final class Certificate implements Serializable {
|
|||
private final ZonedDateTime loginTime;
|
||||
private final boolean keepAlive;
|
||||
|
||||
private final Set<String> userGroups;
|
||||
private final Set<String> userRoles;
|
||||
private final Map<String, String> propertyMap;
|
||||
|
||||
|
@ -64,49 +63,28 @@ public final class Certificate implements Serializable {
|
|||
* by the {@link PrivilegeHandler}
|
||||
* </p>
|
||||
*
|
||||
* @param usage
|
||||
* the usage allowed for this certificate
|
||||
* @param sessionId
|
||||
* the users session id
|
||||
* @param username
|
||||
* the users login name
|
||||
* @param firstName
|
||||
* the users first name
|
||||
* @param lastName
|
||||
* the users last name
|
||||
* @param authToken
|
||||
* the authentication token defining the users unique session and is a private field of this certificate.
|
||||
* @param locale
|
||||
* the users {@link Locale}
|
||||
* @param userRoles
|
||||
* the user's roles
|
||||
* @param propertyMap
|
||||
* a {@link Map} containing string value pairs of properties for the logged in user. These properties can be
|
||||
* edited and can be used for the user to change settings of this session
|
||||
* @param usage the usage allowed for this certificate
|
||||
* @param sessionId the users session id
|
||||
* @param username the users login name
|
||||
* @param firstName the users first name
|
||||
* @param lastName the users last name
|
||||
* @param authToken the authentication token defining the users unique session and is a private field of this
|
||||
* certificate.
|
||||
* @param locale the users {@link Locale}
|
||||
* @param userRoles the user's roles
|
||||
* @param propertyMap a {@link Map} containing string value pairs of properties for the logged in user. These
|
||||
* properties can be edited and can be used for the user to change settings of this session
|
||||
*/
|
||||
public Certificate(Usage usage, String sessionId, String username, String firstName, String lastName,
|
||||
UserState userState, String authToken, String source, ZonedDateTime loginTime, boolean keepAlive,
|
||||
Locale locale, Set<String> userRoles, Map<String, String> propertyMap) {
|
||||
Locale locale, Set<String> userGroups, Set<String> userRoles, Map<String, String> propertyMap) {
|
||||
|
||||
// validate arguments are not null
|
||||
if (StringHelper.isEmpty(sessionId)) {
|
||||
throw new PrivilegeException("sessionId is null!");
|
||||
}
|
||||
if (StringHelper.isEmpty(username)) {
|
||||
throw new PrivilegeException("username is null!");
|
||||
}
|
||||
if (StringHelper.isEmpty(authToken)) {
|
||||
throw new PrivilegeException("authToken is null!");
|
||||
}
|
||||
if (userState == null) {
|
||||
throw new PrivilegeException("userState is null!");
|
||||
}
|
||||
if (usage == null) {
|
||||
throw new PrivilegeException("usage is null!");
|
||||
}
|
||||
if (source == null) {
|
||||
throw new PrivilegeException("source is null!");
|
||||
}
|
||||
DBC.PRE.assertNotEmpty("sessionId must not be empty", sessionId);
|
||||
DBC.PRE.assertNotEmpty("username must not be empty", username);
|
||||
DBC.PRE.assertNotEmpty("authToken must not be empty", authToken);
|
||||
DBC.PRE.assertNotNull("userState must not be empty", userState);
|
||||
DBC.PRE.assertNotNull("usage must not be empty", usage);
|
||||
DBC.PRE.assertNotNull("source must not be null", source);
|
||||
|
||||
this.usage = usage;
|
||||
this.sessionId = sessionId;
|
||||
|
@ -126,11 +104,12 @@ public final class Certificate implements Serializable {
|
|||
this.locale = locale;
|
||||
|
||||
if (propertyMap == null)
|
||||
this.propertyMap = Collections.emptyMap();
|
||||
this.propertyMap = Map.of();
|
||||
else
|
||||
this.propertyMap = Collections.unmodifiableMap(propertyMap);
|
||||
this.propertyMap = Map.copyOf(propertyMap);
|
||||
|
||||
this.userRoles = Collections.unmodifiableSet(userRoles);
|
||||
this.userGroups = Set.copyOf(userGroups);
|
||||
this.userRoles = Set.copyOf(userRoles);
|
||||
this.lastAccess = ZonedDateTime.now();
|
||||
}
|
||||
|
||||
|
@ -150,15 +129,29 @@ public final class Certificate implements Serializable {
|
|||
return this.usage;
|
||||
}
|
||||
|
||||
public Set<String> getUserGroups() {
|
||||
return this.userGroups;
|
||||
}
|
||||
|
||||
public Set<String> getUserRoles() {
|
||||
return this.userRoles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the user of this certificate has the given group
|
||||
*
|
||||
* @param group the group to check for
|
||||
*
|
||||
* @return true if the user of this certificate has the given group
|
||||
*/
|
||||
public boolean hasGroup(String group) {
|
||||
return this.userGroups.contains(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the user of this certificate has the given role
|
||||
*
|
||||
* @param role
|
||||
* the role to check for
|
||||
* @param role the role to check for
|
||||
*
|
||||
* @return true if the user of this certificate has the given role
|
||||
*/
|
||||
|
@ -178,8 +171,7 @@ public final class Certificate implements Serializable {
|
|||
/**
|
||||
* Returns the property with the given key
|
||||
*
|
||||
* @param key
|
||||
* the key for which the property is to be returned
|
||||
* @param key the key for which the property is to be returned
|
||||
*
|
||||
* @return the value of the property with the given key, or null if it does not exist
|
||||
*/
|
||||
|
@ -283,12 +275,12 @@ public final class Certificate implements Serializable {
|
|||
builder.append(", username=");
|
||||
builder.append(this.username);
|
||||
|
||||
if (StringHelper.isNotEmpty(this.firstname)) {
|
||||
if (isNotEmpty(this.firstname)) {
|
||||
builder.append(", firstname=");
|
||||
builder.append(this.firstname);
|
||||
}
|
||||
|
||||
if (StringHelper.isNotEmpty(this.lastname)) {
|
||||
if (isNotEmpty(this.lastname)) {
|
||||
builder.append(", lastname=");
|
||||
builder.append(this.lastname);
|
||||
}
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.privilege.model;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@link IPrivilege} is the main model object for Privilege. A {@link Role} has a set of Privileges assigned to it
|
||||
* which defines the privileges a logged in user with that role has. If the {@link IPrivilege} has a {@link
|
||||
* PrivilegePolicy} defined, then that policy will be used for finer granularity and with the deny and allow lists
|
||||
* configured which is used to evaluate if privilege is granted to a {@link Restrictable}
|
||||
* </p>
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public interface IPrivilege {
|
||||
|
||||
/**
|
||||
* @return a {@link PrivilegeRep} which is a representation of this object used to serialize and view on clients
|
||||
*/
|
||||
PrivilegeRep asPrivilegeRep();
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* @return the policy
|
||||
*/
|
||||
String getPolicy();
|
||||
|
||||
/**
|
||||
* @return the allAllowed
|
||||
*/
|
||||
boolean isAllAllowed();
|
||||
|
||||
/**
|
||||
* @return the allowList
|
||||
*/
|
||||
Set<String> getAllowList();
|
||||
|
||||
/**
|
||||
* @return the denyList
|
||||
*/
|
||||
Set<String> getDenyList();
|
||||
|
||||
/**
|
||||
* @return true if there are values in the allow list
|
||||
*/
|
||||
boolean hasAllowed();
|
||||
|
||||
/**
|
||||
* @return if the value is in the allow list
|
||||
*/
|
||||
boolean isAllowed(String value);
|
||||
|
||||
/**
|
||||
* @return true if there are values in the deny list
|
||||
*/
|
||||
boolean hasDenied();
|
||||
|
||||
/**
|
||||
* @return true if the value is in the deny list
|
||||
*/
|
||||
boolean isDenied(String value);
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright 2013 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.privilege.model;
|
||||
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@link Privilege} is the main model object for Privilege. A {@link Role} has a set of Privileges assigned to it which
|
||||
* defines the privileges a logged in user with that role has. If the {@link Privilege} has a {@link PrivilegePolicy}
|
||||
* defined, then that policy will be used for finer granularity and with the deny and allow lists configured which is
|
||||
* used to evaluate if privilege is granted to a {@link Restrictable}
|
||||
* </p>
|
||||
*
|
||||
* @param name the name of this privilege, which is unique to all privileges known in the
|
||||
* {@link PrivilegeHandler}
|
||||
* @param policy the {@link PrivilegePolicy} configured to evaluate if the privilege is granted. If null, then
|
||||
* privilege is granted
|
||||
* @param allAllowed a boolean defining if a {@link Role} with this {@link Privilege} has unrestricted access to a
|
||||
* {@link Restrictable} in which case the deny and allow lists are ignored and can be null
|
||||
* @param denyList a list of deny rules for this {@link Privilege}, can be null if all allowed
|
||||
* @param allowList a list of allow rules for this {@link Privilege}, can be null if all allowed
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public record Privilege(String name, String policy, boolean allAllowed, Set<String> denyList, Set<String> allowList) {
|
||||
|
||||
public Privilege(String name, String policy, boolean allAllowed, Set<String> denyList, Set<String> allowList) {
|
||||
DBC.PRE.assertNotEmpty("name must not be empty", name);
|
||||
DBC.PRE.assertNotEmpty("policy must not be empty", policy);
|
||||
DBC.PRE.assertNotNull("denyList must not be null", denyList);
|
||||
DBC.PRE.assertNotNull("allowList must not be null", allowList);
|
||||
|
||||
this.name = name;
|
||||
this.allAllowed = allAllowed;
|
||||
this.policy = policy;
|
||||
this.denyList = Set.copyOf(denyList);
|
||||
this.allowList = Set.copyOf(allowList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a {@link PrivilegeRep} which is a representation of this object used to serialize and view on clients
|
||||
*/
|
||||
public PrivilegeRep asPrivilegeRep() {
|
||||
return new PrivilegeRep(this.name, this.policy, this.allAllowed, new HashSet<>(this.denyList),
|
||||
new HashSet<>(this.allowList));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getPolicy() {
|
||||
return this.policy;
|
||||
}
|
||||
|
||||
public boolean isAllAllowed() {
|
||||
return this.allAllowed;
|
||||
}
|
||||
|
||||
public Set<String> getAllowList() {
|
||||
return this.allowList;
|
||||
}
|
||||
|
||||
public Set<String> getDenyList() {
|
||||
return this.denyList;
|
||||
}
|
||||
|
||||
public boolean hasAllowed() {
|
||||
return !this.allowList.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isAllowed(String value) {
|
||||
return this.allowList.contains(value);
|
||||
}
|
||||
|
||||
public boolean hasDenied() {
|
||||
return !this.allowList.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isDenied(String value) {
|
||||
return this.denyList.contains(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Privilege [name=" + this.name + ", policy=" + this.policy + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Privilege other = (Privilege) obj;
|
||||
if (this.name == null)
|
||||
return other.name == null;
|
||||
return this.name.equals(other.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@link Privilege} from the {@link PrivilegeRep}
|
||||
*
|
||||
* @param privilegeRep the {@link PrivilegeRep} from which to create the {@link Privilege}
|
||||
*/
|
||||
public static Privilege of(PrivilegeRep privilegeRep) {
|
||||
return new Privilege(privilegeRep.getName(), privilegeRep.getPolicy(), privilegeRep.isAllAllowed(),
|
||||
privilegeRep.getDenyList(), privilegeRep.getAllowList());
|
||||
}
|
||||
}
|
|
@ -15,14 +15,16 @@
|
|||
*/
|
||||
package li.strolch.privilege.model;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import static java.text.MessageFormat.format;
|
||||
import static li.strolch.privilege.i18n.PrivilegeMessages.getString;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -36,19 +38,15 @@ import li.strolch.privilege.policy.PrivilegePolicy;
|
|||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class PrivilegeContext {
|
||||
public record PrivilegeContext(UserRep userRep, Certificate certificate, Map<String, Privilege> privileges,
|
||||
Map<String, PrivilegePolicy> policies) {
|
||||
|
||||
//
|
||||
// object state
|
||||
//
|
||||
|
||||
private final UserRep userRep;
|
||||
private final Certificate certificate;
|
||||
private final Map<String, IPrivilege> privileges;
|
||||
private final Map<String, PrivilegePolicy> policies;
|
||||
|
||||
public PrivilegeContext(UserRep userRep, Certificate certificate, Map<String, IPrivilege> privileges,
|
||||
public PrivilegeContext(UserRep userRep, Certificate certificate, Map<String, Privilege> privileges,
|
||||
Map<String, PrivilegePolicy> policies) {
|
||||
DBC.PRE.assertNotNull("userRep must not be null", userRep);
|
||||
DBC.PRE.assertNotNull("certificate must not be null", certificate);
|
||||
DBC.PRE.assertNotNull("privileges must not be null", privileges);
|
||||
DBC.PRE.assertNotNull("policies must not be null", policies);
|
||||
this.userRep = userRep;
|
||||
this.certificate = certificate;
|
||||
this.privileges = Map.copyOf(privileges);
|
||||
|
@ -85,35 +83,64 @@ public class PrivilegeContext {
|
|||
|
||||
public void assertHasPrivilege(String privilegeName) throws AccessDeniedException {
|
||||
if (!this.privileges.containsKey(privilegeName)) {
|
||||
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.user"),
|
||||
userRep.getUsername(), privilegeName);
|
||||
String msg = format(getString("Privilege.noprivilege.user"), userRep.getUsername(), privilegeName);
|
||||
throw new AccessDeniedException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasGroup(String groupName) {
|
||||
return this.userRep.hasGroup(groupName);
|
||||
}
|
||||
|
||||
public boolean hasRole(String roleName) {
|
||||
return this.userRep.hasRole(roleName);
|
||||
}
|
||||
|
||||
public void assertHasRole(String roleName) throws AccessDeniedException {
|
||||
if (!this.userRep.hasRole(roleName)) {
|
||||
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.role"),
|
||||
userRep.getUsername(), roleName);
|
||||
public void assertHasGroup(String groupName) throws AccessDeniedException {
|
||||
if (!this.userRep.hasGroup(groupName)) {
|
||||
String msg = format(getString("Privilege.noprivilege.group"), userRep.getUsername(), groupName);
|
||||
throw new AccessDeniedException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void assertHasRole(String roleName) throws AccessDeniedException {
|
||||
if (!this.userRep.hasRole(roleName)) {
|
||||
String msg = format(getString("Privilege.noprivilege.role"), userRep.getUsername(), roleName);
|
||||
throw new AccessDeniedException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void assertHasAnyGroup(String... groupNames) throws AccessDeniedException {
|
||||
for (String groupName : groupNames) {
|
||||
if (this.userRep.hasGroup(groupName))
|
||||
return;
|
||||
}
|
||||
|
||||
String msg = format(getString("Privilege.noprivilege.group"), userRep.getUsername(),
|
||||
String.join(", ", groupNames));
|
||||
throw new AccessDeniedException(msg);
|
||||
}
|
||||
|
||||
public void assertHasAnyRole(String... roleNames) throws AccessDeniedException {
|
||||
for (String roleName : roleNames) {
|
||||
if (this.userRep.hasRole(roleName))
|
||||
return;
|
||||
}
|
||||
|
||||
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.role"),
|
||||
userRep.getUsername(), String.join(", ", roleNames));
|
||||
String msg = format(getString("Privilege.noprivilege.role"), userRep.getUsername(),
|
||||
String.join(", ", roleNames));
|
||||
throw new AccessDeniedException(msg);
|
||||
}
|
||||
|
||||
public boolean hasAnyGroup(String... groupNames) throws AccessDeniedException {
|
||||
for (String groupName : groupNames) {
|
||||
if (this.userRep.hasGroup(groupName))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasAnyRole(String... roleNames) throws AccessDeniedException {
|
||||
for (String roleName : roleNames) {
|
||||
if (this.userRep.hasRole(roleName))
|
||||
|
@ -123,7 +150,7 @@ public class PrivilegeContext {
|
|||
return false;
|
||||
}
|
||||
|
||||
public IPrivilege getPrivilege(String privilegeName) throws AccessDeniedException {
|
||||
public Privilege getPrivilege(String privilegeName) throws AccessDeniedException {
|
||||
assertHasPrivilege(privilegeName);
|
||||
return this.privileges.get(privilegeName);
|
||||
}
|
||||
|
@ -132,7 +159,7 @@ public class PrivilegeContext {
|
|||
PrivilegePolicy policy = this.policies.get(policyName);
|
||||
if (policy == null) {
|
||||
String msg = "The PrivilegePolicy {0} does not exist on the PrivilegeContext!";
|
||||
throw new PrivilegeException(MessageFormat.format(msg, policyName));
|
||||
throw new PrivilegeException(format(msg, policyName));
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
|
@ -148,15 +175,12 @@ public class PrivilegeContext {
|
|||
*
|
||||
* <p>This method uses the {@link SimpleRestrictable} to verify access</p>
|
||||
*
|
||||
* @param privilegeName
|
||||
* the name of the privilege to verify
|
||||
* @param privilegeValue
|
||||
* the value
|
||||
* @param privilegeName the name of the privilege to verify
|
||||
* @param privilegeValue the value
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
* if the user does not have access
|
||||
* @throws PrivilegeException
|
||||
* if there is an internal error due to wrongly configured privileges or programming errors
|
||||
* @throws AccessDeniedException if the user does not have access
|
||||
* @throws PrivilegeException if there is an internal error due to wrongly configured privileges or programming
|
||||
* errors
|
||||
*/
|
||||
public void validateAction(String privilegeName, String privilegeValue)
|
||||
throws PrivilegeException, AccessDeniedException {
|
||||
|
@ -168,22 +192,20 @@ public class PrivilegeContext {
|
|||
* has the privilege, then this method returns with no exception and void, if the user does not have the privilege,
|
||||
* then a {@link AccessDeniedException} is thrown.
|
||||
*
|
||||
* @param restrictable
|
||||
* the {@link Restrictable} which the user wants to access
|
||||
* @param restrictable the {@link Restrictable} which the user wants to access
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
* if the user does not have access
|
||||
* @throws PrivilegeException
|
||||
* if there is an internal error due to wrongly configured privileges or programming errors
|
||||
* @throws AccessDeniedException if the user does not have access
|
||||
* @throws PrivilegeException if there is an internal error due to wrongly configured privileges or programming
|
||||
* errors
|
||||
*/
|
||||
public void validateAction(Restrictable restrictable) throws PrivilegeException, AccessDeniedException {
|
||||
|
||||
// the privilege for the restrictable
|
||||
String privilegeName = restrictable.getPrivilegeName();
|
||||
IPrivilege privilege = this.privileges.get(privilegeName);
|
||||
Privilege privilege = this.privileges.get(privilegeName);
|
||||
if (privilege == null) {
|
||||
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"),
|
||||
getUsername(), privilegeName, restrictable.getClass().getName(), restrictable.getPrivilegeValue());
|
||||
String msg = format(getString("Privilege.accessdenied.noprivilege"), getUsername(), privilegeName,
|
||||
restrictable.getClass().getName(), restrictable.getPrivilegeValue());
|
||||
throw new AccessDeniedException(msg);
|
||||
}
|
||||
|
||||
|
@ -199,19 +221,18 @@ public class PrivilegeContext {
|
|||
* Validates if the user for this context has the privilege to access to the given {@link Restrictable}. Returning
|
||||
* true if the user has the privilege, and false if not
|
||||
*
|
||||
* @param restrictable
|
||||
* the {@link Restrictable} which the user wants to access
|
||||
* @param restrictable the {@link Restrictable} which the user wants to access
|
||||
*
|
||||
* @return returns true if the user has the privilege, and false if not
|
||||
*
|
||||
* @throws PrivilegeException
|
||||
* if there is an internal error due to wrongly configured privileges or programming errors
|
||||
* @throws PrivilegeException if there is an internal error due to wrongly configured privileges or programming
|
||||
* errors
|
||||
*/
|
||||
public boolean hasPrivilege(Restrictable restrictable) throws PrivilegeException {
|
||||
|
||||
// the privilege for the restrictable
|
||||
String privilegeName = restrictable.getPrivilegeName();
|
||||
IPrivilege privilege = this.privileges.get(privilegeName);
|
||||
Privilege privilege = this.privileges.get(privilegeName);
|
||||
if (privilege == null)
|
||||
return false;
|
||||
|
||||
|
@ -229,15 +250,13 @@ public class PrivilegeContext {
|
|||
*
|
||||
* <p>This method uses the {@link SimpleRestrictable} to verify access</p>
|
||||
*
|
||||
* @param privilegeName
|
||||
* the name of the privilege to verify
|
||||
* @param privilegeValue
|
||||
* the value
|
||||
* @param privilegeName the name of the privilege to verify
|
||||
* @param privilegeValue the value
|
||||
*
|
||||
* @return returns true if the user has the privilege, and false if not
|
||||
*
|
||||
* @throws PrivilegeException
|
||||
* if there is an internal error due to wrongly configured privileges or programming errors
|
||||
* @throws PrivilegeException if there is an internal error due to wrongly configured privileges or programming
|
||||
* errors
|
||||
*/
|
||||
public boolean hasPrivilege(String privilegeName, String privilegeValue) throws PrivilegeException {
|
||||
return hasPrivilege(new SimpleRestrictable(privilegeName, privilegeValue));
|
||||
|
|
|
@ -15,27 +15,26 @@
|
|||
*/
|
||||
package li.strolch.privilege.model;
|
||||
|
||||
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* To keep certain details of the {@link IPrivilege} itself hidden from remote clients and make sure instances are only
|
||||
* To keep certain details of the {@link Privilege} itself hidden from remote clients and make sure instances are only
|
||||
* edited by users with the correct privilege, this representational version is allowed to be viewed by remote clients
|
||||
* and simply wraps all public data from the {@link IPrivilege}
|
||||
* and simply wraps all public data from the {@link Privilege}
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class PrivilegeRep implements Serializable {
|
||||
public class PrivilegeRep {
|
||||
|
||||
private String name;
|
||||
private String policy;
|
||||
|
@ -46,45 +45,34 @@ public class PrivilegeRep implements Serializable {
|
|||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param name
|
||||
* the name of this privilege, which is unique to all privileges known in the {@link PrivilegeHandler}
|
||||
* @param policy
|
||||
* the {@link PrivilegePolicy} configured to evaluate if the privilege is granted
|
||||
* @param allAllowed
|
||||
* a boolean defining if a {@link Role} with this {@link IPrivilege} has unrestricted access to a {@link
|
||||
* Restrictable}
|
||||
* @param denyList
|
||||
* a list of deny rules for this {@link IPrivilege}
|
||||
* @param allowList
|
||||
* a list of allow rules for this {@link IPrivilege}
|
||||
* @param name the name of this privilege, which is unique to all privileges known in the
|
||||
* {@link PrivilegeHandler}
|
||||
* @param policy the {@link PrivilegePolicy} configured to evaluate if the privilege is granted
|
||||
* @param allAllowed a boolean defining if a {@link Role} with this {@link Privilege} has unrestricted access to a
|
||||
* {@link Restrictable}
|
||||
* @param denyList a list of deny rules for this {@link Privilege}
|
||||
* @param allowList a list of allow rules for this {@link Privilege}
|
||||
*/
|
||||
public PrivilegeRep(String name, String policy, boolean allAllowed, Set<String> denyList, Set<String> allowList) {
|
||||
this.name = trimOrEmpty(name);
|
||||
this.policy = trimOrEmpty(policy);
|
||||
this.allAllowed = allAllowed;
|
||||
this.denyList = denyList;
|
||||
this.allowList = allowList;
|
||||
this.denyList = denyList == null ? Set.of() : Set.copyOf(denyList);
|
||||
this.allowList = allowList == null ? Set.of() : Set.copyOf(allowList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that all required fields are set
|
||||
*/
|
||||
public void validate() {
|
||||
|
||||
if (StringHelper.isEmpty(this.name)) {
|
||||
if (isEmpty(this.name))
|
||||
throw new PrivilegeException("No name defined!");
|
||||
}
|
||||
|
||||
if (StringHelper.isEmpty(this.policy)) {
|
||||
throw new PrivilegeException("policy is null!");
|
||||
}
|
||||
|
||||
if (this.denyList == null) {
|
||||
if (isEmpty(this.policy))
|
||||
throw new PrivilegeException("No policy defined!");
|
||||
if (this.denyList == null)
|
||||
throw new PrivilegeException("denyList is null");
|
||||
}
|
||||
if (this.allowList == null) {
|
||||
if (this.allowList == null)
|
||||
throw new PrivilegeException("allowList is null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,8 +83,7 @@ public class PrivilegeRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = trimOrEmpty(name);
|
||||
|
@ -110,8 +97,7 @@ public class PrivilegeRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param policy
|
||||
* the policy to set
|
||||
* @param policy the policy to set
|
||||
*/
|
||||
public void setPolicy(String policy) {
|
||||
this.policy = trimOrEmpty(policy);
|
||||
|
@ -125,8 +111,7 @@ public class PrivilegeRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param allAllowed
|
||||
* the allAllowed to set
|
||||
* @param allAllowed the allAllowed to set
|
||||
*/
|
||||
public void setAllAllowed(boolean allAllowed) {
|
||||
this.allAllowed = allAllowed;
|
||||
|
@ -136,12 +121,11 @@ public class PrivilegeRep implements Serializable {
|
|||
* @return the denyList
|
||||
*/
|
||||
public Set<String> getDenyList() {
|
||||
return this.denyList == null ? new HashSet<>() : this.denyList;
|
||||
return this.denyList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param denyList
|
||||
* the denyList to set
|
||||
* @param denyList the denyList to set
|
||||
*/
|
||||
public void setDenyList(Set<String> denyList) {
|
||||
this.denyList = denyList.stream().map(String::trim).collect(Collectors.toSet());
|
||||
|
@ -151,12 +135,11 @@ public class PrivilegeRep implements Serializable {
|
|||
* @return the allowList
|
||||
*/
|
||||
public Set<String> getAllowList() {
|
||||
return this.allowList == null ? new HashSet<>() : this.allowList;
|
||||
return this.allowList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowList
|
||||
* the allowList to set
|
||||
* @param allowList the allowList to set
|
||||
*/
|
||||
public void setAllowList(Set<String> allowList) {
|
||||
this.allowList = allowList.stream().map(String::trim).collect(Collectors.toSet());
|
||||
|
@ -169,11 +152,8 @@ public class PrivilegeRep implements Serializable {
|
|||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrivilegeRep [name=" + this.name + ", policy=" + this.policy + ", allAllowed=" + this.allAllowed
|
||||
+ ", denyList=" + (this.denyList == null ? "null" : this.denyList.size()) + ", allowList=" + (
|
||||
this.allowList == null ?
|
||||
"null" :
|
||||
this.allowList.size()) + "]";
|
||||
return "PrivilegeRep [name=" + this.name + ", policy=" + this.policy + ", allAllowed=" + this.allAllowed +
|
||||
", denyList=" + this.denyList.size() + ", allowList=" + this.allowList.size() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -193,10 +173,9 @@ public class PrivilegeRep implements Serializable {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PrivilegeRep other = (PrivilegeRep) obj;
|
||||
if (this.name == null) {
|
||||
if (this.name == null)
|
||||
return other.name == null;
|
||||
} else
|
||||
return this.name.equals(other.name);
|
||||
return this.name.equals(other.name);
|
||||
}
|
||||
|
||||
public <T> T accept(PrivilegeElementVisitor<T> visitor) {
|
||||
|
|
|
@ -21,7 +21,7 @@ import li.strolch.privilege.policy.PrivilegePolicy;
|
|||
* <p>
|
||||
* Objects implementing this interface are used to grant/restrict privileges to them. A {@link PrivilegePolicy}
|
||||
* implements the logic on granting/restricting privileges for a {@link Restrictable} and the {@link
|
||||
* #getPrivilegeName()} is used to find the {@link IPrivilege} which has the associated {@link PrivilegePolicy} for
|
||||
* #getPrivilegeName()} is used to find the {@link Privilege} which has the associated {@link PrivilegePolicy} for
|
||||
* evaluating access
|
||||
* </p>
|
||||
*
|
||||
|
@ -30,9 +30,9 @@ import li.strolch.privilege.policy.PrivilegePolicy;
|
|||
public interface Restrictable {
|
||||
|
||||
/**
|
||||
* Returns the name of the {@link IPrivilege} which is to be used to validate privileges against
|
||||
* Returns the name of the {@link Privilege} which is to be used to validate privileges against
|
||||
*
|
||||
* @return the name of the {@link IPrivilege} which is to be used to validate privileges against
|
||||
* @return the name of the {@link Privilege} which is to be used to validate privileges against
|
||||
*/
|
||||
String getPrivilegeName();
|
||||
|
||||
|
|
|
@ -15,16 +15,15 @@
|
|||
*/
|
||||
package li.strolch.privilege.model;
|
||||
|
||||
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
||||
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
|
||||
|
||||
/**
|
||||
* To keep certain details of the {@link Role} itself hidden from remote clients and make sure instances are only edited
|
||||
|
@ -33,7 +32,7 @@ import li.strolch.utils.helper.StringHelper;
|
|||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class RoleRep implements Serializable {
|
||||
public class RoleRep {
|
||||
|
||||
private String name;
|
||||
private List<PrivilegeRep> privileges;
|
||||
|
@ -41,32 +40,28 @@ public class RoleRep implements Serializable {
|
|||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param name
|
||||
* the name of this role
|
||||
* @param privileges
|
||||
* the list of privileges granted to this role
|
||||
* @param name the name of this role
|
||||
* @param privileges the list of privileges granted to this role
|
||||
*/
|
||||
public RoleRep(String name, List<PrivilegeRep> privileges) {
|
||||
this.name = trimOrEmpty(name);
|
||||
this.privileges = privileges;
|
||||
this.privileges = privileges == null ? List.of() : List.copyOf(privileges);
|
||||
}
|
||||
|
||||
/**
|
||||
* validates that all required fields are set
|
||||
*/
|
||||
public void validate() {
|
||||
if (StringHelper.isEmpty(this.name))
|
||||
if (isEmpty(this.name))
|
||||
throw new PrivilegeException("name is null");
|
||||
|
||||
if (this.privileges != null && !this.privileges.isEmpty()) {
|
||||
for (PrivilegeRep privilege : this.privileges) {
|
||||
try {
|
||||
privilege.validate();
|
||||
} catch (Exception e) {
|
||||
String msg = "Privilege {0} is invalid on role {1}";
|
||||
msg = MessageFormat.format(msg, privilege.getName(), this.name);
|
||||
throw new PrivilegeException(msg, e);
|
||||
}
|
||||
for (PrivilegeRep privilege : this.privileges) {
|
||||
try {
|
||||
privilege.validate();
|
||||
} catch (Exception e) {
|
||||
String msg = "Privilege {0} is invalid on role {1}";
|
||||
msg = MessageFormat.format(msg, privilege.getName(), this.name);
|
||||
throw new PrivilegeException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,8 +74,7 @@ public class RoleRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = trimOrEmpty(name);
|
||||
|
@ -92,17 +86,17 @@ public class RoleRep implements Serializable {
|
|||
* @return the privileges assigned to this Role as a list
|
||||
*/
|
||||
public List<PrivilegeRep> getPrivileges() {
|
||||
return this.privileges == null ? new ArrayList<>() : this.privileges;
|
||||
return this.privileges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the privileges on this from a list
|
||||
*
|
||||
* @param privileges
|
||||
* the list of privileges to assign to this role
|
||||
* @param privileges the list of privileges to assign to this role
|
||||
*/
|
||||
public void setPrivileges(List<PrivilegeRep> privileges) {
|
||||
this.privileges = privileges;
|
||||
DBC.PRE.assertNotNull("privileges must not be null!", privileges);
|
||||
this.privileges = List.copyOf(privileges);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,8 +106,7 @@ public class RoleRep implements Serializable {
|
|||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RoleRep [name=" + this.name + ", privilegeMap=" + (this.privileges == null ? "null" : this.privileges)
|
||||
+ "]";
|
||||
return "RoleRep [name=" + this.name + ", privilegeMap=" + this.privileges + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,10 +126,9 @@ public class RoleRep implements Serializable {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RoleRep other = (RoleRep) obj;
|
||||
if (this.name == null) {
|
||||
if (this.name == null)
|
||||
return other.name == null;
|
||||
} else
|
||||
return this.name.equals(other.name);
|
||||
return this.name.equals(other.name);
|
||||
}
|
||||
|
||||
public <T> T accept(PrivilegeElementVisitor<T> visitor) {
|
||||
|
|
|
@ -26,10 +26,8 @@ public class SimpleRestrictable implements Restrictable {
|
|||
private final Object value;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name of the privilege
|
||||
* @param value
|
||||
* the value allowed on the privilege
|
||||
* @param name the name of the privilege
|
||||
* @param value the value allowed on the privilege
|
||||
*/
|
||||
public SimpleRestrictable(String name, Object value) {
|
||||
DBC.PRE.assertNotEmpty("name must not be empty", name);
|
||||
|
|
|
@ -15,20 +15,20 @@
|
|||
*/
|
||||
package li.strolch.privilege.model;
|
||||
|
||||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeConstants;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
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;
|
||||
|
||||
/**
|
||||
* To keep certain details of the {@link User} itself hidden from remote clients and make sure instances are only edited
|
||||
|
@ -37,7 +37,7 @@ import li.strolch.utils.helper.StringHelper;
|
|||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class UserRep implements Serializable {
|
||||
public class UserRep {
|
||||
|
||||
private String userId;
|
||||
private String username;
|
||||
|
@ -45,45 +45,42 @@ public class UserRep implements Serializable {
|
|||
private String lastname;
|
||||
private UserState userState;
|
||||
private Locale locale;
|
||||
private Set<String> groups;
|
||||
private Set<String> roles;
|
||||
private Map<String, String> properties;
|
||||
|
||||
private UserHistory history;
|
||||
|
||||
private boolean readOnly;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param userId
|
||||
* the user's id
|
||||
* @param username
|
||||
* the user's login name
|
||||
* @param firstname
|
||||
* the user's first name
|
||||
* @param lastname
|
||||
* the user's last name
|
||||
* @param userState
|
||||
* the user's {@link UserState}
|
||||
* @param roles
|
||||
* the set of {@link Role}s assigned to this user
|
||||
* @param locale
|
||||
* the user's {@link Locale}
|
||||
* @param propertyMap
|
||||
* a {@link Map} containing string value pairs of properties for this user
|
||||
* @param userId the user's id
|
||||
* @param username the user's login name
|
||||
* @param firstname the user's first name
|
||||
* @param lastname the user's last name
|
||||
* @param userState the user's {@link UserState}
|
||||
* @param groups the set of {@link li.strolch.privilege.model.internal.Group}s assigned to this user
|
||||
* @param roles the set of {@link Role}s assigned to this user
|
||||
* @param locale the user's {@link Locale}
|
||||
* @param propertyMap a {@link Map} containing string value pairs of properties for this user
|
||||
*/
|
||||
public UserRep(String userId, String username, String firstname, String lastname, UserState userState,
|
||||
Set<String> roles, Locale locale, Map<String, String> propertyMap, UserHistory history) {
|
||||
Set<String> groups, Set<String> roles, Locale locale, Map<String, String> propertyMap,
|
||||
UserHistory history) {
|
||||
this.userId = trimOrEmpty(userId);
|
||||
this.username = trimOrEmpty(username);
|
||||
this.firstname = trimOrEmpty(firstname);
|
||||
this.lastname = trimOrEmpty(lastname);
|
||||
this.userState = userState;
|
||||
this.roles = roles == null ? null : roles.stream().map(String::trim).collect(Collectors.toSet());
|
||||
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;
|
||||
|
||||
if (propertyMap != null) {
|
||||
this.properties = new HashMap<>();
|
||||
this.properties = new HashMap<>();
|
||||
if (propertyMap != null)
|
||||
propertyMap.forEach((key, value) -> this.properties.put(key.trim(), value.trim()));
|
||||
}
|
||||
|
||||
this.history = history;
|
||||
}
|
||||
|
@ -97,30 +94,52 @@ public class UserRep implements Serializable {
|
|||
* Validates that all required fields are set
|
||||
*/
|
||||
public void validate() {
|
||||
if (isEmpty(this.userId))
|
||||
throw new PrivilegeException("userId must not be empty");
|
||||
if (isEmpty(this.username))
|
||||
throw new PrivilegeException("username must not be empty");
|
||||
|
||||
if (StringHelper.isEmpty(this.userId))
|
||||
throw new PrivilegeException("userId is null or empty");
|
||||
|
||||
if (StringHelper.isEmpty(this.username))
|
||||
throw new PrivilegeException("username is null or empty");
|
||||
|
||||
// username must be at least 2 characters in length
|
||||
if (this.username.length() < 2) {
|
||||
String msg = MessageFormat.format("The given username ''{0}'' is shorter than 2 characters", this.username);
|
||||
// username must be at least 3 characters in length
|
||||
if (this.username.length() < 3) {
|
||||
String msg = MessageFormat.format("The given username ''{0}'' is shorter than 3 characters", this.username);
|
||||
throw new PrivilegeException(msg);
|
||||
}
|
||||
|
||||
if (this.userState == null)
|
||||
throw new PrivilegeException("userState is null");
|
||||
throw new PrivilegeException("userState may not be null");
|
||||
|
||||
if (StringHelper.isEmpty(this.firstname))
|
||||
throw new PrivilegeException("firstname is null or empty");
|
||||
if (this.userState != UserState.SYSTEM) {
|
||||
if (isEmpty(this.firstname))
|
||||
throw new PrivilegeException("firstname may not be empty for non-system users");
|
||||
if (isEmpty(this.lastname))
|
||||
throw new PrivilegeException("lastname may not be empty for non-system users");
|
||||
}
|
||||
|
||||
if (StringHelper.isEmpty(this.lastname))
|
||||
throw new PrivilegeException("lastname is null or empty");
|
||||
if (this.groups == null)
|
||||
throw new PrivilegeException("groups may not be null");
|
||||
if (this.roles == null)
|
||||
throw new PrivilegeException("roles may not be null");
|
||||
|
||||
if (this.roles == null || this.roles.isEmpty())
|
||||
throw new PrivilegeException("roles is null or empty");
|
||||
if (this.groups.isEmpty() && this.roles.isEmpty())
|
||||
throw new PrivilegeException("User must have at least one group or role assigned!");
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
public UserRep readOnly() {
|
||||
assertNotReadonly();
|
||||
this.readOnly = true;
|
||||
this.groups = Set.copyOf(this.groups);
|
||||
this.roles = Set.copyOf(this.roles);
|
||||
this.properties = Map.copyOf(this.properties);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void assertNotReadonly() {
|
||||
if (this.readOnly)
|
||||
throw new IllegalStateException("User is currently readOnly, to modify get a copy!");
|
||||
}
|
||||
|
||||
public boolean isSystemUser() {
|
||||
|
@ -145,10 +164,10 @@ public class UserRep implements Serializable {
|
|||
/**
|
||||
* Set the userId
|
||||
*
|
||||
* @param userId
|
||||
* to set
|
||||
* @param userId to set
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
assertNotReadonly();
|
||||
this.userId = trimOrEmpty(userId);
|
||||
}
|
||||
|
||||
|
@ -160,10 +179,10 @@ public class UserRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param username
|
||||
* the username to set
|
||||
* @param username the username to set
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
assertNotReadonly();
|
||||
this.username = trimOrEmpty(username);
|
||||
}
|
||||
|
||||
|
@ -175,10 +194,10 @@ public class UserRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param firstname
|
||||
* the firstname to set
|
||||
* @param firstname the firstname to set
|
||||
*/
|
||||
public void setFirstname(String firstname) {
|
||||
assertNotReadonly();
|
||||
this.firstname = trimOrEmpty(firstname);
|
||||
}
|
||||
|
||||
|
@ -190,10 +209,10 @@ public class UserRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param lastname
|
||||
* the lastname to set
|
||||
* @param lastname the lastname to set
|
||||
*/
|
||||
public void setLastname(String lastname) {
|
||||
assertNotReadonly();
|
||||
this.lastname = trimOrEmpty(lastname);
|
||||
}
|
||||
|
||||
|
@ -205,13 +224,27 @@ public class UserRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param userState
|
||||
* the userState to set
|
||||
* @param userState the userState to set
|
||||
*/
|
||||
public void setUserState(UserState userState) {
|
||||
assertNotReadonly();
|
||||
this.userState = userState;
|
||||
}
|
||||
|
||||
public Set<String> getGroups() {
|
||||
return 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());
|
||||
}
|
||||
|
||||
public boolean hasGroup(String group) {
|
||||
return this.groups != null && this.groups.contains(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roles
|
||||
*/
|
||||
|
@ -220,23 +253,16 @@ public class UserRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param roles
|
||||
* the roles to set
|
||||
* @param roles the roles to set
|
||||
*/
|
||||
public void setRoles(Set<String> roles) {
|
||||
this.roles = roles.stream().map(String::trim).collect(Collectors.toSet());
|
||||
DBC.PRE.assertNotNull("roles must not be null!", roles);
|
||||
assertNotReadonly();
|
||||
this.roles = roles.stream().map(String::trim).collect(toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this user has the given role
|
||||
*
|
||||
* @param role
|
||||
* the role to check for
|
||||
*
|
||||
* @return returns true if this user has the given role
|
||||
*/
|
||||
public boolean hasRole(String role) {
|
||||
return this.roles.contains(role);
|
||||
return this.roles != null && this.roles.contains(role);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,10 +273,10 @@ public class UserRep implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param locale
|
||||
* the locale to set
|
||||
* @param locale the locale to set
|
||||
*/
|
||||
public void setLocale(Locale locale) {
|
||||
assertNotReadonly();
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
|
@ -261,17 +287,16 @@ public class UserRep implements Serializable {
|
|||
*/
|
||||
public UserHistory getHistory() {
|
||||
if (this.history == null)
|
||||
return new UserHistory();
|
||||
return UserHistory.EMPTY;
|
||||
return this.history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the the given property exists
|
||||
* Returns true if the given property exists
|
||||
*
|
||||
* @param key
|
||||
* the property key to check
|
||||
* @param key the property key to check
|
||||
*
|
||||
* @return true if the the given property exists
|
||||
* @return true if the given property exists
|
||||
*/
|
||||
public boolean hasProperty(String key) {
|
||||
return this.properties.containsKey(key);
|
||||
|
@ -280,39 +305,41 @@ public class UserRep implements Serializable {
|
|||
/**
|
||||
* Returns the property with the given key
|
||||
*
|
||||
* @param key
|
||||
* the key for which the property is to be returned
|
||||
* @param key the key for which the property is to be returned
|
||||
*
|
||||
* @return the property with the given key, or null if the property is not defined
|
||||
*/
|
||||
public String getProperty(String key) {
|
||||
if (this.properties == null)
|
||||
return null;
|
||||
return this.properties.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the property with the key to the value
|
||||
*
|
||||
* @param key
|
||||
* the key of the property to set
|
||||
* @param value
|
||||
* the value of the property to set
|
||||
* @param key the key of the property to set
|
||||
* @param value the value of the property to set
|
||||
*/
|
||||
public void setProperty(String key, String value) {
|
||||
if (this.properties == null)
|
||||
this.properties = new HashMap<>(1);
|
||||
DBC.PRE.assertNotEmpty("key must not be empty!", key);
|
||||
DBC.PRE.assertNotEmpty("value must not be empty!", value);
|
||||
assertNotReadonly();
|
||||
this.properties.put(key.trim(), value.trim());
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
DBC.PRE.assertNotNull("properties must not be null!", properties);
|
||||
assertNotReadonly();
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Set} of keys of all properties
|
||||
*
|
||||
* @return the {@link Set} of keys of all properties
|
||||
*/
|
||||
public Set<String> getPropertyKeySet() {
|
||||
if (this.properties == null)
|
||||
return new HashSet<>();
|
||||
if (this.readOnly)
|
||||
return this.properties.keySet();
|
||||
return new HashSet<>(this.properties.keySet());
|
||||
}
|
||||
|
||||
|
@ -322,8 +349,8 @@ public class UserRep implements Serializable {
|
|||
* @return the map of properties
|
||||
*/
|
||||
public Map<String, String> getProperties() {
|
||||
if (this.properties == null)
|
||||
return new HashMap<>();
|
||||
if (this.readOnly)
|
||||
return this.properties;
|
||||
return new HashMap<>(this.properties);
|
||||
}
|
||||
|
||||
|
@ -361,9 +388,9 @@ public class UserRep implements Serializable {
|
|||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserRep [userId=" + this.userId + ", username=" + this.username + ", firstname=" + this.firstname
|
||||
+ ", lastname=" + this.lastname + ", userState=" + this.userState + ", locale=" + this.locale
|
||||
+ ", roles=" + this.roles + "]";
|
||||
return "UserRep [userId=" + this.userId + ", username=" + this.username + ", firstname=" + this.firstname +
|
||||
", lastname=" + this.lastname + ", userState=" + this.userState + ", locale=" + this.locale +
|
||||
", roles=" + this.roles + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -391,11 +418,12 @@ public class UserRep implements Serializable {
|
|||
|
||||
public UserRep getCopy() {
|
||||
|
||||
Set<String> roles = new HashSet<>(this.roles);
|
||||
Map<String, String> propertyMap = this.properties == null ? null : new HashMap<>(this.properties);
|
||||
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, roles,
|
||||
this.locale, propertyMap, this.history == null ? new UserHistory() : this.history.getClone());
|
||||
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);
|
||||
}
|
||||
|
||||
public <T> T accept(PrivilegeElementVisitor<T> visitor) {
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package li.strolch.privilege.model.internal;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeConstants;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
|
||||
/**
|
||||
* This entity represents a group with which {@link User Users} can be associated. This allows to put roles and
|
||||
* properties which are always duplicated on users on to the group, and the User is then in the group, eliminating
|
||||
* duplication.
|
||||
*/
|
||||
public record Group(String name, Set<String> roles, Map<String, String> propertyMap) {
|
||||
public Group(String name, Set<String> roles, Map<String, String> propertyMap) {
|
||||
DBC.PRE.assertNotEmpty("name must not be empty", name);
|
||||
DBC.PRE.assertNotNull("roles must not be null", roles);
|
||||
DBC.PRE.assertNotNull("propertyMap must not be null", propertyMap);
|
||||
this.name = name;
|
||||
this.roles = Set.copyOf(roles);
|
||||
this.propertyMap = Map.copyOf(propertyMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this group has the specified role
|
||||
*
|
||||
* @param role the name of the {@link Role} to check for
|
||||
*
|
||||
* @return true if this group has the specified role
|
||||
*/
|
||||
public boolean hasRole(String role) {
|
||||
return this.roles.contains(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property with the given key
|
||||
*
|
||||
* @param key the key for which the property is to be returned
|
||||
*
|
||||
* @return the property with the given key, or null if the property is not defined
|
||||
*/
|
||||
public String getProperty(String key) {
|
||||
return this.propertyMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Set} of keys of all properties
|
||||
*
|
||||
* @return the {@link Set} of keys of all properties
|
||||
*/
|
||||
public Set<String> getPropertyKeySet() {
|
||||
return this.propertyMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of properties
|
||||
*
|
||||
* @return the map of properties
|
||||
*/
|
||||
public Map<String, String> getProperties() {
|
||||
return this.propertyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the property {@link PrivilegeConstants#REALM}
|
||||
*
|
||||
* @return the value of the property {@link PrivilegeConstants#REALM}
|
||||
*/
|
||||
public String getRealm() {
|
||||
return getProperty(REALM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the property {@link PrivilegeConstants#ORGANISATION}
|
||||
*
|
||||
* @return the value of the property {@link PrivilegeConstants#ORGANISATION}
|
||||
*/
|
||||
public String getOrganisation() {
|
||||
return getProperty(ORGANISATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the property {@link PrivilegeConstants#LOCATION}
|
||||
*
|
||||
* @return the value of the property {@link PrivilegeConstants#LOCATION}
|
||||
*/
|
||||
public String getLocation() {
|
||||
return getProperty(LOCATION);
|
||||
}
|
||||
}
|
|
@ -2,48 +2,33 @@ package li.strolch.privilege.model.internal;
|
|||
|
||||
import static li.strolch.utils.helper.StringHelper.*;
|
||||
|
||||
public class PasswordCrypt {
|
||||
public record PasswordCrypt(byte[] password, byte[] salt, String hashAlgorithm, int hashIterations, int hashKeyLength) {
|
||||
|
||||
private final byte[] password;
|
||||
private final byte[] salt;
|
||||
private final String hashAlgorithm;
|
||||
private final int hashIterations;
|
||||
private final int hashKeyLength;
|
||||
|
||||
public PasswordCrypt(byte[] password, byte[] salt) {
|
||||
this.password = password;
|
||||
this.salt = salt;
|
||||
this.hashAlgorithm = null;
|
||||
this.hashIterations = -1;
|
||||
this.hashKeyLength = -1;
|
||||
@Override
|
||||
public String toString() {
|
||||
return buildPasswordString();
|
||||
}
|
||||
|
||||
public PasswordCrypt(byte[] password, byte[] salt, String hashAlgorithm, int hashIterations, int hashKeyLength) {
|
||||
this.password = password;
|
||||
this.salt = salt;
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.hashIterations = hashIterations;
|
||||
this.hashKeyLength = hashKeyLength;
|
||||
public String buildPasswordString() {
|
||||
if (this.password == null || this.salt == null || this.hashAlgorithm == null || this.hashIterations == -1 ||
|
||||
this.hashKeyLength == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return buildPasswordString(this.hashAlgorithm, this.hashIterations, this.hashKeyLength, this.salt,
|
||||
this.password);
|
||||
}
|
||||
|
||||
public byte[] getPassword() {
|
||||
return password;
|
||||
public static String buildPasswordString(String hashAlgorithm, int hashIterations, int hashKeyLength, byte[] salt,
|
||||
byte[] passwordArr) {
|
||||
String algo = hashAlgorithm + "," + hashIterations + "," + hashKeyLength;
|
||||
String hash = toHexString(salt);
|
||||
String password = toHexString(passwordArr);
|
||||
return "$" + algo + "$" + hash + "$" + password;
|
||||
}
|
||||
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public String getHashAlgorithm() {
|
||||
return hashAlgorithm;
|
||||
}
|
||||
|
||||
public int getHashIterations() {
|
||||
return hashIterations;
|
||||
}
|
||||
|
||||
public int getHashKeyLength() {
|
||||
return hashKeyLength;
|
||||
public static PasswordCrypt of(byte[] password, byte[] salt) {
|
||||
return new PasswordCrypt(password, salt, null, -1, -1);
|
||||
}
|
||||
|
||||
public static PasswordCrypt parse(String passwordS, String saltS) {
|
||||
|
@ -55,14 +40,14 @@ public class PasswordCrypt {
|
|||
salt = fromHexString(saltS.trim());
|
||||
|
||||
if (isEmpty(passwordS))
|
||||
return new PasswordCrypt(null, salt);
|
||||
return PasswordCrypt.of(null, salt);
|
||||
|
||||
passwordS = passwordS.trim();
|
||||
|
||||
byte[] password;
|
||||
if (!passwordS.startsWith("$")) {
|
||||
password = fromHexString(passwordS);
|
||||
return new PasswordCrypt(password, salt);
|
||||
return PasswordCrypt.of(password, salt);
|
||||
}
|
||||
|
||||
String[] parts = passwordS.split("\\$");
|
||||
|
@ -86,28 +71,4 @@ public class PasswordCrypt {
|
|||
|
||||
return new PasswordCrypt(password, salt, hashAlgorithm, hashIterations, hashKeyLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return buildPasswordString();
|
||||
}
|
||||
|
||||
public String buildPasswordString() {
|
||||
if (this.password == null || this.salt == null || this.hashAlgorithm == null || this.hashIterations == -1 ||
|
||||
this.hashKeyLength == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return buildPasswordString(getHashAlgorithm(), getHashIterations(), getHashKeyLength(), getSalt(),
|
||||
getPassword());
|
||||
|
||||
}
|
||||
|
||||
public static String buildPasswordString(String hashAlgorithm, int hashIterations, int hashKeyLength, byte[] salt,
|
||||
byte[] passwordArr) {
|
||||
String algo = hashAlgorithm + "," + hashIterations + "," + hashKeyLength;
|
||||
String hash = toHexString(salt);
|
||||
String password = toHexString(passwordArr);
|
||||
return "$" + algo + "$" + hash + "$" + password;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,223 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.privilege.model.internal;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.PrivilegeRep;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@link IPrivilege} is the main model object for Privilege. A {@link Role} has a set of Privileges assigned to it
|
||||
* which defines the privileges a logged in user with that role has. If the {@link IPrivilege} has a {@link
|
||||
* PrivilegePolicy} defined, then that policy will be used for finer granularity and with the deny and allow lists
|
||||
* configured which is used to evaluate if privilege is granted to a {@link Restrictable}
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* {@link IPrivilege}s have allow and deny rules which the configured {@link PrivilegeHandler} uses to
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note: This is an internal object which is not to be serialized or passed to clients, {@link PrivilegeRep}s are used
|
||||
* for that
|
||||
* </p>
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public final class PrivilegeImpl implements IPrivilege {
|
||||
|
||||
private final String name;
|
||||
private final String policy;
|
||||
private final boolean allAllowed;
|
||||
private final Set<String> denyList;
|
||||
private final Set<String> allowList;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param name
|
||||
* the name of this privilege, which is unique to all privileges known in the {@link PrivilegeHandler}
|
||||
* @param policy
|
||||
* the {@link PrivilegePolicy} configured to evaluate if the privilege is granted. If null, then privilege is
|
||||
* granted
|
||||
* @param allAllowed
|
||||
* a boolean defining if a {@link Role} with this {@link PrivilegeImpl} has unrestricted access to a {@link
|
||||
* Restrictable} in which case the deny and allow lists are ignored and can be null
|
||||
* @param denyList
|
||||
* a list of deny rules for this {@link PrivilegeImpl}, can be null if all allowed
|
||||
* @param allowList
|
||||
* a list of allow rules for this {@link PrivilegeImpl}, can be null if all allowed
|
||||
*/
|
||||
public PrivilegeImpl(String name, String policy, boolean allAllowed, Set<String> denyList, Set<String> allowList) {
|
||||
|
||||
if (StringHelper.isEmpty(name)) {
|
||||
throw new PrivilegeException("No name defined!");
|
||||
}
|
||||
if (StringHelper.isEmpty(policy)) {
|
||||
throw new PrivilegeException(
|
||||
MessageFormat.format("Policy may not be empty for Privilege {0}!", name));
|
||||
}
|
||||
if (denyList == null) {
|
||||
throw new PrivilegeException(
|
||||
MessageFormat.format("denyList is null for Privilege {0}!", name));
|
||||
}
|
||||
if (allowList == null) {
|
||||
throw new PrivilegeException(
|
||||
MessageFormat.format("allowList is null for Privilege {0}!", name));
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
this.allAllowed = allAllowed;
|
||||
this.policy = policy;
|
||||
this.denyList = Collections.unmodifiableSet(denyList);
|
||||
this.allowList = Collections.unmodifiableSet(allowList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@link PrivilegeImpl} from the {@link PrivilegeRep}
|
||||
*
|
||||
* @param privilegeRep
|
||||
* the {@link PrivilegeRep} from which to create the {@link PrivilegeImpl}
|
||||
*/
|
||||
public PrivilegeImpl(PrivilegeRep privilegeRep) {
|
||||
this(privilegeRep.getName(), privilegeRep.getPolicy(), privilegeRep.isAllAllowed(), privilegeRep.getDenyList(),
|
||||
privilegeRep.getAllowList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a {@link PrivilegeRep} which is a representation of this object used to serialize and view on clients
|
||||
*/
|
||||
@Override
|
||||
public PrivilegeRep asPrivilegeRep() {
|
||||
return new PrivilegeRep(this.name, this.policy, this.allAllowed, new HashSet<>(this.denyList),
|
||||
new HashSet<>(this.allowList));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the policy
|
||||
*/
|
||||
@Override
|
||||
public String getPolicy() {
|
||||
return this.policy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the allAllowed
|
||||
*/
|
||||
@Override
|
||||
public boolean isAllAllowed() {
|
||||
return this.allAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the allowList
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getAllowList() {
|
||||
return this.allowList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the denyList
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getDenyList() {
|
||||
return this.denyList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if there are values in the allow list
|
||||
*/
|
||||
@Override
|
||||
public boolean hasAllowed() {
|
||||
return !this.allowList.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if the value is in the allow list
|
||||
*/
|
||||
@Override
|
||||
public boolean isAllowed(String value) {
|
||||
return this.allowList.contains(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if there are values in the deny list
|
||||
*/
|
||||
@Override
|
||||
public boolean hasDenied() {
|
||||
return !this.allowList.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the value is in the deny list
|
||||
*/
|
||||
@Override
|
||||
public boolean isDenied(String value) {
|
||||
return this.denyList.contains(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object displaying its concrete type and its values
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Privilege [name=" + this.name + ", policy=" + this.policy + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PrivilegeImpl other = (PrivilegeImpl) obj;
|
||||
if (this.name == null) {
|
||||
return other.name == null;
|
||||
} else
|
||||
return this.name.equals(other.name);
|
||||
}
|
||||
}
|
|
@ -15,14 +15,16 @@
|
|||
*/
|
||||
package li.strolch.privilege.model.internal;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
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 li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.PrivilegeRep;
|
||||
import li.strolch.privilege.model.RoleRep;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -37,57 +39,34 @@ import li.strolch.utils.helper.StringHelper;
|
|||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public final class Role {
|
||||
|
||||
private final String name;
|
||||
private final Map<String, IPrivilege> privilegeMap;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param name
|
||||
* the name of the role
|
||||
* @param privilegeMap
|
||||
* a map of {@link IPrivilege}s granted to this role
|
||||
*/
|
||||
public Role(String name, Map<String, IPrivilege> privilegeMap) {
|
||||
|
||||
if (StringHelper.isEmpty(name)) {
|
||||
throw new PrivilegeException("No name defined!");
|
||||
}
|
||||
if (privilegeMap == null) {
|
||||
throw new PrivilegeException("No privileges defined!");
|
||||
}
|
||||
public record Role(String name, Map<String, Privilege> privilegeMap) {
|
||||
|
||||
public Role(String name, Map<String, Privilege> privilegeMap) {
|
||||
DBC.PRE.assertNotEmpty("name must not be empty", name);
|
||||
DBC.PRE.assertNotNull("privilegeMap must not be null", privilegeMap);
|
||||
this.name = name;
|
||||
this.privilegeMap = Collections.unmodifiableMap(privilegeMap);
|
||||
this.privilegeMap = Map.copyOf(privilegeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct {@link Role} from its representation {@link RoleRep}
|
||||
*
|
||||
* @param roleRep
|
||||
* the representation from which to create the {@link Role}
|
||||
* @param roleRep the representation from which to create the {@link Role}
|
||||
*/
|
||||
public Role(RoleRep roleRep) {
|
||||
|
||||
public static Role of(RoleRep roleRep) {
|
||||
String name = roleRep.getName();
|
||||
if (StringHelper.isEmpty(name)) {
|
||||
if (isEmpty(name))
|
||||
throw new PrivilegeException("No name defined!");
|
||||
}
|
||||
|
||||
if (roleRep.getPrivileges() == null) {
|
||||
if (roleRep.getPrivileges() == null)
|
||||
throw new PrivilegeException("Privileges may not be null!");
|
||||
}
|
||||
|
||||
// build privileges from rep
|
||||
Map<String, IPrivilege> privilegeMap = new HashMap<>(roleRep.getPrivileges().size());
|
||||
Map<String, Privilege> privilegeMap = new HashMap<>(roleRep.getPrivileges().size());
|
||||
for (PrivilegeRep privilege : roleRep.getPrivileges()) {
|
||||
privilegeMap.put(privilege.getName(), new PrivilegeImpl(privilege));
|
||||
privilegeMap.put(privilege.getName(), Privilege.of(privilege));
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
this.privilegeMap = Collections.unmodifiableMap(privilegeMap);
|
||||
return new Role(name, privilegeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,30 +77,29 @@ public final class Role {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Set} of names for the currently stored {@link IPrivilege Privileges}
|
||||
* Returns the {@link Set} of names for the currently stored {@link Privilege Privileges}
|
||||
*
|
||||
* @return the {@link Set} of names for the currently stored {@link IPrivilege Privileges}
|
||||
* @return the {@link Set} of names for the currently stored {@link Privilege Privileges}
|
||||
*/
|
||||
public Set<String> getPrivilegeNames() {
|
||||
return this.privilegeMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link IPrivilege} for the given name, null if it does not exist
|
||||
* Returns the {@link Privilege} for the given name, null if it does not exist
|
||||
*
|
||||
* @return the {@link IPrivilege} for the given name, null if it does not exist
|
||||
* @return the {@link Privilege} for the given name, null if it does not exist
|
||||
*/
|
||||
public IPrivilege getPrivilege(String name) {
|
||||
public Privilege getPrivilege(String name) {
|
||||
return this.privilegeMap.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this {@link Role} has the {@link IPrivilege} with the given name
|
||||
* Determines if this {@link Role} has the {@link Privilege} with the given name
|
||||
*
|
||||
* @param name
|
||||
* the name of the {@link IPrivilege}
|
||||
* @param name the name of the {@link Privilege}
|
||||
*
|
||||
* @return true if this {@link Role} has the {@link IPrivilege} with the given name
|
||||
* @return true if this {@link Role} has the {@link Privilege} with the given name
|
||||
*/
|
||||
public boolean hasPrivilege(String name) {
|
||||
return this.privilegeMap.containsKey(name);
|
||||
|
@ -132,7 +110,7 @@ public final class Role {
|
|||
*/
|
||||
public RoleRep asRoleRep() {
|
||||
List<PrivilegeRep> privileges = new ArrayList<>();
|
||||
for (Entry<String, IPrivilege> entry : this.privilegeMap.entrySet()) {
|
||||
for (Entry<String, Privilege> entry : this.privilegeMap.entrySet()) {
|
||||
privileges.add(entry.getValue().asPrivilegeRep());
|
||||
}
|
||||
return new RoleRep(this.name, privileges);
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
package li.strolch.privilege.model.internal;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeConstants;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.UserRep;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
|
||||
|
@ -34,59 +36,36 @@ import static li.strolch.privilege.base.PrivilegeConstants.*;
|
|||
* that
|
||||
* </p>
|
||||
*
|
||||
* @param userId the user's id
|
||||
* @param username the user's login name
|
||||
* @param passwordCrypt the {@link PasswordCrypt} containing user's password information
|
||||
* @param firstname the user's first name
|
||||
* @param lastname the user's lastname
|
||||
* @param userState the user's {@link UserState}
|
||||
* @param groups the set of {@link Group}s assigned to this user
|
||||
* @param roles the set of {@link Role}s assigned to this user
|
||||
* @param locale the user's {@link Locale}
|
||||
* @param propertyMap a {@link Map} containing string value pairs of properties for this user
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public final class User {
|
||||
public record User(String userId, String username, PasswordCrypt passwordCrypt, String firstname, String lastname,
|
||||
UserState userState, Set<String> groups, Set<String> roles, Locale locale,
|
||||
Map<String, String> propertyMap, boolean passwordChangeRequested, UserHistory history) {
|
||||
|
||||
private final String userId;
|
||||
|
||||
private final String username;
|
||||
private final PasswordCrypt passwordCrypt;
|
||||
|
||||
private final String firstname;
|
||||
private final String lastname;
|
||||
|
||||
private final Set<String> roles;
|
||||
|
||||
private final UserState userState;
|
||||
private final Map<String, String> propertyMap;
|
||||
private final Locale locale;
|
||||
|
||||
private final boolean passwordChangeRequested;
|
||||
private final UserHistory history;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param userId the user's id
|
||||
* @param username the user's login name
|
||||
* @param passwordCrypt the {@link PasswordCrypt} containing user's password information
|
||||
* @param firstname the user's first name
|
||||
* @param lastname the user's lastname
|
||||
* @param userState the user's {@link UserState}
|
||||
* @param roles the set of {@link Role}s assigned to this user
|
||||
* @param locale the user's {@link Locale}
|
||||
* @param propertyMap a {@link Map} containing string value pairs of properties for this user
|
||||
*/
|
||||
public User(String userId, String username, PasswordCrypt passwordCrypt, String firstname, String lastname,
|
||||
UserState userState, Set<String> roles, Locale locale, Map<String, String> propertyMap,
|
||||
UserState userState, Set<String> groups, Set<String> roles, Locale locale, Map<String, String> propertyMap,
|
||||
boolean passwordChangeRequested, UserHistory history) {
|
||||
|
||||
if (StringHelper.isEmpty(userId))
|
||||
throw new PrivilegeException("No UserId defined!");
|
||||
if (userState == null)
|
||||
throw new PrivilegeException("No userState defined!");
|
||||
if (StringHelper.isEmpty(username))
|
||||
throw new PrivilegeException("No username defined!");
|
||||
if (userState != UserState.SYSTEM) {
|
||||
if (StringHelper.isEmpty(lastname))
|
||||
throw new PrivilegeException("No lastname defined!");
|
||||
if (StringHelper.isEmpty(firstname))
|
||||
throw new PrivilegeException("No firstname defined!");
|
||||
}
|
||||
DBC.PRE.assertNotEmpty("userId must not be empty", userId);
|
||||
DBC.PRE.assertNotEmpty("username must not be empty", username);
|
||||
DBC.PRE.assertNotNull("userState must not be null", userState);
|
||||
DBC.PRE.assertNotNull("history must not be null", history);
|
||||
|
||||
if (history == null)
|
||||
throw new PrivilegeException("History must not be null!");
|
||||
if (userState != UserState.SYSTEM) {
|
||||
DBC.PRE.assertNotEmpty("lastname must not be empty when not system user!", username);
|
||||
DBC.PRE.assertNotEmpty("firstname must not be empty when not system user!", firstname);
|
||||
}
|
||||
|
||||
// passwordCrypt may be null, meaning not able to login
|
||||
// roles may be null, meaning not able to login and must be added later
|
||||
|
@ -103,35 +82,19 @@ public final class User {
|
|||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
|
||||
if (roles == null)
|
||||
this.roles = Collections.emptySet();
|
||||
else
|
||||
this.roles = Set.copyOf(roles);
|
||||
|
||||
if (locale == null)
|
||||
this.locale = Locale.getDefault();
|
||||
else
|
||||
this.locale = locale;
|
||||
|
||||
if (propertyMap == null)
|
||||
this.propertyMap = Collections.emptyMap();
|
||||
else
|
||||
this.propertyMap = Map.copyOf(propertyMap);
|
||||
this.groups = groups == null ? Set.of() : Set.copyOf(groups);
|
||||
this.roles = roles == null ? Set.of() : Set.copyOf(roles);
|
||||
this.locale = locale == null ? Locale.getDefault() : locale;
|
||||
this.propertyMap = propertyMap == null ? Map.of() : Map.copyOf(propertyMap);
|
||||
|
||||
this.passwordChangeRequested = passwordChangeRequested;
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userId
|
||||
*/
|
||||
public String getUserId() {
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the username
|
||||
*/
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
@ -145,48 +108,34 @@ public final class User {
|
|||
return this.passwordCrypt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the first name
|
||||
*/
|
||||
public String getFirstname() {
|
||||
return this.firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last name
|
||||
*/
|
||||
public String getLastname() {
|
||||
return this.lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userState
|
||||
*/
|
||||
public UserState getUserState() {
|
||||
return this.userState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roles
|
||||
*/
|
||||
public Set<String> getGroups() {
|
||||
return this.groups;
|
||||
}
|
||||
|
||||
public Set<String> getRoles() {
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this user has the specified role
|
||||
*
|
||||
* @param role the name of the {@link Role} to check for
|
||||
*
|
||||
* @return true if the this user has the specified role
|
||||
*/
|
||||
public boolean hasGroup(String group) {
|
||||
return this.groups.contains(group);
|
||||
}
|
||||
|
||||
public boolean hasRole(String role) {
|
||||
return this.roles.contains(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the locale
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return this.locale;
|
||||
}
|
||||
|
@ -195,11 +144,6 @@ public final class User {
|
|||
return this.passwordChangeRequested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the History object
|
||||
*
|
||||
* @return the History object
|
||||
*/
|
||||
public UserHistory getHistory() {
|
||||
return this.history;
|
||||
}
|
||||
|
@ -282,8 +226,8 @@ public final class User {
|
|||
* @return a {@link UserRep} which is a representation of this object used to serialize and view on clients
|
||||
*/
|
||||
public UserRep asUserRep() {
|
||||
return new UserRep(this.userId, this.username, this.firstname, this.lastname, this.userState,
|
||||
new HashSet<>(this.roles), this.locale, new HashMap<>(this.propertyMap), this.history.getClone());
|
||||
return new UserRep(this.userId, this.username, this.firstname, this.lastname, this.userState, this.groups,
|
||||
this.roles, this.locale, new HashMap<>(this.propertyMap), this.history);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -315,9 +259,13 @@ public final class User {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
User other = (User) obj;
|
||||
if (this.userId == null) {
|
||||
if (this.userId == null)
|
||||
return other.userId == null;
|
||||
} else
|
||||
return this.userId.equals(other.userId);
|
||||
return this.userId.equals(other.userId);
|
||||
}
|
||||
|
||||
public User withHistory(UserHistory history) {
|
||||
return new User(this.userId, this.username, this.passwordCrypt, this.firstname, this.lastname, this.userState,
|
||||
this.groups, this.roles, this.locale, this.propertyMap, this.passwordChangeRequested, history);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package li.strolch.privilege.model.internal;
|
||||
|
||||
import li.strolch.privilege.model.Usage;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import li.strolch.privilege.model.Usage;
|
||||
|
||||
public class UserChallenge {
|
||||
public final class UserChallenge {
|
||||
private final User user;
|
||||
private final String challenge;
|
||||
private final String source;
|
||||
|
@ -13,6 +14,10 @@ public class UserChallenge {
|
|||
private boolean fulfilled;
|
||||
|
||||
public UserChallenge(Usage usage, User user, String challenge, String source) {
|
||||
DBC.PRE.assertNotNull("usage may not be null", usage);
|
||||
DBC.PRE.assertNotNull("user may not be null", user);
|
||||
DBC.PRE.assertNotNull("challenge may not be empty", challenge);
|
||||
DBC.PRE.assertNotNull("source may not be empty", source);
|
||||
this.usage = usage;
|
||||
this.user = user;
|
||||
this.challenge = challenge;
|
||||
|
|
|
@ -1,32 +1,20 @@
|
|||
package li.strolch.privilege.model.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import li.strolch.utils.iso8601.ISO8601;
|
||||
import static li.strolch.utils.iso8601.ISO8601.EMPTY_VALUE_ZONED_DATE;
|
||||
|
||||
public class UserHistory implements Serializable {
|
||||
public record UserHistory(ZonedDateTime firstLogin, ZonedDateTime lastLogin, ZonedDateTime lastPasswordChange) {
|
||||
|
||||
private ZonedDateTime firstLogin;
|
||||
private ZonedDateTime lastLogin;
|
||||
private ZonedDateTime lastPasswordChange;
|
||||
|
||||
public UserHistory() {
|
||||
this.firstLogin = ISO8601.EMPTY_VALUE_ZONED_DATE;
|
||||
this.lastLogin = ISO8601.EMPTY_VALUE_ZONED_DATE;
|
||||
this.lastPasswordChange = ISO8601.EMPTY_VALUE_ZONED_DATE;
|
||||
}
|
||||
public static final UserHistory EMPTY = new UserHistory(EMPTY_VALUE_ZONED_DATE, EMPTY_VALUE_ZONED_DATE,
|
||||
EMPTY_VALUE_ZONED_DATE);
|
||||
|
||||
public ZonedDateTime getFirstLogin() {
|
||||
return this.firstLogin;
|
||||
}
|
||||
|
||||
public boolean isFirstLoginEmpty() {
|
||||
return this.firstLogin.equals(ISO8601.EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public void setFirstLogin(ZonedDateTime firstLogin) {
|
||||
this.firstLogin = firstLogin;
|
||||
return this.firstLogin.equals(EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public ZonedDateTime getLastLogin() {
|
||||
|
@ -34,11 +22,7 @@ public class UserHistory implements Serializable {
|
|||
}
|
||||
|
||||
public boolean isLastLoginEmpty() {
|
||||
return this.lastLogin.equals(ISO8601.EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public void setLastLogin(ZonedDateTime lastLogin) {
|
||||
this.lastLogin = lastLogin;
|
||||
return this.lastLogin.equals(EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public ZonedDateTime getLastPasswordChange() {
|
||||
|
@ -46,22 +30,26 @@ public class UserHistory implements Serializable {
|
|||
}
|
||||
|
||||
public boolean isLastPasswordChangeEmpty() {
|
||||
return this.lastPasswordChange.equals(ISO8601.EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public void setLastPasswordChange(ZonedDateTime lastPasswordChange) {
|
||||
this.lastPasswordChange = lastPasswordChange;
|
||||
return this.lastPasswordChange.equals(EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return isFirstLoginEmpty() && isLastLoginEmpty() && isLastPasswordChangeEmpty();
|
||||
}
|
||||
|
||||
public UserHistory getClone() {
|
||||
UserHistory clone = new UserHistory();
|
||||
clone.firstLogin = this.firstLogin;
|
||||
clone.lastLogin = this.lastLogin;
|
||||
clone.lastPasswordChange = this.lastPasswordChange;
|
||||
return clone;
|
||||
public UserHistory withFirstLogin(ZonedDateTime firstLogin) {
|
||||
return new UserHistory(firstLogin, this.lastLogin, lastPasswordChange);
|
||||
}
|
||||
|
||||
public UserHistory withLastLogin(ZonedDateTime lastLogin) {
|
||||
return new UserHistory(this.firstLogin, lastLogin, this.lastPasswordChange);
|
||||
}
|
||||
|
||||
public UserHistory withLogin(ZonedDateTime lastLogin) {
|
||||
return new UserHistory(isFirstLoginEmpty() ? lastLogin : this.firstLogin, lastLogin, this.lastPasswordChange);
|
||||
}
|
||||
|
||||
public UserHistory withLastPasswordChange(ZonedDateTime lastPasswordChange) {
|
||||
return new UserHistory(this.firstLogin, this.lastLogin, lastPasswordChange);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.text.MessageFormat;
|
|||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
|
@ -38,10 +38,10 @@ public class DefaultPrivilege implements PrivilegePolicy {
|
|||
/**
|
||||
* The value of {@link Restrictable#getPrivilegeValue()} is used to check if the {@link Role} has this privilege
|
||||
*
|
||||
* @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, IPrivilege, Restrictable)
|
||||
* @see li.strolch.privilege.policy.PrivilegePolicy#validateAction(PrivilegeContext, Privilege, Restrictable)
|
||||
*/
|
||||
@Override
|
||||
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public void validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException {
|
||||
|
||||
String privilegeValue = validatePrivilegeValue(privilege, restrictable);
|
||||
|
@ -54,7 +54,7 @@ public class DefaultPrivilege implements PrivilegePolicy {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable) {
|
||||
|
||||
String privilegeValue = validatePrivilegeValue(privilege, restrictable);
|
||||
|
||||
|
@ -65,7 +65,7 @@ public class DefaultPrivilege implements PrivilegePolicy {
|
|||
return checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue, false);
|
||||
}
|
||||
|
||||
private String validatePrivilegeValue(IPrivilege privilege, Restrictable restrictable) {
|
||||
private String validatePrivilegeValue(Privilege privilege, Restrictable restrictable) {
|
||||
PrivilegePolicyHelper.preValidate(privilege, restrictable);
|
||||
|
||||
// get the value on which the action is to be performed
|
||||
|
|
|
@ -17,7 +17,7 @@ package li.strolch.privilege.policy;
|
|||
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
|
@ -26,7 +26,7 @@ import li.strolch.privilege.model.internal.User;
|
|||
/**
|
||||
* <p>
|
||||
* {@link PrivilegePolicy} implements logic to determine if a {@link User} which has the given {@link Role} and the
|
||||
* given {@link IPrivilege} has access to the given {@link Restrictable}
|
||||
* given {@link Privilege} has access to the given {@link Restrictable}
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
|
@ -38,29 +38,29 @@ import li.strolch.privilege.model.internal.User;
|
|||
public interface PrivilegePolicy {
|
||||
|
||||
/**
|
||||
* Checks if the given {@link Role} and the given {@link IPrivilege} has access to the given {@link Restrictable}
|
||||
* Checks if the given {@link Role} and the given {@link Privilege} has access to the given {@link Restrictable}
|
||||
*
|
||||
* @param context
|
||||
* the privilege context
|
||||
* @param privilege
|
||||
* the {@link IPrivilege} containing the permissions
|
||||
* the {@link Privilege} containing the permissions
|
||||
* @param restrictable
|
||||
* the {@link Restrictable} to which the user wants access
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
* if action not allowed
|
||||
*/
|
||||
void validateAction(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable)
|
||||
void validateAction(PrivilegeContext context, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException;
|
||||
|
||||
/**
|
||||
* Returns true if the given {@link Role} and the given {@link IPrivilege} has access to the given {@link
|
||||
* Returns true if the given {@link Role} and the given {@link Privilege} has access to the given {@link
|
||||
* Restrictable}
|
||||
*
|
||||
* @param context
|
||||
* the privilege context
|
||||
* @param privilege
|
||||
* the {@link IPrivilege} containing the permissions
|
||||
* the {@link Privilege} containing the permissions
|
||||
* @param restrictable
|
||||
* the {@link Restrictable} to which the user wants access
|
||||
*
|
||||
|
@ -69,6 +69,6 @@ public interface PrivilegePolicy {
|
|||
* @throws AccessDeniedException
|
||||
* if something goes wrong with the validate
|
||||
*/
|
||||
boolean hasPrivilege(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable)
|
||||
boolean hasPrivilege(PrivilegeContext context, Privilege privilege, Restrictable restrictable)
|
||||
throws PrivilegeException;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.text.MessageFormat;
|
|||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
|
@ -34,7 +34,7 @@ public class PrivilegePolicyHelper {
|
|||
* Validates the given values and returns the privilege name
|
||||
*
|
||||
* @param privilege
|
||||
* the {@link IPrivilege}
|
||||
* the {@link Privilege}
|
||||
* @param restrictable
|
||||
* the {@link Restrictable}
|
||||
*
|
||||
|
@ -43,7 +43,7 @@ public class PrivilegePolicyHelper {
|
|||
* @throws PrivilegeException
|
||||
* if something is wrong
|
||||
*/
|
||||
public static String preValidate(IPrivilege privilege, Restrictable restrictable) throws PrivilegeException {
|
||||
public static String preValidate(Privilege privilege, Restrictable restrictable) throws PrivilegeException {
|
||||
if (privilege == null)
|
||||
throw new PrivilegeException(PrivilegeMessages.getString("Privilege.privilegeNull"));
|
||||
if (restrictable == null)
|
||||
|
@ -88,7 +88,7 @@ public class PrivilegePolicyHelper {
|
|||
* @throws AccessDeniedException
|
||||
* if access is denied
|
||||
*/
|
||||
public static boolean checkByAllowDenyValues(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
public static boolean checkByAllowDenyValues(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
String privilegeValue, boolean assertHasPrivilege) throws AccessDeniedException {
|
||||
|
||||
// first check values not allowed
|
||||
|
@ -102,7 +102,7 @@ public class PrivilegePolicyHelper {
|
|||
return handleAccessDenied(ctx, privilege, restrictable, privilegeValue, assertHasPrivilege);
|
||||
}
|
||||
|
||||
private static boolean handleAccessDenied(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
private static boolean handleAccessDenied(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
String privilegeValue, boolean assertHasPrivilege) {
|
||||
|
||||
if (assertHasPrivilege) {
|
||||
|
|
|
@ -24,7 +24,7 @@ import li.strolch.privilege.base.AccessDeniedException;
|
|||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
|
@ -42,18 +42,18 @@ import li.strolch.utils.dbc.DBC;
|
|||
public class RoleAccessPrivilege implements PrivilegePolicy {
|
||||
|
||||
@Override
|
||||
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public void validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException {
|
||||
validateAction(ctx, privilege, restrictable, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws PrivilegeException {
|
||||
return validateAction(ctx, privilege, restrictable, false);
|
||||
}
|
||||
|
||||
private boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
private boolean validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
boolean assertHasPrivilege) throws AccessDeniedException {
|
||||
|
||||
String privilegeName = preValidate(privilege, restrictable);
|
||||
|
|
|
@ -24,7 +24,7 @@ import li.strolch.privilege.base.AccessDeniedException;
|
|||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
|
@ -41,18 +41,18 @@ import li.strolch.utils.dbc.DBC;
|
|||
public class UserAccessPrivilege implements PrivilegePolicy {
|
||||
|
||||
@Override
|
||||
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public void validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException {
|
||||
validateAction(ctx, privilege, restrictable, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws PrivilegeException {
|
||||
return validateAction(ctx, privilege, restrictable, false);
|
||||
}
|
||||
|
||||
protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
protected boolean validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
boolean assertHasPrivilege) throws AccessDeniedException {
|
||||
|
||||
String privilegeName = preValidate(privilege, restrictable);
|
||||
|
|
|
@ -28,7 +28,7 @@ import li.strolch.privilege.base.AccessDeniedException;
|
|||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
|
@ -43,13 +43,13 @@ import li.strolch.utils.dbc.DBC;
|
|||
public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege {
|
||||
|
||||
@Override
|
||||
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public void validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException {
|
||||
validateAction(ctx, privilege, restrictable, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws PrivilegeException {
|
||||
return validateAction(ctx, privilege, restrictable, false);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
protected boolean validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
boolean assertHasPrivilege) throws AccessDeniedException {
|
||||
|
||||
String privilegeName = preValidate(privilege, restrictable);
|
||||
|
|
|
@ -24,7 +24,7 @@ import li.strolch.privilege.base.AccessDeniedException;
|
|||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
|
||||
|
@ -44,18 +44,18 @@ import li.strolch.privilege.model.Restrictable;
|
|||
public class UsernameFromCertificatePrivilege implements PrivilegePolicy {
|
||||
|
||||
@Override
|
||||
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public void validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException {
|
||||
validateAction(ctx, privilege, restrictable, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws PrivilegeException {
|
||||
return validateAction(ctx, privilege, restrictable, false);
|
||||
}
|
||||
|
||||
protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
protected boolean validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
boolean assertHasPrivilege) throws AccessDeniedException {
|
||||
|
||||
preValidate(privilege, restrictable);
|
||||
|
|
|
@ -28,7 +28,7 @@ import li.strolch.privilege.base.AccessDeniedException;
|
|||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.i18n.PrivilegeMessages;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Restrictable;
|
||||
|
||||
|
@ -48,19 +48,19 @@ import li.strolch.privilege.model.Restrictable;
|
|||
public class UsernameFromCertificateWithSameOrganisationPrivilege extends UsernameFromCertificatePrivilege {
|
||||
|
||||
@Override
|
||||
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public void validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws AccessDeniedException {
|
||||
validateAction(ctx, privilege, restrictable, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable)
|
||||
public boolean hasPrivilege(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable)
|
||||
throws PrivilegeException {
|
||||
return validateAction(ctx, privilege, restrictable, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||
protected boolean validateAction(PrivilegeContext ctx, Privilege privilege, Restrictable restrictable,
|
||||
boolean assertHasPrivilege) throws AccessDeniedException {
|
||||
|
||||
preValidate(privilege, restrictable);
|
||||
|
|
|
@ -55,19 +55,19 @@ public class CertificateStubsSaxReader extends DefaultHandler {
|
|||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
|
||||
switch (qName) {
|
||||
case XML_ROOT_CERTIFICATES -> {
|
||||
case ROOT_CERTIFICATES -> {
|
||||
}
|
||||
case XML_CERTIFICATE -> {
|
||||
case CERTIFICATE -> {
|
||||
CertificateStub stub = new CertificateStub();
|
||||
stub.usage = Usage.valueOf(attributes.getValue(XML_ATTR_USAGE).trim());
|
||||
stub.sessionId = attributes.getValue(XML_ATTR_SESSION_ID).trim();
|
||||
stub.username = attributes.getValue(XML_ATTR_USERNAME).trim();
|
||||
stub.authToken = attributes.getValue(XML_ATTR_AUTH_TOKEN).trim();
|
||||
stub.source = attributes.getValue(XML_ATTR_SOURCE).trim();
|
||||
stub.locale = Locale.forLanguageTag(attributes.getValue(XML_ATTR_LOCALE).trim());
|
||||
stub.loginTime = ISO8601.parseToZdt(attributes.getValue(XML_ATTR_LOGIN_TIME).trim());
|
||||
stub.lastAccess = ISO8601.parseToZdt(attributes.getValue(XML_ATTR_LAST_ACCESS).trim());
|
||||
stub.keepAlive = Boolean.parseBoolean(attributes.getValue(XML_ATTR_KEEP_ALIVE).trim());
|
||||
stub.usage = Usage.valueOf(attributes.getValue(ATTR_USAGE).trim());
|
||||
stub.sessionId = attributes.getValue(ATTR_SESSION_ID).trim();
|
||||
stub.username = attributes.getValue(ATTR_USERNAME).trim();
|
||||
stub.authToken = attributes.getValue(ATTR_AUTH_TOKEN).trim();
|
||||
stub.source = attributes.getValue(ATTR_SOURCE).trim();
|
||||
stub.locale = Locale.forLanguageTag(attributes.getValue(ATTR_LOCALE).trim());
|
||||
stub.loginTime = ISO8601.parseToZdt(attributes.getValue(ATTR_LOGIN_TIME).trim());
|
||||
stub.lastAccess = ISO8601.parseToZdt(attributes.getValue(ATTR_LAST_ACCESS).trim());
|
||||
stub.keepAlive = Boolean.parseBoolean(attributes.getValue(ATTR_KEEP_ALIVE).trim());
|
||||
DBC.INTERIM.assertNotEmpty("sessionId missing on sessions data!", stub.sessionId);
|
||||
DBC.INTERIM.assertNotEmpty("username missing on sessions data!", stub.username);
|
||||
DBC.INTERIM.assertNotEmpty("authToken missing on sessions data!", stub.authToken);
|
||||
|
|
|
@ -50,41 +50,41 @@ public class CertificateStubsSaxWriter {
|
|||
Writer ioWriter = new OutputStreamWriter(this.outputStream, StandardCharsets.UTF_8);
|
||||
|
||||
IndentingXMLStreamWriter xmlWriter = openXmlStreamWriterDocument(ioWriter);
|
||||
xmlWriter.writeStartElement(XML_ROOT_CERTIFICATES);
|
||||
xmlWriter.writeStartElement(ROOT_CERTIFICATES);
|
||||
|
||||
List<Certificate> certificates = new ArrayList<>(this.certificates);
|
||||
certificates.sort(comparing(Certificate::getSessionId));
|
||||
for (Certificate cert : certificates) {
|
||||
|
||||
// create the certificate element
|
||||
xmlWriter.writeStartElement(XML_CERTIFICATE);
|
||||
xmlWriter.writeStartElement(CERTIFICATE);
|
||||
|
||||
// sessionId;
|
||||
xmlWriter.writeAttribute(XML_ATTR_SESSION_ID, cert.getSessionId());
|
||||
xmlWriter.writeAttribute(ATTR_SESSION_ID, cert.getSessionId());
|
||||
|
||||
// usage;
|
||||
xmlWriter.writeAttribute(XML_ATTR_USAGE, cert.getUsage().name());
|
||||
xmlWriter.writeAttribute(ATTR_USAGE, cert.getUsage().name());
|
||||
|
||||
// username;
|
||||
xmlWriter.writeAttribute(XML_ATTR_USERNAME, cert.getUsername());
|
||||
xmlWriter.writeAttribute(ATTR_USERNAME, cert.getUsername());
|
||||
|
||||
// authToken;
|
||||
xmlWriter.writeAttribute(XML_ATTR_AUTH_TOKEN, cert.getAuthToken());
|
||||
xmlWriter.writeAttribute(ATTR_AUTH_TOKEN, cert.getAuthToken());
|
||||
|
||||
// source;
|
||||
xmlWriter.writeAttribute(XML_ATTR_SOURCE, cert.getSource());
|
||||
xmlWriter.writeAttribute(ATTR_SOURCE, cert.getSource());
|
||||
|
||||
// locale;
|
||||
xmlWriter.writeAttribute(XML_ATTR_LOCALE, cert.getLocale().toLanguageTag());
|
||||
xmlWriter.writeAttribute(ATTR_LOCALE, cert.getLocale().toLanguageTag());
|
||||
|
||||
// loginTime;
|
||||
xmlWriter.writeAttribute(XML_ATTR_LOGIN_TIME, ISO8601.toString(cert.getLoginTime()));
|
||||
xmlWriter.writeAttribute(ATTR_LOGIN_TIME, ISO8601.toString(cert.getLoginTime()));
|
||||
|
||||
// lastAccess;
|
||||
xmlWriter.writeAttribute(XML_ATTR_LAST_ACCESS, ISO8601.toString(cert.getLastAccess()));
|
||||
xmlWriter.writeAttribute(ATTR_LAST_ACCESS, ISO8601.toString(cert.getLastAccess()));
|
||||
|
||||
// keepAlive;
|
||||
xmlWriter.writeAttribute(XML_ATTR_KEEP_ALIVE, String.valueOf(cert.isKeepAlive()));
|
||||
xmlWriter.writeAttribute(ATTR_KEEP_ALIVE, String.valueOf(cert.isKeepAlive()));
|
||||
}
|
||||
|
||||
// and now end
|
||||
|
|
|
@ -47,9 +47,9 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
|||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
|
||||
switch (qName) {
|
||||
case XML_CONTAINER -> this.buildersStack.push(new ContainerParser());
|
||||
case XML_PARAMETERS -> this.buildersStack.push(new ParametersParser());
|
||||
case XML_POLICIES -> this.buildersStack.push(new PoliciesParser());
|
||||
case CONTAINER -> this.buildersStack.push(new ContainerParser());
|
||||
case PARAMETERS -> this.buildersStack.push(new ParametersParser());
|
||||
case POLICIES -> this.buildersStack.push(new PoliciesParser());
|
||||
default -> {
|
||||
// nothing to do, probably handle on stack
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
|||
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||
|
||||
ElementParser elementParser = switch (qName) {
|
||||
case XML_CONTAINER, XML_PARAMETERS, XML_POLICIES -> this.buildersStack.pop();
|
||||
case CONTAINER, PARAMETERS, POLICIES -> this.buildersStack.pop();
|
||||
default -> null;
|
||||
};
|
||||
|
||||
|
@ -88,35 +88,35 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
|||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
|
||||
switch (qName) {
|
||||
case XML_CONTAINER -> this.currentElement = qName;
|
||||
case XML_HANDLER_PRIVILEGE -> {
|
||||
case CONTAINER -> this.currentElement = qName;
|
||||
case HANDLER_PRIVILEGE -> {
|
||||
this.currentElement = qName;
|
||||
String className = attributes.getValue(XML_ATTR_CLASS).trim();
|
||||
String className = attributes.getValue(ATTR_CLASS).trim();
|
||||
getContainerModel().setPrivilegeHandlerClassName(className);
|
||||
}
|
||||
case XML_HANDLER_ENCRYPTION -> {
|
||||
case HANDLER_ENCRYPTION -> {
|
||||
this.currentElement = qName;
|
||||
String className = attributes.getValue(XML_ATTR_CLASS).trim();
|
||||
String className = attributes.getValue(ATTR_CLASS).trim();
|
||||
getContainerModel().setEncryptionHandlerClassName(className);
|
||||
}
|
||||
case XML_HANDLER_PASSWORD_STRENGTH -> {
|
||||
case HANDLER_PASSWORD_STRENGTH -> {
|
||||
this.currentElement = qName;
|
||||
String className = attributes.getValue(XML_ATTR_CLASS).trim();
|
||||
String className = attributes.getValue(ATTR_CLASS).trim();
|
||||
getContainerModel().setPasswordStrengthHandlerClassName(className);
|
||||
}
|
||||
case XML_HANDLER_PERSISTENCE -> {
|
||||
case HANDLER_PERSISTENCE -> {
|
||||
this.currentElement = qName;
|
||||
String className = attributes.getValue(XML_ATTR_CLASS).trim();
|
||||
String className = attributes.getValue(ATTR_CLASS).trim();
|
||||
getContainerModel().setPersistenceHandlerClassName(className);
|
||||
}
|
||||
case XML_HANDLER_USER_CHALLENGE -> {
|
||||
case HANDLER_USER_CHALLENGE -> {
|
||||
this.currentElement = qName;
|
||||
String className = attributes.getValue(XML_ATTR_CLASS).trim();
|
||||
String className = attributes.getValue(ATTR_CLASS).trim();
|
||||
getContainerModel().setUserChallengeHandlerClassName(className);
|
||||
}
|
||||
case XML_HANDLER_SSO -> {
|
||||
case HANDLER_SSO -> {
|
||||
this.currentElement = qName;
|
||||
String className = attributes.getValue(XML_ATTR_CLASS).trim();
|
||||
String className = attributes.getValue(ATTR_CLASS).trim();
|
||||
getContainerModel().setSsoHandlerClassName(className);
|
||||
}
|
||||
default -> throw new IllegalStateException("Unexpected value: " + qName);
|
||||
|
@ -130,14 +130,14 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
|||
|
||||
final Map<String, String> params = parametersChild.getParameterMap();
|
||||
switch (this.currentElement) {
|
||||
case XML_CONTAINER -> getContainerModel().setParameterMap(params);
|
||||
case XML_HANDLER_PRIVILEGE -> getContainerModel().setPrivilegeHandlerParameterMap(params);
|
||||
case XML_HANDLER_ENCRYPTION -> getContainerModel().setEncryptionHandlerParameterMap(params);
|
||||
case XML_HANDLER_PASSWORD_STRENGTH ->
|
||||
case CONTAINER -> getContainerModel().setParameterMap(params);
|
||||
case HANDLER_PRIVILEGE -> getContainerModel().setPrivilegeHandlerParameterMap(params);
|
||||
case HANDLER_ENCRYPTION -> getContainerModel().setEncryptionHandlerParameterMap(params);
|
||||
case HANDLER_PASSWORD_STRENGTH ->
|
||||
getContainerModel().setPasswordStrengthHandlerParameterMap(params);
|
||||
case XML_HANDLER_PERSISTENCE -> getContainerModel().setPersistenceHandlerParameterMap(params);
|
||||
case XML_HANDLER_USER_CHALLENGE -> getContainerModel().setUserChallengeHandlerParameterMap(params);
|
||||
case XML_HANDLER_SSO -> getContainerModel().setSsoHandlerParameterMap(params);
|
||||
case HANDLER_PERSISTENCE -> getContainerModel().setPersistenceHandlerParameterMap(params);
|
||||
case HANDLER_USER_CHALLENGE -> getContainerModel().setUserChallengeHandlerParameterMap(params);
|
||||
case HANDLER_SSO -> getContainerModel().setSsoHandlerParameterMap(params);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + this.currentElement);
|
||||
}
|
||||
}
|
||||
|
@ -151,9 +151,9 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
|||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
if (qName.equals(XML_PARAMETER)) {
|
||||
String key = attributes.getValue(XML_ATTR_NAME).trim();
|
||||
String value = attributes.getValue(XML_ATTR_VALUE).trim();
|
||||
if (qName.equals(PARAMETER)) {
|
||||
String key = attributes.getValue(ATTR_NAME).trim();
|
||||
String value = attributes.getValue(ATTR_VALUE).trim();
|
||||
this.parameterMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
@ -172,9 +172,9 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
|||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
if (qName.equals(XML_POLICY)) {
|
||||
String policyName = attributes.getValue(XML_ATTR_NAME).trim();
|
||||
String policyClassName = attributes.getValue(XML_ATTR_CLASS).trim();
|
||||
if (qName.equals(POLICY)) {
|
||||
String policyName = attributes.getValue(ATTR_NAME).trim();
|
||||
String policyClassName = attributes.getValue(ATTR_CLASS).trim();
|
||||
|
||||
getContainerModel().addPolicy(policyName, policyClassName);
|
||||
}
|
||||
|
|
|
@ -46,41 +46,41 @@ public class PrivilegeConfigSaxWriter {
|
|||
try (Writer ioWriter = new OutputStreamWriter(new FileOutputStream(this.configFile), StandardCharsets.UTF_8)) {
|
||||
|
||||
IndentingXMLStreamWriter xmlWriter = openXmlStreamWriterDocument(ioWriter);
|
||||
xmlWriter.writeStartElement(XML_ROOT_PRIVILEGE);
|
||||
xmlWriter.writeStartElement(ROOT_PRIVILEGE);
|
||||
|
||||
// write container element
|
||||
xmlWriter.writeStartElement(XML_CONTAINER);
|
||||
writeStringMapElement(xmlWriter, this.containerModel.getParameterMap(), XML_PARAMETERS, XML_PARAMETER);
|
||||
xmlWriter.writeStartElement(CONTAINER);
|
||||
writeStringMapElement(xmlWriter, this.containerModel.getParameterMap(), PARAMETERS, PARAMETER);
|
||||
|
||||
{
|
||||
// write PrivilegeHandler
|
||||
if (this.containerModel.getPrivilegeHandlerClassName() != null)
|
||||
writeHandler(xmlWriter, XML_HANDLER_PRIVILEGE, this.containerModel.getPrivilegeHandlerClassName(),
|
||||
writeHandler(xmlWriter, HANDLER_PRIVILEGE, this.containerModel.getPrivilegeHandlerClassName(),
|
||||
this.containerModel.getPrivilegeHandlerParameterMap());
|
||||
|
||||
// write EncryptionHandler
|
||||
writeHandler(xmlWriter, XML_HANDLER_ENCRYPTION, this.containerModel.getEncryptionHandlerClassName(),
|
||||
writeHandler(xmlWriter, HANDLER_ENCRYPTION, this.containerModel.getEncryptionHandlerClassName(),
|
||||
this.containerModel.getEncryptionHandlerParameterMap());
|
||||
|
||||
// write PersistenceHandler
|
||||
writeHandler(xmlWriter, XML_HANDLER_PERSISTENCE, this.containerModel.getPersistenceHandlerClassName(),
|
||||
writeHandler(xmlWriter, HANDLER_PERSISTENCE, this.containerModel.getPersistenceHandlerClassName(),
|
||||
this.containerModel.getPersistenceHandlerParameterMap());
|
||||
|
||||
// write PasswordStrengthHandler
|
||||
if (this.containerModel.getPasswordStrengthHandlerClassName() != null)
|
||||
writeHandler(xmlWriter, XML_HANDLER_PASSWORD_STRENGTH,
|
||||
writeHandler(xmlWriter, HANDLER_PASSWORD_STRENGTH,
|
||||
this.containerModel.getPasswordStrengthHandlerClassName(),
|
||||
this.containerModel.getPasswordStrengthHandlerParameterMap());
|
||||
|
||||
// write UserChallengeHandler
|
||||
if (this.containerModel.getUserChallengeHandlerClassName() != null)
|
||||
writeHandler(xmlWriter, XML_HANDLER_USER_CHALLENGE,
|
||||
writeHandler(xmlWriter, HANDLER_USER_CHALLENGE,
|
||||
this.containerModel.getUserChallengeHandlerClassName(),
|
||||
this.containerModel.getUserChallengeHandlerParameterMap());
|
||||
|
||||
// write SingleSignOnHandler
|
||||
if (this.containerModel.getSsoHandlerClassName() != null)
|
||||
writeHandler(xmlWriter, XML_HANDLER_SSO, this.containerModel.getSsoHandlerClassName(),
|
||||
writeHandler(xmlWriter, HANDLER_SSO, this.containerModel.getSsoHandlerClassName(),
|
||||
this.containerModel.getSsoHandlerParameterMap());
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ public class PrivilegeConfigSaxWriter {
|
|||
// Policies
|
||||
Map<String, String> policies = new HashMap<>();
|
||||
this.containerModel.getPolicies().forEach((key, value) -> policies.put(key, value.getName()));
|
||||
writeStringMapElement(xmlWriter, policies, XML_POLICIES, XML_POLICY, XML_ATTR_CLASS);
|
||||
writeStringMapElement(xmlWriter, policies, POLICIES, POLICY, ATTR_CLASS);
|
||||
|
||||
// and now end
|
||||
xmlWriter.writeEndDocument();
|
||||
|
@ -103,9 +103,9 @@ public class PrivilegeConfigSaxWriter {
|
|||
xmlWriter.writeEmptyElement(handleName);
|
||||
else
|
||||
xmlWriter.writeStartElement(handleName);
|
||||
xmlWriter.writeAttribute(XML_ATTR_CLASS, className);
|
||||
xmlWriter.writeAttribute(ATTR_CLASS, className);
|
||||
|
||||
writeStringMapElement(xmlWriter, parameters, XML_PARAMETERS, XML_PARAMETER);
|
||||
writeStringMapElement(xmlWriter, parameters, PARAMETERS, PARAMETER);
|
||||
|
||||
if (!parameters.isEmpty())
|
||||
xmlWriter.writeEndElement();
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright 2013 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.privilege.xml;
|
||||
|
||||
import li.strolch.privilege.model.internal.Group;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
import static li.strolch.privilege.helper.XmlConstants.*;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class PrivilegeGroupsSaxReader extends DefaultHandler {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(PrivilegeGroupsSaxReader.class);
|
||||
|
||||
private final Deque<ElementParser> buildersStack = new ArrayDeque<>();
|
||||
|
||||
private final Map<String, Group> groups;
|
||||
|
||||
public PrivilegeGroupsSaxReader() {
|
||||
this.groups = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the users
|
||||
*/
|
||||
public Map<String, Group> getGroups() {
|
||||
return this.groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
if (qName.equals(GROUP)) {
|
||||
if (this.buildersStack.stream().anyMatch(e -> e.getClass().equals(GroupParser.class)))
|
||||
throw new IllegalArgumentException("Previous Group not closed!");
|
||||
this.buildersStack.push(new GroupParser());
|
||||
} else if (qName.equals(PROPERTIES)) {
|
||||
if (this.buildersStack.stream().anyMatch(e -> e.getClass().equals(PropertyParser.class)))
|
||||
throw new IllegalArgumentException("Previous Properties not closed!");
|
||||
this.buildersStack.push(new PropertyParser());
|
||||
}
|
||||
|
||||
if (!this.buildersStack.isEmpty())
|
||||
this.buildersStack.peek().startElement(uri, localName, qName, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
if (!this.buildersStack.isEmpty())
|
||||
this.buildersStack.peek().characters(ch, start, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
|
||||
if (!this.buildersStack.isEmpty())
|
||||
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||
|
||||
ElementParser elementParser = null;
|
||||
if (qName.equals(GROUP)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
} else if (qName.equals(PROPERTIES)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
}
|
||||
|
||||
if (!this.buildersStack.isEmpty() && elementParser != null)
|
||||
this.buildersStack.peek().notifyChild(elementParser);
|
||||
}
|
||||
|
||||
// <User userId="1" username="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918">
|
||||
// <Firstname>Application</Firstname>
|
||||
// <Lastname>Administrator</Lastname>
|
||||
// <State>ENABLED</State>
|
||||
// <Locale>en-GB</Locale>
|
||||
// <Roles>
|
||||
// <Role>PrivilegeAdmin</Role>
|
||||
// <Role>AppUser</Role>
|
||||
// </Roles>
|
||||
// <Properties>
|
||||
// <Property name="organization" value="eitchnet.ch" />
|
||||
// <Property name="organizationalUnit" value="Development" />
|
||||
// </Properties>
|
||||
// <History>
|
||||
// <FirstLogin>2021-02-19T15:32:09.592+01:00</FirstLogin>
|
||||
// <LastLogin>2021-02-19T15:32:09.592+01:00</LastLogin>
|
||||
// <LastPasswordChange>2021-02-19T15:32:09.592+01:00</LastPasswordChange>
|
||||
// </History>
|
||||
// </User>
|
||||
|
||||
public class GroupParser extends ElementParserAdapter {
|
||||
|
||||
StringBuilder text;
|
||||
|
||||
String name;
|
||||
final Set<String> roles;
|
||||
Map<String, String> parameters;
|
||||
|
||||
public GroupParser() {
|
||||
this.roles = new HashSet<>();
|
||||
this.parameters = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
|
||||
this.text = new StringBuilder();
|
||||
|
||||
if (qName.equals(GROUP)) {
|
||||
this.name = attributes.getValue(ATTR_NAME).trim();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) {
|
||||
this.text.append(ch, start, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) {
|
||||
|
||||
switch (qName) {
|
||||
case ROLE -> this.roles.add(getText());
|
||||
case GROUP -> {
|
||||
|
||||
Group group = new Group(this.name, this.roles, this.parameters);
|
||||
|
||||
logger.info(MessageFormat.format("New Group: {0}", group));
|
||||
groups.put(this.name, group);
|
||||
}
|
||||
default -> {
|
||||
if (!(qName.equals(GROUPS) //
|
||||
|| qName.equals(ROLES) //
|
||||
|| qName.equals(PARAMETER) //
|
||||
|| qName.equals(PARAMETERS))) {
|
||||
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getText() {
|
||||
return this.text.toString().trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyChild(ElementParser child) {
|
||||
if (child instanceof PropertyParser) {
|
||||
this.parameters = ((PropertyParser) child).parameterMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2013 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.privilege.xml;
|
||||
|
||||
import javanet.staxutils.IndentingXMLStreamWriter;
|
||||
import li.strolch.privilege.model.internal.Group;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static li.strolch.privilege.helper.XmlConstants.*;
|
||||
import static li.strolch.privilege.helper.XmlHelper.*;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class PrivilegeGroupsSaxWriter {
|
||||
|
||||
private final List<Group> groups;
|
||||
private final File modelFile;
|
||||
|
||||
public PrivilegeGroupsSaxWriter(List<Group> groups, File modelFile) {
|
||||
this.groups = groups;
|
||||
this.modelFile = modelFile;
|
||||
}
|
||||
|
||||
public void write() throws IOException, XMLStreamException {
|
||||
|
||||
try (Writer ioWriter = new OutputStreamWriter(new FileOutputStream(this.modelFile), StandardCharsets.UTF_8)) {
|
||||
|
||||
IndentingXMLStreamWriter xmlWriter = openXmlStreamWriterDocument(ioWriter);
|
||||
xmlWriter.writeStartElement(GROUPS);
|
||||
|
||||
List<Group> groups = new ArrayList<>(this.groups);
|
||||
groups.sort(comparing(g -> g.name().toLowerCase(Locale.ROOT)));
|
||||
for (Group group : this.groups) {
|
||||
|
||||
// start the user element
|
||||
xmlWriter.writeStartElement(GROUP);
|
||||
|
||||
xmlWriter.writeAttribute(ATTR_NAME, group.name());
|
||||
|
||||
// add all the role elements
|
||||
if (!group.roles().isEmpty()) {
|
||||
xmlWriter.writeStartElement(ROLES);
|
||||
writeStringList(xmlWriter, ROLE, group.roles());
|
||||
xmlWriter.writeEndElement();
|
||||
}
|
||||
|
||||
// add the parameters
|
||||
Map<String, String> properties = group.getProperties();
|
||||
if (!properties.isEmpty())
|
||||
writeStringMapElement(xmlWriter, properties, PROPERTIES, PROPERTY);
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
}
|
||||
|
||||
// and now end
|
||||
xmlWriter.writeEndDocument();
|
||||
xmlWriter.flush();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package li.strolch.privilege.xml;
|
||||
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.internal.PrivilegeImpl;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -52,11 +51,11 @@ public class PrivilegeRolesSaxReader extends DefaultHandler {
|
|||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
|
||||
if (qName.equals(XML_ROLE)) {
|
||||
if (qName.equals(ROLE)) {
|
||||
if (this.buildersStack.stream().anyMatch(e -> e.getClass().equals(RoleParser.class)))
|
||||
throw new IllegalArgumentException("Previous Role not closed!");
|
||||
this.buildersStack.push(new RoleParser());
|
||||
} else if (qName.equals(XML_PROPERTIES)) {
|
||||
} else if (qName.equals(PROPERTIES)) {
|
||||
if (this.buildersStack.stream().anyMatch(e -> e.getClass().equals(PropertyParser.class)))
|
||||
throw new IllegalArgumentException("Previous Properties not closed!");
|
||||
this.buildersStack.push(new PropertyParser());
|
||||
|
@ -79,9 +78,9 @@ public class PrivilegeRolesSaxReader extends DefaultHandler {
|
|||
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||
|
||||
ElementParser elementParser = null;
|
||||
if (qName.equals(XML_ROLE)) {
|
||||
if (qName.equals(ROLE)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
} else if (qName.equals(XML_PROPERTIES)) {
|
||||
} else if (qName.equals(PROPERTIES)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
}
|
||||
|
||||
|
@ -114,7 +113,7 @@ public class PrivilegeRolesSaxReader extends DefaultHandler {
|
|||
private Set<String> denyList;
|
||||
private Set<String> allowList;
|
||||
|
||||
private Map<String, IPrivilege> privileges;
|
||||
private Map<String, Privilege> privileges;
|
||||
|
||||
public RoleParser() {
|
||||
init();
|
||||
|
@ -139,12 +138,12 @@ public class PrivilegeRolesSaxReader extends DefaultHandler {
|
|||
this.text = new StringBuilder();
|
||||
|
||||
switch (qName) {
|
||||
case XML_ROLE -> this.roleName = attributes.getValue(XML_ATTR_NAME).trim();
|
||||
case XML_PRIVILEGE -> {
|
||||
this.privilegeName = attributes.getValue(XML_ATTR_NAME).trim();
|
||||
this.privilegePolicy = attributes.getValue(XML_ATTR_POLICY).trim();
|
||||
case ROLE -> this.roleName = attributes.getValue(ATTR_NAME).trim();
|
||||
case PRIVILEGE -> {
|
||||
this.privilegeName = attributes.getValue(ATTR_NAME).trim();
|
||||
this.privilegePolicy = attributes.getValue(ATTR_POLICY).trim();
|
||||
}
|
||||
case XML_ALLOW, XML_DENY, XML_ALL_ALLOWED -> {
|
||||
case ALLOW, DENY, ALL_ALLOWED -> {
|
||||
}
|
||||
// no-op
|
||||
default -> throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
|
@ -160,11 +159,11 @@ public class PrivilegeRolesSaxReader extends DefaultHandler {
|
|||
@Override
|
||||
public void endElement(String uri, String localName, String qName) {
|
||||
switch (qName) {
|
||||
case XML_ALL_ALLOWED -> this.allAllowed = StringHelper.parseBoolean(getText());
|
||||
case XML_ALLOW -> this.allowList.add(getText());
|
||||
case XML_DENY -> this.denyList.add(getText());
|
||||
case XML_PRIVILEGE -> {
|
||||
IPrivilege privilege = new PrivilegeImpl(this.privilegeName, this.privilegePolicy, this.allAllowed,
|
||||
case ALL_ALLOWED -> this.allAllowed = StringHelper.parseBoolean(getText());
|
||||
case ALLOW -> this.allowList.add(getText());
|
||||
case DENY -> this.denyList.add(getText());
|
||||
case PRIVILEGE -> {
|
||||
Privilege privilege = new Privilege(this.privilegeName, this.privilegePolicy, this.allAllowed,
|
||||
this.denyList, this.allowList);
|
||||
this.privileges.put(this.privilegeName, privilege);
|
||||
this.privilegeName = null;
|
||||
|
@ -173,7 +172,7 @@ public class PrivilegeRolesSaxReader extends DefaultHandler {
|
|||
this.denyList = new HashSet<>();
|
||||
this.allowList = new HashSet<>();
|
||||
}
|
||||
case XML_ROLE -> {
|
||||
case ROLE -> {
|
||||
Role role = new Role(this.roleName, this.privileges);
|
||||
roles.put(role.getName(), role);
|
||||
logger.info(MessageFormat.format("New Role: {0}", role));
|
||||
|
@ -196,11 +195,11 @@ public class PrivilegeRolesSaxReader extends DefaultHandler {
|
|||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
if (qName.equals(XML_PROPERTY)) {
|
||||
String key = attributes.getValue(XML_ATTR_NAME).trim();
|
||||
String value = attributes.getValue(XML_ATTR_VALUE).trim();
|
||||
if (qName.equals(PROPERTY)) {
|
||||
String key = attributes.getValue(ATTR_NAME).trim();
|
||||
String value = attributes.getValue(ATTR_VALUE).trim();
|
||||
this.parameterMap.put(key, value);
|
||||
} else if (!qName.equals(XML_PROPERTIES)) {
|
||||
} else if (!qName.equals(PROPERTIES)) {
|
||||
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
package li.strolch.privilege.xml;
|
||||
|
||||
import javanet.staxutils.IndentingXMLStreamWriter;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
|
@ -48,29 +48,29 @@ public class PrivilegeRolesSaxWriter {
|
|||
try (Writer ioWriter = new OutputStreamWriter(new FileOutputStream(this.modelFile), StandardCharsets.UTF_8)) {
|
||||
|
||||
IndentingXMLStreamWriter xmlWriter = openXmlStreamWriterDocument(ioWriter);
|
||||
xmlWriter.writeStartElement(XML_ROLES);
|
||||
xmlWriter.writeStartElement(ROLES);
|
||||
|
||||
List<Role> roles = new ArrayList<>(this.roles);
|
||||
roles.sort(comparing(role1 -> role1.getName().toLowerCase(Locale.ROOT)));
|
||||
roles.sort(comparing(r -> r.getName().toLowerCase(Locale.ROOT)));
|
||||
for (Role role : roles) {
|
||||
|
||||
// start the role element
|
||||
xmlWriter.writeStartElement(XML_ROLE);
|
||||
xmlWriter.writeAttribute(XML_ATTR_NAME, role.getName());
|
||||
xmlWriter.writeStartElement(ROLE);
|
||||
xmlWriter.writeAttribute(ATTR_NAME, role.getName());
|
||||
|
||||
List<String> privilegeNames = new ArrayList<>(role.getPrivilegeNames());
|
||||
privilegeNames.sort(null);
|
||||
for (String privilegeName : privilegeNames) {
|
||||
IPrivilege privilege = role.getPrivilege(privilegeName);
|
||||
Privilege privilege = role.getPrivilege(privilegeName);
|
||||
|
||||
xmlWriter.writeStartElement(XML_PRIVILEGE);
|
||||
xmlWriter.writeAttribute(XML_ATTR_NAME, privilege.getName());
|
||||
xmlWriter.writeAttribute(XML_ATTR_POLICY, privilege.getPolicy());
|
||||
xmlWriter.writeStartElement(PRIVILEGE);
|
||||
xmlWriter.writeAttribute(ATTR_NAME, privilege.getName());
|
||||
xmlWriter.writeAttribute(ATTR_POLICY, privilege.getPolicy());
|
||||
|
||||
if (privilege.isAllAllowed())
|
||||
writeStringElement(xmlWriter, XML_ALL_ALLOWED, "true");
|
||||
writeStringList(xmlWriter, XML_DENY, privilege.getDenyList());
|
||||
writeStringList(xmlWriter, XML_ALLOW, privilege.getAllowList());
|
||||
writeStringElement(xmlWriter, ALL_ALLOWED, "true");
|
||||
writeStringList(xmlWriter, DENY, privilege.getDenyList());
|
||||
writeStringList(xmlWriter, ALLOW, privilege.getAllowList());
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package li.strolch.privilege.xml;
|
||||
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.Group;
|
||||
import li.strolch.privilege.model.internal.PasswordCrypt;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
|
@ -57,11 +58,11 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
if (qName.equals(XML_USER)) {
|
||||
if (qName.equals(USER)) {
|
||||
if (this.buildersStack.stream().anyMatch(e -> e.getClass().equals(UserParser.class)))
|
||||
throw new IllegalArgumentException("Previous User not closed!");
|
||||
this.buildersStack.push(new UserParser());
|
||||
} else if (qName.equals(XML_PROPERTIES)) {
|
||||
} else if (qName.equals(PROPERTIES)) {
|
||||
if (this.buildersStack.stream().anyMatch(e -> e.getClass().equals(PropertyParser.class)))
|
||||
throw new IllegalArgumentException("Previous Properties not closed!");
|
||||
this.buildersStack.push(new PropertyParser());
|
||||
|
@ -84,9 +85,9 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||
|
||||
ElementParser elementParser = null;
|
||||
if (qName.equals(XML_USER)) {
|
||||
if (qName.equals(USER)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
} else if (qName.equals(XML_PROPERTIES)) {
|
||||
} else if (qName.equals(PROPERTIES)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
}
|
||||
|
||||
|
@ -125,12 +126,14 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
String lastname;
|
||||
UserState userState;
|
||||
Locale locale;
|
||||
final Set<String> groups;
|
||||
final Set<String> userRoles;
|
||||
Map<String, String> parameters;
|
||||
UserHistory history;
|
||||
boolean passwordChangeRequested;
|
||||
|
||||
public UserParser() {
|
||||
this.groups = new HashSet<>();
|
||||
this.userRoles = new HashSet<>();
|
||||
}
|
||||
|
||||
|
@ -139,15 +142,15 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
|
||||
this.text = new StringBuilder();
|
||||
|
||||
if (qName.equals(XML_USER)) {
|
||||
this.userId = attributes.getValue(XML_ATTR_USER_ID).trim();
|
||||
this.username = attributes.getValue(XML_ATTR_USERNAME).trim();
|
||||
if (qName.equals(USER)) {
|
||||
this.userId = attributes.getValue(ATTR_USER_ID).trim();
|
||||
this.username = attributes.getValue(ATTR_USERNAME).trim();
|
||||
|
||||
String password = attributes.getValue(XML_ATTR_PASSWORD);
|
||||
String salt = attributes.getValue(XML_ATTR_SALT);
|
||||
String password = attributes.getValue(ATTR_PASSWORD);
|
||||
String salt = attributes.getValue(ATTR_SALT);
|
||||
this.passwordCrypt = PasswordCrypt.parse(password, salt);
|
||||
} else if (qName.equals(XML_HISTORY)) {
|
||||
this.history = new UserHistory();
|
||||
} else if (qName.equals(HISTORY)) {
|
||||
this.history = UserHistory.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,32 +163,35 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
public void endElement(String uri, String localName, String qName) {
|
||||
|
||||
switch (qName) {
|
||||
case XML_FIRSTNAME -> this.firstName = getText();
|
||||
case XML_LASTNAME -> this.lastname = getText();
|
||||
case XML_STATE -> this.userState = UserState.valueOf(getText());
|
||||
case XML_LOCALE -> this.locale = Locale.forLanguageTag(getText());
|
||||
case XML_PASSWORD_CHANGE_REQUESTED -> this.passwordChangeRequested = Boolean.parseBoolean(getText());
|
||||
case XML_FIRST_LOGIN -> this.history.setFirstLogin(ISO8601.parseToZdt(getText()));
|
||||
case XML_LAST_LOGIN -> this.history.setLastLogin(ISO8601.parseToZdt(getText()));
|
||||
case XML_LAST_PASSWORD_CHANGE -> this.history.setLastPasswordChange(ISO8601.parseToZdt(getText()));
|
||||
case XML_ROLE -> this.userRoles.add(getText());
|
||||
case XML_USER -> {
|
||||
case FIRSTNAME -> this.firstName = getText();
|
||||
case LASTNAME -> this.lastname = getText();
|
||||
case STATE -> this.userState = UserState.valueOf(getText());
|
||||
case LOCALE -> this.locale = Locale.forLanguageTag(getText());
|
||||
case PASSWORD_CHANGE_REQUESTED -> this.passwordChangeRequested = Boolean.parseBoolean(getText());
|
||||
case FIRST_LOGIN -> this.history = this.history.withFirstLogin(ISO8601.parseToZdt(getText()));
|
||||
case LAST_LOGIN -> this.history = this.history.withLastLogin(ISO8601.parseToZdt(getText()));
|
||||
case LAST_PASSWORD_CHANGE ->
|
||||
this.history = this.history.withLastPasswordChange(ISO8601.parseToZdt(getText()));
|
||||
case GROUP -> this.groups.add(getText());
|
||||
case ROLE -> this.userRoles.add(getText());
|
||||
case USER -> {
|
||||
if (this.history == null)
|
||||
this.history = new UserHistory();
|
||||
this.history = UserHistory.EMPTY;
|
||||
|
||||
User user = new User(this.userId, this.username, this.passwordCrypt, this.firstName, this.lastname,
|
||||
this.userState, this.userRoles, this.locale, this.parameters, this.passwordChangeRequested,
|
||||
this.history);
|
||||
this.userState, this.groups, this.userRoles, this.locale, this.parameters,
|
||||
this.passwordChangeRequested, this.history);
|
||||
|
||||
logger.info(MessageFormat.format("New User: {0}", user));
|
||||
String username = caseInsensitiveUsername ? user.getUsername().toLowerCase() : user.getUsername();
|
||||
users.put(username, user);
|
||||
}
|
||||
default -> {
|
||||
if (!(qName.equals(XML_ROLES) //
|
||||
|| qName.equals(XML_PARAMETER) //
|
||||
|| qName.equals(XML_HISTORY) //
|
||||
|| qName.equals(XML_PARAMETERS))) {
|
||||
if (!(qName.equals(ROLES) //
|
||||
|| qName.equals(GROUPS) //
|
||||
|| qName.equals(PARAMETER) //
|
||||
|| qName.equals(HISTORY) //
|
||||
|| qName.equals(PARAMETERS))) {
|
||||
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
}
|
||||
}
|
||||
|
@ -203,29 +209,4 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class PropertyParser extends ElementParserAdapter {
|
||||
|
||||
// <Property name="organizationalUnit" value="Development" />
|
||||
|
||||
public final Map<String, String> parameterMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
|
||||
if (qName.equals(XML_PROPERTY)) {
|
||||
String key = attributes.getValue(XML_ATTR_NAME).trim();
|
||||
String value = attributes.getValue(XML_ATTR_VALUE).trim();
|
||||
this.parameterMap.put(key, value);
|
||||
} else {
|
||||
if (!qName.equals(XML_PROPERTIES)) {
|
||||
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getParameterMap() {
|
||||
return this.parameterMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,6 @@ public class PrivilegeUsersSaxWriter {
|
|||
public PrivilegeUsersSaxWriter(List<User> users, File modelFile) {
|
||||
this.users = users;
|
||||
this.modelFile = modelFile;
|
||||
|
||||
this.users.sort(comparing(User::getUsername));
|
||||
}
|
||||
|
||||
public void write() throws IOException, XMLStreamException {
|
||||
|
@ -56,62 +54,68 @@ public class PrivilegeUsersSaxWriter {
|
|||
try (Writer ioWriter = new OutputStreamWriter(new FileOutputStream(this.modelFile), StandardCharsets.UTF_8)) {
|
||||
|
||||
IndentingXMLStreamWriter xmlWriter = openXmlStreamWriterDocument(ioWriter);
|
||||
xmlWriter.writeStartElement(XML_USERS);
|
||||
xmlWriter.writeStartElement(USERS);
|
||||
|
||||
List<User> users = new ArrayList<>(this.users);
|
||||
users.sort(comparing(u -> u.getUsername().toLowerCase(Locale.ROOT)));
|
||||
for (User user : this.users) {
|
||||
|
||||
// start the user element
|
||||
xmlWriter.writeStartElement(XML_USER);
|
||||
xmlWriter.writeStartElement(USER);
|
||||
|
||||
xmlWriter.writeAttribute(XML_ATTR_USER_ID, user.getUserId());
|
||||
xmlWriter.writeAttribute(XML_ATTR_USERNAME, user.getUsername());
|
||||
xmlWriter.writeAttribute(ATTR_USER_ID, user.getUserId());
|
||||
xmlWriter.writeAttribute(ATTR_USERNAME, user.getUsername());
|
||||
writePassword(user, xmlWriter);
|
||||
|
||||
// add first name element
|
||||
if (isNotEmpty(user.getFirstname()))
|
||||
writeStringElement(xmlWriter, XML_FIRSTNAME, user.getFirstname());
|
||||
writeStringElement(xmlWriter, FIRSTNAME, user.getFirstname());
|
||||
|
||||
// add last name element
|
||||
if (isNotEmpty(user.getLastname()))
|
||||
writeStringElement(xmlWriter, XML_LASTNAME, user.getLastname());
|
||||
writeStringElement(xmlWriter, LASTNAME, user.getLastname());
|
||||
|
||||
// add state element
|
||||
writeStringElement(xmlWriter, XML_STATE, user.getUserState().toString());
|
||||
writeStringElement(xmlWriter, STATE, user.getUserState().toString());
|
||||
|
||||
// add locale element
|
||||
writeStringElement(xmlWriter, XML_LOCALE, user.getLocale().toLanguageTag());
|
||||
writeStringElement(xmlWriter, LOCALE, user.getLocale().toLanguageTag());
|
||||
|
||||
// add password change requested element
|
||||
if (user.isPasswordChangeRequested())
|
||||
writeStringElement(xmlWriter, XML_PASSWORD_CHANGE_REQUESTED, "true");
|
||||
writeStringElement(xmlWriter, PASSWORD_CHANGE_REQUESTED, "true");
|
||||
|
||||
// add all the group elements
|
||||
if (!user.getGroups().isEmpty()) {
|
||||
xmlWriter.writeStartElement(GROUPS);
|
||||
writeStringList(xmlWriter, GROUP, user.getGroups());
|
||||
xmlWriter.writeEndElement();
|
||||
}
|
||||
|
||||
// add all the role elements
|
||||
if (!user.getRoles().isEmpty()) {
|
||||
xmlWriter.writeStartElement(XML_ROLES);
|
||||
writeStringList(xmlWriter, XML_ROLE, user.getRoles());
|
||||
xmlWriter.writeStartElement(ROLES);
|
||||
writeStringList(xmlWriter, ROLE, user.getRoles());
|
||||
xmlWriter.writeEndElement();
|
||||
}
|
||||
|
||||
// add the parameters
|
||||
Map<String, String> properties = user.getProperties();
|
||||
if (!properties.isEmpty()) {
|
||||
writeStringMapElement(xmlWriter, properties, XML_PROPERTIES, XML_PROPERTY);
|
||||
}
|
||||
if (!properties.isEmpty())
|
||||
writeStringMapElement(xmlWriter, properties, PROPERTIES, PROPERTY);
|
||||
|
||||
if (!user.isHistoryEmpty()) {
|
||||
UserHistory history = user.getHistory();
|
||||
xmlWriter.writeStartElement(XML_HISTORY);
|
||||
xmlWriter.writeStartElement(HISTORY);
|
||||
|
||||
if (!history.isFirstLoginEmpty())
|
||||
writeStringElement(xmlWriter, XML_FIRST_LOGIN, ISO8601.toString(history.getFirstLogin()));
|
||||
writeStringElement(xmlWriter, FIRST_LOGIN, ISO8601.toString(history.getFirstLogin()));
|
||||
|
||||
if (!history.isLastLoginEmpty())
|
||||
writeStringElement(xmlWriter, XML_LAST_LOGIN, ISO8601.toString(history.getLastLogin()));
|
||||
writeStringElement(xmlWriter, LAST_LOGIN, ISO8601.toString(history.getLastLogin()));
|
||||
|
||||
if (!history.isLastPasswordChangeEmpty())
|
||||
writeStringElement(xmlWriter, XML_LAST_PASSWORD_CHANGE,
|
||||
writeStringElement(xmlWriter, LAST_PASSWORD_CHANGE,
|
||||
ISO8601.toString(history.getLastPasswordChange()));
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
|
@ -133,12 +137,12 @@ public class PrivilegeUsersSaxWriter {
|
|||
|
||||
String passwordString = passwordCrypt.buildPasswordString();
|
||||
if (passwordString != null) {
|
||||
xmlStreamWriter.writeAttribute(XML_ATTR_PASSWORD, passwordString);
|
||||
xmlStreamWriter.writeAttribute(ATTR_PASSWORD, passwordString);
|
||||
} else {
|
||||
if (passwordCrypt.getPassword() != null)
|
||||
xmlStreamWriter.writeAttribute(XML_ATTR_PASSWORD, toHexString(passwordCrypt.getPassword()));
|
||||
if (passwordCrypt.getSalt() != null)
|
||||
xmlStreamWriter.writeAttribute(XML_ATTR_SALT, toHexString(passwordCrypt.getSalt()));
|
||||
if (passwordCrypt.password() != null)
|
||||
xmlStreamWriter.writeAttribute(ATTR_PASSWORD, toHexString(passwordCrypt.password()));
|
||||
if (passwordCrypt.salt() != null)
|
||||
xmlStreamWriter.writeAttribute(ATTR_SALT, toHexString(passwordCrypt.salt()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package li.strolch.privilege.xml;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static li.strolch.privilege.helper.XmlConstants.*;
|
||||
|
||||
class PropertyParser extends ElementParserAdapter {
|
||||
|
||||
// <Property name="organizationalUnit" value="Development" />
|
||||
|
||||
public final Map<String, String> parameterMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
|
||||
if (qName.equals(PROPERTY)) {
|
||||
String key = attributes.getValue(ATTR_NAME).trim();
|
||||
String value = attributes.getValue(ATTR_VALUE).trim();
|
||||
this.parameterMap.put(key, value);
|
||||
} else {
|
||||
if (!qName.equals(PROPERTIES)) {
|
||||
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getParameterMap() {
|
||||
return this.parameterMap;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ Privilege.privilegeNameEmpty=The PrivilegeName for the Restrictable is null or e
|
|||
Privilege.privilegeNull=Privilege may not be null\!
|
||||
Privilege.restrictableNull=Restrictable may not be null\!
|
||||
Privilege.noprivilege=No Privilege exists with name {0}
|
||||
Privilege.noprivilege.group=User {0} does not belong to group {1}
|
||||
Privilege.noprivilege.role=User {0} does not have the role {1}
|
||||
Privilege.noprivilege.user=User {0} does not have the privilege {1}
|
||||
Privilege.roleAccessPrivilege.unknownPrivilege=Unhandled privilege {0} for policy {1}
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
package li.strolch.privilege.test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||
import li.strolch.privilege.helper.PrivilegeInitializer;
|
||||
|
@ -18,6 +11,13 @@ import org.junit.BeforeClass;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class AbstractPrivilegeTest {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(AbstractPrivilegeTest.class);
|
||||
|
@ -57,13 +57,14 @@ public class AbstractPrivilegeTest {
|
|||
}
|
||||
}
|
||||
|
||||
protected static void prepareConfigs(String dst, String configFilename, String usersFilename,
|
||||
protected static void prepareConfigs(String dst, String configFilename, String usersFilename, String groupsFilename,
|
||||
String rolesFilename) {
|
||||
try {
|
||||
File configPath = new File("src/test/resources/config");
|
||||
|
||||
File privilegeConfigFile = new File(configPath, configFilename);
|
||||
File privilegeUsersFile = new File(configPath, usersFilename);
|
||||
File privilegeGroupsFile = new File(configPath, groupsFilename);
|
||||
File privilegeRolesFile = new File(configPath, rolesFilename);
|
||||
|
||||
File targetPath = new File("target/" + dst);
|
||||
|
@ -72,6 +73,7 @@ public class AbstractPrivilegeTest {
|
|||
|
||||
File dstConfig = new File(targetPath, configFilename);
|
||||
File dstUsers = new File(targetPath, usersFilename);
|
||||
File dstGroups = new File(targetPath, groupsFilename);
|
||||
File dstRoles = new File(targetPath, rolesFilename);
|
||||
|
||||
// write config
|
||||
|
@ -81,6 +83,7 @@ public class AbstractPrivilegeTest {
|
|||
|
||||
// copy model
|
||||
Files.copy(privilegeUsersFile.toPath(), dstUsers.toPath());
|
||||
Files.copy(privilegeGroupsFile.toPath(), dstGroups.toPath());
|
||||
Files.copy(privilegeRolesFile.toPath(), dstRoles.toPath());
|
||||
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -20,9 +20,9 @@ public class CryptTest {
|
|||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
Map<String, String> parameterMap = new HashMap<>();
|
||||
parameterMap.put(XML_PARAM_HASH_ALGORITHM, DEFAULT_ALGORITHM);
|
||||
parameterMap.put(XML_PARAM_HASH_ITERATIONS, "" + DEFAULT_SMALL_ITERATIONS);
|
||||
parameterMap.put(XML_PARAM_HASH_KEY_LENGTH, "" + DEFAULT_KEY_LENGTH);
|
||||
parameterMap.put(PARAM_HASH_ALGORITHM, DEFAULT_ALGORITHM);
|
||||
parameterMap.put(PARAM_HASH_ITERATIONS, "" + DEFAULT_SMALL_ITERATIONS);
|
||||
parameterMap.put(PARAM_HASH_KEY_LENGTH, "" + DEFAULT_KEY_LENGTH);
|
||||
|
||||
encryptionHandler = new DefaultEncryptionHandler();
|
||||
encryptionHandler.initialize(parameterMap);
|
||||
|
@ -41,7 +41,7 @@ public class CryptTest {
|
|||
PasswordCrypt passwordCrypt = encryptionHandler.hashPassword(password, salt, "PBKDF2WithHmacSHA512", 100000,
|
||||
256);
|
||||
|
||||
assertArrayEquals(passwordCrypt.getPassword(), parsedCryptHash.getPassword());
|
||||
assertArrayEquals(passwordCrypt.password(), parsedCryptHash.password());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -53,9 +53,9 @@ public class CryptTest {
|
|||
assertNotNull(parsedCryptHash);
|
||||
|
||||
char[] password = "admin".toCharArray();
|
||||
PasswordCrypt passwordCrypt = encryptionHandler.hashPassword(password, parsedCryptHash.getSalt(),
|
||||
PasswordCrypt passwordCrypt = encryptionHandler.hashPassword(password, parsedCryptHash.salt(),
|
||||
"PBKDF2WithHmacSHA512", 100000, 256);
|
||||
|
||||
assertArrayEquals(passwordCrypt.getPassword(), parsedCryptHash.getPassword());
|
||||
assertArrayEquals(passwordCrypt.password(), parsedCryptHash.password());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ public class PersistSessionsTest extends AbstractPrivilegeTest {
|
|||
public static void init() {
|
||||
removeConfigs(PersistSessionsTest.class.getSimpleName());
|
||||
prepareConfigs(PersistSessionsTest.class.getSimpleName(), "PrivilegeConfig.xml", "PrivilegeUsers.xml",
|
||||
"PrivilegeRoles.xml");
|
||||
"PrivilegeGroups.xml", "PrivilegeRoles.xml");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
|
@ -15,14 +15,16 @@
|
|||
*/
|
||||
package li.strolch.privilege.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
|
@ -32,7 +34,7 @@ public class PrivilegeConflictMergeTest extends AbstractPrivilegeTest {
|
|||
public static void init() {
|
||||
removeConfigs(PrivilegeConflictMergeTest.class.getSimpleName());
|
||||
prepareConfigs(PrivilegeConflictMergeTest.class.getSimpleName(), "PrivilegeConfigMerge.xml",
|
||||
"PrivilegeUsersMerge.xml", "PrivilegeRolesMerge.xml");
|
||||
"PrivilegeUsersMerge.xml", "PrivilegeGroupsMerge.xml", "PrivilegeRolesMerge.xml");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
@ -49,7 +51,16 @@ public class PrivilegeConflictMergeTest extends AbstractPrivilegeTest {
|
|||
public void shouldMergePrivileges1() {
|
||||
try {
|
||||
login("userA", "admin".toCharArray());
|
||||
IPrivilege privilege = this.ctx.getPrivilege("Foo");
|
||||
assertEquals(Set.of(), this.ctx.getUserRep().getGroups());
|
||||
assertFalse(this.ctx.hasGroup("GroupA1"));
|
||||
assertFalse(this.ctx.hasGroup("GroupA2"));
|
||||
assertEquals(Set.of("RoleA1", "RoleA2"), this.ctx.getUserRep().getRoles());
|
||||
assertTrue(this.ctx.hasRole("RoleA1"));
|
||||
assertTrue(this.ctx.hasRole("RoleA2"));
|
||||
assertFalse(this.ctx.hasRole("RoleB2"));
|
||||
assertNull(this.ctx.getUserRep().getLocation());
|
||||
assertEquals(Set.of(), this.ctx.getUserRep().getPropertyKeySet());
|
||||
Privilege privilege = this.ctx.getPrivilege("Foo");
|
||||
assertTrue(privilege.isAllAllowed());
|
||||
assertTrue(privilege.getAllowList().isEmpty());
|
||||
assertTrue(privilege.getDenyList().isEmpty());
|
||||
|
@ -63,7 +74,16 @@ public class PrivilegeConflictMergeTest extends AbstractPrivilegeTest {
|
|||
public void shouldMergePrivileges2() {
|
||||
try {
|
||||
login("userB", "admin".toCharArray());
|
||||
IPrivilege privilege = this.ctx.getPrivilege("Bar");
|
||||
assertEquals(Set.of(), this.ctx.getUserRep().getGroups());
|
||||
assertFalse(this.ctx.hasGroup("GroupB1"));
|
||||
assertFalse(this.ctx.hasGroup("GroupB2"));
|
||||
assertEquals(Set.of("RoleB1", "RoleB2"), this.ctx.getUserRep().getRoles());
|
||||
assertTrue(this.ctx.hasRole("RoleB1"));
|
||||
assertTrue(this.ctx.hasRole("RoleB2"));
|
||||
assertFalse(this.ctx.hasRole("RoleA2"));
|
||||
assertNull(this.ctx.getUserRep().getLocation());
|
||||
assertEquals(Set.of(), this.ctx.getUserRep().getPropertyKeySet());
|
||||
Privilege privilege = this.ctx.getPrivilege("Bar");
|
||||
assertFalse(privilege.isAllAllowed());
|
||||
assertEquals(2, privilege.getAllowList().size());
|
||||
assertEquals(2, privilege.getDenyList().size());
|
||||
|
@ -71,4 +91,53 @@ public class PrivilegeConflictMergeTest extends AbstractPrivilegeTest {
|
|||
logout();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMergePrivileges3() {
|
||||
try {
|
||||
login("userC", "admin".toCharArray());
|
||||
assertEquals(Set.of("GroupA1", "GroupA2"), this.ctx.getUserRep().getGroups());
|
||||
assertTrue(this.ctx.hasGroup("GroupA1"));
|
||||
assertTrue(this.ctx.hasGroup("GroupA2"));
|
||||
assertFalse(this.ctx.hasGroup("GroupB2"));
|
||||
assertEquals(Set.of("RoleA1", "RoleA2"), this.ctx.getUserRep().getRoles());
|
||||
assertTrue(this.ctx.hasRole("RoleA1"));
|
||||
assertTrue(this.ctx.hasRole("RoleA2"));
|
||||
assertFalse(this.ctx.hasRole("RoleB2"));
|
||||
assertEquals("LocationA2", this.ctx.getUserRep().getLocation());
|
||||
assertEquals(Set.of("location"), this.ctx.getUserRep().getPropertyKeySet());
|
||||
Privilege privilege = this.ctx.getPrivilege("Foo");
|
||||
assertTrue(privilege.isAllAllowed());
|
||||
assertTrue(privilege.getAllowList().isEmpty());
|
||||
assertTrue(privilege.getDenyList().isEmpty());
|
||||
|
||||
} finally {
|
||||
logout();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMergePrivileges4() {
|
||||
try {
|
||||
login("userD", "admin".toCharArray());
|
||||
assertEquals(Set.of("GroupB1", "GroupB2"), this.ctx.getUserRep().getGroups());
|
||||
assertTrue(this.ctx.hasGroup("GroupB1"));
|
||||
assertTrue(this.ctx.hasGroup("GroupB2"));
|
||||
assertFalse(this.ctx.hasGroup("GroupA2"));
|
||||
assertEquals(Set.of("RoleB1", "RoleB2"), this.ctx.getUserRep().getRoles());
|
||||
assertTrue(this.ctx.hasRole("RoleB1"));
|
||||
assertTrue(this.ctx.hasRole("RoleB2"));
|
||||
assertFalse(this.ctx.hasRole("RoleA2"));
|
||||
assertEquals("LocationB2", this.ctx.getUserRep().getLocation());
|
||||
assertEquals(Set.of("location"), this.ctx.getUserRep().getPropertyKeySet());
|
||||
Privilege privilege = this.ctx.getPrivilege("Bar");
|
||||
assertFalse(privilege.isAllAllowed());
|
||||
assertEquals(2, privilege.getAllowList().size());
|
||||
assertEquals(2, privilege.getDenyList().size());
|
||||
assertEquals(Set.of("allow1", "allow2"), privilege.getAllowList());
|
||||
assertEquals(Set.of("deny1", "deny2"), privilege.getDenyList());
|
||||
} finally {
|
||||
logout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,6 @@
|
|||
*/
|
||||
package li.strolch.privilege.test;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.InvalidCredentialsException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
|
@ -41,9 +35,15 @@ import org.junit.Test;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* JUnit for performing Privilege tests. This JUnit is by no means complete, but checks the bare minimum.br />
|
||||
*
|
||||
* <p>
|
||||
* TODO add more tests, especially with deny and allow lists
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
|
@ -77,12 +77,12 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
public static void init() {
|
||||
removeConfigs(PrivilegeTest.class.getSimpleName());
|
||||
prepareConfigs(PrivilegeTest.class.getSimpleName(), "PrivilegeConfig.xml", "PrivilegeUsers.xml",
|
||||
"PrivilegeRoles.xml");
|
||||
"PrivilegeGroups.xml", "PrivilegeRoles.xml");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void destroy() {
|
||||
removeConfigs(PrivilegeTest.class.getSimpleName());
|
||||
//removeConfigs(PrivilegeTest.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -209,7 +209,9 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
}
|
||||
});
|
||||
MatcherAssert.assertThat(exception.getMessage(), containsString(
|
||||
"User system_admin2 does not have the privilege li.strolch.privilege.handler.SystemAction with value li.strolch.privilege.test.model.TestSystemUserActionDeny needed for Restrictable li.strolch.privilege.test.model.TestSystemUserActionDeny"));
|
||||
"User system_admin2 does not have the privilege li.strolch.privilege.handler.SystemAction with value " +
|
||||
"li.strolch.privilege.test.model.TestSystemUserActionDeny needed for Restrictable " +
|
||||
"li.strolch.privilege.test.model.TestSystemUserActionDeny"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,7 +254,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
assertNotEquals("Admin", user.getLastname());
|
||||
|
||||
// let's add a new user bob
|
||||
UserRep userRep = new UserRep(null, ADMIN, "The", "Admin", null, null, null, null, null);
|
||||
UserRep userRep = new UserRep(null, ADMIN, "The", "Admin", null, null, null, null, null, null);
|
||||
this.privilegeHandler.updateUser(certificate, userRep);
|
||||
|
||||
user = this.privilegeHandler.getUser(certificate, ADMIN);
|
||||
|
@ -273,7 +275,7 @@ 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);
|
||||
UserRep userRep = new UserRep(null, BOB, null, null, null, null, null, null, null, null);
|
||||
this.privilegeHandler.updateUser(certificate, userRep);
|
||||
} finally {
|
||||
logout();
|
||||
|
@ -291,7 +293,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
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);
|
||||
UserRep userRep = new UserRep(null, ADMIN, null, null, null, null, null, null, null, null);
|
||||
this.privilegeHandler.updateUser(certificate, userRep);
|
||||
} finally {
|
||||
logout();
|
||||
|
@ -308,7 +310,24 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
|
||||
Certificate certificate = this.ctx.getCertificate();
|
||||
|
||||
UserRep selectorRep = new UserRep(null, ADMIN, null, null, null, null, null, null, null);
|
||||
UserRep selectorRep = new UserRep(null, ADMIN, null, null, null, null, null, null, null, null);
|
||||
List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep);
|
||||
assertEquals(1, users.size());
|
||||
assertEquals(ADMIN, users.get(0).getUsername());
|
||||
|
||||
} finally {
|
||||
logout();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldQueryUsersByGroups() {
|
||||
try {
|
||||
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||
|
||||
Certificate certificate = this.ctx.getCertificate();
|
||||
|
||||
UserRep selectorRep = new UserRep(null, null, null, null, null, Set.of("GroupA"), null, null, null, null);
|
||||
List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep);
|
||||
assertEquals(1, users.size());
|
||||
assertEquals(ADMIN, users.get(0).getUsername());
|
||||
|
@ -325,8 +344,8 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
|
||||
Certificate certificate = this.ctx.getCertificate();
|
||||
|
||||
UserRep selectorRep = new UserRep(null, null, null, null, null,
|
||||
new HashSet<>(Collections.singletonList("PrivilegeAdmin")), null, null, null);
|
||||
UserRep selectorRep = new UserRep(null, null, null, null, null, null, Set.of("PrivilegeAdmin"), null, null,
|
||||
null);
|
||||
List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep);
|
||||
assertEquals(2, users.size());
|
||||
assertEquals(ADMIN, users.get(0).getUsername());
|
||||
|
@ -344,7 +363,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
Certificate certificate = this.ctx.getCertificate();
|
||||
|
||||
UserRep selectorRep = new UserRep(null, null, null, null, null,
|
||||
new HashSet<>(Collections.singletonList(ROLE_TEMP)), null, null, null);
|
||||
new HashSet<>(Collections.singletonList(ROLE_TEMP)), null, null, null, null);
|
||||
List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep);
|
||||
assertEquals(0, users.size());
|
||||
|
||||
|
@ -593,7 +612,10 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
this.ctx.validateAction(restrictable);
|
||||
fail("Should fail as bob does not have role app");
|
||||
} catch (AccessDeniedException e) {
|
||||
String msg = "User bob does not have the privilege li.strolch.privilege.test.model.TestRestrictable needed for Restrictable li.strolch.privilege.test.model.TestRestrictable and value li.strolch.privilege.test.model.TestRestrictable";
|
||||
String msg =
|
||||
"User bob does not have the privilege li.strolch.privilege.test.model.TestRestrictable needed for " +
|
||||
"Restrictable li.strolch.privilege.test.model.TestRestrictable and value " +
|
||||
"li.strolch.privilege.test.model.TestRestrictable";
|
||||
assertEquals(msg, e.getLocalizedMessage());
|
||||
} finally {
|
||||
logout();
|
||||
|
@ -656,7 +678,8 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
// let's add a new user ted
|
||||
HashSet<String> roles = new HashSet<>();
|
||||
roles.add(ROLE_USER);
|
||||
userRep = new UserRep(null, TED, "Ted", "Newman", UserState.ENABLED, roles, null, new HashMap<>(), null);
|
||||
userRep = new UserRep(null, TED, "Ted", "Newman", UserState.ENABLED, Set.of(), roles, null, new HashMap<>(),
|
||||
null);
|
||||
Certificate certificate = this.ctx.getCertificate();
|
||||
this.privilegeHandler.addUser(certificate, userRep, null);
|
||||
logger.info("Added user " + TED);
|
||||
|
@ -688,14 +711,14 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
// auth as Bob
|
||||
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||
// let's add a new user Ted
|
||||
userRep = new UserRep("1", TED, "Ted", "And then Some", UserState.NEW, new HashSet<>(), null,
|
||||
userRep = new UserRep("1", TED, "Ted", "And then Some", UserState.NEW, Set.of(), Set.of(), null,
|
||||
new HashMap<>(), null);
|
||||
certificate = this.ctx.getCertificate();
|
||||
this.privilegeHandler.addUser(certificate, userRep, null);
|
||||
fail("User bob may not add a user as bob does not have admin rights!");
|
||||
} catch (PrivilegeException e) {
|
||||
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.user"),
|
||||
BOB, PrivilegeHandler.PRIVILEGE_ADD_USER);
|
||||
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.user"), BOB,
|
||||
PrivilegeHandler.PRIVILEGE_ADD_USER);
|
||||
assertEquals(msg, e.getMessage());
|
||||
} finally {
|
||||
logout();
|
||||
|
@ -768,8 +791,8 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
|
|||
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||
|
||||
// let's add a new user bob
|
||||
UserRep userRep = new UserRep(null, BOB, "Bob", "Newman", UserState.NEW,
|
||||
new HashSet<>(Collections.singletonList(ROLE_MY)), null, new HashMap<>(), null);
|
||||
UserRep userRep = new UserRep(null, BOB, "Bob", "Newman", UserState.NEW, Set.of(), Set.of(ROLE_MY), null,
|
||||
new HashMap<>(), null);
|
||||
Certificate certificate = this.ctx.getCertificate();
|
||||
this.privilegeHandler.addUser(certificate, userRep, null);
|
||||
logger.info("Added user " + BOB);
|
||||
|
|
|
@ -17,7 +17,7 @@ public class SsoHandlerTest extends AbstractPrivilegeTest {
|
|||
public static void init() {
|
||||
removeConfigs(SsoHandlerTest.class.getSimpleName());
|
||||
prepareConfigs(SsoHandlerTest.class.getSimpleName(), "PrivilegeConfig.xml", "PrivilegeUsers.xml",
|
||||
"PrivilegeRoles.xml");
|
||||
"PrivilegeGroups.xml", "PrivilegeRoles.xml");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
@ -39,6 +39,7 @@ public class SsoHandlerTest extends AbstractPrivilegeTest {
|
|||
data.put("username", "admin");
|
||||
data.put("firstName", "Admin");
|
||||
data.put("lastName", "Istrator");
|
||||
data.put("groups", "AppUserLocationA");
|
||||
data.put("roles", "PrivilegeAdmin, AppUser");
|
||||
|
||||
// auth
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
package li.strolch.privilege.test;
|
||||
|
||||
import li.strolch.privilege.handler.*;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.*;
|
||||
import li.strolch.privilege.test.model.DummySsoHandler;
|
||||
|
@ -80,6 +80,11 @@ public class XmlTest {
|
|||
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
tmpFile = new File(TARGET_TEST + "PrivilegeGroupsTest.xml");
|
||||
if (tmpFile.exists() && !tmpFile.delete()) {
|
||||
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
tmpFile = new File(TARGET_TEST + "PrivilegeRolesTest.xml");
|
||||
if (tmpFile.exists() && !tmpFile.delete()) {
|
||||
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
|
||||
|
@ -194,12 +199,13 @@ public class XmlTest {
|
|||
assertEquals("1", admin.getUserId());
|
||||
assertEquals("admin", admin.getUsername());
|
||||
assertEquals("cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344",
|
||||
StringHelper.toHexString(admin.getPasswordCrypt().getPassword()));
|
||||
assertEquals("61646d696e", StringHelper.toHexString(admin.getPasswordCrypt().getSalt()));
|
||||
StringHelper.toHexString(admin.getPasswordCrypt().password()));
|
||||
assertEquals("61646d696e", StringHelper.toHexString(admin.getPasswordCrypt().salt()));
|
||||
assertEquals("Application", admin.getFirstname());
|
||||
assertEquals("Administrator", admin.getLastname());
|
||||
assertEquals(UserState.ENABLED, admin.getUserState());
|
||||
assertEquals("en-GB", admin.getLocale().toLanguageTag());
|
||||
assertEquals(Set.of("GroupA"), admin.getGroups());
|
||||
MatcherAssert.assertThat(admin.getRoles(), containsInAnyOrder("PrivilegeAdmin", "AppUser"));
|
||||
Map<String, String> properties = admin.getProperties();
|
||||
assertEquals(new HashSet<>(Arrays.asList("organization", "organizationalUnit")), properties.keySet());
|
||||
|
@ -215,8 +221,48 @@ public class XmlTest {
|
|||
assertEquals("Administrator", systemAdmin.getLastname());
|
||||
assertEquals(UserState.SYSTEM, systemAdmin.getUserState());
|
||||
assertEquals("en-GB", systemAdmin.getLocale().toLanguageTag());
|
||||
assertEquals(Set.of(), systemAdmin.getGroups());
|
||||
MatcherAssert.assertThat(systemAdmin.getRoles(), containsInAnyOrder("system_admin_privileges"));
|
||||
assertTrue(systemAdmin.getProperties().isEmpty());
|
||||
|
||||
// admin2
|
||||
User admin2 = findUser("admin2", users);
|
||||
assertEquals("1", admin2.getUserId());
|
||||
assertEquals("admin2", admin2.getUsername());
|
||||
assertEquals("8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",
|
||||
StringHelper.toHexString(admin2.getPasswordCrypt().password()));
|
||||
assertEquals("Application", admin2.getFirstname());
|
||||
assertEquals("Administrator", admin2.getLastname());
|
||||
assertEquals(UserState.ENABLED, admin2.getUserState());
|
||||
assertEquals("en-GB", admin2.getLocale().toLanguageTag());
|
||||
MatcherAssert.assertThat(admin2.getGroups(), containsInAnyOrder("AppUserLocationA"));
|
||||
MatcherAssert.assertThat(admin2.getRoles(), containsInAnyOrder("PrivilegeAdmin"));
|
||||
properties = admin2.getProperties();
|
||||
assertEquals(new HashSet<>(Arrays.asList("organization", "organizationalUnit")), properties.keySet());
|
||||
assertEquals("eitchnet.ch", properties.get("organization"));
|
||||
assertEquals("Development", properties.get("organizationalUnit"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canReadGroups() {
|
||||
|
||||
PrivilegeGroupsSaxReader xmlHandler = new PrivilegeGroupsSaxReader();
|
||||
File xmlFile = new File(SRC_TEST + "PrivilegeGroups.xml");
|
||||
XmlHelper.parseDocument(xmlFile, xmlHandler);
|
||||
|
||||
Map<String, Group> groups = xmlHandler.getGroups();
|
||||
assertNotNull(groups);
|
||||
|
||||
assertEquals(1, groups.size());
|
||||
|
||||
// group AppUserLocationA
|
||||
Group group = groups.get("AppUserLocationA");
|
||||
assertEquals("AppUserLocationA", group.name());
|
||||
MatcherAssert.assertThat(group.roles(), containsInAnyOrder("AppUser", "ModelAccessor", "UserPrivileges"));
|
||||
Map<String, String> properties = group.getProperties();
|
||||
assertEquals(new HashSet<>(List.of("location")), properties.keySet());
|
||||
assertEquals("LocationA", properties.get("location"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -241,18 +287,18 @@ public class XmlTest {
|
|||
Role privilegeAdmin = findRole("PrivilegeAdmin", roles);
|
||||
assertEquals("PrivilegeAdmin", privilegeAdmin.getName());
|
||||
assertEquals(18, privilegeAdmin.getPrivilegeNames().size());
|
||||
IPrivilege privilegeAction = privilegeAdmin.getPrivilege(PrivilegeHandler.PRIVILEGE_ACTION);
|
||||
Privilege privilegeAction = privilegeAdmin.getPrivilege(PrivilegeHandler.PRIVILEGE_ACTION);
|
||||
assertFalse(privilegeAction.isAllAllowed());
|
||||
assertEquals(5, privilegeAction.getAllowList().size());
|
||||
assertEquals(0, privilegeAction.getDenyList().size());
|
||||
assertEquals("DefaultPrivilege", privilegeAction.getPolicy());
|
||||
|
||||
IPrivilege privilegeAddRole = privilegeAdmin.getPrivilege(PrivilegeHandler.PRIVILEGE_ADD_ROLE);
|
||||
Privilege privilegeAddRole = privilegeAdmin.getPrivilege(PrivilegeHandler.PRIVILEGE_ADD_ROLE);
|
||||
assertTrue(privilegeAddRole.isAllAllowed());
|
||||
assertEquals(0, privilegeAddRole.getAllowList().size());
|
||||
assertEquals(0, privilegeAddRole.getDenyList().size());
|
||||
|
||||
IPrivilege privilegeRemRoleFromUser = privilegeAdmin.getPrivilege(
|
||||
Privilege privilegeRemRoleFromUser = privilegeAdmin.getPrivilege(
|
||||
PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER);
|
||||
assertTrue(privilegeRemRoleFromUser.isAllAllowed());
|
||||
assertEquals(0, privilegeRemRoleFromUser.getAllowList().size());
|
||||
|
@ -264,7 +310,7 @@ public class XmlTest {
|
|||
assertEquals(new HashSet<>(Collections.singletonList("li.strolch.privilege.test.model.TestRestrictable")),
|
||||
appUser.getPrivilegeNames());
|
||||
|
||||
IPrivilege testRestrictable = appUser.getPrivilege("li.strolch.privilege.test.model.TestRestrictable");
|
||||
Privilege testRestrictable = appUser.getPrivilege("li.strolch.privilege.test.model.TestRestrictable");
|
||||
assertEquals("li.strolch.privilege.test.model.TestRestrictable", testRestrictable.getName());
|
||||
assertEquals("DefaultPrivilege", testRestrictable.getPolicy());
|
||||
assertTrue(testRestrictable.isAllAllowed());
|
||||
|
@ -279,7 +325,7 @@ public class XmlTest {
|
|||
containsInAnyOrder("li.strolch.privilege.handler.SystemAction",
|
||||
"li.strolch.privilege.test.model.TestSystemRestrictable"));
|
||||
|
||||
IPrivilege testSystemUserAction = systemAdminPrivileges.getPrivilege(
|
||||
Privilege testSystemUserAction = systemAdminPrivileges.getPrivilege(
|
||||
"li.strolch.privilege.handler.SystemAction");
|
||||
assertEquals("li.strolch.privilege.handler.SystemAction", testSystemUserAction.getName());
|
||||
assertEquals("DefaultPrivilege", testSystemUserAction.getPolicy());
|
||||
|
@ -287,7 +333,7 @@ public class XmlTest {
|
|||
assertEquals(1, testSystemUserAction.getAllowList().size());
|
||||
assertEquals(1, testSystemUserAction.getDenyList().size());
|
||||
|
||||
IPrivilege testSystemRestrictable = systemAdminPrivileges.getPrivilege(
|
||||
Privilege testSystemRestrictable = systemAdminPrivileges.getPrivilege(
|
||||
"li.strolch.privilege.test.model.TestSystemRestrictable");
|
||||
assertEquals("li.strolch.privilege.test.model.TestSystemRestrictable", testSystemRestrictable.getName());
|
||||
assertEquals("DefaultPrivilege", testSystemRestrictable.getPolicy());
|
||||
|
@ -302,7 +348,7 @@ public class XmlTest {
|
|||
MatcherAssert.assertThat(restrictedRole.getPrivilegeNames(),
|
||||
containsInAnyOrder("li.strolch.privilege.handler.SystemAction"));
|
||||
|
||||
IPrivilege testSystemUserAction2 = restrictedRole.getPrivilege("li.strolch.privilege.handler.SystemAction");
|
||||
Privilege testSystemUserAction2 = restrictedRole.getPrivilege("li.strolch.privilege.handler.SystemAction");
|
||||
assertEquals("li.strolch.privilege.handler.SystemAction", testSystemUserAction2.getName());
|
||||
assertEquals("DefaultPrivilege", testSystemUserAction2.getPolicy());
|
||||
assertFalse(testSystemUserAction2.isAllAllowed());
|
||||
|
@ -326,29 +372,35 @@ public class XmlTest {
|
|||
public void canWriteUsers() throws XMLStreamException, IOException {
|
||||
|
||||
Map<String, String> propertyMap;
|
||||
Set<String> groups;
|
||||
Set<String> userRoles;
|
||||
|
||||
List<User> users = new ArrayList<>();
|
||||
propertyMap = new HashMap<>();
|
||||
propertyMap.put("prop1", "value1");
|
||||
groups = new HashSet<>();
|
||||
groups.add("group1");
|
||||
userRoles = new HashSet<>();
|
||||
userRoles.add("role1");
|
||||
UserHistory history = new UserHistory();
|
||||
history.setFirstLogin(ZonedDateTime.of(LocalDateTime.of(2020, 1, 2, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
UserHistory history = UserHistory.EMPTY.withFirstLogin(
|
||||
ZonedDateTime.of(LocalDateTime.of(2020, 1, 2, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
User user1 = new User("1", "user1",
|
||||
new PasswordCrypt("blabla".getBytes(), "blabla".getBytes(), "PBKDF2WithHmacSHA512", 10000, 256), "Bob",
|
||||
"White", UserState.DISABLED, userRoles, Locale.ENGLISH, propertyMap, false, history);
|
||||
"White", UserState.DISABLED, groups, userRoles, Locale.ENGLISH, propertyMap, false, history);
|
||||
users.add(user1);
|
||||
|
||||
propertyMap = new HashMap<>();
|
||||
propertyMap.put("prop2", "value2");
|
||||
groups = new HashSet<>();
|
||||
groups.add("group2");
|
||||
userRoles = new HashSet<>();
|
||||
userRoles.add("role2");
|
||||
history = new UserHistory();
|
||||
history.setFirstLogin(ZonedDateTime.of(LocalDateTime.of(2020, 1, 2, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
history.setLastLogin(ZonedDateTime.of(LocalDateTime.of(2020, 1, 5, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
history = UserHistory.EMPTY.withFirstLogin(
|
||||
ZonedDateTime.of(LocalDateTime.of(2020, 1, 2, 2, 3, 4, 5), ZoneId.systemDefault()))
|
||||
.withLastLogin(ZonedDateTime.of(LocalDateTime.of(2020, 1, 5, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
User user2 = new User("2", "user2", new PasswordCrypt("haha".getBytes(), "haha".getBytes(), null, -1, -1),
|
||||
"Leonard", "Sheldon", UserState.ENABLED, userRoles, Locale.ENGLISH, propertyMap, false, history);
|
||||
"Leonard", "Sheldon", UserState.ENABLED, groups, userRoles, Locale.ENGLISH, propertyMap, false,
|
||||
history);
|
||||
users.add(user2);
|
||||
|
||||
File modelFile = new File(TARGET_TEST + "PrivilegeUsersTest.xml");
|
||||
|
@ -370,8 +422,8 @@ public class XmlTest {
|
|||
assertEquals(user1.getFirstname(), parsedUser1.getFirstname());
|
||||
assertEquals(user1.getLastname(), parsedUser1.getLastname());
|
||||
assertEquals(user1.getLocale(), parsedUser1.getLocale());
|
||||
assertArrayEquals(user1.getPasswordCrypt().getPassword(), parsedUser1.getPasswordCrypt().getPassword());
|
||||
assertArrayEquals(user1.getPasswordCrypt().getSalt(), parsedUser1.getPasswordCrypt().getSalt());
|
||||
assertArrayEquals(user1.getPasswordCrypt().password(), parsedUser1.getPasswordCrypt().password());
|
||||
assertArrayEquals(user1.getPasswordCrypt().salt(), parsedUser1.getPasswordCrypt().salt());
|
||||
assertEquals(user1.getProperties(), parsedUser1.getProperties());
|
||||
assertEquals(user1.getUserId(), parsedUser1.getUserId());
|
||||
assertEquals(user1.getUserState(), parsedUser1.getUserState());
|
||||
|
@ -380,22 +432,57 @@ public class XmlTest {
|
|||
assertEquals(user2.getFirstname(), parsedUser2.getFirstname());
|
||||
assertEquals(user2.getLastname(), parsedUser2.getLastname());
|
||||
assertEquals(user2.getLocale(), parsedUser2.getLocale());
|
||||
assertArrayEquals(user2.getPasswordCrypt().getPassword(), parsedUser2.getPasswordCrypt().getPassword());
|
||||
assertArrayEquals(user2.getPasswordCrypt().getSalt(), parsedUser2.getPasswordCrypt().getSalt());
|
||||
assertArrayEquals(user2.getPasswordCrypt().password(), parsedUser2.getPasswordCrypt().password());
|
||||
assertArrayEquals(user2.getPasswordCrypt().salt(), parsedUser2.getPasswordCrypt().salt());
|
||||
assertEquals(user2.getProperties(), parsedUser2.getProperties());
|
||||
assertEquals(user2.getUserId(), parsedUser2.getUserId());
|
||||
assertEquals(user2.getUserState(), parsedUser2.getUserState());
|
||||
assertEquals(user2.getRoles(), parsedUser2.getRoles());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canWriteGroups() throws XMLStreamException, IOException {
|
||||
|
||||
Map<String, String> propertyMap;
|
||||
Set<String> roles;
|
||||
|
||||
List<Group> groups = new ArrayList<>();
|
||||
propertyMap = new HashMap<>();
|
||||
propertyMap.put("prop1", "value1");
|
||||
roles = new HashSet<>();
|
||||
roles.add("role1");
|
||||
Group newGroup = new Group("group1", roles, propertyMap);
|
||||
groups.add(newGroup);
|
||||
|
||||
File modelFile = new File(TARGET_TEST + "PrivilegeGroupsTest.xml");
|
||||
PrivilegeGroupsSaxWriter configSaxWriter = new PrivilegeGroupsSaxWriter(groups, modelFile);
|
||||
configSaxWriter.write();
|
||||
|
||||
PrivilegeGroupsSaxReader xmlHandler = new PrivilegeGroupsSaxReader();
|
||||
XmlHelper.parseDocument(modelFile, xmlHandler);
|
||||
|
||||
Map<String, Group> parsedGroups = xmlHandler.getGroups();
|
||||
assertNotNull(parsedGroups);
|
||||
assertEquals(1, parsedGroups.size());
|
||||
|
||||
// group group1
|
||||
Group parsedGroup1 = parsedGroups.get("group1");
|
||||
assertNotNull(parsedGroup1);
|
||||
assertEquals("group1", parsedGroup1.name());
|
||||
MatcherAssert.assertThat(parsedGroup1.roles(), containsInAnyOrder("role1"));
|
||||
Map<String, String> properties = parsedGroup1.getProperties();
|
||||
assertEquals(new HashSet<>(List.of("prop1")), properties.keySet());
|
||||
assertEquals("value1", properties.get("prop1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canWriteRoles() throws XMLStreamException, IOException {
|
||||
|
||||
Map<String, IPrivilege> privilegeMap;
|
||||
Map<String, Privilege> privilegeMap;
|
||||
List<Role> roles = new ArrayList<>();
|
||||
Set<String> list = Collections.emptySet();
|
||||
privilegeMap = new HashMap<>();
|
||||
privilegeMap.put("priv1", new PrivilegeImpl("priv1", "DefaultPrivilege", true, list, list));
|
||||
privilegeMap.put("priv1", new Privilege("priv1", "DefaultPrivilege", true, list, list));
|
||||
Role role1 = new Role("role1", privilegeMap);
|
||||
roles.add(role1);
|
||||
|
||||
|
@ -404,7 +491,7 @@ public class XmlTest {
|
|||
denyList.add("myself");
|
||||
Set<String> allowList = new HashSet<>();
|
||||
allowList.add("other");
|
||||
privilegeMap.put("priv2", new PrivilegeImpl("priv2", "DefaultPrivilege", false, denyList, allowList));
|
||||
privilegeMap.put("priv2", new Privilege("priv2", "DefaultPrivilege", false, denyList, allowList));
|
||||
Role role2 = new Role("role2", privilegeMap);
|
||||
roles.add(role2);
|
||||
|
||||
|
@ -428,8 +515,8 @@ public class XmlTest {
|
|||
Set<String> privilegeNames = role1.getPrivilegeNames();
|
||||
assertEquals(privilegeNames, parsedRole1.getPrivilegeNames());
|
||||
for (String privilegeName : privilegeNames) {
|
||||
IPrivilege privilege = role1.getPrivilege(privilegeName);
|
||||
IPrivilege privilege2 = parsedRole1.getPrivilege(privilegeName);
|
||||
Privilege privilege = role1.getPrivilege(privilegeName);
|
||||
Privilege privilege2 = parsedRole1.getPrivilege(privilegeName);
|
||||
assertNotNull(privilege);
|
||||
assertNotNull(privilege2);
|
||||
|
||||
|
@ -443,8 +530,8 @@ public class XmlTest {
|
|||
assertEquals(role2.getPrivilegeNames(), parsedRole2.getPrivilegeNames());
|
||||
privilegeNames = role2.getPrivilegeNames();
|
||||
for (String privilegeName : privilegeNames) {
|
||||
IPrivilege privilege = role2.getPrivilege(privilegeName);
|
||||
IPrivilege privilege2 = parsedRole2.getPrivilege(privilegeName);
|
||||
Privilege privilege = role2.getPrivilege(privilegeName);
|
||||
Privilege privilege2 = parsedRole2.getPrivilege(privilegeName);
|
||||
assertNotNull(privilege);
|
||||
assertNotNull(privilege2);
|
||||
|
||||
|
|
|
@ -28,9 +28,10 @@ public class DummySsoHandler implements SingleSignOnHandler {
|
|||
|
||||
@SuppressWarnings("unchecked") Map<String, String> map = (Map<String, String>) data;
|
||||
|
||||
Set<String> groups = Arrays.stream(map.get("groups").split(",")).map(String::trim).collect(Collectors.toSet());
|
||||
Set<String> roles = Arrays.stream(map.get("roles").split(",")).map(String::trim).collect(Collectors.toSet());
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
return new User(map.get("userId"), map.get("username"), null, map.get("firstName"), map.get("lastName"),
|
||||
UserState.REMOTE, roles, Locale.ENGLISH, properties, false, new UserHistory());
|
||||
UserState.REMOTE, groups, roles, Locale.ENGLISH, properties, false, UserHistory.EMPTY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<Parameters>
|
||||
<Parameter name="basePath" value="target/${target}"/>
|
||||
<Parameter name="usersXmlFile" value="PrivilegeUsersMerge.xml"/>
|
||||
<Parameter name="groupsXmlFile" value="PrivilegeGroupsMerge.xml"/>
|
||||
<Parameter name="rolesXmlFile" value="PrivilegeRolesMerge.xml"/>
|
||||
</Parameters>
|
||||
</PersistenceHandler>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<Groups>
|
||||
<Group name="AppUserLocationA">
|
||||
<Roles>
|
||||
<Role>AppUser</Role>
|
||||
<Role>ModelAccessor</Role>
|
||||
<Role>UserPrivileges</Role>
|
||||
</Roles>
|
||||
<Properties>
|
||||
<Property name="location" value="LocationA"/>
|
||||
</Properties>
|
||||
</Group>
|
||||
</Groups>
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<Groups>
|
||||
<Group name="GroupA1">
|
||||
<Roles>
|
||||
<Role>RoleA1</Role>
|
||||
</Roles>
|
||||
<Properties>
|
||||
<Property name="location" value="LocationA1"/>
|
||||
</Properties>
|
||||
</Group>
|
||||
<Group name="GroupA2">
|
||||
<Roles>
|
||||
<Role>RoleA2</Role>
|
||||
</Roles>
|
||||
<Properties>
|
||||
<Property name="location" value="LocationA2"/>
|
||||
</Properties>
|
||||
</Group>
|
||||
|
||||
<Group name="GroupB1">
|
||||
<Roles>
|
||||
<Role>RoleB1</Role>
|
||||
</Roles>
|
||||
<Properties>
|
||||
<Property name="location" value="LocationB1"/>
|
||||
</Properties>
|
||||
</Group>
|
||||
|
||||
<Group name="GroupB2">
|
||||
<Roles>
|
||||
<Role>RoleB2</Role>
|
||||
</Roles>
|
||||
<Properties>
|
||||
<Property name="location" value="LocationB2"/>
|
||||
</Properties>
|
||||
</Group>
|
||||
</Groups>
|
|
@ -6,6 +6,9 @@
|
|||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Groups>
|
||||
<Group>GroupA</Group>
|
||||
</Groups>
|
||||
<Roles>
|
||||
<Role>PrivilegeAdmin</Role>
|
||||
<Role>AppUser</Role>
|
||||
|
@ -21,9 +24,11 @@
|
|||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Groups>
|
||||
<Group>AppUserLocationA</Group>
|
||||
</Groups>
|
||||
<Roles>
|
||||
<Role>PrivilegeAdmin</Role>
|
||||
<Role>AppUser</Role>
|
||||
</Roles>
|
||||
<Properties>
|
||||
<Property name="organization" value="eitchnet.ch"/>
|
||||
|
|
|
@ -23,4 +23,26 @@
|
|||
</Roles>
|
||||
</User>
|
||||
|
||||
<User userId="3" username="userC" password="cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344" salt="61646d696e">
|
||||
<Firstname>System User</Firstname>
|
||||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Groups>
|
||||
<Group>GroupA1</Group>
|
||||
<Group>GroupA2</Group>
|
||||
</Groups>
|
||||
</User>
|
||||
|
||||
<User userId="4" username="userD" password="cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344" salt="61646d696e">
|
||||
<Firstname>System User</Firstname>
|
||||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Groups>
|
||||
<Group>GroupB1</Group>
|
||||
<Group>GroupB2</Group>
|
||||
</Groups>
|
||||
</User>
|
||||
|
||||
</Users>
|
|
@ -5,7 +5,7 @@ import static li.strolch.report.ReportConstants.TYPE_REPORT;
|
|||
import java.util.Set;
|
||||
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.search.ResourceSearch;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ public class ReportSearch extends ResourceSearch {
|
|||
public ReportSearch(StrolchTransaction tx) {
|
||||
types(TYPE_REPORT);
|
||||
|
||||
IPrivilege reportPrivilege = tx.getPrivilegeContext().getPrivilege(ReportSearch.class.getName());
|
||||
Privilege reportPrivilege = tx.getPrivilegeContext().getPrivilege(ReportSearch.class.getName());
|
||||
if (!reportPrivilege.isAllAllowed()) {
|
||||
Set<String> allowedReportIds = reportPrivilege.getAllowList();
|
||||
where(id().isIn(allowedReportIds));
|
||||
|
|
|
@ -15,11 +15,6 @@
|
|||
*/
|
||||
package li.strolch.command.privilege.users;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import li.strolch.command.AbstractRealmCommandTest;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.privilege.model.UserRep;
|
||||
|
@ -27,6 +22,11 @@ import li.strolch.privilege.model.UserState;
|
|||
import li.strolch.service.api.Command;
|
||||
import li.strolch.service.privilege.users.PrivilegeAddUserCommand;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
|
@ -40,12 +40,14 @@ public class PrivilegeAddUserCommandTest extends AbstractRealmCommandTest {
|
|||
@Override
|
||||
protected Command getCommandInstance(StrolchTransaction tx) {
|
||||
|
||||
Set<String> groups = new HashSet<>();
|
||||
groups.add("AppGroups");
|
||||
Set<String> roles = new HashSet<>();
|
||||
roles.add("AppUser");
|
||||
Map<String, String> propertyMap = new HashMap<>();
|
||||
|
||||
UserRep user = new UserRep(null, "dude", "Jeff", "Lebowski", UserState.ENABLED, roles, Locale.getDefault(),
|
||||
propertyMap, null);
|
||||
UserRep user = new UserRep(null, "dude", "Jeff", "Lebowski", UserState.ENABLED, groups, roles,
|
||||
Locale.getDefault(), propertyMap, null);
|
||||
|
||||
PrivilegeAddUserCommand command = new PrivilegeAddUserCommand(tx);
|
||||
command.setUserIn(user);
|
||||
|
|
|
@ -43,12 +43,14 @@ public class PrivilegeAddUserServiceTest extends AbstractRealmServiceTest<Privil
|
|||
|
||||
@Override
|
||||
protected PrivilegeUserArgument getArgInstance() {
|
||||
Set<String> groups = new HashSet<>();
|
||||
groups.add("AppGroups");
|
||||
Set<String> roles = new HashSet<>();
|
||||
roles.add("AppUser");
|
||||
Map<String, String> propertyMap = new HashMap<>();
|
||||
|
||||
PrivilegeUserArgument arg = new PrivilegeUserArgument();
|
||||
arg.user = new UserRep(null, "dude", "Jeff", "Lebowski", UserState.ENABLED, roles, Locale.getDefault(),
|
||||
arg.user = new UserRep(null, "dude", "Jeff", "Lebowski", UserState.ENABLED, groups, roles, Locale.getDefault(),
|
||||
propertyMap, null);
|
||||
|
||||
return arg;
|
||||
|
|
|
@ -33,6 +33,7 @@ import li.strolch.service.test.model.GreetingResult;
|
|||
import li.strolch.service.test.model.GreetingService;
|
||||
import li.strolch.service.test.model.GreetingService.GreetingArgument;
|
||||
import li.strolch.service.test.model.TestService;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -42,11 +43,11 @@ public class ServiceTest extends AbstractServiceTest {
|
|||
|
||||
@Test
|
||||
public void shouldFailInvalidCertificate1() {
|
||||
assertThrows(PrivilegeException.class, () -> {
|
||||
assertThrows(DBC.DbcException.class, () -> {
|
||||
TestService testService = new TestService();
|
||||
getServiceHandler().doService(
|
||||
new Certificate(null, null, null, null, null, null, null, null, ZonedDateTime.now(), false, null,
|
||||
new HashSet<>(), null), testService);
|
||||
new HashSet<>(), new HashSet<>(), null), testService);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -54,7 +55,7 @@ public class ServiceTest extends AbstractServiceTest {
|
|||
public void shouldFailInvalidCertificate2() {
|
||||
TestService testService = new TestService();
|
||||
Certificate badCert = new Certificate(Usage.ANY, "1", "bob", "Bob", "Brown", UserState.ENABLED, "dsdf", "asd",
|
||||
ZonedDateTime.now(), false, null, new HashSet<>(), null);
|
||||
ZonedDateTime.now(), false, null, new HashSet<>(), new HashSet<>(), null);
|
||||
ServiceResult svcResult = getServiceHandler().doService(badCert, testService);
|
||||
assertThat(svcResult.getThrowable(), instanceOf(NotAuthenticatedException.class));
|
||||
}
|
||||
|
@ -67,8 +68,7 @@ public class ServiceTest extends AbstractServiceTest {
|
|||
try {
|
||||
TestService testService = new TestService();
|
||||
ServiceResult svcResult = getServiceHandler().doService(certificate, testService);
|
||||
assertThat(svcResult.getMessage(),
|
||||
containsString("User jill may not perform service TestService"));
|
||||
assertThat(svcResult.getMessage(), containsString("User jill may not perform service TestService"));
|
||||
assertThat(svcResult.getThrowable(), instanceOf(AccessDeniedException.class));
|
||||
} finally {
|
||||
runtimeMock.getPrivilegeHandler().invalidate(certificate);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<Groups>
|
||||
<Group name="AppGroups">
|
||||
<Roles>
|
||||
<Role>AppGroup</Role>
|
||||
</Roles>
|
||||
</Group>
|
||||
</Groups>
|
|
@ -1,174 +1,183 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Roles>
|
||||
<Role name="agent">
|
||||
<Privilege name="li.strolch.privilege.handler.SystemAction" policy="DefaultPrivilege">
|
||||
<Allow>li.strolch.runtime.privilege.StrolchSystemAction</Allow>
|
||||
<Allow>li.strolch.runtime.privilege.StrolchSystemActionWithResult</Allow>
|
||||
<Allow>li.strolch.persistence.postgresql.PostgreSqlSchemaInitializer</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="li.strolch.search.StrolchSearch" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Role name="agent">
|
||||
<Privilege name="li.strolch.privilege.handler.SystemAction" policy="DefaultPrivilege">
|
||||
<Allow>li.strolch.runtime.privilege.StrolchSystemAction</Allow>
|
||||
<Allow>li.strolch.runtime.privilege.StrolchSystemActionWithResult</Allow>
|
||||
<Allow>li.strolch.persistence.postgresql.PostgreSqlSchemaInitializer</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="li.strolch.search.StrolchSearch" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
|
||||
<Privilege name="GetResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="GetOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="GetActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="AddResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="AddOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="AddActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
</Role>
|
||||
<Privilege name="GetResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="GetOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="GetActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="AddResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="AddOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="AddActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveResource" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveOrder" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveActivity" policy="ModelPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
</Role>
|
||||
|
||||
<Role name="AppUser">
|
||||
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="li.strolch.search.StrolchSearch" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Role name="AppGroup">
|
||||
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="li.strolch.search.StrolchSearch" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
</Role>
|
||||
|
||||
<Privilege name="GetResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="GetOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="GetActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="AddResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="AddOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="AddActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
</Role>
|
||||
<Role name="AppUser">
|
||||
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="li.strolch.search.StrolchSearch" policy="DefaultPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
|
||||
<Role name="PrivilegeAdmin">
|
||||
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeUpdateUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeUpdateUserRolesService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeSetUserPasswordService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeSetUserLocaleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeRemoveUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeRemoveRoleFromUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeAddUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeAddRoleToUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeUpdateRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeRemoveRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeRemovePrivilegeFromRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeAddRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeAddOrReplacePrivilegeOnRoleService</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAddUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeRemoveUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="InvalidateSession" policy="UserSessionAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeSetUserPassword" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RequirePasswordChange" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeSetUserLocale" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAction" policy="DefaultPrivilege">
|
||||
<Allow>Reload</Allow>
|
||||
<Allow>GetPolicies</Allow>
|
||||
<Allow>Persist</Allow>
|
||||
<Allow>GetCertificates</Allow>
|
||||
<Allow>PersistSessions</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeGetUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeSetUserState" policy="UserAccessPrivilege">
|
||||
<Deny>SYSTEM</Deny>
|
||||
<Allow>DISABLED</Allow>
|
||||
<Allow>ENABLED</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAddRoleToUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeGetRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="GetSession" policy="UserSessionAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeModifyUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeRemoveRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeRemoveRoleFromUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeModifyRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAddRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
</Role>
|
||||
<Privilege name="GetResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="GetOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="GetActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="AddResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="AddOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="AddActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="UpdateActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveResource" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveOrder" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="RemoveActivity" policy="ModelPrivilege">
|
||||
<Allow>Bike</Allow>
|
||||
</Privilege>
|
||||
</Role>
|
||||
|
||||
<Role name="PrivilegeAdmin">
|
||||
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeUpdateUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeUpdateUserRolesService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeSetUserPasswordService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeSetUserLocaleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeRemoveUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeRemoveRoleFromUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeAddUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.users.PrivilegeAddRoleToUserService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeUpdateRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeRemoveRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeRemovePrivilegeFromRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeAddRoleService</Allow>
|
||||
<Allow>li.strolch.service.privilege.roles.PrivilegeAddOrReplacePrivilegeOnRoleService</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAddUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeRemoveUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="InvalidateSession" policy="UserSessionAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeSetUserPassword" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="RequirePasswordChange" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeSetUserLocale" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAction" policy="DefaultPrivilege">
|
||||
<Allow>Reload</Allow>
|
||||
<Allow>GetPolicies</Allow>
|
||||
<Allow>Persist</Allow>
|
||||
<Allow>GetCertificates</Allow>
|
||||
<Allow>PersistSessions</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeGetUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeSetUserState" policy="UserAccessPrivilege">
|
||||
<Deny>SYSTEM</Deny>
|
||||
<Allow>DISABLED</Allow>
|
||||
<Allow>ENABLED</Allow>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAddRoleToUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeGetRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="GetSession" policy="UserSessionAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeModifyUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeRemoveRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeRemoveRoleFromUser" policy="UserAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeModifyRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
<Privilege name="PrivilegeAddRole" policy="RoleAccessPrivilege">
|
||||
<AllAllowed>true</AllAllowed>
|
||||
</Privilege>
|
||||
</Role>
|
||||
</Roles>
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Users>
|
||||
<User userId="1" username="agent">
|
||||
<State>SYSTEM</State>
|
||||
<Roles>
|
||||
<Role>agent</Role>
|
||||
</Roles>
|
||||
</User>
|
||||
<User userId="3" username="test" password="fdd9d2def3475e1d5cc87107b87e14fd6adbca664c2874fc379a1e53931c0428" salt="74657374">
|
||||
<Firstname>Application</Firstname>
|
||||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Roles>
|
||||
<Role>AppUser</Role>
|
||||
</Roles>
|
||||
</User>
|
||||
<User userId="3" username="admin" password="cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344" salt="61646d696e">
|
||||
<Firstname>Application</Firstname>
|
||||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Roles>
|
||||
<Role>AppUser</Role>
|
||||
<Role>PrivilegeAdmin</Role>
|
||||
</Roles>
|
||||
</User>
|
||||
<User userId="1" username="agent">
|
||||
<State>SYSTEM</State>
|
||||
<Roles>
|
||||
<Role>agent</Role>
|
||||
</Roles>
|
||||
</User>
|
||||
<User userId="3" username="test" password="fdd9d2def3475e1d5cc87107b87e14fd6adbca664c2874fc379a1e53931c0428" salt="74657374">
|
||||
<Firstname>Application</Firstname>
|
||||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Roles>
|
||||
<Role>AppUser</Role>
|
||||
</Roles>
|
||||
</User>
|
||||
<User userId="3" username="admin" password="cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344" salt="61646d696e">
|
||||
<Firstname>Application</Firstname>
|
||||
<Lastname>Administrator</Lastname>
|
||||
<State>ENABLED</State>
|
||||
<Locale>en-GB</Locale>
|
||||
<Roles>
|
||||
<Role>AppUser</Role>
|
||||
<Role>PrivilegeAdmin</Role>
|
||||
</Roles>
|
||||
</User>
|
||||
</Users>
|
||||
|
|
|
@ -37,7 +37,7 @@ import li.strolch.privilege.base.AccessDeniedException;
|
|||
import li.strolch.privilege.base.InvalidCredentialsException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.privilege.model.Usage;
|
||||
import li.strolch.rest.RestfulStrolchComponent;
|
||||
|
@ -401,7 +401,7 @@ public class AuthenticationService {
|
|||
loginResult.add("privileges", privArr);
|
||||
|
||||
for (String name : privilegeContext.getPrivilegeNames()) {
|
||||
IPrivilege privilege = privilegeContext.getPrivilege(name);
|
||||
Privilege privilege = privilegeContext.getPrivilege(name);
|
||||
|
||||
JsonObject privObj = new JsonObject();
|
||||
privArr.add(privObj);
|
||||
|
|
|
@ -33,7 +33,7 @@ import li.strolch.job.StrolchJob;
|
|||
import li.strolch.job.StrolchJobsHandler;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.Privilege;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.rest.RestfulStrolchComponent;
|
||||
import li.strolch.rest.StrolchRestfulConstants;
|
||||
|
@ -76,7 +76,7 @@ public class StrolchJobsResource {
|
|||
if (ctx.hasRole(ROLE_STROLCH_ADMIN))
|
||||
return true;
|
||||
|
||||
IPrivilege privilege = ctx.getPrivilege(StrolchJob.class.getName());
|
||||
Privilege privilege = ctx.getPrivilege(StrolchJob.class.getName());
|
||||
return privilege.isAllAllowed() || privilege.getAllowList().contains(job.getClass().getName());
|
||||
}) //
|
||||
.sorted(comparing(StrolchJob::getName)) //
|
||||
|
|
Loading…
Reference in New Issue