From adf53dd49f5c657946db3a5a7f4157e17a3da203 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 6 Oct 2017 16:59:22 +0200 Subject: [PATCH] [Major] Implemented SingleSignOn facility for Privilege --- .../persistence/api/AbstractTransaction.java | 10 +- .../DefaultStrolchPrivilegeHandler.java | 46 +- .../runtime/privilege/PrivilegeHandler.java | 193 +++---- .../service/api/DefaultServiceHandler.java | 6 +- .../config/PrivilegeConfig.xml | 47 -- .../handler/DefaultPrivilegeHandler.java | 234 +++++--- .../privilege/handler/PrivilegeHandler.java | 539 +++++++++--------- .../handler/SingleSignOnHandler.java | 32 ++ .../helper/PrivilegeInitializationHelper.java | 54 +- .../privilege/helper/XmlConstants.java | 5 + .../internal/PrivilegeContainerModel.java | 25 +- .../xml/PrivilegeConfigDomWriter.java | 99 ++-- .../xml/PrivilegeConfigSaxReader.java | 6 + .../privilege/test/AbstractPrivilegeTest.java | 23 +- .../privilege/test/PersistSessionsTest.java | 4 +- .../strolch/privilege/test/PrivilegeTest.java | 28 +- .../privilege/test/SsoHandlerTest.java | 57 ++ .../li/strolch/privilege/test/XmlTest.java | 80 +-- .../privilege/test/model/DummySsoHandler.java | 29 + .../test/resources/config/PrivilegeConfig.xml | 49 ++ .../config/PrivilegeConfigMerge.xml | 2 +- .../test/resources}/config/PrivilegeRoles.xml | 0 .../resources}/config/PrivilegeRolesMerge.xml | 0 .../test/resources}/config/PrivilegeUsers.xml | 0 .../resources}/config/PrivilegeUsersMerge.xml | 0 .../rest/DefaultStrolchSessionHandler.java | 19 +- .../strolch/rest/StrolchSessionHandler.java | 41 +- .../rest/endpoint/AuthenticationService.java | 2 +- .../rest/endpoint/UserSessionsService.java | 2 +- .../service/test/GreetingServiceTest.java | 2 +- .../li/strolch/service/test/ServiceTest.java | 35 +- .../strolch/testbase/runtime/RuntimeMock.java | 5 +- 32 files changed, 915 insertions(+), 759 deletions(-) delete mode 100644 li.strolch.privilege/config/PrivilegeConfig.xml create mode 100644 li.strolch.privilege/src/main/java/li/strolch/privilege/handler/SingleSignOnHandler.java create mode 100644 li.strolch.privilege/src/test/java/li/strolch/privilege/test/SsoHandlerTest.java create mode 100644 li.strolch.privilege/src/test/java/li/strolch/privilege/test/model/DummySsoHandler.java create mode 100644 li.strolch.privilege/src/test/resources/config/PrivilegeConfig.xml rename li.strolch.privilege/{ => src/test/resources}/config/PrivilegeConfigMerge.xml (95%) rename li.strolch.privilege/{ => src/test/resources}/config/PrivilegeRoles.xml (100%) rename li.strolch.privilege/{ => src/test/resources}/config/PrivilegeRolesMerge.xml (100%) rename li.strolch.privilege/{ => src/test/resources}/config/PrivilegeUsers.xml (100%) rename li.strolch.privilege/{ => src/test/resources}/config/PrivilegeUsersMerge.xml (100%) diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java index 297f97dbf..dec72dd46 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java @@ -336,7 +336,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { private void assertQueryAllowed(StrolchQuery query) { try { - PrivilegeContext privilegeContext = this.privilegeHandler.getPrivilegeContext(this.certificate); + PrivilegeContext privilegeContext = this.privilegeHandler.validate(this.certificate); privilegeContext.validateAction(query); } catch (PrivilegeException 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 { DBC.PRE.assertNotNull("operation must not be null", operation); 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)); } @@ -960,13 +960,9 @@ public abstract class AbstractTransaction implements StrolchTransaction { @Override public void autoCloseableReadOnly() throws StrolchTransactionException { long start = System.nanoTime(); - boolean throwException = false; try { this.txResult.setState(TransactionState.CLOSING); - Thread.currentThread().getUncaughtExceptionHandler(); - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - if (!this.commands.isEmpty()) { autoCloseableRollback(); 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 audits = new ArrayList<>(); - // TODO this is bad... doesn't account for a created and deleted in same TX... - if (this.orderMap != null) { if (this.realm.isAuditTrailEnabledForRead()) auditsFor(audits, AccessType.READ, this.orderMap.getRead()); diff --git a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java index e93da3510..f9916daae 100644 --- a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java @@ -30,14 +30,8 @@ import li.strolch.agent.api.StrolchRealm; import li.strolch.model.audit.AccessType; import li.strolch.model.audit.Audit; import li.strolch.persistence.api.StrolchTransaction; -import li.strolch.privilege.base.NotAuthenticatedException; import li.strolch.privilege.base.PrivilegeException; -import li.strolch.privilege.handler.DefaultPrivilegeHandler; -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.handler.*; import li.strolch.privilege.helper.PrivilegeInitializationHelper; import li.strolch.privilege.helper.XmlConstants; import li.strolch.privilege.model.Certificate; @@ -67,24 +61,22 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements // initialize privilege RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration(); - File privilegeConfigFile = configuration.getConfigFile(PROP_PRIVILEGE_CONFIG_FILE, PRIVILEGE_CONFIG_XML, - runtimeConfiguration); - li.strolch.privilege.handler.PrivilegeHandler privilegeHandler = initializeFromXml(configuration, - privilegeConfigFile); - this.privilegeHandler = privilegeHandler; + File privilegeConfigFile = configuration + .getConfigFile(PROP_PRIVILEGE_CONFIG_FILE, PRIVILEGE_CONFIG_XML, runtimeConfiguration); + this.privilegeHandler = initializeFromXml(configuration, privilegeConfigFile); } /** * Initializes the {@link DefaultPrivilegeHandler} from the configuration file - * + * * @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 - * {@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, - File privilegeXmlFile) { + File privilegeXmlFile) { // make sure file exists if (!privilegeXmlFile.exists()) { @@ -142,14 +134,13 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements } @Override - public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException { - assertStarted(); - this.privilegeHandler.isCertificateValid(certificate); + public PrivilegeContext validate(Certificate certificate) throws PrivilegeException { + return this.privilegeHandler.validate(certificate); } @Override - public boolean invalidateSession(Certificate certificate) { - boolean invalidateSession = this.privilegeHandler.invalidateSession(certificate); + public boolean invalidate(Certificate certificate) { + boolean invalidateSession = this.privilegeHandler.invalidate(certificate); StrolchRealm realm = getContainer().getRealm(certificate); try (StrolchTransaction tx = realm.openTx(certificate, StrolchPrivilegeConstants.LOGOUT)) { tx.setSuppressDoNothingLogging(true); @@ -164,7 +155,7 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements @Override public boolean sessionTimeout(Certificate certificate) { assertStarted(); - boolean invalidateSession = this.privilegeHandler.invalidateSession(certificate); + boolean invalidateSession = this.privilegeHandler.invalidate(certificate); StrolchRealm realm = getContainer().getRealm(certificate); try (StrolchTransaction tx = realm.openTx(certificate, StrolchPrivilegeConstants.SESSION_TIME_OUT)) { tx.setSuppressDoNothingLogging(true); @@ -213,13 +204,8 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements @Override public T runAsAgentWithResult(PrivilegedRunnableWithResult runnable) throws PrivilegeException { - return this.privilegeHandler.runWithResult(StrolchConstants.SYSTEM_USER_AGENT, - new StrolchSystemActionWithResult<>(runnable)); - } - - @Override - public PrivilegeContext getPrivilegeContext(Certificate certificate) throws PrivilegeException { - return this.privilegeHandler.getPrivilegeContext(certificate); + return this.privilegeHandler + .runWithResult(StrolchConstants.SYSTEM_USER_AGENT, new StrolchSystemActionWithResult<>(runnable)); } @Override diff --git a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java index 43ff60d94..adc055c4f 100644 --- a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java @@ -24,183 +24,170 @@ import li.strolch.runtime.StrolchConstants; /** * The privilege handler for authenticating users and performing actions as a system user - * + * * @author Robert von Burg */ public interface PrivilegeHandler { /** * Authenticate a user - * + * * @param username - * the username + * the username * @param password - * the password - * + * the password + * * @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); - - /** - * 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); + Certificate authenticate(String username, char[] password); /** * Returns the {@link PrivilegeContext} for the given certificate - * + * * @param certificate - * the certificate - * + * the certificate + * * @return the {@link PrivilegeContext} for the given certificate - * + * * @throws PrivilegeException - * if the certificate is not valid anymore - * - * @see li.strolch.privilege.handler.PrivilegeHandler#getPrivilegeContext(li.strolch.privilege.model.Certificate) + * if the certificate is not valid anymore + * @see li.strolch.privilege.handler.PrivilegeHandler#validate(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 - * + * * @param username - * the system username + * the system username * @param action - * the action to perform - * + * the action to perform + * * @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 - * + * * @param username - * the system username + * the system username * @param action - * the action to perform - * + * the action to perform + * * @return the result - * + * * @throws PrivilegeException - * if there is something wrong + * if there is something wrong */ - public T runWithResult(String username, SystemActionWithResult action) throws PrivilegeException; + T runWithResult(String username, SystemActionWithResult action) throws PrivilegeException; /** * Run the given {@link PrivilegedRunnable} as the given system user - * + * * @param username - * the system username + * the system username * @param runnable - * the runnable to perform - * + * the runnable to perform + * * @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 - * + * * @param username - * the system username + * the system username * @param runnable - * the runnable to perform - * + * the runnable to perform + * * @return the result - * + * * @throws PrivilegeException - * if there is something wrong + * if there is something wrong */ - public T runWithResult(String username, PrivilegedRunnableWithResult runnable) throws PrivilegeException; + T runWithResult(String username, PrivilegedRunnableWithResult runnable) throws PrivilegeException; /** * Run the given {@link SystemAction} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT} - * - * @param runnable - * the runnable to perform - * + * + * @param action + * the action to perform + * * @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} - * - * @param runnable - * the runnable to perform - * + * + * @param action + * the action to perform + * * @throws PrivilegeException - * if there is something wrong + * if there is something wrong */ - public T runAsAgentWithResult(SystemActionWithResult action) throws PrivilegeException; + T runAsAgentWithResult(SystemActionWithResult action) throws PrivilegeException; /** * Run the given {@link PrivilegedRunnable} as the system user {@link StrolchConstants#SYSTEM_USER_AGENT} - * + * * @param runnable - * the runnable to perform - * + * the runnable to perform + * * @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} - * + * * @param runnable - * the runnable to perform - * + * the runnable to perform + * * @return the result - * + * * @throws PrivilegeException - * if there is something wrong + * if there is something wrong */ - public T runAsAgentWithResult(PrivilegedRunnableWithResult runnable) throws PrivilegeException; + T runAsAgentWithResult(PrivilegedRunnableWithResult runnable) throws PrivilegeException; /** * Returns 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(); } \ No newline at end of file diff --git a/li.strolch.agent/src/main/java/li/strolch/service/api/DefaultServiceHandler.java b/li.strolch.agent/src/main/java/li/strolch/service/api/DefaultServiceHandler.java index ca9e5a451..7e518aaf1 100644 --- a/li.strolch.agent/src/main/java/li/strolch/service/api/DefaultServiceHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/service/api/DefaultServiceHandler.java @@ -39,10 +39,6 @@ public class DefaultServiceHandler extends StrolchComponent implements ServiceHa private PrivilegeHandler privilegeHandler; private boolean throwOnPrivilegeFail; - /** - * @param container - * @param componentName - */ public DefaultServiceHandler(ComponentContainer container, String componentName) { super(container, componentName); } @@ -74,7 +70,7 @@ public class DefaultServiceHandler extends StrolchComponent implements ServiceHa PrivilegeContext privilegeContext; String username = certificate == null ? "null" : certificate.getUsername(); try { - privilegeContext = this.privilegeHandler.getPrivilegeContext(certificate); + privilegeContext = this.privilegeHandler.validate(certificate); privilegeContext.validateAction(service); } catch (PrivilegeException e) { diff --git a/li.strolch.privilege/config/PrivilegeConfig.xml b/li.strolch.privilege/config/PrivilegeConfig.xml deleted file mode 100644 index f38f260d8..000000000 --- a/li.strolch.privilege/config/PrivilegeConfig.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/DefaultPrivilegeHandler.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/DefaultPrivilegeHandler.java index 80b07f0a2..d3444f21c 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/DefaultPrivilegeHandler.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/DefaultPrivilegeHandler.java @@ -85,6 +85,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { */ 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 * password @@ -127,7 +132,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public RoleRep getRole(Certificate certificate, String roleName) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE); Role role = this.persistenceHandler.getRole(roleName); @@ -143,7 +148,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public UserRep getUser(Certificate certificate, String username) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER); User user = this.persistenceHandler.getUser(username); @@ -158,7 +163,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public Map getPolicyDefs(Certificate certificate) { // 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)); Map policyDef = new HashMap<>(this.policyMap.size()); @@ -172,7 +177,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public List getCertificates(Certificate certificate) { // 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)); return this.privilegeContextMap.values().stream().map(PrivilegeContext::getCertificate) @@ -183,7 +188,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public List getRoles(Certificate certificate) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE); Stream rolesStream = this.persistenceHandler.getAllRoles().stream(); @@ -207,7 +212,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public List getUsers(Certificate certificate) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER); Stream usersStream = this.persistenceHandler.getAllUsers().stream(); @@ -231,7 +236,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public List queryUsers(Certificate certificate, UserRep selectorRep) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER); 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 * false is returned * - * @param selectionMap the map defining the expected properties - * @param properties the properties which must be a sub set of selectionMap to have this method return true + * @param selectionMap + * 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 * 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 * empty, then true is returned, otherwise false * - * @param selectionRoles the required roles - * @param roles the roles to check if they contain the selectionRoles + * @param 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 * null or empty, then true is returned, otherwise false */ @@ -379,7 +390,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { try { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_ADD_USER); // make sure userId is not set @@ -444,7 +455,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { try { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER); // first validate user @@ -512,10 +523,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { } private User createUser(UserRep userRep, byte[] passwordHash, byte[] salt) { - User user = new User(userRep.getUserId(), userRep.getUsername(), passwordHash, salt, userRep.getFirstname(), - userRep.getLastname(), userRep.getUserState(), userRep.getRoles(), userRep.getLocale(), - userRep.getProperties()); - return user; + String userId = userRep.getUserId(); + String userName = userRep.getUsername(); + String firstName = userRep.getFirstname(); + String lastName = userRep.getLastname(); + UserState state = userRep.getUserState(); + Set roles = userRep.getRoles(); + Locale locale = userRep.getLocale(); + Map properties = userRep.getProperties(); + return new User(userId, userName, passwordHash, salt, firstName, lastName, state, roles, locale, properties); } @Override @@ -523,7 +539,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { throws AccessDeniedException, PrivilegeException { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER); // get existing user @@ -585,7 +601,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public UserRep removeUser(Certificate certificate, String username) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_USER); // validate user exists @@ -610,7 +626,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public UserRep addRoleToUser(Certificate certificate, String username, String roleName) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE_TO_USER); // get user @@ -658,7 +674,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_ROLE_FROM_USER); // get User @@ -698,7 +714,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public UserRep setUserLocale(Certificate certificate, String username, Locale locale) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_LOCALE); // get User @@ -735,7 +751,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { try { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_PASSWORD); // get User @@ -778,7 +794,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { } if (certificate.getUsage() == Usage.SET_PASSWORD) { - invalidateSession(certificate); + invalidate(certificate); } 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) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_STATE); // get User @@ -821,7 +837,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public RoleRep addRole(Certificate certificate, RoleRep roleRep) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE); // first validate role @@ -854,7 +870,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public RoleRep replaceRole(Certificate certificate, RoleRep roleRep) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE); // first validate role @@ -891,7 +907,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public RoleRep removeRole(Certificate certificate, String roleName) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_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) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE); // validate PrivilegeRep @@ -983,7 +999,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) { // validate user actually has this type of privilege - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_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) { Set userRoles = user.getRoles(); - Certificate certificate = new Certificate(usage, sessionId, user.getUsername(), user.getFirstname(), - user.getLastname(), user.getUserState(), authToken, new Date(), user.getLocale(), userRoles, + return new Certificate(usage, sessionId, user.getUsername(), user.getFirstname(), user.getLastname(), + user.getUserState(), authToken, new Date(), user.getLocale(), userRoles, new HashMap<>(user.getProperties())); - return certificate; } private boolean persistSessions() { @@ -1146,15 +1189,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { return true; } - private boolean loadSessions() { + private void loadSessions() { if (!this.persistSessions) { logger.info("Persisteding of sessions not enabled, so not loading!."); - return false; + return; } if (!this.persistSessionsPath.exists()) { logger.info("No persisted sessions exist to be loaded."); - return false; + return; } if (!this.persistSessionsPath.isFile()) @@ -1170,13 +1213,14 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { } catch (Exception e) { logger.error("Failed to load sessions!", e); - this.persistSessionsPath.delete(); - return false; + if (!this.persistSessionsPath.delete()) + logger.error("Failed to delete session file at " + this.persistSessionsPath.getAbsolutePath()); + return; } if (certificateStubs.isEmpty()) { logger.info("No persisted sessions exist to be loaded."); - return false; + return; } for (CertificateStub certificateStub : certificateStubs) { @@ -1205,17 +1249,22 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { } logger.info("Loaded " + this.privilegeContextMap.size() + " sessions."); - return true; } /** * Checks the credentials and validates that the user may log in. * - * @param username the username of the {@link User} to check against - * @param password the password of this user + * @param username + * 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 - * @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) throws InvalidCredentialsException, AccessDeniedException { @@ -1253,7 +1302,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { byte[] salt = user.getSalt(); if (salt == null) 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 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} * - * @param certificate the certificate for which to build the {@link PrivilegeContext} - * @param user the user for which to build the {@link PrivilegeContext} + * @param certificate + * the certificate for which to build the {@link PrivilegeContext} + * @param user + * the user for which to build the {@link PrivilegeContext} + * * @return the {@link PrivilegeContext} */ private PrivilegeContext buildPrivilegeContext(Certificate certificate, User user) { @@ -1337,12 +1389,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { } UserRep userRep = user.asUserRep(); - PrivilegeContext privilegeContext = new PrivilegeContext(userRep, certificate, privileges, policies); - return privilegeContext; + return new PrivilegeContext(userRep, certificate, privileges, policies); } @Override - public boolean invalidateSession(Certificate certificate) { + public boolean invalidate(Certificate certificate) { // remove registration PrivilegeContext privilegeContext = this.privilegeContextMap.remove(certificate.getSessionId()); @@ -1361,7 +1412,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { } @Override - public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException { + public PrivilegeContext validate(Certificate certificate) throws PrivilegeException, NotAuthenticatedException { // certificate must not be null if (certificate == null) @@ -1387,33 +1438,13 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { LocalDateTime dateTime = LocalDateTime .ofInstant(sessionCertificate.getLoginTime().toInstant(), ZoneId.systemDefault()); if (dateTime.plusHours(1).isBefore(LocalDateTime.now())) { - invalidateSession(sessionCertificate); + invalidate(sessionCertificate); 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()); - } - - @Override - public PrivilegeContext getPrivilegeContext(Certificate certificate) - throws PrivilegeException, NotAuthenticatedException { - - // first validate certificate - isCertificateValid(certificate); - - return this.privilegeContextMap.get(certificate.getSessionId()); + return privilegeContext; } /** @@ -1437,7 +1468,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public boolean persist(Certificate certificate) { // validate who is doing this - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_PERSIST)); return this.persistenceHandler.persist(); @@ -1447,7 +1478,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public boolean persistSessions(Certificate certificate) { // validate who is doing this - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_PERSIST_SESSIONS)); return persistSessions(); @@ -1457,7 +1488,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { public boolean reload(Certificate certificate) { // validate who is doing this - PrivilegeContext prvCtx = getPrivilegeContext(certificate); + PrivilegeContext prvCtx = validate(certificate); prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_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 * concrete implementation * - * @param parameterMap a map containing configuration properties - * @param encryptionHandler the {@link EncryptionHandler} instance for this {@link PrivilegeHandler} - * @param persistenceHandler 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 policyMap map of {@link PrivilegePolicy} classes - * @throws PrivilegeException if the this method is called multiple times or an initialization exception occurs + * @param parameterMap + * a map containing configuration properties + * @param encryptionHandler + * the {@link EncryptionHandler} instance for this {@link PrivilegeHandler} + * @param persistenceHandler + * 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 parameterMap, EncryptionHandler encryptionHandler, - PersistenceHandler persistenceHandler, UserChallengeHandler userChallengeHandler, - Map> policyMap) { + public synchronized void initialize(Map parameterMap, + EncryptionHandler encryptionHandler, + PersistenceHandler persistenceHandler, + UserChallengeHandler userChallengeHandler, + SingleSignOnHandler ssoHandler, + Map> policyMap) { if (this.initialized) throw new PrivilegeException("Already initialized!"); //$NON-NLS-1$ @@ -1486,6 +1529,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { this.encryptionHandler = encryptionHandler; this.persistenceHandler = persistenceHandler; this.userChallengeHandler = userChallengeHandler; + this.ssoHandler = ssoHandler; handleAutoPersistOnUserDataChange(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 * - * @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) { 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 * 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) { if (password != null) { @@ -1734,7 +1780,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { } } - private PrivilegeContext initiateSystemPrivilege(String username, Restrictable restrictable) { + private PrivilegeContext initiateSystemPrivilege(String username, Restrictable restrictable) { if (username == null) throw new PrivilegeException("systemUsername may not be null!"); //$NON-NLS-1$ 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 * 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 */ private PrivilegeContext getSystemUserPrivilegeContext(String systemUsername) { @@ -1833,9 +1881,13 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler { * {@link PrivilegePolicy} object *

* - * @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 - * @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) { diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/PrivilegeHandler.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/PrivilegeHandler.java index 67cc906a4..cf60ce7d2 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/PrivilegeHandler.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/PrivilegeHandler.java @@ -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 * methods to access Privilege data model objects, modify them and validate if users or roles have privileges to perform * an action - * + * * @author Robert von Burg */ 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 * {@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 * allAllowed */ - 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 * allAllowed */ - 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 * allAllowed */ - 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 * allAllowed */ - 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 allAllowed */ - 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 allAllowed */ - 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 */ - 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 */ - 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 */ - 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. Note: * 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 */ - 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 */ - 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 */ - 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 */ - 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 * 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 * 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 * 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 */ - 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 * their own */ - public static final String PRIVILEGE_SET_USER_PASSWORD = "PrivilegeSetUserPassword"; + String PRIVILEGE_SET_USER_PASSWORD = "PrivilegeSetUserPassword"; /// /** * 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 */ - 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 */ - 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 */ - 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 */ - 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} */ - public static final String PARAM_PRIVILEGE_CONFLICT_RESOLUTION = "privilegeConflictResolution"; + String PARAM_PRIVILEGE_CONFLICT_RESOLUTION = "privilegeConflictResolution"; /** * Returns a {@link UserRep} for the given username - * + * * @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 - * 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 */ - public UserRep getUser(Certificate certificate, String username); + UserRep getUser(Certificate certificate, String username); /** * Returns a {@link RoleRep} for the given roleName - * + * * @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 - * 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 */ - public RoleRep getRole(Certificate certificate, String roleName); + RoleRep getRole(Certificate certificate, String roleName); /** * Returns the map of {@link PrivilegePolicy} definitions - * + * * @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 */ - public Map getPolicyDefs(Certificate certificate); + Map getPolicyDefs(Certificate certificate); /** * Returns the list of {@link Certificate Certificates} - * + * * @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} */ - public List getCertificates(Certificate certificate); + List getCertificates(Certificate certificate); /** * Returns all {@link RoleRep RoleReps} - * + * * @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} */ - public List getRoles(Certificate certificate); + List getRoles(Certificate certificate); /** * Returns all {@link UserRep UserReps} - * + * * @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} */ - public List getUsers(Certificate certificate); + List getUsers(Certificate certificate); /** * Method to query {@link UserRep} which meet the criteria set in the given {@link UserRep}. Null fields mean the * fields are irrelevant. - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @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 */ - public List queryUsers(Certificate certificate, UserRep selectorRep); + List queryUsers(Certificate certificate, UserRep selectorRep); /** * Removes the user with the given username - * + * * @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 - * 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 - * + * * @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 - * if there is anything wrong with this certificate + * if there is anything wrong with this certificate */ - public UserRep removeUser(Certificate certificate, String username) - throws AccessDeniedException, PrivilegeException; + UserRep removeUser(Certificate certificate, String username) throws PrivilegeException; /** * Removes the role with the given roleName from the user with the given username - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @param username - * the username of the user from which the role is to be removed + * the username of the user from which the role is to be removed * @param roleName - * the roleName of the role to remove from the user - * + * the roleName of the role to remove from the user + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) throws PrivilegeException; /** * Removes the role with the given roleName - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @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 - * + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + RoleRep removeRole(Certificate certificate, String roleName) throws PrivilegeException; /** * Removes the privilege with the given privilegeName from the role with the given roleName - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @param roleName - * the roleName of the role from which the privilege is to be removed + * the roleName of the role from which the privilege is to be removed * @param privilegeName - * the privilegeName of the privilege to remove from the role - * + * the privilegeName of the privilege to remove from the role + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) + throws PrivilegeException; /** *

* Adds a new user with the information from this {@link UserRep} *

- * + * *

* 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[])} *

- * + * * @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 - * 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 - * the password of the new user. If the password is null, then this is accepted but the user can not - * login, otherwise the password must be validated against - * {@link PrivilegeHandler#validatePassword(char[])} - * + * the password of the new user. If the password is null, then this is accepted but the user can not + * login, otherwise the password must be validated against + * {@link PrivilegeHandler#validatePassword(char[])} + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + UserRep addUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException; /** *

@@ -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 * existing user. *

- * + * * The following fields are considered updateable: *
    *
  • {@link UserRep#getFirstname()}
  • @@ -366,117 +362,113 @@ public interface PrivilegeHandler { *
  • {@link UserRep#getLocale()}
  • *
  • {@link UserRep#getProperties()} - the existing properties will be replaced with the given properties
  • *
- * + * *

* Any other fields will be ignored *

- * + * * @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 - * the {@link UserRep} with the fields set to their new values - * + * the {@link UserRep} with the fields set to their new values + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + UserRep updateUser(Certificate certificate, UserRep userRep) throws PrivilegeException; /** *

* Replaces the existing user with the information from this {@link UserRep} if the user already exists *

- * + * *

* 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[])} *

- * + * * @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 - * 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 - * the password of the new user. If the password is null, then this is accepted but the user can not - * login, otherwise the password must be validated against - * {@link PrivilegeHandler#validatePassword(char[])} - * + * the password of the new user. If the password is null, then this is accepted but the user can not + * login, otherwise the password must be validated against + * {@link PrivilegeHandler#validatePassword(char[])} + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + UserRep replaceUser(Certificate certificate, UserRep userRep, char[] password) throws PrivilegeException; /** * Adds a new role with the information from this {@link RoleRep} - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @param roleRep - * the {@link RoleRep} containing the information to create the new {@link Role} - * + * the {@link RoleRep} containing the information to create the new {@link Role} + * * @throws AccessDeniedException - * if the user for this certificate may not perform the action + * if the user for this certificate may not perform the action * @throws PrivilegeException - * if there is anything wrong with this certificate or if the role already exists + * 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} - * + * * @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 - * 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 - * if the user for this certificate may not perform the action + * if the user for this certificate may not perform the action * @throws PrivilegeException - * if there is anything wrong with this certificate or if the role does not exist + * if there is anything wrong with this certificate or if the role does not exist */ - public RoleRep replaceRole(Certificate certificate, RoleRep roleRep) - throws AccessDeniedException, PrivilegeException; + RoleRep replaceRole(Certificate certificate, RoleRep roleRep) throws PrivilegeException; /** * Adds the role with the given roleName to the {@link User} with the given username - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @param username - * the username of the {@link User} to which the role should be added + * the username of the {@link User} to which the role should be added * @param roleName - * the roleName of the {@link Role} which should be added to the {@link User} - * + * the roleName of the {@link Role} which should be added to the {@link User} + * * @throws AccessDeniedException - * if the user for this certificate may not perform the action + * if the user for this certificate may not perform the action * @throws PrivilegeException - * if there is anything wrong with this certificate or if the role does not exist + * if there is anything wrong with this certificate or if the role does not exist */ - public UserRep addRoleToUser(Certificate certificate, String username, String roleName) - throws AccessDeniedException, PrivilegeException; + UserRep addRoleToUser(Certificate certificate, String username, String roleName) throws PrivilegeException; /** * Adds the {@link PrivilegeRep} to the {@link Role} with the given roleName or replaces it, if it already exists - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @param roleName - * the roleName of the {@link Role} to which the privilege should be added + * the roleName of the {@link Role} to which the privilege should be added * @param privilegeRep - * the representation of the {@link IPrivilege} which should be added or replaced on the {@link Role} - * + * the representation of the {@link IPrivilege} which should be added or replaced on the {@link Role} + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) + throws PrivilegeException; /** *

@@ -484,243 +476,240 @@ public interface PrivilegeHandler { * can not login anymore. Otherwise the password must meet the requirements of the implementation under * {@link PrivilegeHandler#validatePassword(char[])} *

- * + * *

* It should be possible for a user to change their own password *

- * + * * @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 - * 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 - * the new password for this user. If the password is null, then the {@link User} can not login anymore. - * Otherwise the password must meet the requirements of the implementation under - * {@link PrivilegeHandler#validatePassword(char[])} - * + * the new password for this user. If the password is null, then the {@link User} can not login anymore. + * Otherwise the password must meet the requirements of the implementation under + * {@link PrivilegeHandler#validatePassword(char[])} + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + void setUserPassword(Certificate certificate, String username, char[] password) throws PrivilegeException; /** * Changes the {@link UserState} of the user - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @param username - * the username of the {@link User} for which the {@link UserState} is to be changed + * the username of the {@link User} for which the {@link UserState} is to be changed * @param state - * the new state for the user - * + * the new state for the user + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + UserRep setUserState(Certificate certificate, String username, UserState state) throws PrivilegeException; /** * Changes the {@link Locale} of the user - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action + * the {@link Certificate} of the user which has the privilege to perform this action * @param username - * the username of the {@link User} for which the {@link Locale} is to be changed + * the username of the {@link User} for which the {@link Locale} is to be changed * @param locale - * the new {@link Locale} for the user - * + * the new {@link Locale} for the user + * * @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 - * 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) - throws AccessDeniedException, PrivilegeException; + UserRep setUserLocale(Certificate certificate, String username, Locale locale) throws PrivilegeException; /** * Initiate a password reset challenge for the given username - * + * * @param usage - * the usage for which the challenge is requested + * the usage for which the challenge is requested * @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 - * + * * @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 - * 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 - * initiated challenge - * + * initiated challenge + * * @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 * a {@link Certificate} with which this user may then perform actions - * + * * @param username - * the username of the {@link User} which is registered in the {@link PersistenceHandler} + * the username of the {@link User} which is registered in the {@link PersistenceHandler} * @param password - * the password with which this user is to be authenticated. Null passwords are not accepted and they - * must meet the requirements of the {@link #validatePassword(char[])}-method - * + * 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 + * * @return a {@link Certificate} with which this user may then perform actions - * + * * @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 * with the credentials associated to the given {@link 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 */ - 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 * 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 * encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their * actions and do not need to access the {@link PrivilegeHandler} anymore - * + * * @param certificate - * 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} - * + * * @throws PrivilegeException - * if there is a configuration error or the {@link Certificate} is invalid + * if there is anything wrong with this certificate * @throws NotAuthenticatedException - * if the certificate has expired + * if the certificate has expired */ - public PrivilegeContext getPrivilegeContext(Certificate certificate) - throws PrivilegeException, NotAuthenticatedException; + PrivilegeContext validate(Certificate certificate) throws PrivilegeException; /** * Validate that the given password meets certain requirements. What these requirements are is a decision made by * the concrete implementation - * + * * @param password - * the password to be validated to meet certain requirements - * + * the password to be validated to meet certain requirements + * * @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; /** *

* Informs this {@link PersistenceHandler} to reload the data from the backend *

- * + * * Note: It depends on the underlying {@link PersistenceHandler} implementation if data really is read - * + * * @param certificate - * the {@link Certificate} of the user which has the privilege to perform this action - * + * 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 - * + * * @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 * actively performed - * + * * @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 - * + * * @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 - * + * * @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) - * + * * @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 * has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation * of the given {@link SystemAction} instance - * - * + * * @param systemUsername - * the username of the system user to perform the action as + * the username of the system user to perform the action as * @param action - * the action to be performed as the system user - * - * @return the action - * + * the action to be performed as the system user + * * @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 * has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation * of the given {@link SystemAction} instance - * - * + * * @param systemUsername - * the username of the system user to perform the action as + * the username of the system user to perform the action as * @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 + * if the user does not exist, or the system action is not alloed */ - public T runWithResult(String systemUsername, SystemActionWithResult action) throws PrivilegeException; + T runWithResult(String systemUsername, SystemActionWithResult action) throws PrivilegeException; /** * Returns the {@link EncryptionHandler} instance - * + * * @return the {@link EncryptionHandler} instance */ - public EncryptionHandler getEncryptionHandler() throws PrivilegeException; - + EncryptionHandler getEncryptionHandler() throws PrivilegeException; } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/SingleSignOnHandler.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/SingleSignOnHandler.java new file mode 100644 index 000000000..9bc27f4e8 --- /dev/null +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/handler/SingleSignOnHandler.java @@ -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 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; + +} diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/PrivilegeInitializationHelper.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/PrivilegeInitializationHelper.java index d511ffbd2..962c7cffc 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/PrivilegeInitializationHelper.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/PrivilegeInitializationHelper.java @@ -22,11 +22,7 @@ import java.text.MessageFormat; import java.util.Map; import li.strolch.privilege.base.PrivilegeException; -import li.strolch.privilege.handler.DefaultPrivilegeHandler; -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.handler.*; import li.strolch.privilege.model.internal.PrivilegeContainerModel; import li.strolch.privilege.policy.PrivilegePolicy; 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 * configuration - * + * * @author Robert von Burg */ public class PrivilegeInitializationHelper { /** * Initializes the {@link DefaultPrivilegeHandler} from the configuration file - * + * * @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 - * {@link PersistenceHandler} are set and initialized as well + * {@link PersistenceHandler} are set and initialized as well */ 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 * source - * + * * @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 - * {@link PersistenceHandler} are set and initialized as well + * {@link PersistenceHandler} are set and initialized as well */ public static PrivilegeHandler initializeFromXml(InputStream privilegeConfigInputStream) { @@ -91,12 +87,12 @@ public class PrivilegeInitializationHelper { /** * Initializes the {@link PrivilegeHandler} by initializing from the given {@link PrivilegeContainerModel} - * + * * @param containerModel - * the configuration for the {@link PrivilegeHandler} - * + * the configuration for the {@link PrivilegeHandler} + * * @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) { @@ -137,13 +133,31 @@ public class PrivilegeInitializationHelper { 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 DefaultPrivilegeHandler privilegeHandler = new DefaultPrivilegeHandler(); parameterMap = containerModel.getParameterMap(); Map> policyMap = containerModel.getPolicies(); try { - privilegeHandler.initialize(parameterMap, encryptionHandler, persistenceHandler, challengeHandler, - policyMap); + privilegeHandler + .initialize(parameterMap, encryptionHandler, persistenceHandler, challengeHandler, ssoHandler, + policyMap); } catch (Exception e) { String msg = "PrivilegeHandler {0} could not be initialized"; //$NON-NLS-1$ msg = MessageFormat.format(msg, privilegeHandler.getClass().getName()); diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/XmlConstants.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/XmlConstants.java index cad9ab76e..8dafde168 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/XmlConstants.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/helper/XmlConstants.java @@ -68,6 +68,11 @@ public class XmlConstants { */ public static final String XML_HANDLER_ENCRYPTION = "EncryptionHandler"; + /** + * XML_HANDLER_ENCRYPTION = "EncryptionHandler" : + */ + public static final String XML_HANDLER_SSO = "SsoHandler"; + /** * XML_HANDLER_PRIVILEGE = "PrivilegeHandler" : */ diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/model/internal/PrivilegeContainerModel.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/model/internal/PrivilegeContainerModel.java index 6cc895051..c42bf2ad2 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/model/internal/PrivilegeContainerModel.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/model/internal/PrivilegeContainerModel.java @@ -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 * the {@link PrivilegeHandler} - * + * *

* Note: This is an internal object which is not to be serialized or passed to clients *

- * + * * @author Robert von Burg */ public class PrivilegeContainerModel { @@ -39,10 +39,12 @@ public class PrivilegeContainerModel { private String encryptionHandlerClassName; private String persistenceHandlerClassName; private String userChallengeHandlerClassName; + private String ssoHandlerClassName; private Map encryptionHandlerParameterMap; private Map persistenceHandlerParameterMap; private Map challengeHandlerParameterMap; + private Map ssoHandlerParameterMap; private Map parameterMap; @@ -53,6 +55,7 @@ public class PrivilegeContainerModel { this.encryptionHandlerParameterMap = new HashMap<>(); this.persistenceHandlerParameterMap = new HashMap<>(); this.challengeHandlerParameterMap = new HashMap<>(); + this.ssoHandlerParameterMap = new HashMap<>(); } public Map getParameterMap() { @@ -103,6 +106,14 @@ public class PrivilegeContainerModel { this.userChallengeHandlerClassName = userChallengeHandlerClassName; } + public String getSsoHandlerClassName() { + return this.ssoHandlerClassName; + } + + public void setSsoHandlerClassName(String ssoHandlerClassName) { + this.ssoHandlerClassName = ssoHandlerClassName; + } + public Map getUserChallengeHandlerParameterMap() { return this.challengeHandlerParameterMap; } @@ -111,6 +122,14 @@ public class PrivilegeContainerModel { this.challengeHandlerParameterMap = challengeHandlerParameterMap; } + public Map getSsoHandlerParameterMap() { + return this.ssoHandlerParameterMap; + } + + public void setSsoHandlerParameterMap(Map ssoHandlerParameterMap) { + this.ssoHandlerParameterMap = ssoHandlerParameterMap; + } + public void addPolicy(String privilegeName, String policyClassName) { try { @@ -160,6 +179,8 @@ public class PrivilegeContainerModel { builder.append(this.persistenceHandlerParameterMap.size()); builder.append(", challengeHandlerParameterMap="); builder.append(this.challengeHandlerParameterMap.size()); + builder.append(", ssoHandlerParameterMap="); + builder.append(this.ssoHandlerParameterMap.size()); builder.append(", parameterMap="); builder.append(this.parameterMap.size()); builder.append(", policies="); diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigDomWriter.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigDomWriter.java index 97dfb3458..4b1d7e31c 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigDomWriter.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigDomWriter.java @@ -15,20 +15,20 @@ */ package li.strolch.privilege.xml; +import static li.strolch.privilege.helper.XmlConstants.*; + import java.io.File; +import java.util.Map; 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.policy.PrivilegePolicy; import li.strolch.utils.helper.XmlHelper; +import org.w3c.dom.Document; +import org.w3c.dom.Element; /** * @author Robert von Burg - * */ public class PrivilegeConfigDomWriter { @@ -36,7 +36,7 @@ public class PrivilegeConfigDomWriter { private final File configFile; /** - * + * */ public PrivilegeConfigDomWriter(PrivilegeContainerModel containerModel, File configFile) { this.containerModel = containerModel; @@ -44,72 +44,77 @@ public class PrivilegeConfigDomWriter { } /** - * + * */ public void write() { // create document root Document doc = XmlHelper.createDocument(); - Element rootElement = doc.createElement(XmlConstants.XML_ROOT_PRIVILEGE); + Element rootElement = doc.createElement(XML_ROOT_PRIVILEGE); doc.appendChild(rootElement); - Element containerElement = doc.createElement(XmlConstants.XML_CONTAINER); + Element containerElement = doc.createElement(XML_CONTAINER); rootElement.appendChild(containerElement); - Element parameterElement; - Element parametersElement; - - // Parameters - parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); - containerElement.appendChild(parametersElement); - for (Entry 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 - Element encryptionHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_ENCRYPTION); + Element encryptionHandlerElem = doc.createElement(XML_HANDLER_ENCRYPTION); containerElement.appendChild(encryptionHandlerElem); - encryptionHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS, - this.containerModel.getEncryptionHandlerClassName()); + encryptionHandlerElem.setAttribute(XML_ATTR_CLASS, this.containerModel.getEncryptionHandlerClassName()); // Parameters - parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); - encryptionHandlerElem.appendChild(parametersElement); - for (Entry 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); - } + fillParameterMap(doc, encryptionHandlerElem, this.containerModel.getEncryptionHandlerParameterMap()); // create PersistenceHandler - Element persistenceHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_PERSISTENCE); + Element persistenceHandlerElem = doc.createElement(XML_HANDLER_PERSISTENCE); containerElement.appendChild(persistenceHandlerElem); - persistenceHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS, - this.containerModel.getPersistenceHandlerClassName()); + persistenceHandlerElem.setAttribute(XML_ATTR_CLASS, this.containerModel.getPersistenceHandlerClassName()); // Parameters - parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); - persistenceHandlerElem.appendChild(parametersElement); - for (Entry entry : this.containerModel.getPersistenceHandlerParameterMap().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); + fillParameterMap(doc, persistenceHandlerElem, this.containerModel.getPersistenceHandlerParameterMap()); + + // Parameters + fillParameterMap(doc, containerElement, this.containerModel.getParameterMap()); + + // create UserChallengeHandler + 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 - Element policiesElem = doc.createElement(XmlConstants.XML_POLICIES); + Element policiesElem = doc.createElement(XML_POLICIES); rootElement.appendChild(policiesElem); for (Entry> entry : this.containerModel.getPolicies().entrySet()) { - Element policyElem = doc.createElement(XmlConstants.XML_POLICY); - policyElem.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey()); - policyElem.setAttribute(XmlConstants.XML_ATTR_CLASS, entry.getValue().getName()); + Element policyElem = doc.createElement(XML_POLICY); + policyElem.setAttribute(XML_ATTR_NAME, entry.getKey()); + policyElem.setAttribute(XML_ATTR_CLASS, entry.getValue().getName()); policiesElem.appendChild(policyElem); } // write the container file to disk XmlHelper.writeDocument(doc, this.configFile); } + + private void fillParameterMap(Document doc, Element parent, Map parameterMap) { + + if (parameterMap != null && !parameterMap.isEmpty()) { + Element parametersElement = doc.createElement(XML_PARAMETERS); + for (Entry 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); + } + } } diff --git a/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigSaxReader.java b/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigSaxReader.java index 16432ad49..25450531d 100644 --- a/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigSaxReader.java +++ b/li.strolch.privilege/src/main/java/li/strolch/privilege/xml/PrivilegeConfigSaxReader.java @@ -105,6 +105,10 @@ public class PrivilegeConfigSaxReader extends DefaultHandler { this.currentElement = qName; String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS); 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()); } else if (this.currentElement.equals(XmlConstants.XML_HANDLER_USER_CHALLENGE)) { getContainerModel().setUserChallengeHandlerParameterMap(parametersChild.getParameterMap()); + } else if (this.currentElement.equals(XmlConstants.XML_HANDLER_SSO)) { + getContainerModel().setSsoHandlerParameterMap(parametersChild.getParameterMap()); } } } diff --git a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/AbstractPrivilegeTest.java b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/AbstractPrivilegeTest.java index fb5b13f28..3efa69ee9 100644 --- a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/AbstractPrivilegeTest.java +++ b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/AbstractPrivilegeTest.java @@ -25,8 +25,7 @@ public class AbstractPrivilegeTest { protected void login(String username, char[] password) { Certificate certificate = privilegeHandler.authenticate(username, password); assertTrue("Certificate is null!", certificate != null); - PrivilegeContext privilegeContext = privilegeHandler.getPrivilegeContext(certificate); - this.ctx = privilegeContext; + this.ctx = privilegeHandler.validate(certificate); } protected void logout() { @@ -34,7 +33,7 @@ public class AbstractPrivilegeTest { try { PrivilegeContext privilegeContext = this.ctx; this.ctx = null; - privilegeHandler.invalidateSession(privilegeContext.getCertificate()); + privilegeHandler.invalidate(privilegeContext.getCertificate()); } catch (PrivilegeException e) { String msg = "There is no PrivilegeContext currently bound to the ThreadLocal!"; if (!e.getMessage().equals(msg)) @@ -43,18 +42,18 @@ public class AbstractPrivilegeTest { } } - protected static void prepareConfigs(String dst, String configFilename, String usersFilename, - String rolesFilename) { + protected static void prepareConfigs(String dst, + String configFilename, + String usersFilename, + String rolesFilename) { try { - String pwd = System.getProperty("user.dir"); - - File configPath = new File(pwd, "config"); + File configPath = new File("src/test/resources/config"); File privilegeConfigFile = new File(configPath, configFilename); File privilegeUsersFile = new File(configPath, usersFilename); File privilegeRolesFile = new File(configPath, rolesFilename); - File targetPath = new File(pwd, "target/" + dst); + File targetPath = new File("target/" + dst); if (!targetPath.mkdirs()) throw new RuntimeException("Could not create parent " + targetPath); @@ -79,8 +78,7 @@ public class AbstractPrivilegeTest { protected static void removeConfigs(String dst) { try { - String pwd = System.getProperty("user.dir"); - File targetPath = new File(pwd, "target"); + File targetPath = new File("target"); targetPath = new File(targetPath, dst); if (targetPath.exists() && !FileHelper.deleteFile(targetPath, true)) { throw new RuntimeException( @@ -94,8 +92,7 @@ public class AbstractPrivilegeTest { protected static File getPrivilegeConfigFile(String dst, String configFilename) { try { - String pwd = System.getProperty("user.dir"); - File targetPath = new File(pwd, "target"); + File targetPath = new File("target"); targetPath = new File(targetPath, dst); return new File(targetPath, configFilename); } catch (Exception e) { diff --git a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PersistSessionsTest.java b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PersistSessionsTest.java index d5c6d02ef..1b10ac221 100644 --- a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PersistSessionsTest.java +++ b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PersistSessionsTest.java @@ -38,11 +38,11 @@ public class PersistSessionsTest extends AbstractPrivilegeTest { // login and assert sessions file was written login("admin", "admin".toCharArray()); - this.privilegeHandler.isCertificateValid(ctx.getCertificate()); + this.privilegeHandler.validate(ctx.getCertificate()); assertTrue("Sessions File should have been created!", sessionsFile.isFile()); // re-initialize and assert still logged in initialize(PersistSessionsTest.class.getSimpleName(), "PrivilegeConfig.xml"); - this.privilegeHandler.isCertificateValid(ctx.getCertificate()); + this.privilegeHandler.validate(ctx.getCertificate()); } } diff --git a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PrivilegeTest.java b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PrivilegeTest.java index 9c684a42b..25ef9bdec 100644 --- a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PrivilegeTest.java +++ b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/PrivilegeTest.java @@ -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 /> - * + * * TODO add more tests, especially with deny and allow lists - * + * * @author Robert von Burg */ @SuppressWarnings("nls") @@ -117,9 +117,10 @@ public class PrivilegeTest extends AbstractPrivilegeTest { } } + @Test public void testFailAuthenticationNOk() throws Exception { this.exception.expect(AccessDeniedException.class); - this.exception.expectMessage("blabla"); + this.exception.expectMessage("User admin failed to authenticate: Password is incorrect for admin"); try { login(ADMIN, ArraysHelper.copyOf(PASS_BAD)); } finally { @@ -127,9 +128,10 @@ public class PrivilegeTest extends AbstractPrivilegeTest { } } + @Test public void testFailAuthenticationPWNull() throws Exception { this.exception.expect(PrivilegeException.class); - this.exception.expectMessage("blabla"); + this.exception.expectMessage("User admin failed to authenticate: A password may not be empty!"); try { login(ADMIN, null); } finally { @@ -324,7 +326,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest { Certificate certificate = this.ctx.getCertificate(); UserRep selectorRep = new UserRep(null, null, null, null, null, - new HashSet<>(Arrays.asList("PrivilegeAdmin")), null, null); + new HashSet<>(Collections.singletonList("PrivilegeAdmin")), null, null); List users = this.privilegeHandler.queryUsers(certificate, selectorRep); assertEquals(1, users.size()); assertEquals(ADMIN, users.get(0).getUsername()); @@ -341,8 +343,8 @@ public class PrivilegeTest extends AbstractPrivilegeTest { Certificate certificate = this.ctx.getCertificate(); - UserRep selectorRep = new UserRep(null, null, null, null, null, new HashSet<>(Arrays.asList(ROLE_TEMP)), - null, null); + UserRep selectorRep = new UserRep(null, null, null, null, null, + new HashSet<>(Collections.singletonList(ROLE_TEMP)), null, null); List users = this.privilegeHandler.queryUsers(certificate, selectorRep); assertEquals(0, users.size()); @@ -384,12 +386,13 @@ public class PrivilegeTest extends AbstractPrivilegeTest { public void shouldSetPasswordWithChallenge() { this.privilegeHandler.initiateChallengeFor(Usage.SET_PASSWORD, ADMIN); 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()); this.privilegeHandler.setUserPassword(certificate, ADMIN, ArraysHelper.copyOf(PASS_TED)); try { - this.privilegeHandler.isCertificateValid(certificate); + this.privilegeHandler.validate(certificate); fail("Certificate should not be valid anymore!"); } catch (PrivilegeException e) { // expected @@ -398,7 +401,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest { // change password back certificate = this.privilegeHandler.authenticate(ADMIN, PASS_TED); 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 HashSet roles = new HashSet<>(); roles.add(ROLE_USER); - userRep = new UserRep(null, TED, "Ted", "Newman", UserState.ENABLED, roles, null, - new HashMap()); + userRep = new UserRep(null, TED, "Ted", "Newman", UserState.ENABLED, roles, null, new HashMap<>()); Certificate certificate = this.ctx.getCertificate(); this.privilegeHandler.addUser(certificate, userRep, null); logger.info("Added user " + TED); @@ -765,7 +767,7 @@ public class PrivilegeTest extends AbstractPrivilegeTest { // let's add a new user bob UserRep userRep = new UserRep(null, BOB, "Bob", "Newman", UserState.NEW, - new HashSet<>(Arrays.asList(ROLE_MY)), null, new HashMap()); + new HashSet<>(Collections.singletonList(ROLE_MY)), null, new HashMap<>()); Certificate certificate = this.ctx.getCertificate(); this.privilegeHandler.addUser(certificate, userRep, null); logger.info("Added user " + BOB); diff --git a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/SsoHandlerTest.java b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/SsoHandlerTest.java new file mode 100644 index 000000000..0cbeee57a --- /dev/null +++ b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/SsoHandlerTest.java @@ -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 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(); + } + } +} diff --git a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/XmlTest.java b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/XmlTest.java index 1ad31166a..480e53490 100644 --- a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/XmlTest.java +++ b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/XmlTest.java @@ -16,30 +16,13 @@ package li.strolch.privilege.test; import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.junit.Assert.assertEquals; -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 static org.junit.Assert.*; import java.io.File; -import java.util.ArrayList; -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 java.util.*; import li.strolch.privilege.handler.DefaultEncryptionHandler; +import li.strolch.privilege.handler.MailUserChallengeHandler; import li.strolch.privilege.handler.PrivilegeHandler; import li.strolch.privilege.handler.XmlPersistenceHandler; 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.Role; import li.strolch.privilege.model.internal.User; -import li.strolch.privilege.xml.PrivilegeConfigDomWriter; -import li.strolch.privilege.xml.PrivilegeConfigSaxReader; -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.privilege.test.model.DummySsoHandler; +import li.strolch.privilege.xml.*; import li.strolch.utils.helper.FileHelper; import li.strolch.utils.helper.StringHelper; 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 @@ -64,12 +48,13 @@ import li.strolch.utils.helper.XmlHelper; @SuppressWarnings("nls") 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); /** * @throws Exception - * if something goes wrong + * if something goes wrong */ @BeforeClass public static void init() throws Exception { @@ -89,17 +74,17 @@ public class XmlTest { if (!tmpDir.exists()) return; - File tmpFile = new File("target/test/PrivilegeTest.xml"); + File tmpFile = new File(TARGET_TEST + "PrivilegeTest.xml"); if (tmpFile.exists() && !tmpFile.delete()) { throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); } - tmpFile = new File("target/test/PrivilegeUsersTest.xml"); + tmpFile = new File(TARGET_TEST + "PrivilegeUsersTest.xml"); if (tmpFile.exists() && !tmpFile.delete()) { throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); } - tmpFile = new File("target/test/PrivilegeRolesTest.xml"); + tmpFile = new File(TARGET_TEST + "PrivilegeRolesTest.xml"); if (tmpFile.exists() && !tmpFile.delete()) { throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); } @@ -115,7 +100,7 @@ public class XmlTest { PrivilegeContainerModel containerModel = new PrivilegeContainerModel(); PrivilegeConfigSaxReader saxReader = new PrivilegeConfigSaxReader(containerModel); - File xmlFile = new File("config/PrivilegeConfig.xml"); + File xmlFile = new File(SRC_TEST + "PrivilegeConfig.xml"); XmlHelper.parseDocument(xmlFile, saxReader); logger.info(containerModel.toString()); @@ -153,22 +138,24 @@ public class XmlTest { containerModel.setEncryptionHandlerParameterMap(encryptionHandlerParameterMap); containerModel.setPersistenceHandlerClassName(XmlPersistenceHandler.class.getName()); containerModel.setPersistenceHandlerParameterMap(persistenceHandlerParameterMap); + containerModel.setUserChallengeHandlerClassName(MailUserChallengeHandler.class.getName()); + containerModel.setSsoHandlerClassName(DummySsoHandler.class.getName()); 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); configSaxWriter.write(); String fileHash = StringHelper.toHexString(FileHelper.hashFileSha256(configFile)); - assertEquals("800b8e42e15b6b3bb425fa9c12a011d587d2b12343a1d1371eaa36dc1b2ea5f4", fileHash); + assertEquals("55c1212446707563877009f2090a39ad2fdf5462108109bbe0c10759d100a482", fileHash); } @Test public void canReadUsers() { PrivilegeUsersSaxReader xmlHandler = new PrivilegeUsersSaxReader(); - File xmlFile = new File("config/PrivilegeUsers.xml"); + File xmlFile = new File(SRC_TEST + "PrivilegeUsers.xml"); XmlHelper.parseDocument(xmlFile, xmlHandler); List users = xmlHandler.getUsers(); @@ -215,7 +202,7 @@ public class XmlTest { public void canReadRoles() { PrivilegeRolesSaxReader xmlHandler = new PrivilegeRolesSaxReader(); - File xmlFile = new File("config/PrivilegeRoles.xml"); + File xmlFile = new File(SRC_TEST + "PrivilegeRoles.xml"); XmlHelper.parseDocument(xmlFile, xmlHandler); List roles = xmlHandler.getRoles(); @@ -253,7 +240,7 @@ public class XmlTest { // AppUser Role appUser = findRole("AppUser", roles); 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()); IPrivilege testRestrictable = appUser.getPrivilege("li.strolch.privilege.test.model.TestRestrictable"); @@ -267,8 +254,9 @@ public class XmlTest { Role systemAdminPrivileges = findRole("system_admin_privileges", roles); assertEquals("system_admin_privileges", systemAdminPrivileges.getName()); assertEquals(2, systemAdminPrivileges.getPrivilegeNames().size()); - assertThat(systemAdminPrivileges.getPrivilegeNames(), containsInAnyOrder( - "li.strolch.privilege.handler.SystemAction", "li.strolch.privilege.test.model.TestSystemRestrictable")); + assertThat(systemAdminPrivileges.getPrivilegeNames(), + containsInAnyOrder("li.strolch.privilege.handler.SystemAction", + "li.strolch.privilege.test.model.TestSystemRestrictable")); IPrivilege testSystemUserAction = systemAdminPrivileges .getPrivilege("li.strolch.privilege.handler.SystemAction"); @@ -302,11 +290,6 @@ public class XmlTest { assertThat(testSystemUserAction2.getDenyList(), containsInAnyOrder("goodbye")); } - /** - * @param username - * @param users - * @return - */ private User findUser(String username, List users) { for (User user : users) { if (user.getUsername().equals(username)) @@ -316,11 +299,6 @@ public class XmlTest { throw new RuntimeException("No user exists with username " + username); } - /** - * @param name - * @param roles - * @return - */ private Role findRole(String name, List roles) { for (Role role : roles) { if (role.getName().equals(name)) @@ -353,7 +331,7 @@ public class XmlTest { UserState.ENABLED, userRoles, Locale.ENGLISH, propertyMap); 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); configSaxWriter.write(); @@ -408,7 +386,7 @@ public class XmlTest { Role role2 = new Role("role2", privilegeMap); 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); configSaxWriter.write(); diff --git a/li.strolch.privilege/src/test/java/li/strolch/privilege/test/model/DummySsoHandler.java b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/model/DummySsoHandler.java new file mode 100644 index 000000000..87da4ce86 --- /dev/null +++ b/li.strolch.privilege/src/test/java/li/strolch/privilege/test/model/DummySsoHandler.java @@ -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 parameterMap) { + // do nothing + } + + @Override + public User authenticateSingleSignOn(Object data) throws PrivilegeException { + + @SuppressWarnings("unchecked") + Map map = (Map) data; + + Set roles = Arrays.stream(map.get("roles").split(",")).map(String::trim).collect(Collectors.toSet()); + Map 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); + } +} diff --git a/li.strolch.privilege/src/test/resources/config/PrivilegeConfig.xml b/li.strolch.privilege/src/test/resources/config/PrivilegeConfig.xml new file mode 100644 index 000000000..4e3a31061 --- /dev/null +++ b/li.strolch.privilege/src/test/resources/config/PrivilegeConfig.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/li.strolch.privilege/config/PrivilegeConfigMerge.xml b/li.strolch.privilege/src/test/resources/config/PrivilegeConfigMerge.xml similarity index 95% rename from li.strolch.privilege/config/PrivilegeConfigMerge.xml rename to li.strolch.privilege/src/test/resources/config/PrivilegeConfigMerge.xml index 2cc02f506..77abe6fdc 100644 --- a/li.strolch.privilege/config/PrivilegeConfigMerge.xml +++ b/li.strolch.privilege/src/test/resources/config/PrivilegeConfigMerge.xml @@ -23,7 +23,7 @@ - + diff --git a/li.strolch.privilege/config/PrivilegeRoles.xml b/li.strolch.privilege/src/test/resources/config/PrivilegeRoles.xml similarity index 100% rename from li.strolch.privilege/config/PrivilegeRoles.xml rename to li.strolch.privilege/src/test/resources/config/PrivilegeRoles.xml diff --git a/li.strolch.privilege/config/PrivilegeRolesMerge.xml b/li.strolch.privilege/src/test/resources/config/PrivilegeRolesMerge.xml similarity index 100% rename from li.strolch.privilege/config/PrivilegeRolesMerge.xml rename to li.strolch.privilege/src/test/resources/config/PrivilegeRolesMerge.xml diff --git a/li.strolch.privilege/config/PrivilegeUsers.xml b/li.strolch.privilege/src/test/resources/config/PrivilegeUsers.xml similarity index 100% rename from li.strolch.privilege/config/PrivilegeUsers.xml rename to li.strolch.privilege/src/test/resources/config/PrivilegeUsers.xml diff --git a/li.strolch.privilege/config/PrivilegeUsersMerge.xml b/li.strolch.privilege/src/test/resources/config/PrivilegeUsersMerge.xml similarity index 100% rename from li.strolch.privilege/config/PrivilegeUsersMerge.xml rename to li.strolch.privilege/src/test/resources/config/PrivilegeUsersMerge.xml diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java b/li.strolch.rest/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java index 67e58b4f3..93e97882b 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/DefaultStrolchSessionHandler.java @@ -116,7 +116,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St } else if (this.certificateMap != null) { synchronized (this.certificateMap) { for (Certificate certificate : this.certificateMap.values()) { - this.privilegeHandler.invalidateSession(certificate); + this.privilegeHandler.invalidate(certificate); } this.certificateMap.clear(); } @@ -154,14 +154,13 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St throw new StrolchNotAuthenticatedException( MessageFormat.format("No certificate exists for sessionId {0}", authToken)); //$NON-NLS-1$ - return validate(certificate); + return validate(certificate).getCertificate(); } @Override - public Certificate validate(Certificate certificate) throws StrolchNotAuthenticatedException { + public PrivilegeContext validate(Certificate certificate) throws StrolchNotAuthenticatedException { try { - this.privilegeHandler.isCertificateValid(certificate); - return certificate; + return this.privilegeHandler.validate(certificate); } catch (PrivilegeException e) { throw new StrolchNotAuthenticatedException(e.getMessage(), e); } @@ -176,7 +175,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St logger.error(MessageFormat .format("No session was registered with token {0}", certificate.getAuthToken())); //$NON-NLS-1$ - this.privilegeHandler.invalidateSession(certificate); + this.privilegeHandler.invalidate(certificate); } @Override @@ -255,7 +254,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public UserSession getSession(Certificate certificate, String sessionId) { - PrivilegeContext ctx = this.privilegeHandler.getPrivilegeContext(certificate); + PrivilegeContext ctx = this.privilegeHandler.validate(certificate); ctx.assertHasPrivilege(PRIVILEGE_GET_SESSION); synchronized (this.certificateMap) { for (Certificate cert : certificateMap.values()) { @@ -271,7 +270,7 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St @Override public List getSessions(Certificate certificate) { - PrivilegeContext ctx = this.privilegeHandler.getPrivilegeContext(certificate); + PrivilegeContext ctx = this.privilegeHandler.validate(certificate); ctx.assertHasPrivilege(PRIVILEGE_GET_SESSION); List sessions = new ArrayList<>(this.certificateMap.size()); synchronized (this.certificateMap) { @@ -289,8 +288,8 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St } @Override - public void invalidateSession(Certificate certificate, String sessionId) { - PrivilegeContext ctx = this.privilegeHandler.getPrivilegeContext(certificate); + public void invalidate(Certificate certificate, String sessionId) { + PrivilegeContext ctx = this.privilegeHandler.validate(certificate); ctx.assertHasPrivilege(PRIVILEGE_INVALIDATE_SESSION); Map map; diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/StrolchSessionHandler.java b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchSessionHandler.java index f84496bc4..356b04fe9 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/StrolchSessionHandler.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchSessionHandler.java @@ -21,6 +21,7 @@ import java.util.Locale; import li.strolch.exception.StrolchNotAuthenticatedException; import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.model.Certificate; +import li.strolch.privilege.model.PrivilegeContext; import li.strolch.privilege.model.Usage; import li.strolch.rest.model.UserSession; @@ -29,46 +30,46 @@ import li.strolch.rest.model.UserSession; */ 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 getSessions(Certificate certificate); - public List 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 - * + * * @param usage - * the usage for which the challenge is requested + * the usage for which the challenge is requested * @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 - * + * * @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 - * 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 - * initiated challenge - * + * initiated challenge + * * @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; } diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java index 6a37abf2b..53f600089 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/AuthenticationService.java @@ -93,7 +93,7 @@ public class AuthenticationService { PrivilegeHandler privilegeHandler = RestfulStrolchComponent.getInstance().getContainer() .getPrivilegeHandler(); - PrivilegeContext privilegeContext = privilegeHandler.getPrivilegeContext(certificate); + PrivilegeContext privilegeContext = privilegeHandler.validate(certificate); loginResult.addProperty("sessionId", certificate.getSessionId()); loginResult.addProperty("authToken", certificate.getAuthToken()); loginResult.addProperty("username", certificate.getUsername()); diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java index 974764a09..177c745e5 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java @@ -68,7 +68,7 @@ public class UserSessionsService { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); logger.info("[" + cert.getUsername() + "] Invalidating session " + sessionId); StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler(); - sessionHandler.invalidateSession(cert, sessionId); + sessionHandler.invalidate(cert, sessionId); return ResponseUtil.toResponse(); } diff --git a/li.strolch.service/src/test/java/li/strolch/service/test/GreetingServiceTest.java b/li.strolch.service/src/test/java/li/strolch/service/test/GreetingServiceTest.java index 688ac90c8..7d7bb016d 100644 --- a/li.strolch.service/src/test/java/li/strolch/service/test/GreetingServiceTest.java +++ b/li.strolch.service/src/test/java/li/strolch/service/test/GreetingServiceTest.java @@ -43,7 +43,7 @@ public class GreetingServiceTest extends AbstractServiceTest { greetingArgument); assertThat(greetingResult.getGreeting(), containsString("Hello Robert. Nice to meet you!")); //$NON-NLS-1$ } finally { - runtimeMock.getPrivilegeHandler().invalidateSession(certificate); + runtimeMock.getPrivilegeHandler().invalidate(certificate); } } } diff --git a/li.strolch.service/src/test/java/li/strolch/service/test/ServiceTest.java b/li.strolch.service/src/test/java/li/strolch/service/test/ServiceTest.java index e42c8073d..71359c300 100644 --- a/li.strolch.service/src/test/java/li/strolch/service/test/ServiceTest.java +++ b/li.strolch.service/src/test/java/li/strolch/service/test/ServiceTest.java @@ -58,16 +58,17 @@ public class ServiceTest extends AbstractServiceTest { public void shouldFailInvalidCertificate1() { this.thrown.expect(PrivilegeException.class); TestService testService = new TestService(); - getServiceHandler().doService(new Certificate(null, null, null, null, null, null, null, new Date(), null, - new HashSet(), null), testService); + getServiceHandler().doService( + new Certificate(null, null, null, null, null, null, null, new Date(), null, new HashSet<>(), null), + testService); } @Test public void shouldFailInvalidCertificate2() { 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$ - new Date(), null, - new HashSet(), null); + Certificate badCert = new Certificate(Usage.ANY, "1", "bob", "Bob", "Brown", UserState.ENABLED, "dsdf", + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + new Date(), null, new HashSet<>(), null); ServiceResult svcResult = getServiceHandler().doService(badCert, testService); assertThat(svcResult.getThrowable(), instanceOf(NotAuthenticatedException.class)); } @@ -75,21 +76,23 @@ public class ServiceTest extends AbstractServiceTest { @Test 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 { TestService testService = new TestService(); ServiceResult svcResult = getServiceHandler().doService(certificate, testService); - assertThat(svcResult.getMessage(), - containsString("User jill does not have the privilege li.strolch.service.api.Service")); //$NON-NLS-1$ + assertThat(svcResult.getMessage(), containsString( + "User jill does not have the privilege li.strolch.service.api.Service")); //$NON-NLS-1$ assertThat(svcResult.getThrowable(), instanceOf(AccessDeniedException.class)); } finally { - runtimeMock.getPrivilegeHandler().invalidateSession(certificate); + runtimeMock.getPrivilegeHandler().invalidate(certificate); } } @Test 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 { GreetingService service = new GreetingService(); GreetingArgument argument = new GreetingArgument(); @@ -97,25 +100,27 @@ public class ServiceTest extends AbstractServiceTest { GreetingResult greetingResult = getServiceHandler().doService(certificate, service, argument); assertThat(greetingResult.getGreeting(), equalTo("Hello Jill. Nice to meet you!")); //$NON-NLS-1$ } finally { - runtimeMock.getPrivilegeHandler().invalidateSession(certificate); + runtimeMock.getPrivilegeHandler().invalidate(certificate); } } @Test 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 { TestService testService = new TestService(); getServiceHandler().doService(certificate, testService); } finally { - runtimeMock.getPrivilegeHandler().invalidateSession(certificate); + runtimeMock.getPrivilegeHandler().invalidate(certificate); } } @Test 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 { GreetingService service = new GreetingService(); GreetingArgument argument = new GreetingArgument(); @@ -123,7 +128,7 @@ public class ServiceTest extends AbstractServiceTest { GreetingResult greetingResult = getServiceHandler().doService(certificate, service, argument); assertThat(greetingResult.getGreeting(), equalTo("Hello Bob. Nice to meet you!")); //$NON-NLS-1$ } finally { - runtimeMock.getPrivilegeHandler().invalidateSession(certificate); + runtimeMock.getPrivilegeHandler().invalidate(certificate); } } } diff --git a/li.strolch.testbase/src/main/java/li/strolch/testbase/runtime/RuntimeMock.java b/li.strolch.testbase/src/main/java/li/strolch/testbase/runtime/RuntimeMock.java index a0e97761c..8da73235b 100644 --- a/li.strolch.testbase/src/main/java/li/strolch/testbase/runtime/RuntimeMock.java +++ b/li.strolch.testbase/src/main/java/li/strolch/testbase/runtime/RuntimeMock.java @@ -89,7 +89,7 @@ public class RuntimeMock { } public boolean logout(Certificate cert) { - return getPrivilegeHandler().invalidateSession(cert); + return getPrivilegeHandler().invalidate(cert); } public RuntimeMock mockRuntime(String targetPath, String srcPath) { @@ -235,8 +235,7 @@ public class RuntimeMock { } catch (Exception e) { throw new IllegalStateException("Failed to read " + StrolchAgent.AGENT_VERSION_PROPERTIES, e); } - StrolchVersion version = new StrolchVersion(properties); - return version; + return new StrolchVersion(properties); } }