From 6ddb7b6b224a00344a182761e42b2241a721224f Mon Sep 17 00:00:00 2001
From: Mathieu Baudier
Date: Sat, 14 Feb 2015 13:31:59 +0000
Subject: [PATCH] Move security model to CMS
git-svn-id: https://svn.argeo.org/commons/trunk@7868 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc
---
demo/log4j.properties | 14 +-
org.argeo.cms/bnd.bnd | 5 +-
.../org/argeo/cms/auth/ArgeoLoginContext.java | 53 ++++
.../cms/auth}/LoginCanceledException.java | 2 +-
.../internal/auth/AbstractLoginModule.java | 45 ++-
.../internal/auth}/AnonymousLoginModule.java | 18 +-
.../auth}/ConsoleCallbackHandler.java | 2 +-
.../internal/auth}/EndUserLoginModule.java | 19 +-
.../auth}/GrantedAuthorityPrincipal.java | 2 +-
.../auth}/OsJcrAuthenticationProvider.java | 5 +-
.../RemoteJcrAuthenticationProvider.java | 4 +-
.../cms/internal/auth}/SystemLoginModule.java | 16 +-
.../argeo/cms/internal/kernel/Activator.java | 31 +-
.../cms/internal/kernel/NodeSecurity.java | 9 +-
.../org/argeo/cms/internal/kernel/jaas.cfg | 6 +-
.../cms/internal/useradmin/JcrUserAdmin.java | 1 -
.../useradmin}/OsJcrUserAdminService.java | 4 +-
.../useradmin}/SimpleJcrSecurityModel.java | 3 +-
.../jackrabbit/JackrabbitSecurityModel.java | 4 +-
.../JackrabbitUserAdminService.java | 4 +-
.../jackrabbit/ScopedSessionProvider.java | 2 +-
.../ldap/ArgeoLdapShaPasswordEncoder.java | 2 +-
.../ldap/ArgeoLdapUserDetailsManager.java | 3 +-
.../ldap/ArgeoUserAdminDaoLdap.java | 2 +-
.../useradmin/ldap}/JcrLdapSynchronizer.java | 5 +-
.../ldap}/JcrUserDetailsContextMapper.java | 2 +-
org.argeo.security.core/bnd.bnd | 3 -
.../src/org/argeo/security/SecurityUtils.java | 11 -
.../core/AbstractSystemExecution.java | 40 +--
.../argeo/security/jcr/JcrSecurityModel.java | 2 +-
.../jcr/SecureThreadBoundSession.java | 1 +
.../security/login/BundleContextCallback.java | 19 --
.../login/BundleContextCallbackHandler.java | 41 ---
org.argeo.security.ui.rap/.classpath | 2 +-
.../security/ui/rap/SecureEntryPoint.java | 21 +-
.../argeo/security/ui/SecurityUiPlugin.java | 4 +-
.../AbstractLoginDialog.java | 15 +-
.../ui/auth/CompositeCallbackHandler.java | 291 ++++++++++++++++++
.../security/ui/auth/DefaultLoginDialog.java | 77 +++++
.../ui/dialogs/DefaultLoginDialog.java | 199 ------------
.../ext/test/org/argeo/jcr/MapperTest.java | 1 +
.../argeo/jackrabbit/JackrabbitWrapper.java | 9 +-
.../src/org/argeo/jcr/JcrUtils.java | 1 -
43 files changed, 586 insertions(+), 414 deletions(-)
create mode 100644 org.argeo.cms/src/org/argeo/cms/auth/ArgeoLoginContext.java
rename {org.argeo.security.core/src/org/argeo/security/login => org.argeo.cms/src/org/argeo/cms/auth}/LoginCanceledException.java (84%)
rename org.argeo.security.core/src/org/argeo/security/login/AbstractSpringLoginModule.java => org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java (73%)
rename {org.argeo.security.core/src/org/argeo/security/login => org.argeo.cms/src/org/argeo/cms/internal/auth}/AnonymousLoginModule.java (79%)
rename {org.argeo.security.core/src/org/argeo/security/login => org.argeo.cms/src/org/argeo/cms/internal/auth}/ConsoleCallbackHandler.java (98%)
rename {org.argeo.security.core/src/org/argeo/security/login => org.argeo.cms/src/org/argeo/cms/internal/auth}/EndUserLoginModule.java (87%)
rename {org.argeo.security.core/src/org/argeo/security/login => org.argeo.cms/src/org/argeo/cms/internal/auth}/GrantedAuthorityPrincipal.java (97%)
rename {org.argeo.security.core/src/org/argeo/security/jcr => org.argeo.cms/src/org/argeo/cms/internal/auth}/OsJcrAuthenticationProvider.java (95%)
rename {org.argeo.security.core/src/org/argeo/security/jcr => org.argeo.cms/src/org/argeo/cms/internal/auth}/RemoteJcrAuthenticationProvider.java (97%)
rename {org.argeo.security.core/src/org/argeo/security/login => org.argeo.cms/src/org/argeo/cms/internal/auth}/SystemLoginModule.java (68%)
rename {org.argeo.security.core/src/org/argeo/security/jcr => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/OsJcrUserAdminService.java (96%)
rename {org.argeo.security.core/src/org/argeo/security/jcr => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/SimpleJcrSecurityModel.java (98%)
rename {org.argeo.security.core/src/org/argeo/security/jcr => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/jackrabbit/JackrabbitSecurityModel.java (96%)
rename {org.argeo.security.core/src/org/argeo/security/jcr => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/jackrabbit/JackrabbitUserAdminService.java (99%)
rename {org.argeo.security.core/src/org/argeo/security/jcr => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/jackrabbit/ScopedSessionProvider.java (99%)
rename {org.argeo.security.core/src/org/argeo/security => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/ldap/ArgeoLdapShaPasswordEncoder.java (96%)
rename {org.argeo.security.core/src/org/argeo/security => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/ldap/ArgeoLdapUserDetailsManager.java (98%)
rename {org.argeo.security.core/src/org/argeo/security => org.argeo.cms/src/org/argeo/cms/internal/useradmin}/ldap/ArgeoUserAdminDaoLdap.java (99%)
rename {org.argeo.security.core/src/org/argeo/security/ldap/jcr => org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap}/JcrLdapSynchronizer.java (99%)
rename {org.argeo.security.core/src/org/argeo/security/ldap/jcr => org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap}/JcrUserDetailsContextMapper.java (98%)
delete mode 100644 org.argeo.security.core/src/org/argeo/security/login/BundleContextCallback.java
delete mode 100644 org.argeo.security.core/src/org/argeo/security/login/BundleContextCallbackHandler.java
rename org.argeo.security.ui/src/org/argeo/security/ui/{dialogs => auth}/AbstractLoginDialog.java (93%)
create mode 100644 org.argeo.security.ui/src/org/argeo/security/ui/auth/CompositeCallbackHandler.java
create mode 100644 org.argeo.security.ui/src/org/argeo/security/ui/auth/DefaultLoginDialog.java
delete mode 100644 org.argeo.security.ui/src/org/argeo/security/ui/dialogs/DefaultLoginDialog.java
diff --git a/demo/log4j.properties b/demo/log4j.properties
index 13f949ff5..53e2c2f19 100644
--- a/demo/log4j.properties
+++ b/demo/log4j.properties
@@ -2,21 +2,9 @@ log4j.rootLogger=WARN, development
## Levels
log4j.logger.org.argeo=DEBUG
-log4j.logger.org.argeo.jackrabbit.remote.ExtendedDispatcherServlet=WARN
-log4j.logger.org.argeo.server.webextender.TomcatDeployer=INFO
-#log4j.logger.org.springframework.security=DEBUG
-#log4j.logger.org.apache.commons.exec=DEBUG
-#log4j.logger.org.apache.jackrabbit.webdav=DEBUG
-#log4j.logger.org.apache.jackrabbit.remote=DEBUG
-#log4j.logger.org.apache.jackrabbit.core.observation=DEBUG
-
-log4j.logger.org.apache.catalina=INFO
-log4j.logger.org.apache.coyote=INFO
-
-log4j.logger.org.apache.directory=INFO
-log4j.logger.org.apache.directory.server=ERROR
log4j.logger.org.apache.jackrabbit.core.query.lucene=ERROR
+log4j.logger.org.apache.jackrabbit.core.config.ConfigurationErrorHandler=ERROR
## Appenders
# console is set to be a ConsoleAppender.
diff --git a/org.argeo.cms/bnd.bnd b/org.argeo.cms/bnd.bnd
index bdcfd61d0..711fe437a 100644
--- a/org.argeo.cms/bnd.bnd
+++ b/org.argeo.cms/bnd.bnd
@@ -9,9 +9,12 @@ org.xml.sax;version="0.0.0",\
org.eclipse.swt.widgets;version="0.0.0",\
org.argeo.jcr,\
org.springframework.context,\
+org.springframework.security.authentication.jaas,\
org.apache.jackrabbit.api,\
org.apache.jackrabbit.commons,\
-org.eclipse.rap.rwt.osgi,\
org.h2;resolution:=optional,\
org.apache.commons.vfs2.*;resolution:=optional,\
+org.apache.jackrabbit.*;resolution:=optional,\
+org.springframework.ldap.*;resolution:=optional,\
+org.springframework.security.ldap.*;resolution:=optional,\
*
diff --git a/org.argeo.cms/src/org/argeo/cms/auth/ArgeoLoginContext.java b/org.argeo.cms/src/org/argeo/cms/auth/ArgeoLoginContext.java
new file mode 100644
index 000000000..3a536672a
--- /dev/null
+++ b/org.argeo.cms/src/org/argeo/cms/auth/ArgeoLoginContext.java
@@ -0,0 +1,53 @@
+package org.argeo.cms.auth;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/** Integrates JAAS with the Argeo platform */
+public class ArgeoLoginContext extends LoginContext {
+ private static ThreadLocal currentContextClassLoader = new ThreadLocal() {
+ @Override
+ protected ClassLoader initialValue() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+
+ @Override
+ public void set(ClassLoader value) {
+ throw new IllegalAccessError("Current class loader is read-only");
+ }
+ };
+
+ public ArgeoLoginContext(String name, Subject subject,
+ CallbackHandler callbackHandler) throws LoginException {
+ super(setContextClassLoaderForName(name), subject, callbackHandler);
+ // reset current context classloader
+ Thread.currentThread().setContextClassLoader(
+ currentContextClassLoader.get());
+ currentContextClassLoader.remove();
+ }
+
+ /**
+ * Set the context classloader
+ *
+ * @return the passed name, in order to chain calls in the constructor
+ */
+ private static String setContextClassLoaderForName(String name) {
+ // store current context class loader;
+ currentContextClassLoader.get();
+ Thread.currentThread().setContextClassLoader(
+ ArgeoLoginContext.class.getClassLoader());
+ return name;
+ }
+
+ @Override
+ public void login() throws LoginException {
+ super.login();
+ }
+
+ @Override
+ public void logout() throws LoginException {
+ super.logout();
+ }
+}
diff --git a/org.argeo.security.core/src/org/argeo/security/login/LoginCanceledException.java b/org.argeo.cms/src/org/argeo/cms/auth/LoginCanceledException.java
similarity index 84%
rename from org.argeo.security.core/src/org/argeo/security/login/LoginCanceledException.java
rename to org.argeo.cms/src/org/argeo/cms/auth/LoginCanceledException.java
index 5629e2e25..731cdd170 100644
--- a/org.argeo.security.core/src/org/argeo/security/login/LoginCanceledException.java
+++ b/org.argeo.cms/src/org/argeo/cms/auth/LoginCanceledException.java
@@ -1,4 +1,4 @@
-package org.argeo.security.login;
+package org.argeo.cms.auth;
import javax.security.auth.login.LoginException;
diff --git a/org.argeo.security.core/src/org/argeo/security/login/AbstractSpringLoginModule.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java
similarity index 73%
rename from org.argeo.security.core/src/org/argeo/security/login/AbstractSpringLoginModule.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java
index 8a09a08e0..36d5e0fef 100644
--- a/org.argeo.security.core/src/org/argeo/security/login/AbstractSpringLoginModule.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/AbstractLoginModule.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.login;
+package org.argeo.cms.internal.auth;
import java.io.IOException;
import java.util.Map;
@@ -24,14 +24,16 @@ import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
+import org.argeo.ArgeoException;
+import org.argeo.cms.internal.kernel.Activator;
import org.osgi.framework.BundleContext;
-import org.osgi.service.useradmin.UserAdmin;
+import org.osgi.framework.ServiceReference;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
/** Login module which caches one subject per thread. */
-abstract class AbstractSpringLoginModule implements LoginModule {
+public abstract class AbstractLoginModule implements LoginModule {
// private final static Log log = LogFactory
// .getLog(AbstractSpringLoginModule.class);
private CallbackHandler callbackHandler;
@@ -39,16 +41,22 @@ abstract class AbstractSpringLoginModule implements LoginModule {
private Authentication authentication;
+ // state
+ private BundleContext bundleContext;
+ private ServiceReference authenticationManager;
+
protected abstract Authentication processLogin(
CallbackHandler callbackHandler) throws LoginException,
UnsupportedCallbackException, IOException, InterruptedException;
- @SuppressWarnings("rawtypes")
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
- Map sharedState, Map options) {
+ Map sharedState, Map options) {
this.callbackHandler = callbackHandler;
this.subject = subject;
+ this.bundleContext = Activator.getBundleContext();
+ this.authenticationManager = bundleContext
+ .getServiceReference(AuthenticationManager.class);
}
@Override
@@ -115,19 +123,28 @@ abstract class AbstractSpringLoginModule implements LoginModule {
return true;
}
- protected AuthenticationManager getAuthenticationManager(
- BundleContextCallback bundleContextCallback) {
- BundleContext bc = bundleContextCallback.getBundleContext();
- return bc.getService(bc
- .getServiceReference(AuthenticationManager.class));
-
+ /**
+ * Return the related {@link BundleContext} (never null), or throws an
+ * Exception if the login module was not properly initialised.
+ */
+ protected BundleContext getBundleContext() {
+ if (bundleContext == null)
+ throw new ArgeoException("No bundle context provided");
+ return bundleContext;
}
- protected UserAdmin getUserAdmin(BundleContextCallback bundleContextCallback) {
- BundleContext bc = bundleContextCallback.getBundleContext();
- return bc.getService(bc.getServiceReference(UserAdmin.class));
+ AuthenticationManager getAuthenticationManager() {
+ BundleContext bc = getBundleContext();
+ assert authenticationManager != null;
+ return bc.getService(authenticationManager);
}
+ // protected UserAdmin getUserAdmin(BundleContextCallback
+ // bundleContextCallback) {
+ // BundleContext bc = bundleContextCallback.getBundleContext();
+ // return bc.getService(bc.getServiceReference(UserAdmin.class));
+ // }
+
protected Subject getSubject() {
return subject;
}
diff --git a/org.argeo.security.core/src/org/argeo/security/login/AnonymousLoginModule.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/AnonymousLoginModule.java
similarity index 79%
rename from org.argeo.security.core/src/org/argeo/security/login/AnonymousLoginModule.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/AnonymousLoginModule.java
index 0a1279cae..6078b8f2b 100644
--- a/org.argeo.security.core/src/org/argeo/security/login/AnonymousLoginModule.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/AnonymousLoginModule.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.login;
+package org.argeo.cms.internal.auth;
import java.io.IOException;
import java.util.Collections;
@@ -25,7 +25,7 @@ import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
-import org.argeo.security.SecurityUtils;
+import org.argeo.cms.internal.kernel.Activator;
import org.argeo.util.LocaleCallback;
import org.argeo.util.LocaleUtils;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
@@ -33,7 +33,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
/** Login module which caches one subject per thread. */
-public class AnonymousLoginModule extends AbstractSpringLoginModule {
+public class AnonymousLoginModule extends AbstractLoginModule {
private String anonymousRole = "ROLE_ANONYMOUS";
/** Comma separated list of locales */
private String availableLocales = null;
@@ -42,25 +42,23 @@ public class AnonymousLoginModule extends AbstractSpringLoginModule {
protected Authentication processLogin(CallbackHandler callbackHandler)
throws LoginException, UnsupportedCallbackException, IOException,
InterruptedException {
- BundleContextCallback bundleContextCallback = new BundleContextCallback();
Locale selectedLocale = null;
// multi locale
if (availableLocales != null && !availableLocales.trim().equals("")) {
LocaleCallback localeCallback = new LocaleCallback(availableLocales);
- callbackHandler.handle(new Callback[] { localeCallback,
- bundleContextCallback });
+ callbackHandler.handle(new Callback[] { localeCallback });
selectedLocale = localeCallback.getSelectedLocale();
} else {
- callbackHandler.handle(new Callback[] { bundleContextCallback });
+ callbackHandler.handle(new Callback[] {});
}
List authorities = Collections
.singletonList(new SimpleGrantedAuthority(anonymousRole));
AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
- SecurityUtils.getStaticKey(), null, authorities);
+ Activator.getSystemKey(), null, authorities);
- Authentication auth = getAuthenticationManager(bundleContextCallback)
- .authenticate(anonymousToken);
+ Authentication auth = getAuthenticationManager().authenticate(
+ anonymousToken);
if (selectedLocale != null)
LocaleUtils.threadLocale.set(selectedLocale);
diff --git a/org.argeo.security.core/src/org/argeo/security/login/ConsoleCallbackHandler.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/ConsoleCallbackHandler.java
similarity index 98%
rename from org.argeo.security.core/src/org/argeo/security/login/ConsoleCallbackHandler.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/ConsoleCallbackHandler.java
index 4c47ac637..7ea9c0737 100644
--- a/org.argeo.security.core/src/org/argeo/security/login/ConsoleCallbackHandler.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/ConsoleCallbackHandler.java
@@ -1,4 +1,4 @@
-package org.argeo.security.login;
+package org.argeo.cms.internal.auth;
import java.io.Console;
import java.io.IOException;
diff --git a/org.argeo.security.core/src/org/argeo/security/login/EndUserLoginModule.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/EndUserLoginModule.java
similarity index 87%
rename from org.argeo.security.core/src/org/argeo/security/login/EndUserLoginModule.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/EndUserLoginModule.java
index e01e714fd..de2a007de 100644
--- a/org.argeo.security.core/src/org/argeo/security/login/EndUserLoginModule.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/EndUserLoginModule.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.login;
+package org.argeo.cms.internal.auth;
import java.io.IOException;
import java.util.Locale;
@@ -23,6 +23,7 @@ import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.CredentialNotFoundException;
import javax.security.auth.login.LoginException;
import org.argeo.security.NodeAuthenticationToken;
@@ -32,7 +33,7 @@ import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
/** Authenticates an end user */
-public class EndUserLoginModule extends AbstractSpringLoginModule {
+public class EndUserLoginModule extends AbstractLoginModule {
final static String NODE_REPO_URI = "argeo.node.repo.uri";
private Long waitBetweenFailedLoginAttempts = 5 * 1000l;
@@ -53,27 +54,26 @@ public class EndUserLoginModule extends AbstractSpringLoginModule {
"http://localhost:7070/org.argeo.jcr.webapp/remoting/node");
NameCallback urlCallback = new NameCallback("Site URL", defaultNodeUrl);
LocaleCallback localeCallback = new LocaleCallback(availableLocales);
- BundleContextCallback bundleContextCallback = new BundleContextCallback();
-
// handle callbacks
if (remote)
callbackHandler.handle(new Callback[] { nameCallback,
- passwordCallback, urlCallback, localeCallback,
- bundleContextCallback });
+ passwordCallback, urlCallback, localeCallback });
else
callbackHandler.handle(new Callback[] { nameCallback,
- passwordCallback, localeCallback, bundleContextCallback });
+ passwordCallback, localeCallback });
Locale selectedLocale = localeCallback.getSelectedLocale();
// create credentials
final String username = nameCallback.getName();
if (username == null || username.trim().equals(""))
- throw new LoginCanceledException();
+ throw new CredentialNotFoundException("No credentials provided");
char[] password = {};
if (passwordCallback.getPassword() != null)
password = passwordCallback.getPassword();
+ else
+ throw new CredentialNotFoundException("No credentials provided");
NodeAuthenticationToken credentials;
if (remote) {
@@ -85,8 +85,7 @@ public class EndUserLoginModule extends AbstractSpringLoginModule {
Authentication auth;
try {
- auth = getAuthenticationManager(bundleContextCallback)
- .authenticate(credentials);
+ auth = getAuthenticationManager().authenticate(credentials);
} catch (BadCredentialsException e) {
// wait between failed login attempts
Thread.sleep(waitBetweenFailedLoginAttempts);
diff --git a/org.argeo.security.core/src/org/argeo/security/login/GrantedAuthorityPrincipal.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/GrantedAuthorityPrincipal.java
similarity index 97%
rename from org.argeo.security.core/src/org/argeo/security/login/GrantedAuthorityPrincipal.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/GrantedAuthorityPrincipal.java
index c176c04bc..a0622da3b 100644
--- a/org.argeo.security.core/src/org/argeo/security/login/GrantedAuthorityPrincipal.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/GrantedAuthorityPrincipal.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.login;
+package org.argeo.cms.internal.auth;
import java.security.Principal;
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/OsJcrAuthenticationProvider.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/OsJcrAuthenticationProvider.java
similarity index 95%
rename from org.argeo.security.core/src/org/argeo/security/jcr/OsJcrAuthenticationProvider.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/OsJcrAuthenticationProvider.java
index 7125604c7..61ed7ba35 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/OsJcrAuthenticationProvider.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/OsJcrAuthenticationProvider.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.jcr;
+package org.argeo.cms.internal.auth;
import java.util.Collection;
@@ -23,10 +23,13 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.argeo.ArgeoException;
+import org.argeo.cms.internal.useradmin.SimpleJcrSecurityModel;
import org.argeo.jcr.JcrUtils;
import org.argeo.security.OsAuthenticationToken;
import org.argeo.security.SecurityUtils;
import org.argeo.security.core.OsAuthenticationProvider;
+import org.argeo.security.jcr.JcrSecurityModel;
+import org.argeo.security.jcr.JcrUserDetails;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/RemoteJcrAuthenticationProvider.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/RemoteJcrAuthenticationProvider.java
similarity index 97%
rename from org.argeo.security.core/src/org/argeo/security/jcr/RemoteJcrAuthenticationProvider.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/RemoteJcrAuthenticationProvider.java
index 154107576..b9ebaf761 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/RemoteJcrAuthenticationProvider.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/RemoteJcrAuthenticationProvider.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.jcr;
+package org.argeo.cms.internal.auth;
import java.util.ArrayList;
import java.util.Dictionary;
@@ -33,6 +33,8 @@ import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.ArgeoNames;
import org.argeo.jcr.UserJcrUtils;
import org.argeo.security.NodeAuthenticationToken;
+import org.argeo.security.jcr.JcrUserDetails;
+import org.argeo.security.jcr.RemoteJcrRepositoryWrapper;
import org.osgi.framework.BundleContext;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
diff --git a/org.argeo.security.core/src/org/argeo/security/login/SystemLoginModule.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/SystemLoginModule.java
similarity index 68%
rename from org.argeo.security.core/src/org/argeo/security/login/SystemLoginModule.java
rename to org.argeo.cms/src/org/argeo/cms/internal/auth/SystemLoginModule.java
index 54e80e847..5e8587d25 100644
--- a/org.argeo.security.core/src/org/argeo/security/login/SystemLoginModule.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/SystemLoginModule.java
@@ -13,30 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.login;
+package org.argeo.cms.internal.auth;
import java.io.IOException;
-import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
-import org.argeo.security.SecurityUtils;
+import org.argeo.cms.internal.kernel.Activator;
import org.argeo.security.core.InternalAuthentication;
import org.springframework.security.core.Authentication;
/** Login module which caches one subject per thread. */
-public class SystemLoginModule extends AbstractSpringLoginModule {
+public class SystemLoginModule extends AbstractLoginModule {
@Override
protected Authentication processLogin(CallbackHandler callbackHandler)
throws LoginException, UnsupportedCallbackException, IOException,
InterruptedException {
- BundleContextCallback bundleContextCallback = new BundleContextCallback();
- callbackHandler.handle(new Callback[] { bundleContextCallback });
- InternalAuthentication anonymousToken = new InternalAuthentication(
- SecurityUtils.getStaticKey());
- return getAuthenticationManager(bundleContextCallback).authenticate(
- anonymousToken);
+ InternalAuthentication token = new InternalAuthentication(
+ Activator.getSystemKey());
+ return getAuthenticationManager().authenticate(token);
}
}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java
index 4d166eaf6..5ec9f5087 100644
--- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java
@@ -1,15 +1,27 @@
package org.argeo.cms.internal.kernel;
+import java.util.UUID;
+
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+/**
+ * Activates the {@link Kernel} from the provided {@link BundleContext}. Gives
+ * access to kernel information for the rest of the bundle (and only it)
+ */
public class Activator implements BundleActivator {
+ private final static String systemKey = UUID.randomUUID().toString();
+
+ private static BundleContext bundleContext;
private Kernel kernel;
@Override
public void start(BundleContext context) throws Exception {
+ assert bundleContext == null;
assert kernel == null;
- kernel = new Kernel(context);
+
+ bundleContext = context;
+ kernel = new Kernel(bundleContext);
kernel.init();
}
@@ -17,6 +29,23 @@ public class Activator implements BundleActivator {
public void stop(BundleContext context) throws Exception {
kernel.destroy();
kernel = null;
+ bundleContext = null;
+ }
+
+ /**
+ * Singleton interface to the {@link BundleContext} related to the calling
+ * thread. Can be used only within the CMS bundle.
+ */
+ public static BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ /**
+ * @return a String which is guaranteed to be unique between and constant
+ * within a Java static context (typically a VM launch)
+ */
+ public final static String getSystemKey() {
+ return systemKey;
}
}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java
index d0aec2023..13f48f369 100644
--- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java
@@ -8,12 +8,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
import org.argeo.cms.internal.useradmin.JcrUserAdmin;
-import org.argeo.security.SecurityUtils;
+import org.argeo.cms.internal.useradmin.SimpleJcrSecurityModel;
+import org.argeo.cms.internal.useradmin.jackrabbit.JackrabbitUserAdminService;
import org.argeo.security.UserAdminService;
import org.argeo.security.core.InternalAuthentication;
import org.argeo.security.core.InternalAuthenticationProvider;
-import org.argeo.security.jcr.SimpleJcrSecurityModel;
-import org.argeo.security.jcr.jackrabbit.JackrabbitUserAdminService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.useradmin.UserAdmin;
@@ -52,9 +51,9 @@ class NodeSecurity implements AuthenticationManager {
this.bundleContext = bundleContext;
internalAuth = new InternalAuthenticationProvider(
- SecurityUtils.getStaticKey());
+ Activator.getSystemKey());
anonymousAuth = new AnonymousAuthenticationProvider(
- SecurityUtils.getStaticKey());
+ Activator.getSystemKey());
// user admin
userAdminService = new JackrabbitUserAdminService();
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg
index 55194eab8..cc1a07499 100644
--- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg
+++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg
@@ -1,15 +1,15 @@
USER {
- org.argeo.security.login.EndUserLoginModule requisite;
+ org.argeo.cms.internal.auth.EndUserLoginModule requisite;
org.springframework.security.authentication.jaas.SecurityContextLoginModule requisite;
};
ANONYMOUS {
- org.argeo.security.login.AnonymousLoginModule requisite;
+ org.argeo.cms.internal.auth.AnonymousLoginModule requisite;
org.springframework.security.authentication.jaas.SecurityContextLoginModule requisite;
};
SYSTEM {
- org.argeo.security.login.SystemLoginModule requisite;
+ org.argeo.cms.internal.auth.SystemLoginModule requisite;
org.springframework.security.authentication.jaas.SecurityContextLoginModule requisite;
};
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrUserAdmin.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrUserAdmin.java
index 94051d92e..ecaf5e0af 100644
--- a/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrUserAdmin.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrUserAdmin.java
@@ -15,7 +15,6 @@ import org.argeo.jcr.JcrUtils;
import org.argeo.security.UserAdminService;
import org.argeo.security.jcr.JcrSecurityModel;
import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.jcr.SimpleJcrSecurityModel;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/OsJcrUserAdminService.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/OsJcrUserAdminService.java
similarity index 96%
rename from org.argeo.security.core/src/org/argeo/security/jcr/OsJcrUserAdminService.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/OsJcrUserAdminService.java
index 1eab37048..4ad2ad16d 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/OsJcrUserAdminService.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/OsJcrUserAdminService.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.jcr;
+package org.argeo.cms.internal.useradmin;
import java.util.ArrayList;
import java.util.HashSet;
@@ -26,9 +26,11 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.argeo.ArgeoException;
+import org.argeo.cms.internal.auth.OsJcrAuthenticationProvider;
import org.argeo.jcr.JcrUtils;
import org.argeo.jcr.UserJcrUtils;
import org.argeo.security.UserAdminService;
+import org.argeo.security.jcr.JcrUserDetails;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/SimpleJcrSecurityModel.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/SimpleJcrSecurityModel.java
similarity index 98%
rename from org.argeo.security.core/src/org/argeo/security/jcr/SimpleJcrSecurityModel.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/SimpleJcrSecurityModel.java
index fc0158738..029719c3a 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/SimpleJcrSecurityModel.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/SimpleJcrSecurityModel.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.jcr;
+package org.argeo.cms.internal.useradmin;
import java.util.List;
@@ -32,6 +32,7 @@ import org.argeo.jcr.ArgeoNames;
import org.argeo.jcr.ArgeoTypes;
import org.argeo.jcr.JcrUtils;
import org.argeo.jcr.UserJcrUtils;
+import org.argeo.security.jcr.JcrSecurityModel;
/**
* Manages data expected by the Argeo security model, such as user home and
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitSecurityModel.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/JackrabbitSecurityModel.java
similarity index 96%
rename from org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitSecurityModel.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/JackrabbitSecurityModel.java
index e52e6c6cb..de7f72466 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitSecurityModel.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/JackrabbitSecurityModel.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.jcr.jackrabbit;
+package org.argeo.cms.internal.useradmin.jackrabbit;
import java.util.ArrayList;
import java.util.Iterator;
@@ -30,8 +30,8 @@ import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.argeo.ArgeoException;
+import org.argeo.cms.internal.useradmin.SimpleJcrSecurityModel;
import org.argeo.jcr.ArgeoNames;
-import org.argeo.security.jcr.SimpleJcrSecurityModel;
/** Make sure that user authorizable exists before syncing user directories. */
public class JackrabbitSecurityModel extends SimpleJcrSecurityModel {
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/JackrabbitUserAdminService.java
similarity index 99%
rename from org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/JackrabbitUserAdminService.java
index aceb51612..f846e1c74 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/JackrabbitUserAdminService.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/JackrabbitUserAdminService.java
@@ -1,4 +1,4 @@
-package org.argeo.security.jcr.jackrabbit;
+package org.argeo.cms.internal.useradmin.jackrabbit;
import java.util.ArrayList;
import java.util.Arrays;
@@ -24,9 +24,9 @@ import org.argeo.jcr.JcrUtils;
import org.argeo.jcr.UserJcrUtils;
import org.argeo.security.NodeAuthenticationToken;
import org.argeo.security.UserAdminService;
+import org.argeo.cms.internal.auth.GrantedAuthorityPrincipal;
import org.argeo.security.jcr.JcrSecurityModel;
import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.login.GrantedAuthorityPrincipal;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/ScopedSessionProvider.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/ScopedSessionProvider.java
similarity index 99%
rename from org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/ScopedSessionProvider.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/ScopedSessionProvider.java
index 635f71ee2..dcb139939 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/jackrabbit/ScopedSessionProvider.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/ScopedSessionProvider.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.jcr.jackrabbit;
+package org.argeo.cms.internal.useradmin.jackrabbit;
import java.io.Serializable;
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoLdapShaPasswordEncoder.java
similarity index 96%
rename from org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoLdapShaPasswordEncoder.java
index a2c43a589..a1d25e92c 100644
--- a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoLdapShaPasswordEncoder.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.ldap;
+package org.argeo.cms.internal.useradmin.ldap;
import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoLdapUserDetailsManager.java
similarity index 98%
rename from org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoLdapUserDetailsManager.java
index 89b5aa92d..4381fa991 100644
--- a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoLdapUserDetailsManager.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.ldap;
+package org.argeo.cms.internal.useradmin.ldap;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@@ -36,6 +36,7 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.ldap.userdetails.LdapUserDetailsManager;
/** Extends {@link LdapUserDetailsManager} by adding password encoding support. */
+@SuppressWarnings("deprecation")
public class ArgeoLdapUserDetailsManager extends LdapUserDetailsManager
implements UserAdminService {
private String superUsername = "root";
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoUserAdminDaoLdap.java
similarity index 99%
rename from org.argeo.security.core/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoUserAdminDaoLdap.java
index 37d2a06a0..faead2e76 100644
--- a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/ArgeoUserAdminDaoLdap.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.ldap;
+package org.argeo.cms.internal.useradmin.ldap;
import java.util.Collections;
import java.util.List;
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/JcrLdapSynchronizer.java
similarity index 99%
rename from org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/JcrLdapSynchronizer.java
index e0519c37c..de28c7f49 100644
--- a/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/JcrLdapSynchronizer.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.ldap.jcr;
+package org.argeo.cms.internal.useradmin.ldap;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@@ -41,13 +41,13 @@ import javax.naming.directory.ModificationItem;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
+import org.argeo.cms.internal.useradmin.SimpleJcrSecurityModel;
import org.argeo.jcr.ArgeoNames;
import org.argeo.jcr.ArgeoTypes;
import org.argeo.jcr.JcrUtils;
import org.argeo.security.SecurityUtils;
import org.argeo.security.jcr.JcrSecurityModel;
import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.jcr.SimpleJcrSecurityModel;
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DirContextOperations;
@@ -60,6 +60,7 @@ import org.springframework.security.ldap.LdapUsernameToDnMapper;
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
/** Makes sure that LDAP and JCR are in line. */
+@SuppressWarnings("deprecation")
public class JcrLdapSynchronizer implements UserDetailsContextMapper,
ArgeoNames {
private final static Log log = LogFactory.getLog(JcrLdapSynchronizer.class);
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/JcrUserDetailsContextMapper.java
similarity index 98%
rename from org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java
rename to org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/JcrUserDetailsContextMapper.java
index f63250c31..acfcebc11 100644
--- a/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java
+++ b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/ldap/JcrUserDetailsContextMapper.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.ldap.jcr;
+package org.argeo.cms.internal.useradmin.ldap;
import java.util.Collection;
import java.util.UUID;
diff --git a/org.argeo.security.core/bnd.bnd b/org.argeo.security.core/bnd.bnd
index fa20c3d9e..9124816cb 100644
--- a/org.argeo.security.core/bnd.bnd
+++ b/org.argeo.security.core/bnd.bnd
@@ -2,7 +2,4 @@ Bundle-ActivationPolicy: lazy
Import-Package:org.bouncycastle.*;resolution:=optional,\
org.springframework.util,\
javax.jcr.security,\
-org.apache.jackrabbit.*;resolution:=optional,\
-org.springframework.ldap.*;resolution:=optional,\
-org.springframework.security.ldap.*;resolution:=optional,\
*
diff --git a/org.argeo.security.core/src/org/argeo/security/SecurityUtils.java b/org.argeo.security.core/src/org/argeo/security/SecurityUtils.java
index 8c6715446..2d453d3da 100644
--- a/org.argeo.security.core/src/org/argeo/security/SecurityUtils.java
+++ b/org.argeo.security.core/src/org/argeo/security/SecurityUtils.java
@@ -19,7 +19,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.UUID;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -29,19 +28,9 @@ import org.springframework.security.core.context.SecurityContextHolder;
/** Static utilities */
public final class SecurityUtils {
- private final static String systemKey = UUID.randomUUID().toString();
-
private SecurityUtils() {
}
- /**
- * @return a String which is guaranteed to be unique between and constant
- * within a Java static context (typically a VM launch)
- */
- public final static String getStaticKey() {
- return systemKey;
- }
-
/** Whether the current thread has the admin role */
public static boolean hasCurrentThreadAuthority(String authority) {
SecurityContext securityContext = SecurityContextHolder.getContext();
diff --git a/org.argeo.security.core/src/org/argeo/security/core/AbstractSystemExecution.java b/org.argeo.security.core/src/org/argeo/security/core/AbstractSystemExecution.java
index 0d075c3a6..bdd110da9 100644
--- a/org.argeo.security.core/src/org/argeo/security/core/AbstractSystemExecution.java
+++ b/org.argeo.security.core/src/org/argeo/security/core/AbstractSystemExecution.java
@@ -15,17 +15,11 @@
*/
package org.argeo.security.core;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
import org.argeo.security.SystemAuthentication;
-import org.argeo.security.login.BundleContextCallbackHandler;
-import org.osgi.framework.BundleContext;
import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -45,9 +39,7 @@ public abstract class AbstractSystemExecution {
private final static Log log = LogFactory
.getLog(AbstractSystemExecution.class);
private AuthenticationManager authenticationManager;
- private BundleContext bundleContext;
private String systemAuthenticationKey;
- private String loginContextName = "SYSTEM";
/** Whether the current thread was authenticated by this component. */
private ThreadLocal authenticatedBySelf = new ThreadLocal() {
@@ -85,24 +77,12 @@ public abstract class AbstractSystemExecution {
InternalAuthentication.SYSTEM_KEY_DEFAULT);
if (key == null)
throw new ArgeoException("No system key defined");
- if (authenticationManager != null) {
- Authentication auth = authenticationManager
- .authenticate(new InternalAuthentication(key));
- securityContext.setAuthentication(auth);
- } else {
- try {
- // TODO test this
- if (bundleContext == null)
- throw new ArgeoException("bundleContext must be set");
- BundleContextCallbackHandler callbackHandler = new BundleContextCallbackHandler(
- bundleContext);
- LoginContext loginContext = new LoginContext(loginContextName,
- callbackHandler);
- loginContext.login();
- } catch (LoginException e) {
- throw new BadCredentialsException("Cannot authenticate");
- }
- }
+ if (authenticationManager == null)
+ throw new ArgeoException("Authentication manager cannot be null.");
+ Authentication auth = authenticationManager
+ .authenticate(new InternalAuthentication(key));
+ securityContext.setAuthentication(auth);
+
authenticatedBySelf.set(true);
if (log.isTraceEnabled())
log.trace("System authenticated");
@@ -128,20 +108,12 @@ public abstract class AbstractSystemExecution {
return authenticatedBySelf.get();
}
- @Deprecated
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
- // log.warn("This approach is deprecated, inject bundleContext instead");
this.authenticationManager = authenticationManager;
}
- @Deprecated
public void setSystemAuthenticationKey(String systemAuthenticationKey) {
this.systemAuthenticationKey = systemAuthenticationKey;
}
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
}
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/JcrSecurityModel.java b/org.argeo.security.core/src/org/argeo/security/jcr/JcrSecurityModel.java
index e9ab89c2a..a151c7f30 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/JcrSecurityModel.java
+++ b/org.argeo.security.core/src/org/argeo/security/jcr/JcrSecurityModel.java
@@ -30,7 +30,7 @@ public interface JcrSecurityModel {
* user has a home directory with full access and a profile with information
* about him (read access)
*
- * @return the user profile (whose parent is the user home), never null
+ * @return the user profile, never null
*/
public Node sync(Session session, String username, List roles);
}
diff --git a/org.argeo.security.core/src/org/argeo/security/jcr/SecureThreadBoundSession.java b/org.argeo.security.core/src/org/argeo/security/jcr/SecureThreadBoundSession.java
index 7ef15947f..e0e887a3e 100644
--- a/org.argeo.security.core/src/org/argeo/security/jcr/SecureThreadBoundSession.java
+++ b/org.argeo.security.core/src/org/argeo/security/jcr/SecureThreadBoundSession.java
@@ -27,6 +27,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
* Thread bounded JCR session factory which checks authentication and is
* autoconfigured in Spring.
*/
+@Deprecated
public class SecureThreadBoundSession extends ThreadBoundSession {
private final static Log log = LogFactory
.getLog(SecureThreadBoundSession.class);
diff --git a/org.argeo.security.core/src/org/argeo/security/login/BundleContextCallback.java b/org.argeo.security.core/src/org/argeo/security/login/BundleContextCallback.java
deleted file mode 100644
index cf32af55c..000000000
--- a/org.argeo.security.core/src/org/argeo/security/login/BundleContextCallback.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.argeo.security.login;
-
-import javax.security.auth.callback.Callback;
-
-import org.osgi.framework.BundleContext;
-
-/** Gives access to the OSGi {@link BundleContext} */
-public class BundleContextCallback implements Callback {
- private BundleContext bundleContext;
-
- public BundleContext getBundleContext() {
- return bundleContext;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
-}
diff --git a/org.argeo.security.core/src/org/argeo/security/login/BundleContextCallbackHandler.java b/org.argeo.security.core/src/org/argeo/security/login/BundleContextCallbackHandler.java
deleted file mode 100644
index 3c7f9e844..000000000
--- a/org.argeo.security.core/src/org/argeo/security/login/BundleContextCallbackHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.argeo.security.login;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.osgi.framework.BundleContext;
-
-/**
- * {@link CallbackHandler} that simply wraps a {@link BundleContext} and inject
- * it in provided {@link BundleContextCallback}
- */
-public class BundleContextCallbackHandler implements CallbackHandler {
- private BundleContext bundleContext;
-
- public BundleContextCallbackHandler() {
- }
-
- public BundleContextCallbackHandler(BundleContext bundleContext) {
- super();
- this.bundleContext = bundleContext;
- }
-
- @Override
- public void handle(Callback[] callbacks) throws IOException,
- UnsupportedCallbackException {
- for (Callback callback : callbacks) {
- if (callback instanceof BundleContextCallback)
- ((BundleContextCallback) callback)
- .setBundleContext(bundleContext);
- }
-
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
-}
diff --git a/org.argeo.security.ui.rap/.classpath b/org.argeo.security.ui.rap/.classpath
index d2953a684..f9f1a39d8 100644
--- a/org.argeo.security.ui.rap/.classpath
+++ b/org.argeo.security.ui.rap/.classpath
@@ -4,6 +4,6 @@
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7" />
diff --git a/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java b/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java
index 65657dc66..9b01c5525 100644
--- a/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java
+++ b/org.argeo.security.ui.rap/src/org/argeo/security/ui/rap/SecureEntryPoint.java
@@ -18,6 +18,8 @@ package org.argeo.security.ui.rap;
import java.security.PrivilegedAction;
import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.CredentialNotFoundException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
@@ -27,9 +29,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
import org.argeo.cms.KernelHeader;
+import org.argeo.cms.auth.ArgeoLoginContext;
import org.argeo.eclipse.ui.workbench.ErrorFeedback;
-import org.argeo.security.login.LoginCanceledException;
-import org.argeo.security.ui.dialogs.DefaultLoginDialog;
+import org.argeo.security.ui.auth.DefaultLoginDialog;
import org.argeo.util.LocaleUtils;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.rap.rwt.RWT;
@@ -94,12 +96,14 @@ public class SecureEntryPoint implements EntryPoint {
Subject subject = new Subject();
// log in
- Thread.currentThread().setContextClassLoader(
- getClass().getClassLoader());
+ // Thread.currentThread().setContextClassLoader(
+ // getClass().getClassLoader());
final LoginContext loginContext;
try {
- loginContext = new LoginContext(KernelHeader.LOGIN_CONTEXT_USER,
- subject, new DefaultLoginDialog(display.getActiveShell()));
+ CallbackHandler callbackHandler = new DefaultLoginDialog(
+ display.getActiveShell());
+ loginContext = new ArgeoLoginContext(
+ KernelHeader.LOGIN_CONTEXT_USER, subject, callbackHandler);
} catch (LoginException e1) {
throw new ArgeoException("Cannot initialize login context", e1);
}
@@ -119,7 +123,8 @@ public class SecureEntryPoint implements EntryPoint {
httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
SecurityContextHolder.getContext());
// add thread locale to RWT session
- log.info("Locale " + LocaleUtils.threadLocale.get());
+ if (log.isTraceEnabled())
+ log.trace("Locale " + LocaleUtils.threadLocale.get());
RWT.setLocale(LocaleUtils.threadLocale.get());
// Once the user is logged in, longer session timeout
@@ -201,7 +206,7 @@ public class SecureEntryPoint implements EntryPoint {
if (t instanceof BadCredentialsException)
return (BadCredentialsException) t;
- if (t instanceof LoginCanceledException)
+ if (t instanceof CredentialNotFoundException)
return new BadCredentialsException("Login canceled");
if (t.getCause() != null)
diff --git a/org.argeo.security.ui/src/org/argeo/security/ui/SecurityUiPlugin.java b/org.argeo.security.ui/src/org/argeo/security/ui/SecurityUiPlugin.java
index ad5b36203..a4190d69a 100644
--- a/org.argeo.security.ui/src/org/argeo/security/ui/SecurityUiPlugin.java
+++ b/org.argeo.security.ui/src/org/argeo/security/ui/SecurityUiPlugin.java
@@ -22,7 +22,7 @@ import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.argeo.ArgeoException;
-import org.argeo.security.ui.dialogs.DefaultLoginDialog;
+import org.argeo.security.ui.auth.DefaultLoginDialog;
import org.eclipse.swt.widgets.Display;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -44,7 +44,7 @@ public class SecurityUiPlugin implements BundleActivator {
// The plug-in ID
public final static String PLUGIN_ID = "org.argeo.security.ui"; //$NON-NLS-1$
- public final static String CONTEXT_KEYRING = "KEYRING";
+ final static String CONTEXT_KEYRING = "KEYRING";
private CallbackHandler defaultCallbackHandler;
private ServiceRegistration defaultCallbackHandlerReg;
diff --git a/org.argeo.security.ui/src/org/argeo/security/ui/dialogs/AbstractLoginDialog.java b/org.argeo.security.ui/src/org/argeo/security/ui/auth/AbstractLoginDialog.java
similarity index 93%
rename from org.argeo.security.ui/src/org/argeo/security/ui/dialogs/AbstractLoginDialog.java
rename to org.argeo.security.ui/src/org/argeo/security/ui/auth/AbstractLoginDialog.java
index 8a8d1f66d..107697e75 100644
--- a/org.argeo.security.ui/src/org/argeo/security/ui/dialogs/AbstractLoginDialog.java
+++ b/org.argeo.security.ui/src/org/argeo/security/ui/auth/AbstractLoginDialog.java
@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.argeo.security.ui.dialogs;
+package org.argeo.security.ui.auth;
import java.io.IOException;
+import java.util.Arrays;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
@@ -158,9 +159,15 @@ public abstract class AbstractLoginDialog extends TrayDialog implements
else
// clear callbacks are when cancelling
for (Callback callback : callbacks)
- if (callback instanceof PasswordCallback)
- ((PasswordCallback) callback).setPassword(null);
- else if (callback instanceof NameCallback)
+ if (callback instanceof PasswordCallback) {
+ char[] arr = ((PasswordCallback) callback)
+ .getPassword();
+ if (arr != null) {
+ Arrays.fill(arr, '*');
+ ((PasswordCallback) callback)
+ .setPassword(null);
+ }
+ } else if (callback instanceof NameCallback)
((NameCallback) callback).setName(null);
}
}, true, new NullProgressMonitor(), Display.getDefault());
diff --git a/org.argeo.security.ui/src/org/argeo/security/ui/auth/CompositeCallbackHandler.java b/org.argeo.security.ui/src/org/argeo/security/ui/auth/CompositeCallbackHandler.java
new file mode 100644
index 000000000..a2fc83162
--- /dev/null
+++ b/org.argeo.security.ui/src/org/argeo/security/ui/auth/CompositeCallbackHandler.java
@@ -0,0 +1,291 @@
+package org.argeo.security.ui.auth;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.TextOutputCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.argeo.util.LocaleCallback;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A composite that can populate itself based on {@link Callback}s. It can be
+ * used directly as a {@link CallbackHandler} or be used by one by calling the
+ * {@link #createCallbackHandlers(Callback[])}.
+ *
+ * Supported standard {@link Callback}s are:
+ *
+ * - {@link PasswordCallback}
+ * - {@link NameCallback}
+ * - {@link TextOutputCallback}
+ *
+ *
+ *
+ * Supported Argeo {@link Callback}s are:
+ *
+ * - {@link LocaleCallback}
+ *
+ *
+ */
+public class CompositeCallbackHandler extends Composite implements
+ CallbackHandler {
+ private static final long serialVersionUID = -928223893722723777L;
+
+ private boolean wasUsedAlready = false;
+ private boolean isSubmitted = false;
+ private boolean isCanceled = false;
+
+ public CompositeCallbackHandler(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ @Override
+ public synchronized void handle(final Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ // reset
+ if (wasUsedAlready && !isSubmitted() && !isCanceled()) {
+ cancel();
+ for (Control control : getChildren())
+ control.dispose();
+ isSubmitted = false;
+ isCanceled = false;
+ }
+
+ for (Callback callback : callbacks)
+ checkCallbackSupported(callback);
+ // create controls synchronously in the UI thread
+ getDisplay().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ createCallbackHandlers(callbacks);
+ }
+ });
+
+ if (!wasUsedAlready)
+ wasUsedAlready = true;
+
+ while (!isSubmitted() && !isCanceled()) {
+ try {
+ wait(1000l);
+ } catch (InterruptedException e) {
+ // silent
+ }
+ }
+
+ cleanCallbacksAfterCancel(callbacks);
+ }
+
+ public void checkCallbackSupported(Callback callback)
+ throws UnsupportedCallbackException {
+ if (callback instanceof TextOutputCallback
+ || callback instanceof NameCallback
+ || callback instanceof PasswordCallback
+ || callback instanceof LocaleCallback) {
+ return;
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+
+ /**
+ * Set writable callbacks to null if the handle is canceled (check is done
+ * by the method)
+ */
+ public void cleanCallbacksAfterCancel(Callback[] callbacks) {
+ if (isCanceled()) {
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback) {
+ ((NameCallback) callback).setName(null);
+ } else if (callback instanceof PasswordCallback) {
+ PasswordCallback pCallback = (PasswordCallback) callback;
+ char[] arr = pCallback.getPassword();
+ if (arr != null) {
+ Arrays.fill(arr, '*');
+ pCallback.setPassword(null);
+ }
+ }
+ }
+ }
+ }
+
+ public void createCallbackHandlers(Callback[] callbacks) {
+ Composite composite = this;
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof TextOutputCallback) {
+ createLabelTextoutputHandler(composite,
+ (TextOutputCallback) callback);
+ } else if (callback instanceof NameCallback) {
+ createNameHandler(composite, (NameCallback) callback);
+ } else if (callback instanceof PasswordCallback) {
+ createPasswordHandler(composite, (PasswordCallback) callback);
+ } else if (callback instanceof LocaleCallback) {
+ createLocaleHandler(composite, (LocaleCallback) callback);
+ }
+ }
+ }
+
+ protected Text createNameHandler(Composite composite,
+ final NameCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+ final Text text = new Text(composite, SWT.SINGLE | SWT.LEAD
+ | SWT.BORDER);
+ if (callback.getDefaultName() != null) {
+ // set default value, if provided
+ text.setText(callback.getDefaultName());
+ callback.setName(callback.getDefaultName());
+ }
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ text.addModifyListener(new ModifyListener() {
+ private static final long serialVersionUID = 7300032545287292973L;
+
+ public void modifyText(ModifyEvent event) {
+ callback.setName(text.getText());
+ }
+ });
+ text.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = 1820530045857665111L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ submit();
+ }
+ });
+
+ text.addKeyListener(new KeyListener() {
+ private static final long serialVersionUID = -8698107785092095713L;
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ }
+ });
+ return text;
+ }
+
+ protected Text createPasswordHandler(Composite composite,
+ final PasswordCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+ final Text passwordText = new Text(composite, SWT.SINGLE | SWT.LEAD
+ | SWT.PASSWORD | SWT.BORDER);
+ passwordText
+ .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ passwordText.addModifyListener(new ModifyListener() {
+ private static final long serialVersionUID = -7099363995047686732L;
+
+ public void modifyText(ModifyEvent event) {
+ callback.setPassword(passwordText.getTextChars());
+ }
+ });
+ passwordText.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = 1820530045857665111L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ submit();
+ }
+ });
+ return passwordText;
+ }
+
+ protected Combo createLocaleHandler(Composite composite,
+ final LocaleCallback callback) {
+ String[] labels = callback.getSupportedLocalesLabels();
+ if (labels.length == 0)
+ return null;
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+
+ final Combo combo = new Combo(composite, SWT.READ_ONLY);
+ combo.setItems(labels);
+ combo.select(callback.getDefaultIndex());
+ combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ combo.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = 38678989091946277L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ callback.setSelectedIndex(combo.getSelectionIndex());
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+ return combo;
+ }
+
+ protected Label createLabelTextoutputHandler(Composite composite,
+ final TextOutputCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getMessage());
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+ return label;
+ // TODO: find a way to pass this information
+ // int messageType = callback.getMessageType();
+ // int dialogMessageType = IMessageProvider.NONE;
+ // switch (messageType) {
+ // case TextOutputCallback.INFORMATION:
+ // dialogMessageType = IMessageProvider.INFORMATION;
+ // break;
+ // case TextOutputCallback.WARNING:
+ // dialogMessageType = IMessageProvider.WARNING;
+ // break;
+ // case TextOutputCallback.ERROR:
+ // dialogMessageType = IMessageProvider.ERROR;
+ // break;
+ // }
+ // setMessage(callback.getMessage(), dialogMessageType);
+ }
+
+ synchronized boolean isSubmitted() {
+ return isSubmitted;
+ }
+
+ synchronized boolean isCanceled() {
+ return isCanceled;
+ }
+
+ protected synchronized void submit() {
+ isSubmitted = true;
+ notifyAll();
+ }
+
+ protected synchronized void cancel() {
+ isCanceled = true;
+ notifyAll();
+ }
+}
diff --git a/org.argeo.security.ui/src/org/argeo/security/ui/auth/DefaultLoginDialog.java b/org.argeo.security.ui/src/org/argeo/security/ui/auth/DefaultLoginDialog.java
new file mode 100644
index 000000000..85f90bd3f
--- /dev/null
+++ b/org.argeo.security.ui/src/org/argeo/security/ui/auth/DefaultLoginDialog.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.security.ui.auth;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/** Default authentication dialog, to be used as {@link CallbackHandler}. */
+public class DefaultLoginDialog extends AbstractLoginDialog {
+ private static final long serialVersionUID = -8551827590693035734L;
+
+ public DefaultLoginDialog() {
+ this(SecurityUiPlugin.display.get().getActiveShell());
+ }
+
+ public DefaultLoginDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ protected Point getInitialSize() {
+ return new Point(350, 180);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Control control = super.createContents(parent);
+ parent.pack();
+
+ // Move the dialog to the center of the top level shell.
+ Rectangle shellBounds;
+ if (Display.getCurrent().getActiveShell() != null) // RCP
+ shellBounds = Display.getCurrent().getActiveShell().getBounds();
+ else
+ shellBounds = Display.getCurrent().getBounds();// RAP
+ Point dialogSize = parent.getSize();
+ int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+ int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+ parent.setLocation(x, y);
+ return control;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ CompositeCallbackHandler composite = new CompositeCallbackHandler(
+ dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ composite.createCallbackHandlers(getCallbacks());
+ return composite;
+ }
+
+ public void internalHandle() {
+ }
+}
diff --git a/org.argeo.security.ui/src/org/argeo/security/ui/dialogs/DefaultLoginDialog.java b/org.argeo.security.ui/src/org/argeo/security/ui/dialogs/DefaultLoginDialog.java
deleted file mode 100644
index 3dea95bf9..000000000
--- a/org.argeo.security.ui/src/org/argeo/security/ui/dialogs/DefaultLoginDialog.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.security.ui.dialogs;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.TextOutputCallback;
-
-import org.argeo.security.login.BundleContextCallback;
-import org.argeo.security.ui.SecurityUiPlugin;
-import org.argeo.util.LocaleCallback;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/** Default authentication dialog, to be used as {@link CallbackHandler}. */
-public class DefaultLoginDialog extends AbstractLoginDialog {
- private static final long serialVersionUID = -8551827590693035734L;
-
- public DefaultLoginDialog() {
- this(SecurityUiPlugin.display.get().getActiveShell());
- }
-
- public DefaultLoginDialog(Shell parentShell) {
- super(parentShell);
- }
-
- protected Point getInitialSize() {
- return new Point(350, 180);
- }
-
- @Override
- protected Control createContents(Composite parent) {
- Control control = super.createContents(parent);
- parent.pack();
-
- // Move the dialog to the center of the top level shell.
- Rectangle shellBounds;
- if (Display.getCurrent().getActiveShell() != null) // RCP
- shellBounds = Display.getCurrent().getActiveShell().getBounds();
- else
- shellBounds = Display.getCurrent().getBounds();// RAP
- Point dialogSize = parent.getSize();
- int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
- int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
- parent.setLocation(x, y);
- return control;
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- createCallbackHandlers(composite);
- // parent.pack();
- return composite;
- }
-
- private void createCallbackHandlers(Composite composite) {
- Callback[] callbacks = getCallbacks();
- for (int i = 0; i < callbacks.length; i++) {
- Callback callback = callbacks[i];
- if (callback instanceof TextOutputCallback) {
- createLabelTextoutputHandler(composite,
- (TextOutputCallback) callback);
- } else if (callback instanceof NameCallback) {
- createNameHandler(composite, (NameCallback) callback);
- } else if (callback instanceof PasswordCallback) {
- createPasswordHandler(composite, (PasswordCallback) callback);
- } else if (callback instanceof LocaleCallback) {
- createLocaleHandler(composite, (LocaleCallback) callback);
- } else if (callback instanceof BundleContextCallback) {
- ((BundleContextCallback) callback)
- .setBundleContext(SecurityUiPlugin.getBundleContext());
- }
- }
- }
-
- private void createPasswordHandler(Composite composite,
- final PasswordCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
- final Text passwordText = new Text(composite, SWT.SINGLE | SWT.LEAD
- | SWT.PASSWORD | SWT.BORDER);
- passwordText
- .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- passwordText.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = -7099363995047686732L;
-
- public void modifyText(ModifyEvent event) {
- // FIXME use getTextChars() in Eclipse 3.7
- callback.setPassword(passwordText.getText().toCharArray());
- }
- });
- }
-
- private void createLocaleHandler(Composite composite,
- final LocaleCallback callback) {
- String[] labels = callback.getSupportedLocalesLabels();
- if (labels.length == 0)
- return;
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
-
- final Combo combo = new Combo(composite, SWT.READ_ONLY);
- combo.setItems(labels);
- combo.select(callback.getDefaultIndex());
- combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- combo.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = 38678989091946277L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- callback.setSelectedIndex(combo.getSelectionIndex());
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
- }
-
- private void createNameHandler(Composite composite,
- final NameCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
- final Text text = new Text(composite, SWT.SINGLE | SWT.LEAD
- | SWT.BORDER);
- if (callback.getDefaultName() != null) {
- // set default value, if provided
- text.setText(callback.getDefaultName());
- callback.setName(callback.getDefaultName());
- }
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- text.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = 7300032545287292973L;
-
- public void modifyText(ModifyEvent event) {
- callback.setName(text.getText());
- }
- });
- }
-
- private void createLabelTextoutputHandler(Composite composite,
- final TextOutputCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getMessage());
- GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
- data.horizontalSpan = 2;
- label.setLayoutData(data);
- // TODO: find a way to pass this information
- // int messageType = callback.getMessageType();
- // int dialogMessageType = IMessageProvider.NONE;
- // switch (messageType) {
- // case TextOutputCallback.INFORMATION:
- // dialogMessageType = IMessageProvider.INFORMATION;
- // break;
- // case TextOutputCallback.WARNING:
- // dialogMessageType = IMessageProvider.WARNING;
- // break;
- // case TextOutputCallback.ERROR:
- // dialogMessageType = IMessageProvider.ERROR;
- // break;
- // }
- // setMessage(callback.getMessage(), dialogMessageType);
- }
-
- public void internalHandle() {
- }
-}
diff --git a/org.argeo.server.jcr/ext/test/org/argeo/jcr/MapperTest.java b/org.argeo.server.jcr/ext/test/org/argeo/jcr/MapperTest.java
index 5486ff458..8f4599cd6 100644
--- a/org.argeo.server.jcr/ext/test/org/argeo/jcr/MapperTest.java
+++ b/org.argeo.server.jcr/ext/test/org/argeo/jcr/MapperTest.java
@@ -19,6 +19,7 @@ import javax.jcr.Node;
import org.argeo.jcr.spring.BeanNodeMapper;
+@Deprecated
public class MapperTest extends AbstractInternalJackrabbitTestCase {
public void testSimpleObject() throws Exception {
SimpleObject mySo = new SimpleObject();
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java
index 53a9ff1e2..c1addf162 100644
--- a/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java
+++ b/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java
@@ -58,6 +58,7 @@ import org.springframework.core.io.ResourceLoader;
* Wrapper around a Jackrabbit repository which allows to simplify configuration
* and intercept some actions. It exposes itself as a {@link Repository}.
*/
+@SuppressWarnings("deprecation")
public class JackrabbitWrapper extends JcrRepositoryWrapper implements
ResourceLoaderAware {
private final static Log log = LogFactory.getLog(JackrabbitWrapper.class);
@@ -170,8 +171,8 @@ public class JackrabbitWrapper extends JcrRepositoryWrapper implements
String oldDigest = JcrUtils.checksumFile(dataModel,
DIGEST_ALGORITHM);
if (oldDigest.equals(newDigest)) {
- if (log.isDebugEnabled())
- log.debug("Data model " + resUrl
+ if (log.isTraceEnabled())
+ log.trace("Data model " + resUrl
+ " hasn't changed, keeping version "
+ currentVersion);
return;
@@ -313,8 +314,8 @@ public class JackrabbitWrapper extends JcrRepositoryWrapper implements
resUrl = resUrl.substring(1);
String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/',
'.');
- ServiceReference paSr = bundleContext
- .getServiceReference(PackageAdmin.class.getName());
+ ServiceReference paSr = bundleContext
+ .getServiceReference(PackageAdmin.class);
PackageAdmin packageAdmin = (PackageAdmin) bundleContext
.getService(paSr);
diff --git a/org.argeo.server.jcr/src/org/argeo/jcr/JcrUtils.java b/org.argeo.server.jcr/src/org/argeo/jcr/JcrUtils.java
index 2176e757c..3b546684a 100644
--- a/org.argeo.server.jcr/src/org/argeo/jcr/JcrUtils.java
+++ b/org.argeo.server.jcr/src/org/argeo/jcr/JcrUtils.java
@@ -1415,7 +1415,6 @@ public class JcrUtils implements ArgeoJcrConstants {
* files
* @return how many files were copied
*/
- @SuppressWarnings("resource")
public static Long copyFiles(Node fromNode, Node toNode, Boolean recursive,
ArgeoMonitor monitor) {
long count = 0l;
--
2.39.2