[Major] Implemented SingleSignOn facility for Privilege

This commit is contained in:
Robert von Burg 2017-10-06 16:59:22 +02:00
parent 484d0a9e92
commit adf53dd49f
32 changed files with 915 additions and 759 deletions

View File

@ -336,7 +336,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
private void assertQueryAllowed(StrolchQuery query) { private void assertQueryAllowed(StrolchQuery query) {
try { try {
PrivilegeContext privilegeContext = this.privilegeHandler.getPrivilegeContext(this.certificate); PrivilegeContext privilegeContext = this.privilegeHandler.validate(this.certificate);
privilegeContext.validateAction(query); privilegeContext.validateAction(query);
} catch (PrivilegeException e) { } catch (PrivilegeException e) {
throw new StrolchAccessDeniedException(this.certificate, query, ExceptionHelper.getExceptionMessage(e), e); throw new StrolchAccessDeniedException(this.certificate, query, ExceptionHelper.getExceptionMessage(e), e);
@ -705,7 +705,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
public void assertHasPrivilege(Operation operation, StrolchRootElement element) throws AccessDeniedException { public void assertHasPrivilege(Operation operation, StrolchRootElement element) throws AccessDeniedException {
DBC.PRE.assertNotNull("operation must not be null", operation); DBC.PRE.assertNotNull("operation must not be null", operation);
DBC.PRE.assertNotNull("element must not be null", element); DBC.PRE.assertNotNull("element must not be null", element);
this.privilegeHandler.getPrivilegeContext(this.certificate) this.privilegeHandler.validate(this.certificate)
.validateAction(new TransactedRestrictable(this, operation.getPrivilegeName(element), element)); .validateAction(new TransactedRestrictable(this, operation.getPrivilegeName(element), element));
} }
@ -960,13 +960,9 @@ public abstract class AbstractTransaction implements StrolchTransaction {
@Override @Override
public void autoCloseableReadOnly() throws StrolchTransactionException { public void autoCloseableReadOnly() throws StrolchTransactionException {
long start = System.nanoTime(); long start = System.nanoTime();
boolean throwException = false;
try { try {
this.txResult.setState(TransactionState.CLOSING); this.txResult.setState(TransactionState.CLOSING);
Thread.currentThread().getUncaughtExceptionHandler();
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (!this.commands.isEmpty()) { if (!this.commands.isEmpty()) {
autoCloseableRollback(); autoCloseableRollback();
String msg = "There are commands registered on a read-only transaction. Changing to rollback! Did you forget to commit?"; String msg = "There are commands registered on a read-only transaction. Changing to rollback! Did you forget to commit?";
@ -1218,8 +1214,6 @@ public abstract class AbstractTransaction implements StrolchTransaction {
List<Audit> audits = new ArrayList<>(); List<Audit> audits = new ArrayList<>();
// TODO this is bad... doesn't account for a created and deleted in same TX...
if (this.orderMap != null) { if (this.orderMap != null) {
if (this.realm.isAuditTrailEnabledForRead()) if (this.realm.isAuditTrailEnabledForRead())
auditsFor(audits, AccessType.READ, this.orderMap.getRead()); auditsFor(audits, AccessType.READ, this.orderMap.getRead());

View File

@ -30,14 +30,8 @@ import li.strolch.agent.api.StrolchRealm;
import li.strolch.model.audit.AccessType; import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit; import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.StrolchTransaction; import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.base.NotAuthenticatedException;
import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.handler.DefaultPrivilegeHandler; import li.strolch.privilege.handler.*;
import li.strolch.privilege.handler.EncryptionHandler;
import li.strolch.privilege.handler.PersistenceHandler;
import li.strolch.privilege.handler.SystemAction;
import li.strolch.privilege.handler.SystemActionWithResult;
import li.strolch.privilege.handler.XmlPersistenceHandler;
import li.strolch.privilege.helper.PrivilegeInitializationHelper; import li.strolch.privilege.helper.PrivilegeInitializationHelper;
import li.strolch.privilege.helper.XmlConstants; import li.strolch.privilege.helper.XmlConstants;
import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.Certificate;
@ -67,24 +61,22 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements
// initialize privilege // initialize privilege
RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration(); RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
File privilegeConfigFile = configuration.getConfigFile(PROP_PRIVILEGE_CONFIG_FILE, PRIVILEGE_CONFIG_XML, File privilegeConfigFile = configuration
runtimeConfiguration); .getConfigFile(PROP_PRIVILEGE_CONFIG_FILE, PRIVILEGE_CONFIG_XML, runtimeConfiguration);
li.strolch.privilege.handler.PrivilegeHandler privilegeHandler = initializeFromXml(configuration, this.privilegeHandler = initializeFromXml(configuration, privilegeConfigFile);
privilegeConfigFile);
this.privilegeHandler = privilegeHandler;
} }
/** /**
* Initializes the {@link DefaultPrivilegeHandler} from the configuration file * Initializes the {@link DefaultPrivilegeHandler} from the configuration file
* *
* @param privilegeXmlFile * @param privilegeXmlFile
* a {@link File} reference to the XML file containing the configuration for Privilege * a {@link File} reference to the XML file containing the configuration for Privilege
* *
* @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and * @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and
* {@link PersistenceHandler} are set and initialized as well * {@link PersistenceHandler} are set and initialized as well
*/ */
private li.strolch.privilege.handler.PrivilegeHandler initializeFromXml(ComponentConfiguration configuration, private li.strolch.privilege.handler.PrivilegeHandler initializeFromXml(ComponentConfiguration configuration,
File privilegeXmlFile) { File privilegeXmlFile) {
// make sure file exists // make sure file exists
if (!privilegeXmlFile.exists()) { if (!privilegeXmlFile.exists()) {
@ -142,14 +134,13 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements
} }
@Override @Override
public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException { public PrivilegeContext validate(Certificate certificate) throws PrivilegeException {
assertStarted(); return this.privilegeHandler.validate(certificate);
this.privilegeHandler.isCertificateValid(certificate);
} }
@Override @Override
public boolean invalidateSession(Certificate certificate) { public boolean invalidate(Certificate certificate) {
boolean invalidateSession = this.privilegeHandler.invalidateSession(certificate); boolean invalidateSession = this.privilegeHandler.invalidate(certificate);
StrolchRealm realm = getContainer().getRealm(certificate); StrolchRealm realm = getContainer().getRealm(certificate);
try (StrolchTransaction tx = realm.openTx(certificate, StrolchPrivilegeConstants.LOGOUT)) { try (StrolchTransaction tx = realm.openTx(certificate, StrolchPrivilegeConstants.LOGOUT)) {
tx.setSuppressDoNothingLogging(true); tx.setSuppressDoNothingLogging(true);
@ -164,7 +155,7 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements
@Override @Override
public boolean sessionTimeout(Certificate certificate) { public boolean sessionTimeout(Certificate certificate) {
assertStarted(); assertStarted();
boolean invalidateSession = this.privilegeHandler.invalidateSession(certificate); boolean invalidateSession = this.privilegeHandler.invalidate(certificate);
StrolchRealm realm = getContainer().getRealm(certificate); StrolchRealm realm = getContainer().getRealm(certificate);
try (StrolchTransaction tx = realm.openTx(certificate, StrolchPrivilegeConstants.SESSION_TIME_OUT)) { try (StrolchTransaction tx = realm.openTx(certificate, StrolchPrivilegeConstants.SESSION_TIME_OUT)) {
tx.setSuppressDoNothingLogging(true); tx.setSuppressDoNothingLogging(true);
@ -213,13 +204,8 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements
@Override @Override
public <T> T runAsAgentWithResult(PrivilegedRunnableWithResult<T> runnable) throws PrivilegeException { public <T> T runAsAgentWithResult(PrivilegedRunnableWithResult<T> runnable) throws PrivilegeException {
return this.privilegeHandler.runWithResult(StrolchConstants.SYSTEM_USER_AGENT, return this.privilegeHandler
new StrolchSystemActionWithResult<>(runnable)); .runWithResult(StrolchConstants.SYSTEM_USER_AGENT, new StrolchSystemActionWithResult<>(runnable));
}
@Override
public PrivilegeContext getPrivilegeContext(Certificate certificate) throws PrivilegeException {
return this.privilegeHandler.getPrivilegeContext(certificate);
} }
@Override @Override

View File

@ -24,183 +24,170 @@ import li.strolch.runtime.StrolchConstants;
/** /**
* The privilege handler for authenticating users and performing actions as a system user * The privilege handler for authenticating users and performing actions as a system user
* *
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*/ */
public interface PrivilegeHandler { public interface PrivilegeHandler {
/** /**
* Authenticate a user * Authenticate a user
* *
* @param username * @param username
* the username * the username
* @param password * @param password
* the password * the password
* *
* @return the certificate * @return the certificate
* *
* @see li.strolch.privilege.handler.PrivilegeHandler#authenticate(String, byte[]) * @see li.strolch.privilege.handler.PrivilegeHandler#authenticate(String, char[])
*/ */
public Certificate authenticate(String username, char[] password); Certificate authenticate(String username, char[] password);
/**
* Validate that the certificate is still valid
*
* @param certificate
* the certificate
*
* @throws PrivilegeException
* if the certificate is not valid
*
* @see li.strolch.privilege.handler.PrivilegeHandler#isCertificateValid(Certificate)
*/
public void isCertificateValid(Certificate certificate) throws PrivilegeException;
/**
* Invalidates the given certificate
*
* @param certificate
* the certificate
*
* @return true if the certificate was invalidated, or false if it was already invalidated
*
* @see li.strolch.privilege.handler.PrivilegeHandler#invalidateSession(li.strolch.privilege.model.Certificate)
*/
public boolean invalidateSession(Certificate certificate);
/**
* Notifies that the session has timed out, i.e. the certificate must be invalidated
*
* @param certificate
* the certificate that has timed out
* @return true if the certificate was invalidated, or false it was already invalidated
*
* @see li.strolch.privilege.handler.PrivilegeHandler#invalidateSession(li.strolch.privilege.model.Certificate)
*/
public boolean sessionTimeout(Certificate certificate);
/** /**
* Returns the {@link PrivilegeContext} for the given certificate * Returns the {@link PrivilegeContext} for the given certificate
* *
* @param certificate * @param certificate
* the certificate * the certificate
* *
* @return the {@link PrivilegeContext} for the given certificate * @return the {@link PrivilegeContext} for the given certificate
* *
* @throws PrivilegeException * @throws PrivilegeException
* if the certificate is not valid anymore * if the certificate is not valid anymore
* * @see li.strolch.privilege.handler.PrivilegeHandler#validate(li.strolch.privilege.model.Certificate)
* @see li.strolch.privilege.handler.PrivilegeHandler#getPrivilegeContext(li.strolch.privilege.model.Certificate)
*/ */
public PrivilegeContext getPrivilegeContext(Certificate certificate) throws PrivilegeException; PrivilegeContext validate(Certificate certificate) throws PrivilegeException;
/**
* Invalidates the given certificate
*
* @param certificate
* the certificate
*
* @return true if the certificate was invalidated, or false if it was already invalidated
*
* @see li.strolch.privilege.handler.PrivilegeHandler#invalidate(li.strolch.privilege.model.Certificate)
*/
boolean invalidate(Certificate certificate);
/**
* Notifies that the session has timed out, i.e. the certificate must be invalidated
*
* @param certificate
* the certificate that has timed out
*
* @return true if the certificate was invalidated, or false it was already invalidated
*
* @see li.strolch.privilege.handler.PrivilegeHandler#invalidate(li.strolch.privilege.model.Certificate)
*/
boolean sessionTimeout(Certificate certificate);
/** /**
* Run the given {@link SystemAction} as the given system user * Run the given {@link SystemAction} as the given system user
* *
* @param username * @param username
* the system username * the system username
* @param action * @param action
* the action to perform * the action to perform
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public void runAs(String username, SystemAction action) throws PrivilegeException; void runAs(String username, SystemAction action) throws PrivilegeException;
/** /**
* Run the given {@link SystemActionWithResult} as the given system user * Run the given {@link SystemActionWithResult} as the given system user
* *
* @param username * @param username
* the system username * the system username
* @param action * @param action
* the action to perform * the action to perform
* *
* @return the result * @return the result
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public <T> T runWithResult(String username, SystemActionWithResult<T> action) throws PrivilegeException; <T> T runWithResult(String username, SystemActionWithResult<T> action) throws PrivilegeException;
/** /**
* Run the given {@link PrivilegedRunnable} as the given system user * Run the given {@link PrivilegedRunnable} as the given system user
* *
* @param username * @param username
* the system username * the system username
* @param runnable * @param runnable
* the runnable to perform * the runnable to perform
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public void runAs(String username, PrivilegedRunnable runnable) throws PrivilegeException; void runAs(String username, PrivilegedRunnable runnable) throws PrivilegeException;
/** /**
* Run the given {@link PrivilegedRunnable} as the given system user * Run the given {@link PrivilegedRunnable} as the given system user
* *
* @param username * @param username
* the system username * the system username
* @param runnable * @param runnable
* the runnable to perform * the runnable to perform
* *
* @return the result * @return the result
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public <T> T runWithResult(String username, PrivilegedRunnableWithResult<T> runnable) throws PrivilegeException; <T> T runWithResult(String username, PrivilegedRunnableWithResult<T> runnable) throws PrivilegeException;
/** /**
* Run the given {@link SystemAction} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT} * Run the given {@link SystemAction} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT}
* *
* @param runnable * @param action
* the runnable to perform * the action to perform
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public void runAsAgent(SystemAction action) throws PrivilegeException; void runAsAgent(SystemAction action) throws PrivilegeException;
/** /**
* Run the given {@link SystemActionWithResult} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT} * Run the given {@link SystemActionWithResult} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT}
* *
* @param runnable * @param action
* the runnable to perform * the action to perform
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public <T> T runAsAgentWithResult(SystemActionWithResult<T> action) throws PrivilegeException; <T> T runAsAgentWithResult(SystemActionWithResult<T> action) throws PrivilegeException;
/** /**
* Run the given {@link PrivilegedRunnable} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT} * Run the given {@link PrivilegedRunnable} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT}
* *
* @param runnable * @param runnable
* the runnable to perform * the runnable to perform
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public void runAsAgent(PrivilegedRunnable runnable) throws PrivilegeException; void runAsAgent(PrivilegedRunnable runnable) throws PrivilegeException;
/** /**
* Run the given {@link PrivilegedRunnableWithResult} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT} * Run the given {@link PrivilegedRunnableWithResult} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT}
* *
* @param runnable * @param runnable
* the runnable to perform * the runnable to perform
* *
* @return the result * @return the result
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is something wrong * if there is something wrong
*/ */
public <T> T runAsAgentWithResult(PrivilegedRunnableWithResult<T> runnable) throws PrivilegeException; <T> T runAsAgentWithResult(PrivilegedRunnableWithResult<T> runnable) throws PrivilegeException;
/** /**
* Returns the {@link li.strolch.privilege.handler.PrivilegeHandler} * Returns the {@link li.strolch.privilege.handler.PrivilegeHandler}
* *
* @return the {@link li.strolch.privilege.handler.PrivilegeHandler} * @return the {@link li.strolch.privilege.handler.PrivilegeHandler}
*/ */
public abstract li.strolch.privilege.handler.PrivilegeHandler getPrivilegeHandler(); li.strolch.privilege.handler.PrivilegeHandler getPrivilegeHandler();
} }

View File

@ -39,10 +39,6 @@ public class DefaultServiceHandler extends StrolchComponent implements ServiceHa
private PrivilegeHandler privilegeHandler; private PrivilegeHandler privilegeHandler;
private boolean throwOnPrivilegeFail; private boolean throwOnPrivilegeFail;
/**
* @param container
* @param componentName
*/
public DefaultServiceHandler(ComponentContainer container, String componentName) { public DefaultServiceHandler(ComponentContainer container, String componentName) {
super(container, componentName); super(container, componentName);
} }
@ -74,7 +70,7 @@ public class DefaultServiceHandler extends StrolchComponent implements ServiceHa
PrivilegeContext privilegeContext; PrivilegeContext privilegeContext;
String username = certificate == null ? "null" : certificate.getUsername(); String username = certificate == null ? "null" : certificate.getUsername();
try { try {
privilegeContext = this.privilegeHandler.getPrivilegeContext(certificate); privilegeContext = this.privilegeHandler.validate(certificate);
privilegeContext.validateAction(service); privilegeContext.validateAction(service);
} catch (PrivilegeException e) { } catch (PrivilegeException e) {

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Privilege>
<Container>
<Parameters>
<!-- parameters for the container itself -->
<Parameter name="secretKey" value="5185F447-6317-4856-B40E-573919BA0A16" />
<Parameter name="secretSalt" value="00F6E88C-A64F-410A-8FCF-9CD340E340F7" />
<Parameter name="persistSessions" value="true" />
<Parameter name="persistSessionsPath" value="./target/${target}/sessions.dat" />
<Parameter name="autoPersistOnUserChangesData" value="true" />
<Parameter name="privilegeConflictResolution" value="STRICT" />
</Parameters>
<EncryptionHandler class="li.strolch.privilege.handler.DefaultEncryptionHandler">
<Parameters>
<!-- WARNING: If you change iterations or keyLength, then all passwords are invalid -->
<!-- default algorithm is: PBKDF2WithHmacSHA512 -->
<Parameter name="hashAlgorithm" value="PBKDF2WithHmacSHA512" />
<!-- default iterations: 200000 -->
<Parameter name="hashIterations" value="10000" />
<!-- default key length: 256 -->
<Parameter name="hashKeyLength" value="256" />
</Parameters>
</EncryptionHandler>
<PersistenceHandler class="li.strolch.privilege.handler.XmlPersistenceHandler">
<Parameters>
<Parameter name="basePath" value="./target/${target}" />
<Parameter name="usersXmlFile" value="PrivilegeUsers.xml" />
<Parameter name="rolesXmlFile" value="PrivilegeRoles.xml" />
</Parameters>
</PersistenceHandler>
<UserChallengeHandler class="li.strolch.privilege.test.model.TestUserChallengeHandler">
</UserChallengeHandler>
</Container>
<Policies>
<Policy name="DefaultPrivilege" class="li.strolch.privilege.policy.DefaultPrivilege" />
<Policy name="RoleAccessPrivilege" class="li.strolch.privilege.policy.RoleAccessPrivilege" />
<Policy name="UserAccessPrivilege" class="li.strolch.privilege.policy.UserAccessPrivilege" />
</Policies>
</Privilege>

View File

@ -85,6 +85,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
*/ */
private EncryptionHandler encryptionHandler; private EncryptionHandler encryptionHandler;
/**
* The Single Sign On Handler
*/
private SingleSignOnHandler ssoHandler;
/** /**
* The {@link UserChallengeHandler} is used to challenge a user which tries to authenticate and/or change their * The {@link UserChallengeHandler} is used to challenge a user which tries to authenticate and/or change their
* password * password
@ -127,7 +132,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public RoleRep getRole(Certificate certificate, String roleName) { public RoleRep getRole(Certificate certificate, String roleName) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE); prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE);
Role role = this.persistenceHandler.getRole(roleName); Role role = this.persistenceHandler.getRole(roleName);
@ -143,7 +148,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep getUser(Certificate certificate, String username) { public UserRep getUser(Certificate certificate, String username) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER); prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER);
User user = this.persistenceHandler.getUser(username); User user = this.persistenceHandler.getUser(username);
@ -158,7 +163,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public Map<String, String> getPolicyDefs(Certificate certificate) { public Map<String, String> getPolicyDefs(Certificate certificate) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_GET_POLICIES)); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_GET_POLICIES));
Map<String, String> policyDef = new HashMap<>(this.policyMap.size()); Map<String, String> policyDef = new HashMap<>(this.policyMap.size());
@ -172,7 +177,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public List<Certificate> getCertificates(Certificate certificate) { public List<Certificate> getCertificates(Certificate certificate) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_GET_CERTIFICATES)); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_GET_CERTIFICATES));
return this.privilegeContextMap.values().stream().map(PrivilegeContext::getCertificate) return this.privilegeContextMap.values().stream().map(PrivilegeContext::getCertificate)
@ -183,7 +188,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public List<RoleRep> getRoles(Certificate certificate) { public List<RoleRep> getRoles(Certificate certificate) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE); prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE);
Stream<Role> rolesStream = this.persistenceHandler.getAllRoles().stream(); Stream<Role> rolesStream = this.persistenceHandler.getAllRoles().stream();
@ -207,7 +212,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public List<UserRep> getUsers(Certificate certificate) { public List<UserRep> getUsers(Certificate certificate) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER); prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER);
Stream<User> usersStream = this.persistenceHandler.getAllUsers().stream(); Stream<User> usersStream = this.persistenceHandler.getAllUsers().stream();
@ -231,7 +236,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public List<UserRep> queryUsers(Certificate certificate, UserRep selectorRep) { public List<UserRep> queryUsers(Certificate certificate, UserRep selectorRep) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER); prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER);
String selUserId = selectorRep.getUserId(); String selUserId = selectorRep.getUserId();
@ -334,8 +339,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
* null or empty, then true is returned. If a key/value pair from the selectionMap is not in the properties, then * null or empty, then true is returned. If a key/value pair from the selectionMap is not in the properties, then
* false is returned * false is returned
* *
* @param selectionMap the map defining the expected properties * @param selectionMap
* @param properties the properties which must be a sub set of selectionMap to have this method return true * the map defining the expected properties
* @param properties
* the properties which must be a sub set of selectionMap to have this method return true
*
* @return If the selectionMap is null or empty, then true is returned. If a key/value pair from the selectionMap is * @return If the selectionMap is null or empty, then true is returned. If a key/value pair from the selectionMap is
* not in the properties, then false is returned * not in the properties, then false is returned
*/ */
@ -361,8 +369,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
* Checks if the given roles contains the given selectionRoles, if this is the case, or selectionRoles is null or * Checks if the given roles contains the given selectionRoles, if this is the case, or selectionRoles is null or
* empty, then true is returned, otherwise false * empty, then true is returned, otherwise false
* *
* @param selectionRoles the required roles * @param selectionRoles
* @param roles the roles to check if they contain the selectionRoles * the required roles
* @param roles
* the roles to check if they contain the selectionRoles
*
* @return Checks if the given roles contains the given selectionRoles, if this is the case, or selectionRoles is * @return Checks if the given roles contains the given selectionRoles, if this is the case, or selectionRoles is
* null or empty, then true is returned, otherwise false * null or empty, then true is returned, otherwise false
*/ */
@ -379,7 +390,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
try { try {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_ADD_USER); prvCtx.assertHasPrivilege(PRIVILEGE_ADD_USER);
// make sure userId is not set // make sure userId is not set
@ -444,7 +455,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
try { try {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
// first validate user // first validate user
@ -512,10 +523,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} }
private User createUser(UserRep userRep, byte[] passwordHash, byte[] salt) { private User createUser(UserRep userRep, byte[] passwordHash, byte[] salt) {
User user = new User(userRep.getUserId(), userRep.getUsername(), passwordHash, salt, userRep.getFirstname(), String userId = userRep.getUserId();
userRep.getLastname(), userRep.getUserState(), userRep.getRoles(), userRep.getLocale(), String userName = userRep.getUsername();
userRep.getProperties()); String firstName = userRep.getFirstname();
return user; String lastName = userRep.getLastname();
UserState state = userRep.getUserState();
Set<String> roles = userRep.getRoles();
Locale locale = userRep.getLocale();
Map<String, String> properties = userRep.getProperties();
return new User(userId, userName, passwordHash, salt, firstName, lastName, state, roles, locale, properties);
} }
@Override @Override
@ -523,7 +539,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
throws AccessDeniedException, PrivilegeException { throws AccessDeniedException, PrivilegeException {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
// get existing user // get existing user
@ -585,7 +601,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep removeUser(Certificate certificate, String username) { public UserRep removeUser(Certificate certificate, String username) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_USER); prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_USER);
// validate user exists // validate user exists
@ -610,7 +626,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep addRoleToUser(Certificate certificate, String username, String roleName) { public UserRep addRoleToUser(Certificate certificate, String username, String roleName) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE_TO_USER); prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE_TO_USER);
// get user // get user
@ -658,7 +674,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) { public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_ROLE_FROM_USER); prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_ROLE_FROM_USER);
// get User // get User
@ -698,7 +714,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep setUserLocale(Certificate certificate, String username, Locale locale) { public UserRep setUserLocale(Certificate certificate, String username, Locale locale) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_LOCALE); prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_LOCALE);
// get User // get User
@ -735,7 +751,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
try { try {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_PASSWORD); prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_PASSWORD);
// get User // get User
@ -778,7 +794,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} }
if (certificate.getUsage() == Usage.SET_PASSWORD) { if (certificate.getUsage() == Usage.SET_PASSWORD) {
invalidateSession(certificate); invalidate(certificate);
} }
logger.info("Updated password for " + newUser.getUsername()); logger.info("Updated password for " + newUser.getUsername());
@ -792,7 +808,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep setUserState(Certificate certificate, String username, UserState state) { public UserRep setUserState(Certificate certificate, String username, UserState state) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_STATE); prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_STATE);
// get User // get User
@ -821,7 +837,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public RoleRep addRole(Certificate certificate, RoleRep roleRep) { public RoleRep addRole(Certificate certificate, RoleRep roleRep) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE); prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE);
// first validate role // first validate role
@ -854,7 +870,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public RoleRep replaceRole(Certificate certificate, RoleRep roleRep) { public RoleRep replaceRole(Certificate certificate, RoleRep roleRep) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE);
// first validate role // first validate role
@ -891,7 +907,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public RoleRep removeRole(Certificate certificate, String roleName) { public RoleRep removeRole(Certificate certificate, String roleName) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_ROLE); prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_ROLE);
// validate no user is using this role // validate no user is using this role
@ -927,7 +943,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) { public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE);
// validate PrivilegeRep // validate PrivilegeRep
@ -983,7 +999,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) { public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) {
// validate user actually has this type of privilege // validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE);
// get role // get role
@ -1116,12 +1132,39 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} }
} }
@Override
public Certificate authenticateSingleSignOn(Object data) throws PrivilegeException {
if (this.ssoHandler == null)
throw new IllegalStateException("The SSO Handler is not configured!");
User user = this.ssoHandler.authenticateSingleSignOn(data);
// get 2 auth tokens
String authToken = this.encryptionHandler.nextToken();
// get next session id
String sessionId = UUID.randomUUID().toString();
// create a new certificate, with details of the user
Certificate certificate = buildCertificate(Usage.ANY, user, authToken, sessionId);
certificate.setLastAccess(new Date());
PrivilegeContext privilegeContext = buildPrivilegeContext(certificate, user);
this.privilegeContextMap.put(sessionId, privilegeContext);
persistSessions();
// log
logger.info(MessageFormat.format("User {0} authenticated: {1}", user.getUsername(), certificate)); //$NON-NLS-1$
return certificate;
}
private Certificate buildCertificate(Usage usage, User user, String authToken, String sessionId) { private Certificate buildCertificate(Usage usage, User user, String authToken, String sessionId) {
Set<String> userRoles = user.getRoles(); Set<String> userRoles = user.getRoles();
Certificate certificate = new Certificate(usage, sessionId, user.getUsername(), user.getFirstname(), return new Certificate(usage, sessionId, user.getUsername(), user.getFirstname(), user.getLastname(),
user.getLastname(), user.getUserState(), authToken, new Date(), user.getLocale(), userRoles, user.getUserState(), authToken, new Date(), user.getLocale(), userRoles,
new HashMap<>(user.getProperties())); new HashMap<>(user.getProperties()));
return certificate;
} }
private boolean persistSessions() { private boolean persistSessions() {
@ -1146,15 +1189,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
return true; return true;
} }
private boolean loadSessions() { private void loadSessions() {
if (!this.persistSessions) { if (!this.persistSessions) {
logger.info("Persisteding of sessions not enabled, so not loading!."); logger.info("Persisteding of sessions not enabled, so not loading!.");
return false; return;
} }
if (!this.persistSessionsPath.exists()) { if (!this.persistSessionsPath.exists()) {
logger.info("No persisted sessions exist to be loaded."); logger.info("No persisted sessions exist to be loaded.");
return false; return;
} }
if (!this.persistSessionsPath.isFile()) if (!this.persistSessionsPath.isFile())
@ -1170,13 +1213,14 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} catch (Exception e) { } catch (Exception e) {
logger.error("Failed to load sessions!", e); logger.error("Failed to load sessions!", e);
this.persistSessionsPath.delete(); if (!this.persistSessionsPath.delete())
return false; logger.error("Failed to delete session file at " + this.persistSessionsPath.getAbsolutePath());
return;
} }
if (certificateStubs.isEmpty()) { if (certificateStubs.isEmpty()) {
logger.info("No persisted sessions exist to be loaded."); logger.info("No persisted sessions exist to be loaded.");
return false; return;
} }
for (CertificateStub certificateStub : certificateStubs) { for (CertificateStub certificateStub : certificateStubs) {
@ -1205,17 +1249,22 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} }
logger.info("Loaded " + this.privilegeContextMap.size() + " sessions."); logger.info("Loaded " + this.privilegeContextMap.size() + " sessions.");
return true;
} }
/** /**
* Checks the credentials and validates that the user may log in. * Checks the credentials and validates that the user may log in.
* *
* @param username the username of the {@link User} to check against * @param username
* @param password the password of this user * the username of the {@link User} to check against
* @param password
* the password of this user
*
* @return the {@link User} if the credentials are valid and the user may login * @return the {@link User} if the credentials are valid and the user may login
* @throws AccessDeniedException if anything is wrong with the credentials or the user state *
* @throws InvalidCredentialsException if the given credentials are invalid, the user does not exist, or has no password set * @throws AccessDeniedException
* if anything is wrong with the credentials or the user state
* @throws InvalidCredentialsException
* if the given credentials are invalid, the user does not exist, or has no password set
*/ */
private User checkCredentialsAndUserState(String username, char[] password) private User checkCredentialsAndUserState(String username, char[] password)
throws InvalidCredentialsException, AccessDeniedException { throws InvalidCredentialsException, AccessDeniedException {
@ -1253,7 +1302,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
byte[] salt = user.getSalt(); byte[] salt = user.getSalt();
if (salt == null) if (salt == null)
throw new AccessDeniedException( throw new AccessDeniedException(
MessageFormat.format("User {0} has no salt and may not login!", salt)); //$NON-NLS-1$ MessageFormat.format("User {0} has no salt and may not login!", username)); //$NON-NLS-1$
// we only work with hashed passwords // we only work with hashed passwords
byte[] passwordHash = this.encryptionHandler.hashPassword(password, salt); byte[] passwordHash = this.encryptionHandler.hashPassword(password, salt);
@ -1269,8 +1318,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
/** /**
* Builds a {@link PrivilegeContext} for the given {@link User} and its {@link Certificate} * Builds a {@link PrivilegeContext} for the given {@link User} and its {@link Certificate}
* *
* @param certificate the certificate for which to build the {@link PrivilegeContext} * @param certificate
* @param user the user for which to build the {@link PrivilegeContext} * the certificate for which to build the {@link PrivilegeContext}
* @param user
* the user for which to build the {@link PrivilegeContext}
*
* @return the {@link PrivilegeContext} * @return the {@link PrivilegeContext}
*/ */
private PrivilegeContext buildPrivilegeContext(Certificate certificate, User user) { private PrivilegeContext buildPrivilegeContext(Certificate certificate, User user) {
@ -1337,12 +1389,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} }
UserRep userRep = user.asUserRep(); UserRep userRep = user.asUserRep();
PrivilegeContext privilegeContext = new PrivilegeContext(userRep, certificate, privileges, policies); return new PrivilegeContext(userRep, certificate, privileges, policies);
return privilegeContext;
} }
@Override @Override
public boolean invalidateSession(Certificate certificate) { public boolean invalidate(Certificate certificate) {
// remove registration // remove registration
PrivilegeContext privilegeContext = this.privilegeContextMap.remove(certificate.getSessionId()); PrivilegeContext privilegeContext = this.privilegeContextMap.remove(certificate.getSessionId());
@ -1361,7 +1412,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} }
@Override @Override
public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException { public PrivilegeContext validate(Certificate certificate) throws PrivilegeException, NotAuthenticatedException {
// certificate must not be null // certificate must not be null
if (certificate == null) if (certificate == null)
@ -1387,33 +1438,13 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
LocalDateTime dateTime = LocalDateTime LocalDateTime dateTime = LocalDateTime
.ofInstant(sessionCertificate.getLoginTime().toInstant(), ZoneId.systemDefault()); .ofInstant(sessionCertificate.getLoginTime().toInstant(), ZoneId.systemDefault());
if (dateTime.plusHours(1).isBefore(LocalDateTime.now())) { if (dateTime.plusHours(1).isBefore(LocalDateTime.now())) {
invalidateSession(sessionCertificate); invalidate(sessionCertificate);
throw new NotAuthenticatedException("Certificate has already expired!"); //$NON-NLS-1$ throw new NotAuthenticatedException("Certificate has already expired!"); //$NON-NLS-1$
} }
} }
// get user object
User user = this.persistenceHandler.getUser(privilegeContext.getUsername());
// if user exists, then certificate is valid
if (user == null) {
String msg = "Oh boy, how did this happen: No User in user map although the certificate is valid!"; //$NON-NLS-1$
throw new PrivilegeException(msg);
}
// everything is ok
certificate.setLastAccess(new Date()); certificate.setLastAccess(new Date());
} return privilegeContext;
@Override
public PrivilegeContext getPrivilegeContext(Certificate certificate)
throws PrivilegeException, NotAuthenticatedException {
// first validate certificate
isCertificateValid(certificate);
return this.privilegeContextMap.get(certificate.getSessionId());
} }
/** /**
@ -1437,7 +1468,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public boolean persist(Certificate certificate) { public boolean persist(Certificate certificate) {
// validate who is doing this // validate who is doing this
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_PERSIST)); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_PERSIST));
return this.persistenceHandler.persist(); return this.persistenceHandler.persist();
@ -1447,7 +1478,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public boolean persistSessions(Certificate certificate) { public boolean persistSessions(Certificate certificate) {
// validate who is doing this // validate who is doing this
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_PERSIST_SESSIONS)); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_PERSIST_SESSIONS));
return persistSessions(); return persistSessions();
@ -1457,7 +1488,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public boolean reload(Certificate certificate) { public boolean reload(Certificate certificate) {
// validate who is doing this // validate who is doing this
PrivilegeContext prvCtx = getPrivilegeContext(certificate); PrivilegeContext prvCtx = validate(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_RELOAD)); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_RELOAD));
return this.persistenceHandler.reload(); return this.persistenceHandler.reload();
@ -1468,16 +1499,28 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
* {@link PrivilegeHandler} might need. This method may only be called once and this must be enforced by the * {@link PrivilegeHandler} might need. This method may only be called once and this must be enforced by the
* concrete implementation * concrete implementation
* *
* @param parameterMap a map containing configuration properties * @param parameterMap
* @param encryptionHandler the {@link EncryptionHandler} instance for this {@link PrivilegeHandler} * a map containing configuration properties
* @param persistenceHandler the {@link PersistenceHandler} instance for this {@link PrivilegeHandler} * @param encryptionHandler
* @param userChallengeHandler the handler to challenge a user's actions e.g. password change or authentication * the {@link EncryptionHandler} instance for this {@link PrivilegeHandler}
* @param policyMap map of {@link PrivilegePolicy} classes * @param persistenceHandler
* @throws PrivilegeException if the this method is called multiple times or an initialization exception occurs * the {@link PersistenceHandler} instance for this {@link PrivilegeHandler}
* @param userChallengeHandler
* the handler to challenge a user's actions e.g. password change or authentication
* @param ssoHandler
* the {@link SingleSignOnHandler}
* @param policyMap
* map of {@link PrivilegePolicy} classes
*
* @throws PrivilegeException
* if the this method is called multiple times or an initialization exception occurs
*/ */
public synchronized void initialize(Map<String, String> parameterMap, EncryptionHandler encryptionHandler, public synchronized void initialize(Map<String, String> parameterMap,
PersistenceHandler persistenceHandler, UserChallengeHandler userChallengeHandler, EncryptionHandler encryptionHandler,
Map<String, Class<PrivilegePolicy>> policyMap) { PersistenceHandler persistenceHandler,
UserChallengeHandler userChallengeHandler,
SingleSignOnHandler ssoHandler,
Map<String, Class<PrivilegePolicy>> policyMap) {
if (this.initialized) if (this.initialized)
throw new PrivilegeException("Already initialized!"); //$NON-NLS-1$ throw new PrivilegeException("Already initialized!"); //$NON-NLS-1$
@ -1486,6 +1529,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
this.encryptionHandler = encryptionHandler; this.encryptionHandler = encryptionHandler;
this.persistenceHandler = persistenceHandler; this.persistenceHandler = persistenceHandler;
this.userChallengeHandler = userChallengeHandler; this.userChallengeHandler = userChallengeHandler;
this.ssoHandler = ssoHandler;
handleAutoPersistOnUserDataChange(parameterMap); handleAutoPersistOnUserDataChange(parameterMap);
handlePersistSessionsParam(parameterMap); handlePersistSessionsParam(parameterMap);
@ -1678,7 +1722,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
/** /**
* Validates that the policies which are not null on the privileges of the role exist * Validates that the policies which are not null on the privileges of the role exist
* *
* @param role the role for which the policies are to be checked * @param role
* the role for which the policies are to be checked
*/ */
private void validatePolicies(Role role) { private void validatePolicies(Role role) {
for (String privilegeName : role.getPrivilegeNames()) { for (String privilegeName : role.getPrivilegeNames()) {
@ -1696,7 +1741,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
* Passwords should not be kept as strings, as string are immutable, this method thus clears the char array so that * Passwords should not be kept as strings, as string are immutable, this method thus clears the char array so that
* the password is not in memory anymore * the password is not in memory anymore
* *
* @param password the char array containing the passwort which is to be set to zeroes * @param password
* the char array containing the passwort which is to be set to zeroes
*/ */
private void clearPassword(char[] password) { private void clearPassword(char[] password) {
if (password != null) { if (password != null) {
@ -1734,7 +1780,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} }
} }
private <T> PrivilegeContext initiateSystemPrivilege(String username, Restrictable restrictable) { private PrivilegeContext initiateSystemPrivilege(String username, Restrictable restrictable) {
if (username == null) if (username == null)
throw new PrivilegeException("systemUsername may not be null!"); //$NON-NLS-1$ throw new PrivilegeException("systemUsername may not be null!"); //$NON-NLS-1$
if (restrictable == null) if (restrictable == null)
@ -1767,7 +1813,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
* Returns the {@link Certificate} for the given system username. If it does not yet exist, then it is created by * Returns the {@link Certificate} for the given system username. If it does not yet exist, then it is created by
* authenticating the system user * authenticating the system user
* *
* @param systemUsername the name of the system user * @param systemUsername
* the name of the system user
*
* @return the {@link Certificate} for this system user * @return the {@link Certificate} for this system user
*/ */
private PrivilegeContext getSystemUserPrivilegeContext(String systemUsername) { private PrivilegeContext getSystemUserPrivilegeContext(String systemUsername) {
@ -1833,9 +1881,13 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
* {@link PrivilegePolicy} object * {@link PrivilegePolicy} object
* </p> * </p>
* *
* @param policyName the class name of the {@link PrivilegePolicy} object to return * @param policyName
* the class name of the {@link PrivilegePolicy} object to return
*
* @return the {@link PrivilegePolicy} object * @return the {@link PrivilegePolicy} object
* @throws PrivilegeException if the {@link PrivilegePolicy} object for the given policy name could not be instantiated *
* @throws PrivilegeException
* if the {@link PrivilegePolicy} object for the given policy name could not be instantiated
*/ */
private PrivilegePolicy getPolicy(String policyName) { private PrivilegePolicy getPolicy(String policyName) {

View File

@ -39,7 +39,7 @@ import li.strolch.privilege.policy.PrivilegePolicy;
* The {@link PrivilegeHandler} is the centrally exposed API for accessing the privilege library. It exposes all needed * The {@link PrivilegeHandler} is the centrally exposed API for accessing the privilege library. It exposes all needed
* methods to access Privilege data model objects, modify them and validate if users or roles have privileges to perform * methods to access Privilege data model objects, modify them and validate if users or roles have privileges to perform
* an action * an action
* *
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*/ */
public interface PrivilegeHandler { public interface PrivilegeHandler {
@ -50,307 +50,303 @@ public interface PrivilegeHandler {
* Privilege "PrivilegeAction" which is used for privileges which are not further categorized e.g. s * Privilege "PrivilegeAction" which is used for privileges which are not further categorized e.g. s
* {@link #PRIVILEGE_ACTION_PERSIST} and {@link #PRIVILEGE_ACTION_GET_POLICIES} * {@link #PRIVILEGE_ACTION_PERSIST} and {@link #PRIVILEGE_ACTION_GET_POLICIES}
*/ */
public static final String PRIVILEGE_ACTION = "PrivilegeAction"; String PRIVILEGE_ACTION = "PrivilegeAction";
/** /**
* For Privilege "PrivilegeAction" value required to be able to persist changes if not exempted by auto persist or * For Privilege "PrivilegeAction" value required to be able to persist changes if not exempted by auto persist or
* <code>allAllowed</code> * <code>allAllowed</code>
*/ */
public static final String PRIVILEGE_ACTION_PERSIST = "Persist"; String PRIVILEGE_ACTION_PERSIST = "Persist";
/** /**
* For Privilege "PrivilegeAction" value required to be able to persist session if not exempted by * For Privilege "PrivilegeAction" value required to be able to persist session if not exempted by
* <code>allAllowed</code> * <code>allAllowed</code>
*/ */
public static final String PRIVILEGE_ACTION_PERSIST_SESSIONS = "PersistSessions"; String PRIVILEGE_ACTION_PERSIST_SESSIONS = "PersistSessions";
/** /**
* For Privilege "PrivilegeAction" value required to be able to reload changes if not exempted by * For Privilege "PrivilegeAction" value required to be able to reload changes if not exempted by
* <code>allAllowed</code> * <code>allAllowed</code>
*/ */
public static final String PRIVILEGE_ACTION_RELOAD = "Reload"; String PRIVILEGE_ACTION_RELOAD = "Reload";
/** /**
* For Privilege "PrivilegeAction" value required to get currently configured policies if not * For Privilege "PrivilegeAction" value required to get currently configured policies if not
* <code>allAllowed</code> * <code>allAllowed</code>
*/ */
public static final String PRIVILEGE_ACTION_GET_POLICIES = "GetPolicies"; String PRIVILEGE_ACTION_GET_POLICIES = "GetPolicies";
/** /**
* For Privilege "PrivilegeAction" value required to get a certificate if not <code>allAllowed</code> * For Privilege "PrivilegeAction" value required to get a certificate if not <code>allAllowed</code>
*/ */
public static final String PRIVILEGE_ACTION_GET_CERTIFICATE = "GetCertificate"; String PRIVILEGE_ACTION_GET_CERTIFICATE = "GetCertificate";
/** /**
* For Privilege "PrivilegeAction" value required to get all certificates if not <code>allAllowed</code> * For Privilege "PrivilegeAction" value required to get all certificates if not <code>allAllowed</code>
*/ */
public static final String PRIVILEGE_ACTION_GET_CERTIFICATES = "GetCertificates"; String PRIVILEGE_ACTION_GET_CERTIFICATES = "GetCertificates";
/// ///
/** /**
* Privilege "PrivilegeGetRole" which is used to validate that a user can get a specific role * Privilege "PrivilegeGetRole" which is used to validate that a user can get a specific role
*/ */
public static final String PRIVILEGE_GET_ROLE = "PrivilegeGetRole"; String PRIVILEGE_GET_ROLE = "PrivilegeGetRole";
/** /**
* Privilege "PrivilegeAddRole" which is used to validate that a user can add a specific role * Privilege "PrivilegeAddRole" which is used to validate that a user can add a specific role
*/ */
public static final String PRIVILEGE_ADD_ROLE = "PrivilegeAddRole"; String PRIVILEGE_ADD_ROLE = "PrivilegeAddRole";
/** /**
* Privilege "PrivilegeRemoveRole" which is used to validate that a user can remove a specific role * Privilege "PrivilegeRemoveRole" which is used to validate that a user can remove a specific role
*/ */
public static final String PRIVILEGE_REMOVE_ROLE = "PrivilegeRemoveRole"; String PRIVILEGE_REMOVE_ROLE = "PrivilegeRemoveRole";
/** /**
* Privilege "PrivilegeModifyRole" which is used to validate that a user can modify a specific role. <b>Note:</b> * Privilege "PrivilegeModifyRole" which is used to validate that a user can modify a specific role. <b>Note:</b>
* This includes modifying of the privileges on the role * This includes modifying of the privileges on the role
*/ */
public static final String PRIVILEGE_MODIFY_ROLE = "PrivilegeModifyRole"; String PRIVILEGE_MODIFY_ROLE = "PrivilegeModifyRole";
/// ///
/** /**
* Privilege "PrivilegeGetUser" which is used to validate that a user can get a specific user * Privilege "PrivilegeGetUser" which is used to validate that a user can get a specific user
*/ */
public static final String PRIVILEGE_GET_USER = "PrivilegeGetUser"; String PRIVILEGE_GET_USER = "PrivilegeGetUser";
/** /**
* Privilege "PrivilegeAddUser" which is used to validate that a user can add a specific user * Privilege "PrivilegeAddUser" which is used to validate that a user can add a specific user
*/ */
public static final String PRIVILEGE_ADD_USER = "PrivilegeAddUser"; String PRIVILEGE_ADD_USER = "PrivilegeAddUser";
/** /**
* Privilege "PrivilegeRemoveUser" which is used to validate that a user can remove a specific user * Privilege "PrivilegeRemoveUser" which is used to validate that a user can remove a specific user
*/ */
public static final String PRIVILEGE_REMOVE_USER = "PrivilegeRemoveUser"; String PRIVILEGE_REMOVE_USER = "PrivilegeRemoveUser";
/** /**
* Privilege "PrivilegeModifyUser" which is used to validate that a user can modify a specific user * Privilege "PrivilegeModifyUser" which is used to validate that a user can modify a specific user
*/ */
public static final String PRIVILEGE_MODIFY_USER = "PrivilegeModifyUser"; String PRIVILEGE_MODIFY_USER = "PrivilegeModifyUser";
/** /**
* Privilege "PrivilegeAddRoleToUser" which is used to validate that a user can add a specific role to a specific * Privilege "PrivilegeAddRoleToUser" which is used to validate that a user can add a specific role to a specific
* user * user
*/ */
public static final String PRIVILEGE_ADD_ROLE_TO_USER = "PrivilegeAddRoleToUser"; String PRIVILEGE_ADD_ROLE_TO_USER = "PrivilegeAddRoleToUser";
/** /**
* Privilege "PrivilegeRemoveRoleFromUser" which is used to validate that a user can remove a specific role from a * Privilege "PrivilegeRemoveRoleFromUser" which is used to validate that a user can remove a specific role from a
* specific user * specific user
*/ */
public static final String PRIVILEGE_REMOVE_ROLE_FROM_USER = "PrivilegeRemoveRoleFromUser"; String PRIVILEGE_REMOVE_ROLE_FROM_USER = "PrivilegeRemoveRoleFromUser";
/** /**
* Privilege "PRIVILEGE_SET_USER_LOCALE" which is used to validate that a user can set the locale of a user, or * Privilege "PRIVILEGE_SET_USER_LOCALE" which is used to validate that a user can set the locale of a user, or
* their own * their own
*/ */
public static final String PRIVILEGE_SET_USER_LOCALE = "PrivilegeSetUserLocale"; String PRIVILEGE_SET_USER_LOCALE = "PrivilegeSetUserLocale";
/** /**
* Privilege "PRIVILEGE_SET_USER_STATE" which is used to validate that a user can set the state of a user * Privilege "PRIVILEGE_SET_USER_STATE" which is used to validate that a user can set the state of a user
*/ */
public static final String PRIVILEGE_SET_USER_STATE = "PrivilegeSetUserState"; String PRIVILEGE_SET_USER_STATE = "PrivilegeSetUserState";
/** /**
* Privilege "PRIVILEGE_SET_USER_PASSWORD" which is used to validate that a user can set the password of a user, or * Privilege "PRIVILEGE_SET_USER_PASSWORD" which is used to validate that a user can set the password of a user, or
* their own * their own
*/ */
public static final String PRIVILEGE_SET_USER_PASSWORD = "PrivilegeSetUserPassword"; String PRIVILEGE_SET_USER_PASSWORD = "PrivilegeSetUserPassword";
/// ///
/** /**
* configuration parameter to define a secret_key * configuration parameter to define a secret_key
*/ */
public static final String PARAM_SECRET_KEY = "secretKey"; //$NON-NLS-1$ String PARAM_SECRET_KEY = "secretKey"; //$NON-NLS-1$
/** /**
* configuration parameter to define a secret salt * configuration parameter to define a secret salt
*/ */
public static final String PARAM_SECRET_SALT = "secretSalt"; //$NON-NLS-1$ String PARAM_SECRET_SALT = "secretSalt"; //$NON-NLS-1$
/** /**
* configuration parameter to define automatic persisting on password change * configuration parameter to define automatic persisting on password change
*/ */
public static final String PARAM_AUTO_PERSIST_ON_USER_CHANGES_DATA = "autoPersistOnUserChangesData"; //$NON-NLS-1$ String PARAM_AUTO_PERSIST_ON_USER_CHANGES_DATA = "autoPersistOnUserChangesData"; //$NON-NLS-1$
/** /**
* configuration parameter to define if sessions should be persisted * configuration parameter to define if sessions should be persisted
*/ */
public static final String PARAM_PERSIST_SESSIONS = "persistSessions"; //$NON-NLS-1$ String PARAM_PERSIST_SESSIONS = "persistSessions"; //$NON-NLS-1$
/** /**
* configuration parameter to define where sessions are to be persisted * configuration parameter to define where sessions are to be persisted
*/ */
public static final String PARAM_PERSIST_SESSIONS_PATH = "persistSessionsPath"; //$NON-NLS-1$ String PARAM_PERSIST_SESSIONS_PATH = "persistSessionsPath"; //$NON-NLS-1$
/** /**
* configuration parameter to define {@link PrivilegeConflictResolution} * configuration parameter to define {@link PrivilegeConflictResolution}
*/ */
public static final String PARAM_PRIVILEGE_CONFLICT_RESOLUTION = "privilegeConflictResolution"; String PARAM_PRIVILEGE_CONFLICT_RESOLUTION = "privilegeConflictResolution";
/** /**
* Returns a {@link UserRep} for the given username * Returns a {@link UserRep} for the given username
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param username * @param username
* the name of the {@link UserRep} to return * the name of the {@link UserRep} to return
* *
* @return the {@link UserRep} for the given username, or null if it was not found * @return the {@link UserRep} for the given username, or null if it was not found
*/ */
public UserRep getUser(Certificate certificate, String username); UserRep getUser(Certificate certificate, String username);
/** /**
* Returns a {@link RoleRep} for the given roleName * Returns a {@link RoleRep} for the given roleName
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName * @param roleName
* the name of the {@link RoleRep} to return * the name of the {@link RoleRep} to return
* *
* @return the {@link RoleRep} for the given roleName, or null if it was not found * @return the {@link RoleRep} for the given roleName, or null if it was not found
*/ */
public RoleRep getRole(Certificate certificate, String roleName); RoleRep getRole(Certificate certificate, String roleName);
/** /**
* Returns the map of {@link PrivilegePolicy} definitions * Returns the map of {@link PrivilegePolicy} definitions
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* *
* @return the map of {@link PrivilegePolicy} definitions * @return the map of {@link PrivilegePolicy} definitions
*/ */
public Map<String, String> getPolicyDefs(Certificate certificate); Map<String, String> getPolicyDefs(Certificate certificate);
/** /**
* Returns the list of {@link Certificate Certificates} * Returns the list of {@link Certificate Certificates}
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* *
* @return the list of {@link Certificate Certificates} * @return the list of {@link Certificate Certificates}
*/ */
public List<Certificate> getCertificates(Certificate certificate); List<Certificate> getCertificates(Certificate certificate);
/** /**
* Returns all {@link RoleRep RoleReps} * Returns all {@link RoleRep RoleReps}
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* *
* @return the list of {@link RoleRep RoleReps} * @return the list of {@link RoleRep RoleReps}
*/ */
public List<RoleRep> getRoles(Certificate certificate); List<RoleRep> getRoles(Certificate certificate);
/** /**
* Returns all {@link UserRep UserReps} * Returns all {@link UserRep UserReps}
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* *
* @return the list of {@link UserRep UserReps} * @return the list of {@link UserRep UserReps}
*/ */
public List<UserRep> getUsers(Certificate certificate); List<UserRep> getUsers(Certificate certificate);
/** /**
* Method to query {@link UserRep} which meet the criteria set in the given {@link UserRep}. Null fields mean the * Method to query {@link UserRep} which meet the criteria set in the given {@link UserRep}. Null fields mean the
* fields are irrelevant. * fields are irrelevant.
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param selectorRep * @param selectorRep
* the {@link UserRep} to use as criteria selection * the {@link UserRep} to use as criteria selection
* *
* @return a list of {@link UserRep}s which fit the given criteria * @return a list of {@link UserRep}s which fit the given criteria
*/ */
public List<UserRep> queryUsers(Certificate certificate, UserRep selectorRep); List<UserRep> queryUsers(Certificate certificate, UserRep selectorRep);
/** /**
* Removes the user with the given username * Removes the user with the given username
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param username * @param username
* the username of the user to remove * the username of the user to remove
* *
* @return the {@link UserRep} of the user removed, or null if the user did not exist * @return the {@link UserRep} of the user removed, or null if the user did not exist
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate * if there is anything wrong with this certificate
*/ */
public UserRep removeUser(Certificate certificate, String username) UserRep removeUser(Certificate certificate, String username) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Removes the role with the given roleName from the user with the given username * Removes the role with the given roleName from the user with the given username
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param username * @param username
* the username of the user from which the role is to be removed * the username of the user from which the role is to be removed
* @param roleName * @param roleName
* the roleName of the role to remove from the user * the roleName of the role to remove from the user
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate * if there is anything wrong with this certificate
*/ */
public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Removes the role with the given roleName * Removes the role with the given roleName
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName * @param roleName
* the roleName of the role to remove * the roleName of the role to remove
* *
* @return the {@link RoleRep} of the role removed, or null if the role did not exist * @return the {@link RoleRep} of the role removed, or null if the role did not exist
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or the role is still in use by a user * if there is anything wrong with this certificate or the role is still in use by a user
*/ */
public RoleRep removeRole(Certificate certificate, String roleName) RoleRep removeRole(Certificate certificate, String roleName) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Removes the privilege with the given privilegeName from the role with the given roleName * Removes the privilege with the given privilegeName from the role with the given roleName
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName * @param roleName
* the roleName of the role from which the privilege is to be removed * the roleName of the role from which the privilege is to be removed
* @param privilegeName * @param privilegeName
* the privilegeName of the privilege to remove from the role * the privilegeName of the privilege to remove from the role
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate * if there is anything wrong with this certificate
*/ */
public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName)
throws AccessDeniedException, PrivilegeException; throws PrivilegeException;
/** /**
* <p> * <p>
* Adds a new user with the information from this {@link UserRep} * Adds a new user with the information from this {@link UserRep}
* </p> * </p>
* *
* <p> * <p>
* If the password given is null, then the user is created, but can not not login! Otherwise the password must meet * If the password given is null, then the user is created, but can not not login! Otherwise the password must meet
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(char[])} * the requirements of the implementation under {@link PrivilegeHandler#validatePassword(char[])}
* </p> * </p>
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep * @param userRep
* the {@link UserRep} containing the information to create the new {@link User} * the {@link UserRep} containing the information to create the new {@link User}
* @param password * @param password
* the password of the new user. If the password is null, then this is accepted but the user can not * the password of the new user. If the password is null, then this is accepted but the user can not
* login, otherwise the password must be validated against * login, otherwise the password must be validated against
* {@link PrivilegeHandler#validatePassword(char[])} * {@link PrivilegeHandler#validatePassword(char[])}
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or the user already exists * if there is anything wrong with this certificate or the user already exists
*/ */
public UserRep addUser(Certificate certificate, UserRep userRep, char[] password) UserRep addUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* <p> * <p>
@ -358,7 +354,7 @@ public interface PrivilegeHandler {
* will be updated on the existing user. The username on the given {@link UserRep} must be set and correspond to an * will be updated on the existing user. The username on the given {@link UserRep} must be set and correspond to an
* existing user. * existing user.
* </p> * </p>
* *
* The following fields are considered updateable: * The following fields are considered updateable:
* <ul> * <ul>
* <li>{@link UserRep#getFirstname()}</li> * <li>{@link UserRep#getFirstname()}</li>
@ -366,117 +362,113 @@ public interface PrivilegeHandler {
* <li>{@link UserRep#getLocale()}</li> * <li>{@link UserRep#getLocale()}</li>
* <li>{@link UserRep#getProperties()} - the existing properties will be replaced with the given properties</li> * <li>{@link UserRep#getProperties()} - the existing properties will be replaced with the given properties</li>
* </ul> * </ul>
* *
* <p> * <p>
* Any other fields will be ignored * Any other fields will be ignored
* </p> * </p>
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep * @param userRep
* the {@link UserRep} with the fields set to their new values * the {@link UserRep} with the fields set to their new values
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or if the user does not exist * if there is anything wrong with this certificate or if the user does not exist
*/ */
public UserRep updateUser(Certificate certificate, UserRep userRep) UserRep updateUser(Certificate certificate, UserRep userRep) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* <p> * <p>
* Replaces the existing user with the information from this {@link UserRep} if the user already exists * Replaces the existing user with the information from this {@link UserRep} if the user already exists
* </p> * </p>
* *
* <p> * <p>
* If the password given is null, then the user is created, but can not not login! Otherwise the password must meet * If the password given is null, then the user is created, but can not not login! Otherwise the password must meet
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(char[])} * the requirements of the implementation under {@link PrivilegeHandler#validatePassword(char[])}
* </p> * </p>
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param userRep * @param userRep
* the {@link UserRep} containing the information to replace the existing {@link User} * the {@link UserRep} containing the information to replace the existing {@link User}
* @param password * @param password
* the password of the new user. If the password is null, then this is accepted but the user can not * the password of the new user. If the password is null, then this is accepted but the user can not
* login, otherwise the password must be validated against * login, otherwise the password must be validated against
* {@link PrivilegeHandler#validatePassword(char[])} * {@link PrivilegeHandler#validatePassword(char[])}
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or if the user does not exist * if there is anything wrong with this certificate or if the user does not exist
*/ */
public UserRep replaceUser(Certificate certificate, UserRep userRep, char[] password) UserRep replaceUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Adds a new role with the information from this {@link RoleRep} * Adds a new role with the information from this {@link RoleRep}
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param roleRep * @param roleRep
* the {@link RoleRep} containing the information to create the new {@link Role} * the {@link RoleRep} containing the information to create the new {@link Role}
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or if the role already exists * if there is anything wrong with this certificate or if the role already exists
*/ */
public RoleRep addRole(Certificate certificate, RoleRep roleRep) throws AccessDeniedException, PrivilegeException; RoleRep addRole(Certificate certificate, RoleRep roleRep) throws PrivilegeException;
/** /**
* Replaces the existing role with the information from this {@link RoleRep} * Replaces the existing role with the information from this {@link RoleRep}
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param roleRep * @param roleRep
* the {@link RoleRep} containing the information to replace the existing {@link Role} * the {@link RoleRep} containing the information to replace the existing {@link Role}
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or if the role does not exist * if there is anything wrong with this certificate or if the role does not exist
*/ */
public RoleRep replaceRole(Certificate certificate, RoleRep roleRep) RoleRep replaceRole(Certificate certificate, RoleRep roleRep) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Adds the role with the given roleName to the {@link User} with the given username * Adds the role with the given roleName to the {@link User} with the given username
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param username * @param username
* the username of the {@link User} to which the role should be added * the username of the {@link User} to which the role should be added
* @param roleName * @param roleName
* the roleName of the {@link Role} which should be added to the {@link User} * the roleName of the {@link Role} which should be added to the {@link User}
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or if the role does not exist * if there is anything wrong with this certificate or if the role does not exist
*/ */
public UserRep addRoleToUser(Certificate certificate, String username, String roleName) UserRep addRoleToUser(Certificate certificate, String username, String roleName) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Adds the {@link PrivilegeRep} to the {@link Role} with the given roleName or replaces it, if it already exists * Adds the {@link PrivilegeRep} to the {@link Role} with the given roleName or replaces it, if it already exists
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param roleName * @param roleName
* the roleName of the {@link Role} to which the privilege should be added * the roleName of the {@link Role} to which the privilege should be added
* @param privilegeRep * @param privilegeRep
* the representation of the {@link IPrivilege} which should be added or replaced on the {@link Role} * the representation of the {@link IPrivilege} which should be added or replaced on the {@link Role}
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate or the role does not exist * if there is anything wrong with this certificate or the role does not exist
*/ */
public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep)
throws AccessDeniedException, PrivilegeException; throws PrivilegeException;
/** /**
* <p> * <p>
@ -484,243 +476,240 @@ public interface PrivilegeHandler {
* can not login anymore. Otherwise the password must meet the requirements of the implementation under * can not login anymore. Otherwise the password must meet the requirements of the implementation under
* {@link PrivilegeHandler#validatePassword(char[])} * {@link PrivilegeHandler#validatePassword(char[])}
* </p> * </p>
* *
* <p> * <p>
* It should be possible for a user to change their own password * It should be possible for a user to change their own password
* </p> * </p>
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param username * @param username
* the username of the {@link User} for which the password is to be changed * the username of the {@link User} for which the password is to be changed
* @param password * @param password
* the new password for this user. If the password is null, then the {@link User} can not login anymore. * the new password for this user. If the password is null, then the {@link User} can not login anymore.
* Otherwise the password must meet the requirements of the implementation under * Otherwise the password must meet the requirements of the implementation under
* {@link PrivilegeHandler#validatePassword(char[])} * {@link PrivilegeHandler#validatePassword(char[])}
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate * if there is anything wrong with this certificate
*/ */
public void setUserPassword(Certificate certificate, String username, char[] password) void setUserPassword(Certificate certificate, String username, char[] password) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Changes the {@link UserState} of the user * Changes the {@link UserState} of the user
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param username * @param username
* the username of the {@link User} for which the {@link UserState} is to be changed * the username of the {@link User} for which the {@link UserState} is to be changed
* @param state * @param state
* the new state for the user * the new state for the user
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate * if there is anything wrong with this certificate
*/ */
public UserRep setUserState(Certificate certificate, String username, UserState state) UserRep setUserState(Certificate certificate, String username, UserState state) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Changes the {@link Locale} of the user * Changes the {@link Locale} of the user
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* @param username * @param username
* the username of the {@link User} for which the {@link Locale} is to be changed * the username of the {@link User} for which the {@link Locale} is to be changed
* @param locale * @param locale
* the new {@link Locale} for the user * the new {@link Locale} for the user
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user for this certificate may not perform the action * if the user for this certificate may not perform the action
* @throws PrivilegeException * @throws PrivilegeException
* if there is anything wrong with this certificate * if there is anything wrong with this certificate
*/ */
public UserRep setUserLocale(Certificate certificate, String username, Locale locale) UserRep setUserLocale(Certificate certificate, String username, Locale locale) throws PrivilegeException;
throws AccessDeniedException, PrivilegeException;
/** /**
* Initiate a password reset challenge for the given username * Initiate a password reset challenge for the given username
* *
* @param usage * @param usage
* the usage for which the challenge is requested * the usage for which the challenge is requested
* @param username * @param username
* the username of the user to initiate the challenge for * the username of the user to initiate the challenge for
*/ */
public void initiateChallengeFor(Usage usage, String username); void initiateChallengeFor(Usage usage, String username);
/** /**
* Validate the response of a challenge for the given username * Validate the response of a challenge for the given username
* *
* @param username * @param username
* the username of the user for which the challenge is to be validated * the username of the user for which the challenge is to be validated
* @param challenge * @param challenge
* the challenge from the user * the challenge from the user
* *
* @return certificate with which the user can access the system with the {@link Usage} set to the value from the * @return certificate with which the user can access the system with the {@link Usage} set to the value from the
* initiated challenge * initiated challenge
* *
* @throws PrivilegeException * @throws PrivilegeException
* if anything goes wrong * if anything goes wrong
*/ */
public Certificate validateChallenge(String username, String challenge) throws PrivilegeException; Certificate validateChallenge(String username, String challenge) throws PrivilegeException;
/** /**
* Authenticates a user by validating that a {@link User} for the given username and password exist and then returns * Authenticates a user by validating that a {@link User} for the given username and password exist and then returns
* a {@link Certificate} with which this user may then perform actions * a {@link Certificate} with which this user may then perform actions
* *
* @param username * @param username
* the username of the {@link User} which is registered in the {@link PersistenceHandler} * the username of the {@link User} which is registered in the {@link PersistenceHandler}
* @param password * @param password
* the password with which this user is to be authenticated. Null passwords are not accepted and they * the password with which this user is to be authenticated. Null passwords are not accepted and they
* must meet the requirements of the {@link #validatePassword(char[])}-method * must meet the requirements of the {@link #validatePassword(char[])}-method
* *
* @return a {@link Certificate} with which this user may then perform actions * @return a {@link Certificate} with which this user may then perform actions
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the user credentials are not valid * if the user credentials are not valid
*/ */
public Certificate authenticate(String username, char[] password) throws AccessDeniedException; Certificate authenticate(String username, char[] password) throws AccessDeniedException;
/**
* Authenticates a user on a remote Single Sign On service. This is implemented by the
*
* @param data
* the data to perform the SSO
*
* @return the {@link Certificate} for the user
*
* @throws PrivilegeException
* if something goes wrong with the SSO
*/
Certificate authenticateSingleSignOn(Object data) throws PrivilegeException;
/** /**
* Invalidates the session for the given {@link Certificate}, effectively logging out the user who was authenticated * Invalidates the session for the given {@link Certificate}, effectively logging out the user who was authenticated
* with the credentials associated to the given {@link Certificate} * with the credentials associated to the given {@link Certificate}
* *
* @param certificate * @param certificate
* the {@link Certificate} for which the session is to be invalidated * the {@link Certificate} for which the session is to be invalidated
*
* @return true if the session was still valid and is now invalidated, false otherwise * @return true if the session was still valid and is now invalidated, false otherwise
*/ */
public boolean invalidateSession(Certificate certificate); boolean invalidate(Certificate certificate);
/** /**
* Checks if the given {@link Certificate} is valid. This means that the certificate is for a valid session and that * Checks if the given {@link Certificate} is valid. This means that the certificate is for a valid session and that
* the user exists for the certificate. This method checks if the {@link Certificate} has been tampered with * the user exists for the certificate. This method checks if the {@link Certificate} has been tampered with
* *
* @param certificate
* the {@link Certificate} to check
*
* @throws PrivilegeException
* if there is anything wrong with this certificate
* @throws NotAuthenticatedException
* if the certificate has expired
*/
public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException;
/**
* Returns the {@link PrivilegeContext} for the given {@link Certificate}. The {@link PrivilegeContext} is an * Returns the {@link PrivilegeContext} for the given {@link Certificate}. The {@link PrivilegeContext} is an
* encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their * encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their
* actions and do not need to access the {@link PrivilegeHandler} anymore * actions and do not need to access the {@link PrivilegeHandler} anymore
* *
* @param certificate * @param certificate
* a valid {@link Certificate} for which a {@link PrivilegeContext} is to be returned * the {@link Certificate} to check
*
* @return the {@link PrivilegeContext} for the given {@link Certificate} * @return the {@link PrivilegeContext} for the given {@link Certificate}
* *
* @throws PrivilegeException * @throws PrivilegeException
* if there is a configuration error or the {@link Certificate} is invalid * if there is anything wrong with this certificate
* @throws NotAuthenticatedException * @throws NotAuthenticatedException
* if the certificate has expired * if the certificate has expired
*/ */
public PrivilegeContext getPrivilegeContext(Certificate certificate) PrivilegeContext validate(Certificate certificate) throws PrivilegeException;
throws PrivilegeException, NotAuthenticatedException;
/** /**
* Validate that the given password meets certain requirements. What these requirements are is a decision made by * Validate that the given password meets certain requirements. What these requirements are is a decision made by
* the concrete implementation * the concrete implementation
* *
* @param password * @param password
* the password to be validated to meet certain requirements * the password to be validated to meet certain requirements
* *
* @throws PrivilegeException * @throws PrivilegeException
* if the password does not implement the requirement of the concrete implementation * if the password does not implement the requirement of the concrete implementation
*/ */
public void validatePassword(char[] password) throws PrivilegeException; void validatePassword(char[] password) throws PrivilegeException;
/** /**
* <p> * <p>
* Informs this {@link PersistenceHandler} to reload the data from the backend * Informs this {@link PersistenceHandler} to reload the data from the backend
* </p> * </p>
* *
* <b>Note:</b> It depends on the underlying {@link PersistenceHandler} implementation if data really is read * <b>Note:</b> It depends on the underlying {@link PersistenceHandler} implementation if data really is read
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* *
* @return true if the reload was successful, false if something went wrong * @return true if the reload was successful, false if something went wrong
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the users of the given certificate does not have the privilege to perform this action * if the users of the given certificate does not have the privilege to perform this action
*/ */
public boolean reload(Certificate certificate); boolean reload(Certificate certificate);
/** /**
* Persists any changes to the privilege data model. Changes are thus not persisted immediately, but must be * Persists any changes to the privilege data model. Changes are thus not persisted immediately, but must be
* actively performed * actively performed
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* *
* @return true if changes were persisted, false if no changes were persisted * @return true if changes were persisted, false if no changes were persisted
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the users of the given certificate does not have the privilege to perform this action * if the users of the given certificate does not have the privilege to perform this action
*/ */
public boolean persist(Certificate certificate) throws AccessDeniedException; boolean persist(Certificate certificate) throws AccessDeniedException;
/** /**
* Persists all currently active sessions * Persists all currently active sessions
* *
* @param certificate * @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action * the {@link Certificate} of the user which has the privilege to perform this action
* *
* @return true if changes were persisted, false if not (i.e. not enabled) * @return true if changes were persisted, false if not (i.e. not enabled)
* *
* @throws AccessDeniedException * @throws AccessDeniedException
* if the users of the given certificate does not have the privilege to perform this action * if the users of the given certificate does not have the privilege to perform this action
*/ */
public boolean persistSessions(Certificate certificate) throws AccessDeniedException; boolean persistSessions(Certificate certificate) throws AccessDeniedException;
/** /**
* Special method to perform work as a System user, meaning the given systemUsername corresponds to an account which * Special method to perform work as a System user, meaning the given systemUsername corresponds to an account which
* has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation * has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation
* of the given {@link SystemAction} instance * of the given {@link SystemAction} instance
* *
*
* @param systemUsername * @param systemUsername
* the username of the system user to perform the action as * the username of the system user to perform the action as
* @param action * @param action
* the action to be performed as the system user * the action to be performed as the system user
* *
* @return the action
*
* @throws PrivilegeException * @throws PrivilegeException
* if the user does not exist, or the system action is not alloed
*/ */
public void runAs(String systemUsername, SystemAction action) throws PrivilegeException; void runAs(String systemUsername, SystemAction action) throws PrivilegeException;
/** /**
* Special method to perform work as a System user, meaning the given systemUsername corresponds to an account which * Special method to perform work as a System user, meaning the given systemUsername corresponds to an account which
* has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation * has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation
* of the given {@link SystemAction} instance * of the given {@link SystemAction} instance
* *
*
* @param systemUsername * @param systemUsername
* the username of the system user to perform the action as * the username of the system user to perform the action as
* @param action * @param action
* the action to be performed as the system user * the action to be performed as the system user
* *
* @return the action * @return the action
* *
* @throws PrivilegeException * @throws PrivilegeException
* if the user does not exist, or the system action is not alloed
*/ */
public <T> T runWithResult(String systemUsername, SystemActionWithResult<T> action) throws PrivilegeException; <T> T runWithResult(String systemUsername, SystemActionWithResult<T> action) throws PrivilegeException;
/** /**
* Returns the {@link EncryptionHandler} instance * Returns the {@link EncryptionHandler} instance
* *
* @return the {@link EncryptionHandler} instance * @return the {@link EncryptionHandler} instance
*/ */
public EncryptionHandler getEncryptionHandler() throws PrivilegeException; EncryptionHandler getEncryptionHandler() throws PrivilegeException;
} }

View File

@ -0,0 +1,32 @@
package li.strolch.privilege.handler;
import java.util.Map;
import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.model.internal.User;
public interface SingleSignOnHandler {
/**
* Initialize the concrete {@link SingleSignOnHandler}. The passed parameter map contains any configuration the
* concrete {@link SingleSignOnHandler} might need
*
* @param parameterMap
* a map containing configuration properties
*/
void initialize(Map<String, String> parameterMap);
/**
* Authenticates a user on a remote Single Sign On service.
*
* @param data
* the data required to sign on the user
*
* @return the user, configured with the remote
*
* @throws PrivilegeException
* if the SSO can not be performed with the given data
*/
User authenticateSingleSignOn(Object data) throws PrivilegeException;
}

View File

@ -22,11 +22,7 @@ import java.text.MessageFormat;
import java.util.Map; import java.util.Map;
import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.handler.DefaultPrivilegeHandler; import li.strolch.privilege.handler.*;
import li.strolch.privilege.handler.EncryptionHandler;
import li.strolch.privilege.handler.PersistenceHandler;
import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.handler.UserChallengeHandler;
import li.strolch.privilege.model.internal.PrivilegeContainerModel; import li.strolch.privilege.model.internal.PrivilegeContainerModel;
import li.strolch.privilege.policy.PrivilegePolicy; import li.strolch.privilege.policy.PrivilegePolicy;
import li.strolch.privilege.xml.PrivilegeConfigSaxReader; import li.strolch.privilege.xml.PrivilegeConfigSaxReader;
@ -36,19 +32,19 @@ import li.strolch.utils.helper.XmlHelper;
/** /**
* This class implements the initializing of the {@link PrivilegeHandler} by loading an XML file containing the * This class implements the initializing of the {@link PrivilegeHandler} by loading an XML file containing the
* configuration * configuration
* *
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*/ */
public class PrivilegeInitializationHelper { public class PrivilegeInitializationHelper {
/** /**
* Initializes the {@link DefaultPrivilegeHandler} from the configuration file * Initializes the {@link DefaultPrivilegeHandler} from the configuration file
* *
* @param privilegeXmlFile * @param privilegeXmlFile
* a {@link File} reference to the XML file containing the configuration for Privilege * a {@link File} reference to the XML file containing the configuration for Privilege
* *
* @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and * @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and
* {@link PersistenceHandler} are set and initialized as well * {@link PersistenceHandler} are set and initialized as well
*/ */
public static PrivilegeHandler initializeFromXml(File privilegeXmlFile) { public static PrivilegeHandler initializeFromXml(File privilegeXmlFile) {
@ -72,12 +68,12 @@ public class PrivilegeInitializationHelper {
/** /**
* Initializes the {@link PrivilegeHandler} by loading from the given input stream. This stream must be a valid XML * Initializes the {@link PrivilegeHandler} by loading from the given input stream. This stream must be a valid XML
* source * source
* *
* @param privilegeConfigInputStream * @param privilegeConfigInputStream
* the XML stream containing the privilege configuration * the XML stream containing the privilege configuration
* *
* @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and * @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and
* {@link PersistenceHandler} are set and initialized as well * {@link PersistenceHandler} are set and initialized as well
*/ */
public static PrivilegeHandler initializeFromXml(InputStream privilegeConfigInputStream) { public static PrivilegeHandler initializeFromXml(InputStream privilegeConfigInputStream) {
@ -91,12 +87,12 @@ public class PrivilegeInitializationHelper {
/** /**
* Initializes the {@link PrivilegeHandler} by initializing from the given {@link PrivilegeContainerModel} * Initializes the {@link PrivilegeHandler} by initializing from the given {@link PrivilegeContainerModel}
* *
* @param containerModel * @param containerModel
* the configuration for the {@link PrivilegeHandler} * the configuration for the {@link PrivilegeHandler}
* *
* @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and * @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and
* {@link PersistenceHandler} are set and initialized as well * {@link PersistenceHandler} are set and initialized as well
*/ */
public static PrivilegeHandler initializeFromXml(PrivilegeContainerModel containerModel) { public static PrivilegeHandler initializeFromXml(PrivilegeContainerModel containerModel) {
@ -137,13 +133,31 @@ public class PrivilegeInitializationHelper {
throw new PrivilegeException(msg, e); throw new PrivilegeException(msg, e);
} }
// initialize SSO handler
SingleSignOnHandler ssoHandler;
if (containerModel.getSsoHandlerClassName() == null) {
ssoHandler = null;
} else {
String ssoHandlerClassName = containerModel.getSsoHandlerClassName();
ssoHandler = ClassHelper.instantiateClass(ssoHandlerClassName);
parameterMap = containerModel.getSsoHandlerParameterMap();
try {
ssoHandler.initialize(parameterMap);
} catch (Exception e) {
String msg = "SingleSignOnHandler {0} could not be initialized"; //$NON-NLS-1$
msg = MessageFormat.format(msg, ssoHandlerClassName);
throw new PrivilegeException(msg, e);
}
}
// initialize privilege handler // initialize privilege handler
DefaultPrivilegeHandler privilegeHandler = new DefaultPrivilegeHandler(); DefaultPrivilegeHandler privilegeHandler = new DefaultPrivilegeHandler();
parameterMap = containerModel.getParameterMap(); parameterMap = containerModel.getParameterMap();
Map<String, Class<PrivilegePolicy>> policyMap = containerModel.getPolicies(); Map<String, Class<PrivilegePolicy>> policyMap = containerModel.getPolicies();
try { try {
privilegeHandler.initialize(parameterMap, encryptionHandler, persistenceHandler, challengeHandler, privilegeHandler
policyMap); .initialize(parameterMap, encryptionHandler, persistenceHandler, challengeHandler, ssoHandler,
policyMap);
} catch (Exception e) { } catch (Exception e) {
String msg = "PrivilegeHandler {0} could not be initialized"; //$NON-NLS-1$ String msg = "PrivilegeHandler {0} could not be initialized"; //$NON-NLS-1$
msg = MessageFormat.format(msg, privilegeHandler.getClass().getName()); msg = MessageFormat.format(msg, privilegeHandler.getClass().getName());

View File

@ -68,6 +68,11 @@ public class XmlConstants {
*/ */
public static final String XML_HANDLER_ENCRYPTION = "EncryptionHandler"; public static final String XML_HANDLER_ENCRYPTION = "EncryptionHandler";
/**
* XML_HANDLER_ENCRYPTION = "EncryptionHandler" :
*/
public static final String XML_HANDLER_SSO = "SsoHandler";
/** /**
* XML_HANDLER_PRIVILEGE = "PrivilegeHandler" : * XML_HANDLER_PRIVILEGE = "PrivilegeHandler" :
*/ */

View File

@ -27,11 +27,11 @@ import li.strolch.privilege.policy.PrivilegePolicy;
/** /**
* This class is used during XML parsing to hold the model before it is properly validated and made accessible through * This class is used during XML parsing to hold the model before it is properly validated and made accessible through
* the {@link PrivilegeHandler} * the {@link PrivilegeHandler}
* *
* <p> * <p>
* Note: This is an internal object which is not to be serialized or passed to clients * Note: This is an internal object which is not to be serialized or passed to clients
* </p> * </p>
* *
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*/ */
public class PrivilegeContainerModel { public class PrivilegeContainerModel {
@ -39,10 +39,12 @@ public class PrivilegeContainerModel {
private String encryptionHandlerClassName; private String encryptionHandlerClassName;
private String persistenceHandlerClassName; private String persistenceHandlerClassName;
private String userChallengeHandlerClassName; private String userChallengeHandlerClassName;
private String ssoHandlerClassName;
private Map<String, String> encryptionHandlerParameterMap; private Map<String, String> encryptionHandlerParameterMap;
private Map<String, String> persistenceHandlerParameterMap; private Map<String, String> persistenceHandlerParameterMap;
private Map<String, String> challengeHandlerParameterMap; private Map<String, String> challengeHandlerParameterMap;
private Map<String, String> ssoHandlerParameterMap;
private Map<String, String> parameterMap; private Map<String, String> parameterMap;
@ -53,6 +55,7 @@ public class PrivilegeContainerModel {
this.encryptionHandlerParameterMap = new HashMap<>(); this.encryptionHandlerParameterMap = new HashMap<>();
this.persistenceHandlerParameterMap = new HashMap<>(); this.persistenceHandlerParameterMap = new HashMap<>();
this.challengeHandlerParameterMap = new HashMap<>(); this.challengeHandlerParameterMap = new HashMap<>();
this.ssoHandlerParameterMap = new HashMap<>();
} }
public Map<String, String> getParameterMap() { public Map<String, String> getParameterMap() {
@ -103,6 +106,14 @@ public class PrivilegeContainerModel {
this.userChallengeHandlerClassName = userChallengeHandlerClassName; this.userChallengeHandlerClassName = userChallengeHandlerClassName;
} }
public String getSsoHandlerClassName() {
return this.ssoHandlerClassName;
}
public void setSsoHandlerClassName(String ssoHandlerClassName) {
this.ssoHandlerClassName = ssoHandlerClassName;
}
public Map<String, String> getUserChallengeHandlerParameterMap() { public Map<String, String> getUserChallengeHandlerParameterMap() {
return this.challengeHandlerParameterMap; return this.challengeHandlerParameterMap;
} }
@ -111,6 +122,14 @@ public class PrivilegeContainerModel {
this.challengeHandlerParameterMap = challengeHandlerParameterMap; this.challengeHandlerParameterMap = challengeHandlerParameterMap;
} }
public Map<String, String> getSsoHandlerParameterMap() {
return this.ssoHandlerParameterMap;
}
public void setSsoHandlerParameterMap(Map<String, String> ssoHandlerParameterMap) {
this.ssoHandlerParameterMap = ssoHandlerParameterMap;
}
public void addPolicy(String privilegeName, String policyClassName) { public void addPolicy(String privilegeName, String policyClassName) {
try { try {
@ -160,6 +179,8 @@ public class PrivilegeContainerModel {
builder.append(this.persistenceHandlerParameterMap.size()); builder.append(this.persistenceHandlerParameterMap.size());
builder.append(", challengeHandlerParameterMap="); builder.append(", challengeHandlerParameterMap=");
builder.append(this.challengeHandlerParameterMap.size()); builder.append(this.challengeHandlerParameterMap.size());
builder.append(", ssoHandlerParameterMap=");
builder.append(this.ssoHandlerParameterMap.size());
builder.append(", parameterMap="); builder.append(", parameterMap=");
builder.append(this.parameterMap.size()); builder.append(this.parameterMap.size());
builder.append(", policies="); builder.append(", policies=");

View File

@ -15,20 +15,20 @@
*/ */
package li.strolch.privilege.xml; package li.strolch.privilege.xml;
import static li.strolch.privilege.helper.XmlConstants.*;
import java.io.File; import java.io.File;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import li.strolch.privilege.helper.XmlConstants;
import li.strolch.privilege.model.internal.PrivilegeContainerModel; import li.strolch.privilege.model.internal.PrivilegeContainerModel;
import li.strolch.privilege.policy.PrivilegePolicy; import li.strolch.privilege.policy.PrivilegePolicy;
import li.strolch.utils.helper.XmlHelper; import li.strolch.utils.helper.XmlHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/** /**
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*
*/ */
public class PrivilegeConfigDomWriter { public class PrivilegeConfigDomWriter {
@ -36,7 +36,7 @@ public class PrivilegeConfigDomWriter {
private final File configFile; private final File configFile;
/** /**
* *
*/ */
public PrivilegeConfigDomWriter(PrivilegeContainerModel containerModel, File configFile) { public PrivilegeConfigDomWriter(PrivilegeContainerModel containerModel, File configFile) {
this.containerModel = containerModel; this.containerModel = containerModel;
@ -44,72 +44,77 @@ public class PrivilegeConfigDomWriter {
} }
/** /**
* *
*/ */
public void write() { public void write() {
// create document root // create document root
Document doc = XmlHelper.createDocument(); Document doc = XmlHelper.createDocument();
Element rootElement = doc.createElement(XmlConstants.XML_ROOT_PRIVILEGE); Element rootElement = doc.createElement(XML_ROOT_PRIVILEGE);
doc.appendChild(rootElement); doc.appendChild(rootElement);
Element containerElement = doc.createElement(XmlConstants.XML_CONTAINER); Element containerElement = doc.createElement(XML_CONTAINER);
rootElement.appendChild(containerElement); rootElement.appendChild(containerElement);
Element parameterElement;
Element parametersElement;
// Parameters
parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS);
containerElement.appendChild(parametersElement);
for (Entry<String, String> entry : this.containerModel.getParameterMap().entrySet()) {
parameterElement = doc.createElement(XmlConstants.XML_PARAMETER);
parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue());
parametersElement.appendChild(parameterElement);
}
// create EncryptionHandler // create EncryptionHandler
Element encryptionHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_ENCRYPTION); Element encryptionHandlerElem = doc.createElement(XML_HANDLER_ENCRYPTION);
containerElement.appendChild(encryptionHandlerElem); containerElement.appendChild(encryptionHandlerElem);
encryptionHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS, encryptionHandlerElem.setAttribute(XML_ATTR_CLASS, this.containerModel.getEncryptionHandlerClassName());
this.containerModel.getEncryptionHandlerClassName());
// Parameters // Parameters
parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); fillParameterMap(doc, encryptionHandlerElem, this.containerModel.getEncryptionHandlerParameterMap());
encryptionHandlerElem.appendChild(parametersElement);
for (Entry<String, String> entry : this.containerModel.getEncryptionHandlerParameterMap().entrySet()) {
parameterElement = doc.createElement(XmlConstants.XML_PARAMETER);
parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue());
parametersElement.appendChild(parameterElement);
}
// create PersistenceHandler // create PersistenceHandler
Element persistenceHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_PERSISTENCE); Element persistenceHandlerElem = doc.createElement(XML_HANDLER_PERSISTENCE);
containerElement.appendChild(persistenceHandlerElem); containerElement.appendChild(persistenceHandlerElem);
persistenceHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS, persistenceHandlerElem.setAttribute(XML_ATTR_CLASS, this.containerModel.getPersistenceHandlerClassName());
this.containerModel.getPersistenceHandlerClassName());
// Parameters // Parameters
parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); fillParameterMap(doc, persistenceHandlerElem, this.containerModel.getPersistenceHandlerParameterMap());
persistenceHandlerElem.appendChild(parametersElement);
for (Entry<String, String> entry : this.containerModel.getPersistenceHandlerParameterMap().entrySet()) { // Parameters
parameterElement = doc.createElement(XmlConstants.XML_PARAMETER); fillParameterMap(doc, containerElement, this.containerModel.getParameterMap());
parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue()); // create UserChallengeHandler
parametersElement.appendChild(parameterElement); Element userChallengeHandlerElem = doc.createElement(XML_HANDLER_USER_CHALLENGE);
containerElement.appendChild(userChallengeHandlerElem);
userChallengeHandlerElem.setAttribute(XML_ATTR_CLASS, this.containerModel.getUserChallengeHandlerClassName());
// Parameters
fillParameterMap(doc, userChallengeHandlerElem, this.containerModel.getUserChallengeHandlerParameterMap());
// create SingleSignOnHandler
if (this.containerModel.getSsoHandlerClassName() != null) {
Element ssoHandlerElem = doc.createElement(XML_HANDLER_SSO);
containerElement.appendChild(ssoHandlerElem);
ssoHandlerElem.setAttribute(XML_ATTR_CLASS, this.containerModel.getSsoHandlerClassName());
// Parameters
fillParameterMap(doc, ssoHandlerElem, this.containerModel.getSsoHandlerParameterMap());
} }
// Policies // Policies
Element policiesElem = doc.createElement(XmlConstants.XML_POLICIES); Element policiesElem = doc.createElement(XML_POLICIES);
rootElement.appendChild(policiesElem); rootElement.appendChild(policiesElem);
for (Entry<String, Class<PrivilegePolicy>> entry : this.containerModel.getPolicies().entrySet()) { for (Entry<String, Class<PrivilegePolicy>> entry : this.containerModel.getPolicies().entrySet()) {
Element policyElem = doc.createElement(XmlConstants.XML_POLICY); Element policyElem = doc.createElement(XML_POLICY);
policyElem.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey()); policyElem.setAttribute(XML_ATTR_NAME, entry.getKey());
policyElem.setAttribute(XmlConstants.XML_ATTR_CLASS, entry.getValue().getName()); policyElem.setAttribute(XML_ATTR_CLASS, entry.getValue().getName());
policiesElem.appendChild(policyElem); policiesElem.appendChild(policyElem);
} }
// write the container file to disk // write the container file to disk
XmlHelper.writeDocument(doc, this.configFile); XmlHelper.writeDocument(doc, this.configFile);
} }
private void fillParameterMap(Document doc, Element parent, Map<String, String> parameterMap) {
if (parameterMap != null && !parameterMap.isEmpty()) {
Element parametersElement = doc.createElement(XML_PARAMETERS);
for (Entry<String, String> entry : parameterMap.entrySet()) {
Element parameterElement = doc.createElement(XML_PARAMETER);
parameterElement.setAttribute(XML_ATTR_NAME, entry.getKey());
parameterElement.setAttribute(XML_ATTR_VALUE, entry.getValue());
parametersElement.appendChild(parameterElement);
}
parent.appendChild(parametersElement);
}
}
} }

View File

@ -105,6 +105,10 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
this.currentElement = qName; this.currentElement = qName;
String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS); String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
getContainerModel().setUserChallengeHandlerClassName(className); getContainerModel().setUserChallengeHandlerClassName(className);
} else if (qName.equals(XmlConstants.XML_HANDLER_SSO)) {
this.currentElement = qName;
String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
getContainerModel().setSsoHandlerClassName(className);
} }
} }
@ -123,6 +127,8 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
getContainerModel().setPersistenceHandlerParameterMap(parametersChild.getParameterMap()); getContainerModel().setPersistenceHandlerParameterMap(parametersChild.getParameterMap());
} else if (this.currentElement.equals(XmlConstants.XML_HANDLER_USER_CHALLENGE)) { } else if (this.currentElement.equals(XmlConstants.XML_HANDLER_USER_CHALLENGE)) {
getContainerModel().setUserChallengeHandlerParameterMap(parametersChild.getParameterMap()); getContainerModel().setUserChallengeHandlerParameterMap(parametersChild.getParameterMap());
} else if (this.currentElement.equals(XmlConstants.XML_HANDLER_SSO)) {
getContainerModel().setSsoHandlerParameterMap(parametersChild.getParameterMap());
} }
} }
} }

View File

@ -25,8 +25,7 @@ public class AbstractPrivilegeTest {
protected void login(String username, char[] password) { protected void login(String username, char[] password) {
Certificate certificate = privilegeHandler.authenticate(username, password); Certificate certificate = privilegeHandler.authenticate(username, password);
assertTrue("Certificate is null!", certificate != null); assertTrue("Certificate is null!", certificate != null);
PrivilegeContext privilegeContext = privilegeHandler.getPrivilegeContext(certificate); this.ctx = privilegeHandler.validate(certificate);
this.ctx = privilegeContext;
} }
protected void logout() { protected void logout() {
@ -34,7 +33,7 @@ public class AbstractPrivilegeTest {
try { try {
PrivilegeContext privilegeContext = this.ctx; PrivilegeContext privilegeContext = this.ctx;
this.ctx = null; this.ctx = null;
privilegeHandler.invalidateSession(privilegeContext.getCertificate()); privilegeHandler.invalidate(privilegeContext.getCertificate());
} catch (PrivilegeException e) { } catch (PrivilegeException e) {
String msg = "There is no PrivilegeContext currently bound to the ThreadLocal!"; String msg = "There is no PrivilegeContext currently bound to the ThreadLocal!";
if (!e.getMessage().equals(msg)) if (!e.getMessage().equals(msg))
@ -43,18 +42,18 @@ public class AbstractPrivilegeTest {
} }
} }
protected static void prepareConfigs(String dst, String configFilename, String usersFilename, protected static void prepareConfigs(String dst,
String rolesFilename) { String configFilename,
String usersFilename,
String rolesFilename) {
try { try {
String pwd = System.getProperty("user.dir"); File configPath = new File("src/test/resources/config");
File configPath = new File(pwd, "config");
File privilegeConfigFile = new File(configPath, configFilename); File privilegeConfigFile = new File(configPath, configFilename);
File privilegeUsersFile = new File(configPath, usersFilename); File privilegeUsersFile = new File(configPath, usersFilename);
File privilegeRolesFile = new File(configPath, rolesFilename); File privilegeRolesFile = new File(configPath, rolesFilename);
File targetPath = new File(pwd, "target/" + dst); File targetPath = new File("target/" + dst);
if (!targetPath.mkdirs()) if (!targetPath.mkdirs())
throw new RuntimeException("Could not create parent " + targetPath); throw new RuntimeException("Could not create parent " + targetPath);
@ -79,8 +78,7 @@ public class AbstractPrivilegeTest {
protected static void removeConfigs(String dst) { protected static void removeConfigs(String dst) {
try { try {
String pwd = System.getProperty("user.dir"); File targetPath = new File("target");
File targetPath = new File(pwd, "target");
targetPath = new File(targetPath, dst); targetPath = new File(targetPath, dst);
if (targetPath.exists() && !FileHelper.deleteFile(targetPath, true)) { if (targetPath.exists() && !FileHelper.deleteFile(targetPath, true)) {
throw new RuntimeException( throw new RuntimeException(
@ -94,8 +92,7 @@ public class AbstractPrivilegeTest {
protected static File getPrivilegeConfigFile(String dst, String configFilename) { protected static File getPrivilegeConfigFile(String dst, String configFilename) {
try { try {
String pwd = System.getProperty("user.dir"); File targetPath = new File("target");
File targetPath = new File(pwd, "target");
targetPath = new File(targetPath, dst); targetPath = new File(targetPath, dst);
return new File(targetPath, configFilename); return new File(targetPath, configFilename);
} catch (Exception e) { } catch (Exception e) {

View File

@ -38,11 +38,11 @@ public class PersistSessionsTest extends AbstractPrivilegeTest {
// login and assert sessions file was written // login and assert sessions file was written
login("admin", "admin".toCharArray()); login("admin", "admin".toCharArray());
this.privilegeHandler.isCertificateValid(ctx.getCertificate()); this.privilegeHandler.validate(ctx.getCertificate());
assertTrue("Sessions File should have been created!", sessionsFile.isFile()); assertTrue("Sessions File should have been created!", sessionsFile.isFile());
// re-initialize and assert still logged in // re-initialize and assert still logged in
initialize(PersistSessionsTest.class.getSimpleName(), "PrivilegeConfig.xml"); initialize(PersistSessionsTest.class.getSimpleName(), "PrivilegeConfig.xml");
this.privilegeHandler.isCertificateValid(ctx.getCertificate()); this.privilegeHandler.validate(ctx.getCertificate());
} }
} }

View File

@ -59,9 +59,9 @@ import li.strolch.utils.helper.ArraysHelper;
/** /**
* JUnit for performing Privilege tests. This JUnit is by no means complete, but checks the bare minimum.br /> * JUnit for performing Privilege tests. This JUnit is by no means complete, but checks the bare minimum.br />
* *
* TODO add more tests, especially with deny and allow lists * TODO add more tests, especially with deny and allow lists
* *
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*/ */
@SuppressWarnings("nls") @SuppressWarnings("nls")
@ -117,9 +117,10 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
} }
} }
@Test
public void testFailAuthenticationNOk() throws Exception { public void testFailAuthenticationNOk() throws Exception {
this.exception.expect(AccessDeniedException.class); this.exception.expect(AccessDeniedException.class);
this.exception.expectMessage("blabla"); this.exception.expectMessage("User admin failed to authenticate: Password is incorrect for admin");
try { try {
login(ADMIN, ArraysHelper.copyOf(PASS_BAD)); login(ADMIN, ArraysHelper.copyOf(PASS_BAD));
} finally { } finally {
@ -127,9 +128,10 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
} }
} }
@Test
public void testFailAuthenticationPWNull() throws Exception { public void testFailAuthenticationPWNull() throws Exception {
this.exception.expect(PrivilegeException.class); this.exception.expect(PrivilegeException.class);
this.exception.expectMessage("blabla"); this.exception.expectMessage("User admin failed to authenticate: A password may not be empty!");
try { try {
login(ADMIN, null); login(ADMIN, null);
} finally { } finally {
@ -324,7 +326,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
Certificate certificate = this.ctx.getCertificate(); Certificate certificate = this.ctx.getCertificate();
UserRep selectorRep = new UserRep(null, null, null, null, null, UserRep selectorRep = new UserRep(null, null, null, null, null,
new HashSet<>(Arrays.asList("PrivilegeAdmin")), null, null); new HashSet<>(Collections.singletonList("PrivilegeAdmin")), null, null);
List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep); List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep);
assertEquals(1, users.size()); assertEquals(1, users.size());
assertEquals(ADMIN, users.get(0).getUsername()); assertEquals(ADMIN, users.get(0).getUsername());
@ -341,8 +343,8 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
Certificate certificate = this.ctx.getCertificate(); Certificate certificate = this.ctx.getCertificate();
UserRep selectorRep = new UserRep(null, null, null, null, null, new HashSet<>(Arrays.asList(ROLE_TEMP)), UserRep selectorRep = new UserRep(null, null, null, null, null,
null, null); new HashSet<>(Collections.singletonList(ROLE_TEMP)), null, null);
List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep); List<UserRep> users = this.privilegeHandler.queryUsers(certificate, selectorRep);
assertEquals(0, users.size()); assertEquals(0, users.size());
@ -384,12 +386,13 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
public void shouldSetPasswordWithChallenge() { public void shouldSetPasswordWithChallenge() {
this.privilegeHandler.initiateChallengeFor(Usage.SET_PASSWORD, ADMIN); this.privilegeHandler.initiateChallengeFor(Usage.SET_PASSWORD, ADMIN);
UserChallenge userChallenge = TestUserChallengeHandler.getInstance().getChallenges().values().stream() UserChallenge userChallenge = TestUserChallengeHandler.getInstance().getChallenges().values().stream()
.filter(u -> u.getUser().getUsername().equals(ADMIN)).findFirst().get(); .filter(u -> u.getUser().getUsername().equals(ADMIN)).findFirst()
.orElseThrow(() -> new IllegalStateException("Missing admin user!"));
Certificate certificate = this.privilegeHandler.validateChallenge(ADMIN, userChallenge.getChallenge()); Certificate certificate = this.privilegeHandler.validateChallenge(ADMIN, userChallenge.getChallenge());
this.privilegeHandler.setUserPassword(certificate, ADMIN, ArraysHelper.copyOf(PASS_TED)); this.privilegeHandler.setUserPassword(certificate, ADMIN, ArraysHelper.copyOf(PASS_TED));
try { try {
this.privilegeHandler.isCertificateValid(certificate); this.privilegeHandler.validate(certificate);
fail("Certificate should not be valid anymore!"); fail("Certificate should not be valid anymore!");
} catch (PrivilegeException e) { } catch (PrivilegeException e) {
// expected // expected
@ -398,7 +401,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
// change password back // change password back
certificate = this.privilegeHandler.authenticate(ADMIN, PASS_TED); certificate = this.privilegeHandler.authenticate(ADMIN, PASS_TED);
this.privilegeHandler.setUserPassword(certificate, ADMIN, ArraysHelper.copyOf(PASS_ADMIN)); this.privilegeHandler.setUserPassword(certificate, ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
this.privilegeHandler.invalidateSession(certificate); this.privilegeHandler.invalidate(certificate);
} }
/** /**
@ -651,8 +654,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
// let's add a new user ted // let's add a new user ted
HashSet<String> roles = new HashSet<>(); HashSet<String> roles = new HashSet<>();
roles.add(ROLE_USER); roles.add(ROLE_USER);
userRep = new UserRep(null, TED, "Ted", "Newman", UserState.ENABLED, roles, null, userRep = new UserRep(null, TED, "Ted", "Newman", UserState.ENABLED, roles, null, new HashMap<>());
new HashMap<String, String>());
Certificate certificate = this.ctx.getCertificate(); Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addUser(certificate, userRep, null); this.privilegeHandler.addUser(certificate, userRep, null);
logger.info("Added user " + TED); logger.info("Added user " + TED);
@ -765,7 +767,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest {
// let's add a new user bob // let's add a new user bob
UserRep userRep = new UserRep(null, BOB, "Bob", "Newman", UserState.NEW, UserRep userRep = new UserRep(null, BOB, "Bob", "Newman", UserState.NEW,
new HashSet<>(Arrays.asList(ROLE_MY)), null, new HashMap<String, String>()); new HashSet<>(Collections.singletonList(ROLE_MY)), null, new HashMap<>());
Certificate certificate = this.ctx.getCertificate(); Certificate certificate = this.ctx.getCertificate();
this.privilegeHandler.addUser(certificate, userRep, null); this.privilegeHandler.addUser(certificate, userRep, null);
logger.info("Added user " + BOB); logger.info("Added user " + BOB);

View File

@ -0,0 +1,57 @@
package li.strolch.privilege.test;
import java.util.HashMap;
import java.util.Map;
import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.Restrictable;
import li.strolch.privilege.test.model.TestRestrictable;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class SsoHandlerTest extends AbstractPrivilegeTest {
@BeforeClass
public static void init() throws Exception {
removeConfigs(SsoHandlerTest.class.getSimpleName());
prepareConfigs(SsoHandlerTest.class.getSimpleName(), "PrivilegeConfig.xml", "PrivilegeUsers.xml",
"PrivilegeRoles.xml");
}
@AfterClass
public static void destroy() throws Exception {
removeConfigs(SsoHandlerTest.class.getSimpleName());
}
@Before
public void setup() throws Exception {
initialize(SsoHandlerTest.class.getSimpleName(), "PrivilegeConfig.xml");
}
@Test
public void testSsoAdmin() throws Exception {
try {
Map<String, String> data = new HashMap<>();
data.put("userId", "admin");
data.put("username", "admin");
data.put("firstName", "Admin");
data.put("lastName", "Istrator");
data.put("roles", "PrivilegeAdmin, AppUser");
// auth
Certificate cert = this.privilegeHandler.authenticateSingleSignOn(data);
this.ctx = this.privilegeHandler.validate(cert);
// validate action
Restrictable restrictable = new TestRestrictable();
this.ctx.validateAction(restrictable);
} finally {
// de-auth
logout();
}
}
}

View File

@ -16,30 +16,13 @@
package li.strolch.privilege.test; package li.strolch.privilege.test;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.privilege.handler.DefaultEncryptionHandler; import li.strolch.privilege.handler.DefaultEncryptionHandler;
import li.strolch.privilege.handler.MailUserChallengeHandler;
import li.strolch.privilege.handler.PrivilegeHandler; import li.strolch.privilege.handler.PrivilegeHandler;
import li.strolch.privilege.handler.XmlPersistenceHandler; import li.strolch.privilege.handler.XmlPersistenceHandler;
import li.strolch.privilege.model.IPrivilege; import li.strolch.privilege.model.IPrivilege;
@ -48,15 +31,16 @@ import li.strolch.privilege.model.internal.PrivilegeContainerModel;
import li.strolch.privilege.model.internal.PrivilegeImpl; import li.strolch.privilege.model.internal.PrivilegeImpl;
import li.strolch.privilege.model.internal.Role; import li.strolch.privilege.model.internal.Role;
import li.strolch.privilege.model.internal.User; import li.strolch.privilege.model.internal.User;
import li.strolch.privilege.xml.PrivilegeConfigDomWriter; import li.strolch.privilege.test.model.DummySsoHandler;
import li.strolch.privilege.xml.PrivilegeConfigSaxReader; import li.strolch.privilege.xml.*;
import li.strolch.privilege.xml.PrivilegeRolesDomWriter;
import li.strolch.privilege.xml.PrivilegeRolesSaxReader;
import li.strolch.privilege.xml.PrivilegeUsersDomWriter;
import li.strolch.privilege.xml.PrivilegeUsersSaxReader;
import li.strolch.utils.helper.FileHelper; import li.strolch.utils.helper.FileHelper;
import li.strolch.utils.helper.StringHelper; import li.strolch.utils.helper.StringHelper;
import li.strolch.utils.helper.XmlHelper; import li.strolch.utils.helper.XmlHelper;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
@ -64,12 +48,13 @@ import li.strolch.utils.helper.XmlHelper;
@SuppressWarnings("nls") @SuppressWarnings("nls")
public class XmlTest { public class XmlTest {
private static final String TARGET_TEST = "./target/test"; private static final String TARGET_TEST = "target/test/";
private static final String SRC_TEST = "src/test/resources/config/";
private static final Logger logger = LoggerFactory.getLogger(XmlTest.class); private static final Logger logger = LoggerFactory.getLogger(XmlTest.class);
/** /**
* @throws Exception * @throws Exception
* if something goes wrong * if something goes wrong
*/ */
@BeforeClass @BeforeClass
public static void init() throws Exception { public static void init() throws Exception {
@ -89,17 +74,17 @@ public class XmlTest {
if (!tmpDir.exists()) if (!tmpDir.exists())
return; return;
File tmpFile = new File("target/test/PrivilegeTest.xml"); File tmpFile = new File(TARGET_TEST + "PrivilegeTest.xml");
if (tmpFile.exists() && !tmpFile.delete()) { if (tmpFile.exists() && !tmpFile.delete()) {
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
} }
tmpFile = new File("target/test/PrivilegeUsersTest.xml"); tmpFile = new File(TARGET_TEST + "PrivilegeUsersTest.xml");
if (tmpFile.exists() && !tmpFile.delete()) { if (tmpFile.exists() && !tmpFile.delete()) {
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
} }
tmpFile = new File("target/test/PrivilegeRolesTest.xml"); tmpFile = new File(TARGET_TEST + "PrivilegeRolesTest.xml");
if (tmpFile.exists() && !tmpFile.delete()) { if (tmpFile.exists() && !tmpFile.delete()) {
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
} }
@ -115,7 +100,7 @@ public class XmlTest {
PrivilegeContainerModel containerModel = new PrivilegeContainerModel(); PrivilegeContainerModel containerModel = new PrivilegeContainerModel();
PrivilegeConfigSaxReader saxReader = new PrivilegeConfigSaxReader(containerModel); PrivilegeConfigSaxReader saxReader = new PrivilegeConfigSaxReader(containerModel);
File xmlFile = new File("config/PrivilegeConfig.xml"); File xmlFile = new File(SRC_TEST + "PrivilegeConfig.xml");
XmlHelper.parseDocument(xmlFile, saxReader); XmlHelper.parseDocument(xmlFile, saxReader);
logger.info(containerModel.toString()); logger.info(containerModel.toString());
@ -153,22 +138,24 @@ public class XmlTest {
containerModel.setEncryptionHandlerParameterMap(encryptionHandlerParameterMap); containerModel.setEncryptionHandlerParameterMap(encryptionHandlerParameterMap);
containerModel.setPersistenceHandlerClassName(XmlPersistenceHandler.class.getName()); containerModel.setPersistenceHandlerClassName(XmlPersistenceHandler.class.getName());
containerModel.setPersistenceHandlerParameterMap(persistenceHandlerParameterMap); containerModel.setPersistenceHandlerParameterMap(persistenceHandlerParameterMap);
containerModel.setUserChallengeHandlerClassName(MailUserChallengeHandler.class.getName());
containerModel.setSsoHandlerClassName(DummySsoHandler.class.getName());
containerModel.addPolicy("DefaultPrivilege", "li.strolch.privilege.policy.DefaultPrivilege"); containerModel.addPolicy("DefaultPrivilege", "li.strolch.privilege.policy.DefaultPrivilege");
File configFile = new File("./target/test/PrivilegeTest.xml"); File configFile = new File(TARGET_TEST + "PrivilegeTest.xml");
PrivilegeConfigDomWriter configSaxWriter = new PrivilegeConfigDomWriter(containerModel, configFile); PrivilegeConfigDomWriter configSaxWriter = new PrivilegeConfigDomWriter(containerModel, configFile);
configSaxWriter.write(); configSaxWriter.write();
String fileHash = StringHelper.toHexString(FileHelper.hashFileSha256(configFile)); String fileHash = StringHelper.toHexString(FileHelper.hashFileSha256(configFile));
assertEquals("800b8e42e15b6b3bb425fa9c12a011d587d2b12343a1d1371eaa36dc1b2ea5f4", fileHash); assertEquals("55c1212446707563877009f2090a39ad2fdf5462108109bbe0c10759d100a482", fileHash);
} }
@Test @Test
public void canReadUsers() { public void canReadUsers() {
PrivilegeUsersSaxReader xmlHandler = new PrivilegeUsersSaxReader(); PrivilegeUsersSaxReader xmlHandler = new PrivilegeUsersSaxReader();
File xmlFile = new File("config/PrivilegeUsers.xml"); File xmlFile = new File(SRC_TEST + "PrivilegeUsers.xml");
XmlHelper.parseDocument(xmlFile, xmlHandler); XmlHelper.parseDocument(xmlFile, xmlHandler);
List<User> users = xmlHandler.getUsers(); List<User> users = xmlHandler.getUsers();
@ -215,7 +202,7 @@ public class XmlTest {
public void canReadRoles() { public void canReadRoles() {
PrivilegeRolesSaxReader xmlHandler = new PrivilegeRolesSaxReader(); PrivilegeRolesSaxReader xmlHandler = new PrivilegeRolesSaxReader();
File xmlFile = new File("config/PrivilegeRoles.xml"); File xmlFile = new File(SRC_TEST + "PrivilegeRoles.xml");
XmlHelper.parseDocument(xmlFile, xmlHandler); XmlHelper.parseDocument(xmlFile, xmlHandler);
List<Role> roles = xmlHandler.getRoles(); List<Role> roles = xmlHandler.getRoles();
@ -253,7 +240,7 @@ public class XmlTest {
// AppUser // AppUser
Role appUser = findRole("AppUser", roles); Role appUser = findRole("AppUser", roles);
assertEquals("AppUser", appUser.getName()); assertEquals("AppUser", appUser.getName());
assertEquals(new HashSet<>(Arrays.asList("li.strolch.privilege.test.model.TestRestrictable")), assertEquals(new HashSet<>(Collections.singletonList("li.strolch.privilege.test.model.TestRestrictable")),
appUser.getPrivilegeNames()); appUser.getPrivilegeNames());
IPrivilege testRestrictable = appUser.getPrivilege("li.strolch.privilege.test.model.TestRestrictable"); IPrivilege testRestrictable = appUser.getPrivilege("li.strolch.privilege.test.model.TestRestrictable");
@ -267,8 +254,9 @@ public class XmlTest {
Role systemAdminPrivileges = findRole("system_admin_privileges", roles); Role systemAdminPrivileges = findRole("system_admin_privileges", roles);
assertEquals("system_admin_privileges", systemAdminPrivileges.getName()); assertEquals("system_admin_privileges", systemAdminPrivileges.getName());
assertEquals(2, systemAdminPrivileges.getPrivilegeNames().size()); assertEquals(2, systemAdminPrivileges.getPrivilegeNames().size());
assertThat(systemAdminPrivileges.getPrivilegeNames(), containsInAnyOrder( assertThat(systemAdminPrivileges.getPrivilegeNames(),
"li.strolch.privilege.handler.SystemAction", "li.strolch.privilege.test.model.TestSystemRestrictable")); containsInAnyOrder("li.strolch.privilege.handler.SystemAction",
"li.strolch.privilege.test.model.TestSystemRestrictable"));
IPrivilege testSystemUserAction = systemAdminPrivileges IPrivilege testSystemUserAction = systemAdminPrivileges
.getPrivilege("li.strolch.privilege.handler.SystemAction"); .getPrivilege("li.strolch.privilege.handler.SystemAction");
@ -302,11 +290,6 @@ public class XmlTest {
assertThat(testSystemUserAction2.getDenyList(), containsInAnyOrder("goodbye")); assertThat(testSystemUserAction2.getDenyList(), containsInAnyOrder("goodbye"));
} }
/**
* @param username
* @param users
* @return
*/
private User findUser(String username, List<User> users) { private User findUser(String username, List<User> users) {
for (User user : users) { for (User user : users) {
if (user.getUsername().equals(username)) if (user.getUsername().equals(username))
@ -316,11 +299,6 @@ public class XmlTest {
throw new RuntimeException("No user exists with username " + username); throw new RuntimeException("No user exists with username " + username);
} }
/**
* @param name
* @param roles
* @return
*/
private Role findRole(String name, List<Role> roles) { private Role findRole(String name, List<Role> roles) {
for (Role role : roles) { for (Role role : roles) {
if (role.getName().equals(name)) if (role.getName().equals(name))
@ -353,7 +331,7 @@ public class XmlTest {
UserState.ENABLED, userRoles, Locale.ENGLISH, propertyMap); UserState.ENABLED, userRoles, Locale.ENGLISH, propertyMap);
users.add(user2); users.add(user2);
File modelFile = new File("./target/test/PrivilegeUsersTest.xml"); File modelFile = new File(TARGET_TEST + "PrivilegeUsersTest.xml");
PrivilegeUsersDomWriter configSaxWriter = new PrivilegeUsersDomWriter(users, modelFile); PrivilegeUsersDomWriter configSaxWriter = new PrivilegeUsersDomWriter(users, modelFile);
configSaxWriter.write(); configSaxWriter.write();
@ -408,7 +386,7 @@ public class XmlTest {
Role role2 = new Role("role2", privilegeMap); Role role2 = new Role("role2", privilegeMap);
roles.add(role2); roles.add(role2);
File modelFile = new File("./target/test/PrivilegeRolesTest.xml"); File modelFile = new File(TARGET_TEST + "PrivilegeRolesTest.xml");
PrivilegeRolesDomWriter configSaxWriter = new PrivilegeRolesDomWriter(roles, modelFile); PrivilegeRolesDomWriter configSaxWriter = new PrivilegeRolesDomWriter(roles, modelFile);
configSaxWriter.write(); configSaxWriter.write();

View File

@ -0,0 +1,29 @@
package li.strolch.privilege.test.model;
import java.util.*;
import java.util.stream.Collectors;
import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.handler.SingleSignOnHandler;
import li.strolch.privilege.model.UserState;
import li.strolch.privilege.model.internal.User;
public class DummySsoHandler implements SingleSignOnHandler {
@Override
public void initialize(Map<String, String> parameterMap) {
// do nothing
}
@Override
public User authenticateSingleSignOn(Object data) throws PrivilegeException {
@SuppressWarnings("unchecked")
Map<String, String> map = (Map<String, String>) data;
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, null, map.get("firstName"), map.get("lastName"),
UserState.ENABLED, roles, Locale.ENGLISH, properties);
}
}

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<Privilege>
<Container>
<Parameters>
<!-- parameters for the container itself -->
<Parameter name="secretKey" value="5185F447-6317-4856-B40E-573919BA0A16"/>
<Parameter name="secretSalt" value="00F6E88C-A64F-410A-8FCF-9CD340E340F7"/>
<Parameter name="persistSessions" value="true"/>
<Parameter name="persistSessionsPath" value="target/${target}/sessions.dat"/>
<Parameter name="autoPersistOnUserChangesData" value="true"/>
<Parameter name="privilegeConflictResolution" value="STRICT"/>
</Parameters>
<EncryptionHandler class="li.strolch.privilege.handler.DefaultEncryptionHandler">
<Parameters>
<!-- WARNING: If you change iterations or keyLength, then all passwords are invalid -->
<!-- default algorithm is: PBKDF2WithHmacSHA512 -->
<Parameter name="hashAlgorithm" value="PBKDF2WithHmacSHA512"/>
<!-- default iterations: 200000 -->
<Parameter name="hashIterations" value="10000"/>
<!-- default key length: 256 -->
<Parameter name="hashKeyLength" value="256"/>
</Parameters>
</EncryptionHandler>
<PersistenceHandler class="li.strolch.privilege.handler.XmlPersistenceHandler">
<Parameters>
<Parameter name="basePath" value="target/${target}"/>
<Parameter name="usersXmlFile" value="PrivilegeUsers.xml"/>
<Parameter name="rolesXmlFile" value="PrivilegeRoles.xml"/>
</Parameters>
</PersistenceHandler>
<UserChallengeHandler class="li.strolch.privilege.test.model.TestUserChallengeHandler">
</UserChallengeHandler>
<SsoHandler class="li.strolch.privilege.test.model.DummySsoHandler"/>
</Container>
<Policies>
<Policy name="DefaultPrivilege" class="li.strolch.privilege.policy.DefaultPrivilege"/>
<Policy name="RoleAccessPrivilege" class="li.strolch.privilege.policy.RoleAccessPrivilege"/>
<Policy name="UserAccessPrivilege" class="li.strolch.privilege.policy.UserAccessPrivilege"/>
</Policies>
</Privilege>

View File

@ -23,7 +23,7 @@
<PersistenceHandler class="li.strolch.privilege.handler.XmlPersistenceHandler"> <PersistenceHandler class="li.strolch.privilege.handler.XmlPersistenceHandler">
<Parameters> <Parameters>
<Parameter name="basePath" value="./target/${target}" /> <Parameter name="basePath" value="target/${target}" />
<Parameter name="usersXmlFile" value="PrivilegeUsersMerge.xml" /> <Parameter name="usersXmlFile" value="PrivilegeUsersMerge.xml" />
<Parameter name="rolesXmlFile" value="PrivilegeRolesMerge.xml" /> <Parameter name="rolesXmlFile" value="PrivilegeRolesMerge.xml" />
</Parameters> </Parameters>

View File

@ -116,7 +116,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
} else if (this.certificateMap != null) { } else if (this.certificateMap != null) {
synchronized (this.certificateMap) { synchronized (this.certificateMap) {
for (Certificate certificate : this.certificateMap.values()) { for (Certificate certificate : this.certificateMap.values()) {
this.privilegeHandler.invalidateSession(certificate); this.privilegeHandler.invalidate(certificate);
} }
this.certificateMap.clear(); this.certificateMap.clear();
} }
@ -154,14 +154,13 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
throw new StrolchNotAuthenticatedException( throw new StrolchNotAuthenticatedException(
MessageFormat.format("No certificate exists for sessionId {0}", authToken)); //$NON-NLS-1$ MessageFormat.format("No certificate exists for sessionId {0}", authToken)); //$NON-NLS-1$
return validate(certificate); return validate(certificate).getCertificate();
} }
@Override @Override
public Certificate validate(Certificate certificate) throws StrolchNotAuthenticatedException { public PrivilegeContext validate(Certificate certificate) throws StrolchNotAuthenticatedException {
try { try {
this.privilegeHandler.isCertificateValid(certificate); return this.privilegeHandler.validate(certificate);
return certificate;
} catch (PrivilegeException e) { } catch (PrivilegeException e) {
throw new StrolchNotAuthenticatedException(e.getMessage(), e); throw new StrolchNotAuthenticatedException(e.getMessage(), e);
} }
@ -176,7 +175,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
logger.error(MessageFormat logger.error(MessageFormat
.format("No session was registered with token {0}", certificate.getAuthToken())); //$NON-NLS-1$ .format("No session was registered with token {0}", certificate.getAuthToken())); //$NON-NLS-1$
this.privilegeHandler.invalidateSession(certificate); this.privilegeHandler.invalidate(certificate);
} }
@Override @Override
@ -255,7 +254,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
@Override @Override
public UserSession getSession(Certificate certificate, String sessionId) { public UserSession getSession(Certificate certificate, String sessionId) {
PrivilegeContext ctx = this.privilegeHandler.getPrivilegeContext(certificate); PrivilegeContext ctx = this.privilegeHandler.validate(certificate);
ctx.assertHasPrivilege(PRIVILEGE_GET_SESSION); ctx.assertHasPrivilege(PRIVILEGE_GET_SESSION);
synchronized (this.certificateMap) { synchronized (this.certificateMap) {
for (Certificate cert : certificateMap.values()) { for (Certificate cert : certificateMap.values()) {
@ -271,7 +270,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
@Override @Override
public List<UserSession> getSessions(Certificate certificate) { public List<UserSession> getSessions(Certificate certificate) {
PrivilegeContext ctx = this.privilegeHandler.getPrivilegeContext(certificate); PrivilegeContext ctx = this.privilegeHandler.validate(certificate);
ctx.assertHasPrivilege(PRIVILEGE_GET_SESSION); ctx.assertHasPrivilege(PRIVILEGE_GET_SESSION);
List<UserSession> sessions = new ArrayList<>(this.certificateMap.size()); List<UserSession> sessions = new ArrayList<>(this.certificateMap.size());
synchronized (this.certificateMap) { synchronized (this.certificateMap) {
@ -289,8 +288,8 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
} }
@Override @Override
public void invalidateSession(Certificate certificate, String sessionId) { public void invalidate(Certificate certificate, String sessionId) {
PrivilegeContext ctx = this.privilegeHandler.getPrivilegeContext(certificate); PrivilegeContext ctx = this.privilegeHandler.validate(certificate);
ctx.assertHasPrivilege(PRIVILEGE_INVALIDATE_SESSION); ctx.assertHasPrivilege(PRIVILEGE_INVALIDATE_SESSION);
Map<String, Certificate> map; Map<String, Certificate> map;

View File

@ -21,6 +21,7 @@ import java.util.Locale;
import li.strolch.exception.StrolchNotAuthenticatedException; import li.strolch.exception.StrolchNotAuthenticatedException;
import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.PrivilegeContext;
import li.strolch.privilege.model.Usage; import li.strolch.privilege.model.Usage;
import li.strolch.rest.model.UserSession; import li.strolch.rest.model.UserSession;
@ -29,46 +30,46 @@ import li.strolch.rest.model.UserSession;
*/ */
public interface StrolchSessionHandler { public interface StrolchSessionHandler {
public Certificate authenticate(String username, char[] password); Certificate authenticate(String username, char[] password);
public Certificate validate(String authToken) throws StrolchNotAuthenticatedException; Certificate validate(String authToken) throws StrolchNotAuthenticatedException;
public Certificate validate(Certificate certificate) throws StrolchNotAuthenticatedException; PrivilegeContext validate(Certificate certificate) throws StrolchNotAuthenticatedException;
public void invalidate(Certificate certificate); List<UserSession> getSessions(Certificate certificate);
public List<UserSession> getSessions(Certificate certificate); UserSession getSession(Certificate certificate, String sessionId);
public UserSession getSession(Certificate certificate, String sessionId); void invalidate(Certificate certificate);
public void invalidateSession(Certificate certificate, String sessionId); void invalidate(Certificate certificate, String sessionId);
public void setSessionLocale(Certificate certificate, String sessionId, Locale locale); void setSessionLocale(Certificate certificate, String sessionId, Locale locale);
/** /**
* Initiate a password reset challenge for the given username * Initiate a password reset challenge for the given username
* *
* @param usage * @param usage
* the usage for which the challenge is requested * the usage for which the challenge is requested
* @param username * @param username
* the username of the user to initiate the challenge for * the username of the user to initiate the challenge for
*/ */
public void initiateChallengeFor(Usage usage, String username); void initiateChallengeFor(Usage usage, String username);
/** /**
* Validate the response of a challenge for the given username * Validate the response of a challenge for the given username
* *
* @param username * @param username
* the username of the user for which the challenge is to be validated * the username of the user for which the challenge is to be validated
* @param challenge * @param challenge
* the challenge from the user * the challenge from the user
* *
* @return certificate with which the user can access the system with the {@link Usage} set to the value from the * @return certificate with which the user can access the system with the {@link Usage} set to the value from the
* initiated challenge * initiated challenge
* *
* @throws PrivilegeException * @throws PrivilegeException
* if anything goes wrong * if anything goes wrong
*/ */
public Certificate validateChallenge(String username, String challenge) throws PrivilegeException; Certificate validateChallenge(String username, String challenge) throws PrivilegeException;
} }

View File

@ -93,7 +93,7 @@ public class AuthenticationService {
PrivilegeHandler privilegeHandler = RestfulStrolchComponent.getInstance().getContainer() PrivilegeHandler privilegeHandler = RestfulStrolchComponent.getInstance().getContainer()
.getPrivilegeHandler(); .getPrivilegeHandler();
PrivilegeContext privilegeContext = privilegeHandler.getPrivilegeContext(certificate); PrivilegeContext privilegeContext = privilegeHandler.validate(certificate);
loginResult.addProperty("sessionId", certificate.getSessionId()); loginResult.addProperty("sessionId", certificate.getSessionId());
loginResult.addProperty("authToken", certificate.getAuthToken()); loginResult.addProperty("authToken", certificate.getAuthToken());
loginResult.addProperty("username", certificate.getUsername()); loginResult.addProperty("username", certificate.getUsername());

View File

@ -68,7 +68,7 @@ public class UserSessionsService {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
logger.info("[" + cert.getUsername() + "] Invalidating session " + sessionId); logger.info("[" + cert.getUsername() + "] Invalidating session " + sessionId);
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler(); StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
sessionHandler.invalidateSession(cert, sessionId); sessionHandler.invalidate(cert, sessionId);
return ResponseUtil.toResponse(); return ResponseUtil.toResponse();
} }

View File

@ -43,7 +43,7 @@ public class GreetingServiceTest extends AbstractServiceTest {
greetingArgument); greetingArgument);
assertThat(greetingResult.getGreeting(), containsString("Hello Robert. Nice to meet you!")); //$NON-NLS-1$ assertThat(greetingResult.getGreeting(), containsString("Hello Robert. Nice to meet you!")); //$NON-NLS-1$
} finally { } finally {
runtimeMock.getPrivilegeHandler().invalidateSession(certificate); runtimeMock.getPrivilegeHandler().invalidate(certificate);
} }
} }
} }

View File

@ -58,16 +58,17 @@ public class ServiceTest extends AbstractServiceTest {
public void shouldFailInvalidCertificate1() { public void shouldFailInvalidCertificate1() {
this.thrown.expect(PrivilegeException.class); this.thrown.expect(PrivilegeException.class);
TestService testService = new TestService(); TestService testService = new TestService();
getServiceHandler().doService(new Certificate(null, null, null, null, null, null, null, new Date(), null, getServiceHandler().doService(
new HashSet<String>(), null), testService); new Certificate(null, null, null, null, null, null, null, new Date(), null, new HashSet<>(), null),
testService);
} }
@Test @Test
public void shouldFailInvalidCertificate2() { public void shouldFailInvalidCertificate2() {
TestService testService = new TestService(); TestService testService = new TestService();
Certificate badCert = new Certificate(Usage.ANY, "1", "bob", "Bob", "Brown", UserState.ENABLED, "dsdf", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ Certificate badCert = new Certificate(Usage.ANY, "1", "bob", "Bob", "Brown", UserState.ENABLED, "dsdf",
new Date(), null, //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
new HashSet<String>(), null); new Date(), null, new HashSet<>(), null);
ServiceResult svcResult = getServiceHandler().doService(badCert, testService); ServiceResult svcResult = getServiceHandler().doService(badCert, testService);
assertThat(svcResult.getThrowable(), instanceOf(NotAuthenticatedException.class)); assertThat(svcResult.getThrowable(), instanceOf(NotAuthenticatedException.class));
} }
@ -75,21 +76,23 @@ public class ServiceTest extends AbstractServiceTest {
@Test @Test
public void shouldFailWithNoAccess() { public void shouldFailWithNoAccess() {
Certificate certificate = runtimeMock.getPrivilegeHandler().authenticate("jill", "jill".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$ Certificate certificate = runtimeMock.getPrivilegeHandler()
.authenticate("jill", "jill".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$
try { try {
TestService testService = new TestService(); TestService testService = new TestService();
ServiceResult svcResult = getServiceHandler().doService(certificate, testService); ServiceResult svcResult = getServiceHandler().doService(certificate, testService);
assertThat(svcResult.getMessage(), assertThat(svcResult.getMessage(), containsString(
containsString("User jill does not have the privilege li.strolch.service.api.Service")); //$NON-NLS-1$ "User jill does not have the privilege li.strolch.service.api.Service")); //$NON-NLS-1$
assertThat(svcResult.getThrowable(), instanceOf(AccessDeniedException.class)); assertThat(svcResult.getThrowable(), instanceOf(AccessDeniedException.class));
} finally { } finally {
runtimeMock.getPrivilegeHandler().invalidateSession(certificate); runtimeMock.getPrivilegeHandler().invalidate(certificate);
} }
} }
@Test @Test
public void shouldNotFailWithAccess() { public void shouldNotFailWithAccess() {
Certificate certificate = runtimeMock.getPrivilegeHandler().authenticate("jill", "jill".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$ Certificate certificate = runtimeMock.getPrivilegeHandler()
.authenticate("jill", "jill".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$
try { try {
GreetingService service = new GreetingService(); GreetingService service = new GreetingService();
GreetingArgument argument = new GreetingArgument(); GreetingArgument argument = new GreetingArgument();
@ -97,25 +100,27 @@ public class ServiceTest extends AbstractServiceTest {
GreetingResult greetingResult = getServiceHandler().doService(certificate, service, argument); GreetingResult greetingResult = getServiceHandler().doService(certificate, service, argument);
assertThat(greetingResult.getGreeting(), equalTo("Hello Jill. Nice to meet you!")); //$NON-NLS-1$ assertThat(greetingResult.getGreeting(), equalTo("Hello Jill. Nice to meet you!")); //$NON-NLS-1$
} finally { } finally {
runtimeMock.getPrivilegeHandler().invalidateSession(certificate); runtimeMock.getPrivilegeHandler().invalidate(certificate);
} }
} }
@Test @Test
public void shouldNotFailWithLogin1() { public void shouldNotFailWithLogin1() {
Certificate certificate = runtimeMock.getPrivilegeHandler().authenticate("bob", "bob".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$ Certificate certificate = runtimeMock.getPrivilegeHandler()
.authenticate("bob", "bob".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$
try { try {
TestService testService = new TestService(); TestService testService = new TestService();
getServiceHandler().doService(certificate, testService); getServiceHandler().doService(certificate, testService);
} finally { } finally {
runtimeMock.getPrivilegeHandler().invalidateSession(certificate); runtimeMock.getPrivilegeHandler().invalidate(certificate);
} }
} }
@Test @Test
public void shouldNotFailWithLogin2() { public void shouldNotFailWithLogin2() {
Certificate certificate = runtimeMock.getPrivilegeHandler().authenticate("bob", "bob".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$ Certificate certificate = runtimeMock.getPrivilegeHandler()
.authenticate("bob", "bob".toCharArray()); //$NON-NLS-1$//$NON-NLS-2$
try { try {
GreetingService service = new GreetingService(); GreetingService service = new GreetingService();
GreetingArgument argument = new GreetingArgument(); GreetingArgument argument = new GreetingArgument();
@ -123,7 +128,7 @@ public class ServiceTest extends AbstractServiceTest {
GreetingResult greetingResult = getServiceHandler().doService(certificate, service, argument); GreetingResult greetingResult = getServiceHandler().doService(certificate, service, argument);
assertThat(greetingResult.getGreeting(), equalTo("Hello Bob. Nice to meet you!")); //$NON-NLS-1$ assertThat(greetingResult.getGreeting(), equalTo("Hello Bob. Nice to meet you!")); //$NON-NLS-1$
} finally { } finally {
runtimeMock.getPrivilegeHandler().invalidateSession(certificate); runtimeMock.getPrivilegeHandler().invalidate(certificate);
} }
} }
} }

View File

@ -89,7 +89,7 @@ public class RuntimeMock {
} }
public boolean logout(Certificate cert) { public boolean logout(Certificate cert) {
return getPrivilegeHandler().invalidateSession(cert); return getPrivilegeHandler().invalidate(cert);
} }
public RuntimeMock mockRuntime(String targetPath, String srcPath) { public RuntimeMock mockRuntime(String targetPath, String srcPath) {
@ -235,8 +235,7 @@ public class RuntimeMock {
} catch (Exception e) { } catch (Exception e) {
throw new IllegalStateException("Failed to read " + StrolchAgent.AGENT_VERSION_PROPERTIES, e); throw new IllegalStateException("Failed to read " + StrolchAgent.AGENT_VERSION_PROPERTIES, e);
} }
StrolchVersion version = new StrolchVersion(properties); return new StrolchVersion(properties);
return version;
} }
} }