Bundle-SymbolicName: org.argeo.cms;singleton=true
Bundle-Activator: org.argeo.cms.internal.kernel.Activator
-Import-Package: org.springframework.core,\
-org.springframework.dao,\
-javax.jcr.security,\
+Import-Package: javax.jcr.security,\
org.xml.sax,\
org.argeo.jcr,\
-org.springframework.context,\
-org.springframework.security.authentication.jaas,\
org.apache.jackrabbit.api,\
org.apache.jackrabbit.commons,\
org.apache.jackrabbit.core.security.user,\
org.postgresql;resolution:=optional,\
org.apache.commons.vfs2.*;resolution:=optional,\
org.apache.jackrabbit.*;resolution:=optional,\
-org.springframework.ldap.*;resolution:=optional,\
-org.springframework.security.ldap.*;resolution:=optional,\
-org.springframework.security.provisioning;resolution:=optional,\
org.joda.time.*;resolution:=optional,\
+org.springframework.context,\
+org.springframework.core.io,\
*
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.io.IOException;
-import java.util.Map;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.cms.internal.kernel.Activator;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.widgets.Display;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
-
-/** Login module which caches one subject per thread. */
-public abstract class AbstractLoginModule implements LoginModule {
- /**
- * From org.springframework.security.context.
- * HttpSessionContextIntegrationFilter
- */
- private final static String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
-
- private final static Log log = LogFactory.getLog(AbstractLoginModule.class);
- private CallbackHandler callbackHandler;
- private Subject subject;
-
- private Authentication authentication;
-
- // state
- private BundleContext bundleContext;
- private ServiceReference<AuthenticationManager> authenticationManager;
-
- protected abstract Authentication processLogin(
- CallbackHandler callbackHandler) throws LoginException,
- UnsupportedCallbackException, IOException, InterruptedException;
-
- @Override
- public void initialize(Subject subject, CallbackHandler callbackHandler,
- Map<String, ?> sharedState, Map<String, ?> options) {
- this.callbackHandler = callbackHandler;
- this.subject = subject;
- this.bundleContext = Activator.getBundleContext();
- this.authenticationManager = bundleContext
- .getServiceReference(AuthenticationManager.class);
- }
-
- @Override
- public boolean login() throws LoginException {
- try {
- Authentication currentAuth = SecurityContextHolder.getContext()
- .getAuthentication();
-
- if (currentAuth == null) {
- // Pre-auth
- // TODO Do it at Spring Security level?
- try {
- // try to load authentication from session
- HttpServletRequest httpRequest = RWT.getRequest();
- HttpSession httpSession = httpRequest.getSession();
- // log.debug(httpSession.getId());
- Object contextFromSessionObject = httpSession
- .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
- if (contextFromSessionObject != null) {
- currentAuth = (Authentication) contextFromSessionObject;
- SecurityContextHolder.getContext().setAuthentication(
- currentAuth);
- }
- } catch (Exception e) {
- if (log.isTraceEnabled())
- log.trace("Could not get session", e);
- // silent
- }
- }
-
- // thread already logged in
- if (currentAuth != null) {
- if (subject.getPrincipals(Authentication.class).size() == 0) {
- // throw new LoginException(
- // "Security context set but not Authentication principal");
- } else {
- Authentication principal = subject
- .getPrincipals(Authentication.class).iterator()
- .next();
- if (principal != currentAuth)
- throw new LoginException(
- "Already authenticated with a different auth");
- }
- return true;
- }
-
- // if (callbackHandler == null)
- // throw new LoginException("No callback handler available");
-
- authentication = processLogin(callbackHandler);
- if (authentication != null) {
- //
- // SET THE AUTHENTICATION
- //
- SecurityContext securityContext = SecurityContextHolder
- .getContext();
- securityContext.setAuthentication(authentication);
- try {
- HttpServletRequest httpRequest = RWT.getRequest();
- HttpSession httpSession = httpRequest.getSession();
- if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null)
- httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
- authentication);
- } catch (Exception e) {
- if (log.isTraceEnabled())
- log.trace("Could not add security context to session",
- e);
- }
- return true;
- } else {
- throw new LoginException("No authentication returned");
- }
- } catch (LoginException e) {
- throw e;
- } catch (ThreadDeath e) {
- LoginException le = new LoginException(
- "Spring Security login thread died");
- le.initCause(e);
- throw le;
- } catch (Exception e) {
- LoginException le = new LoginException(
- "Spring Security login failed");
- le.initCause(e);
- throw le;
- }
- }
-
- @Override
- public boolean logout() throws LoginException {
- SecurityContextHolder.getContext().setAuthentication(null);
- if (Display.getCurrent() != null) {
- HttpServletRequest httpRequest = RWT.getRequest();
- if (httpRequest != null) {
- HttpSession httpSession = httpRequest.getSession();
- if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) != null)
- httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, null);
- // expire session
- httpSession.setMaxInactiveInterval(0);
- }
- }
- return true;
- }
-
- @Override
- public boolean commit() throws LoginException {
- return true;
- }
-
- @Override
- public boolean abort() throws LoginException {
- SecurityContextHolder.getContext().setAuthentication(null);
- return true;
- }
-
- /**
- * 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;
- }
-
- AuthenticationManager getAuthenticationManager() {
- BundleContext bc = getBundleContext();
- assert authenticationManager != null;
- return bc.getService(authenticationManager);
- }
-
- protected Subject getSubject() {
- return subject;
- }
-}
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-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.cms.KernelHeader;
-import org.argeo.cms.internal.kernel.Activator;
-import org.argeo.util.LocaleCallback;
-import org.argeo.util.LocaleUtils;
-import org.springframework.security.authentication.AnonymousAuthenticationToken;
-import org.springframework.security.core.Authentication;
-
-/** Login module which caches one subject per thread. */
-public class AnonymousLoginModule extends AbstractLoginModule {
- /** Comma separated list of locales */
- private String availableLocales = null;
-
- @Override
- protected Authentication processLogin(CallbackHandler callbackHandler)
- throws LoginException, UnsupportedCallbackException, IOException,
- InterruptedException {
- Locale selectedLocale = null;
- // multi locale
- if (callbackHandler != null)
- if (availableLocales != null && !availableLocales.trim().equals("")) {
- LocaleCallback localeCallback = new LocaleCallback(
- availableLocales);
- callbackHandler.handle(new Callback[] { localeCallback });
- selectedLocale = localeCallback.getSelectedLocale();
- } else {
- callbackHandler.handle(new Callback[] {});
- }
-
- List<GrantedAuthorityPrincipal> authorities = Collections
- .singletonList(new GrantedAuthorityPrincipal(
- KernelHeader.ROLE_ANONYMOUS));
- AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
- Activator.getSystemKey(), KernelHeader.USERNAME_ANONYMOUS,
- authorities);
-
- Authentication auth = getAuthenticationManager().authenticate(
- anonymousToken);
-
- if (selectedLocale != null)
- LocaleUtils.threadLocale.set(selectedLocale);
- return auth;
- }
-}
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.io.IOException;
-import java.util.Locale;
-
-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.UnsupportedCallbackException;
-import javax.security.auth.login.CredentialNotFoundException;
-import javax.security.auth.login.LoginException;
-
-import org.argeo.security.NodeAuthenticationToken;
-import org.argeo.util.LocaleCallback;
-import org.argeo.util.LocaleUtils;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.core.Authentication;
-
-/** Authenticates an end user */
-public class EndUserLoginModule extends AbstractLoginModule {
- final static String NODE_REPO_URI = "argeo.node.repo.uri";
-
- private Long waitBetweenFailedLoginAttempts = 5 * 1000l;
-
- private Boolean remote = false;
- /** Comma separated list of locales */
- private String availableLocales = "";
-
- @Override
- protected Authentication processLogin(CallbackHandler callbackHandler)
- throws LoginException, UnsupportedCallbackException, IOException,
- InterruptedException {
- if (callbackHandler == null)
- return null;
-
- // ask for username and password
- NameCallback nameCallback = new NameCallback("User");
- PasswordCallback passwordCallback = new PasswordCallback("Password",
- false);
- final String defaultNodeUrl = System.getProperty(NODE_REPO_URI,
- "http://localhost:7070/org.argeo.jcr.webapp/remoting/node");
- NameCallback urlCallback = new NameCallback("Site URL", defaultNodeUrl);
- LocaleCallback localeCallback = new LocaleCallback(availableLocales);
- // handle callbacks
- if (remote)
- callbackHandler.handle(new Callback[] { nameCallback,
- passwordCallback, urlCallback, localeCallback });
- else
- callbackHandler.handle(new Callback[] { nameCallback,
- passwordCallback, localeCallback });
-
- Locale selectedLocale = localeCallback.getSelectedLocale();
-
- // create credentials
- final String username = nameCallback.getName();
- if (username == null || username.trim().equals(""))
- 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) {
- String url = urlCallback.getName();
- credentials = new NodeAuthenticationToken(username, password, url);
- } else {
- credentials = new NodeAuthenticationToken(username, password);
- }
-
- Authentication auth;
- try {
- auth = getAuthenticationManager().authenticate(credentials);
- } catch (BadCredentialsException e) {
- // wait between failed login attempts
- Thread.sleep(waitBetweenFailedLoginAttempts);
- throw e;
- }
-
- if (selectedLocale != null)
- LocaleUtils.threadLocale.set(selectedLocale);
-
- return auth;
- }
-
- @Override
- public boolean commit() throws LoginException {
- return super.commit();
- }
-}
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.security.Principal;
-
-import javax.security.auth.Subject;
-
-import org.springframework.security.core.GrantedAuthority;
-
-/**
- * A {@link Principal} which is also a {@link GrantedAuthority}, so that the
- * Spring Security can be used to quickly populate a {@link Subject} principals.
- */
-public final class GrantedAuthorityPrincipal implements Principal,
- GrantedAuthority {
- private static final long serialVersionUID = 6768044196343543328L;
- private final String authority;
-
- public GrantedAuthorityPrincipal(String authority) {
- this.authority = authority;
- }
-
- @Override
- public String getAuthority() {
- return authority;
- }
-
- @Override
- public String getName() {
- return authority;
- }
-
- @Override
- public int hashCode() {
- return getName().hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof GrantedAuthorityPrincipal))
- return false;
- return getName().equals(((GrantedAuthorityPrincipal) obj).getName());
- }
-
- @Override
- public String toString() {
- return "Granted Authority " + getName();
- }
-
-}
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.util.Collection;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-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.JcrUserDetails;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-/** Relies on OS to authenticate and additionally setup JCR */
-public class OsJcrAuthenticationProvider extends OsAuthenticationProvider {
- private Repository repository;
- private Session nodeSession;
-
- private UserDetails userDetails;
- private JcrSecurityModel jcrSecurityModel = new SimpleJcrSecurityModel();
-
- private final static String JVM_OSUSER = System.getProperty("user.name");
-
- public void init() {
- try {
- nodeSession = repository.login();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot initialize", e);
- }
- }
-
- public void destroy() {
- JcrUtils.logoutQuietly(nodeSession);
- }
-
- public Authentication authenticate(Authentication authentication)
- throws AuthenticationException {
- if (authentication instanceof UsernamePasswordAuthenticationToken) {
- // deal with remote access to internal server
- // FIXME very primitive and unsecure at this sSession adminSession
- // =tage
- // consider using the keyring for username / password authentication
- // or certificate
- UsernamePasswordAuthenticationToken upat = (UsernamePasswordAuthenticationToken) authentication;
- if (!upat.getPrincipal().toString().equals(JVM_OSUSER))
- throw new BadCredentialsException("Wrong credentials");
- UsernamePasswordAuthenticationToken authen = new UsernamePasswordAuthenticationToken(
- authentication.getPrincipal(),
- authentication.getCredentials(), getBaseAuthorities());
- authen.setDetails(userDetails);
- return authen;
- } else if (authentication instanceof OsAuthenticationToken) {
- OsAuthenticationToken authen = (OsAuthenticationToken) super
- .authenticate(authentication);
- try {
- // WARNING: at this stage we assume that the java properties
- // will have the same value
- Collection<? extends GrantedAuthority> authorities = getBaseAuthorities();
- String username = JVM_OSUSER;
- Node userProfile = jcrSecurityModel.sync(nodeSession, username,
- SecurityUtils.authoritiesToStringList(authorities));
- JcrUserDetails.checkAccountStatus(userProfile);
-
- userDetails = new JcrUserDetails(userProfile, authen
- .getCredentials().toString(), authorities);
- authen.setDetails(userDetails);
- return authen;
- } catch (RepositoryException e) {
- JcrUtils.discardQuietly(nodeSession);
- throw new ArgeoException(
- "Unexpected exception when synchronizing OS and JCR security ",
- e);
- }
- } else {
- throw new ArgeoException("Unsupported authentication "
- + authentication.getClass());
- }
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
- public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
- this.jcrSecurityModel = jcrSecurityModel;
- }
-
- @SuppressWarnings("rawtypes")
- public boolean supports(Class authentication) {
- return OsAuthenticationToken.class.isAssignableFrom(authentication)
- || UsernamePasswordAuthenticationToken.class
- .isAssignableFrom(authentication);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-import javax.jcr.Value;
-
-import org.argeo.ArgeoException;
-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;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-
-/** Connects to a JCR repository and delegates authentication to it. */
-public class RemoteJcrAuthenticationProvider implements AuthenticationProvider,
- ArgeoNames {
- private RepositoryFactory repositoryFactory;
- private BundleContext bundleContext;
-
- public final static String ROLE_REMOTE = "ROLE_REMOTE";
-
- public Authentication authenticate(Authentication authentication)
- throws AuthenticationException {
- NodeAuthenticationToken siteAuth = (NodeAuthenticationToken) authentication;
- String url = siteAuth.getUrl();
- if (url == null)// TODO? login on own node
- throw new ArgeoException("No url set in " + siteAuth);
- Session session;
-
- Node userProfile;
- try {
- SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
- siteAuth.getCredentials().toString().toCharArray());
- // get repository
- Repository repository = new RemoteJcrRepositoryWrapper(
- repositoryFactory, url, sp);
- if (bundleContext != null) {
- Dictionary<String, String> serviceProperties = new Hashtable<String, String>();
- serviceProperties.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS,
- ArgeoJcrConstants.ALIAS_NODE);
- serviceProperties
- .put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
- bundleContext.registerService(Repository.class.getName(),
- repository, serviceProperties);
- }
- // Repository repository = ArgeoJcrUtils.getRepositoryByUri(
- // repositoryFactory, url);
- // if (repository == null)
- // throw new ArgeoException("Cannot connect to " + url);
-
- session = repository.login(sp, null);
-
- userProfile = UserJcrUtils.getUserProfile(session, sp.getUserID());
- JcrUserDetails.checkAccountStatus(userProfile);
-
- // Node userHome = UserJcrUtils.getUserHome(session);
- // if (userHome == null ||
- // !userHome.hasNode(ArgeoNames.ARGEO_PROFILE))
- // throw new ArgeoException("No profile for user "
- // + siteAuth.getName() + " in security workspace "
- // + siteAuth.getSecurityWorkspace() + " of "
- // + siteAuth.getUrl());
- // userProfile = userHome.getNode(ArgeoNames.ARGEO_PROFILE);
- } catch (RepositoryException e) {
- throw new BadCredentialsException(
- "Cannot authenticate " + siteAuth, e);
- }
-
- try {
- // Node userHome = UserJcrUtils.getUserHome(session);
- // retrieve remote roles
- List<GrantedAuthority> authoritiesList = new ArrayList<GrantedAuthority>();
- if (userProfile != null
- && userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
- Value[] roles = userProfile.getProperty(
- ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
- for (int i = 0; i < roles.length; i++)
- authoritiesList.add(new SimpleGrantedAuthority(roles[i]
- .getString()));
- }
- authoritiesList.add(new SimpleGrantedAuthority(ROLE_REMOTE));
-
- // create authenticated objects
- // GrantedAuthority[] authorities = authoritiesList
- // .toArray(new GrantedAuthority[authoritiesList.size()]);
- JcrUserDetails userDetails = new JcrUserDetails(userProfile,
- siteAuth.getCredentials().toString(), authoritiesList);
- NodeAuthenticationToken authenticated = new NodeAuthenticationToken(
- siteAuth, authoritiesList);
- authenticated.setDetails(userDetails);
- return authenticated;
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected exception when authenticating to " + url, e);
- }
- }
-
- @SuppressWarnings("rawtypes")
- public boolean supports(Class authentication) {
- return NodeAuthenticationToken.class.isAssignableFrom(authentication);
- }
-
- public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
- this.repositoryFactory = repositoryFactory;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
-}
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.login.LoginException;
-
-import org.argeo.security.OsAuthenticationToken;
-import org.springframework.security.core.Authentication;
-
-/** Login module which caches one subject per thread. */
-public class SingleUserLoginModule extends AbstractLoginModule {
- @Override
- protected Authentication processLogin(CallbackHandler callbackHandler)
- throws LoginException, UnsupportedCallbackException, IOException,
- InterruptedException {
- OsAuthenticationToken token = new OsAuthenticationToken();
- return getAuthenticationManager().authenticate(token);
- }
-}
+++ /dev/null
-/*
- * 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.cms.internal.auth;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.login.LoginException;
-
-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 AbstractLoginModule {
- @Override
- protected Authentication processLogin(CallbackHandler callbackHandler)
- throws LoginException, UnsupportedCallbackException, IOException,
- InterruptedException {
- InternalAuthentication token = new InternalAuthentication(
- Activator.getSystemKey());
- return getAuthenticationManager().authenticate(token);
- }
-}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.security.SystemAuthentication;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
* access to kernel information for the rest of the bundle (and only it)
*/
public class Activator implements BundleActivator {
+ public final static String SYSTEM_KEY_PROPERTY = "argeo.security.systemKey";
private final Log log = LogFactory.getLog(Activator.class);
private final static String systemKey;
static {
systemKey = UUID.randomUUID().toString();
- System.setProperty(SystemAuthentication.SYSTEM_KEY_PROPERTY, systemKey);
+ System.setProperty(SYSTEM_KEY_PROPERTY, systemKey);
}
private static BundleContext bundleContext;
import org.argeo.cms.internal.transaction.SimpleTransactionManager;
import org.argeo.jackrabbit.OsgiJackrabbitRepositoryFactory;
import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.security.core.InternalAuthentication;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
-import org.springframework.security.core.context.SecurityContextHolder;
/**
* Argeo CMS Kernel. Responsible for :
Thread.currentThread().setContextClassLoader(
Kernel.class.getClassLoader());
long begin = System.currentTimeMillis();
- InternalAuthentication initAuth = new InternalAuthentication(
- KernelConstants.DEFAULT_SECURITY_KEY);
- SecurityContextHolder.getContext().setAuthentication(initAuth);
try {
// Transaction
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.useradmin.UserAdmin;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
/** Authentication and user management. */
-class NodeSecurity implements AuthenticationManager {
+class NodeSecurity {
private final static Log log;
static {
log = LogFactory.getLog(NodeSecurity.class);
private final NodeUserAdmin userAdmin;
private final Subject kernelSubject;
- private ServiceRegistration<AuthenticationManager> authenticationManagerReg;
-
private ServiceRegistration<UserAdmin> userAdminReg;
public NodeSecurity(BundleContext bundleContext) {
public void publish() {
userAdminReg = bundleContext.registerService(UserAdmin.class,
userAdmin, userAdmin.currentState());
- // dummy auth manager, in order to smooth transition from Argeo 1
- authenticationManagerReg = bundleContext.registerService(
- AuthenticationManager.class, this, null);
- }
+ }
void destroy() {
- authenticationManagerReg.unregister();
-
userAdmin.destroy();
userAdminReg.unregister();
return kernelSubject;
}
- @Override
- public Authentication authenticate(Authentication authentication)
- throws AuthenticationException {
- log.error("Authentication manager is deprecated and should not be used.");
- throw new ProviderNotFoundException(
- "Authentication manager is deprecated and should not be used.");
- }
-
private void createKeyStoreIfNeeded() {
char[] ksPwd = "changeit".toCharArray();
char[] keyPwd = Arrays.copyOf(ksPwd, ksPwd.length);
+++ /dev/null
-package org.argeo.cms.internal.useradmin;
-
-import java.util.Dictionary;
-
-import org.argeo.cms.CmsException;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-
-abstract class AbstractJcrUser extends JcrRole implements User {
- public AbstractJcrUser(String name) {
- super(name);
- }
-
- @Override
- public int getType() {
- return Role.USER;
- }
-
- @Override
- public Dictionary<String, Object> getCredentials() {
- throw new CmsException("Not implemented yet");
- }
-
- @Override
- public boolean hasCredential(String key, Object value) {
- throw new CmsException("Not implemented yet");
- }
-
-}
+++ /dev/null
-package org.argeo.cms.internal.useradmin;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.osgi.service.useradmin.Authorization;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-class JcrAuthorization implements Authorization {
- private final String name;
- private final List<String> roles;
-
- public JcrAuthorization(UserDetails userDetails) {
- this.name = userDetails.getUsername();
- List<String> t = new ArrayList<String>();
- for (GrantedAuthority ga : userDetails.getAuthorities()) {
- t.add(ga.getAuthority());
- }
- roles = Collections.unmodifiableList(t);
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public boolean hasRole(String name) {
- return roles.contains(name);
- }
-
- @Override
- public String[] getRoles() {
- return roles.toArray(new String[roles.size()]);
- }
-
-}
+++ /dev/null
-package org.argeo.cms.internal.useradmin;
-
-import org.argeo.security.jcr.JcrUserDetails;
-import org.springframework.security.core.userdetails.UserDetails;
-
-class JcrEndUser extends AbstractJcrUser {
- private final JcrUserDetails userDetails;
-
- public JcrEndUser(JcrUserDetails userDetails) {
- super(userDetails.getUsername());
- this.userDetails = userDetails;
- }
-
- UserDetails getUserDetails() {
- return userDetails;
- }
-
- public String toString() {
- return "ArgeoUser: " + getName();
- }
-
- public boolean equals(Object obj) {
- if (!(obj instanceof JcrEndUser))
- return false;
- else
- return ((JcrEndUser) obj).getName().equals(getName());
- }
-
- public int hashCode() {
- return getName().hashCode();
- }
-
-}
+++ /dev/null
-package org.argeo.cms.internal.useradmin;
-
-import org.argeo.cms.CmsException;
-import org.osgi.service.useradmin.Group;
-import org.osgi.service.useradmin.Role;
-
-class JcrGroup extends AbstractJcrUser implements Group {
- public JcrGroup(String name) {
- super(name);
- }
-
- //
- // OSGi MODEL
- //
- @Override
- public int getType() {
- return Role.GROUP;
- }
-
- @Override
- public boolean addMember(Role role) {
- throw new CmsException("Not implemented yet");
- }
-
- @Override
- public boolean addRequiredMember(Role role) {
- throw new CmsException("Not implemented yet");
- }
-
- @Override
- public boolean removeMember(Role role) {
- throw new CmsException("Not implemented yet");
- }
-
- @Override
- public Role[] getMembers() {
- throw new CmsException("Not implemented yet");
- }
-
- @Override
- public Role[] getRequiredMembers() {
- throw new CmsException("Not implemented yet");
- }
-
- public String toString() {
- return "ArgeoGroup: " + getName();
- }
-
- public boolean equals(Object obj) {
- if (!(obj instanceof JcrGroup))
- return false;
- else
- return ((JcrGroup) obj).getName().equals(getName());
- }
-
- public int hashCode() {
- return getName().hashCode();
- }
-
-}
+++ /dev/null
-package org.argeo.cms.internal.useradmin;
-
-import java.util.Dictionary;
-
-import org.osgi.service.useradmin.Role;
-
-abstract class JcrRole implements Role {
- private String name;
-
- public JcrRole(String name) {
- this.name = name;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public int getType() {
- return Role.ROLE;
- }
-
- @Override
- public Dictionary<String, Object> getProperties() {
- return new JcrRoleProperties();
- }
-
-}
+++ /dev/null
-package org.argeo.cms.internal.useradmin;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-
-import org.argeo.cms.CmsException;
-
-/** Empty for the time being */
-class JcrRoleProperties extends Dictionary<String, Object> {
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public boolean isEmpty() {
- return true;
- }
-
- @Override
- public Enumeration<String> keys() {
- return new KeyEnumeration();
- }
-
- @Override
- public Enumeration<Object> elements() {
- return new ValueEnumeration();
- }
-
- @Override
- public Object get(Object key) {
- return null;
- }
-
- @Override
- public Object put(String key, Object value) {
- throw new CmsException("Not implemented yet");
- }
-
- @Override
- public Object remove(Object key) {
- return null;
- }
-
- private class KeyEnumeration implements Enumeration<String> {
-
- @Override
- public boolean hasMoreElements() {
- return false;
- }
-
- @Override
- public String nextElement() {
- return null;
- }
-
- }
-
- private class ValueEnumeration implements Enumeration<Object> {
-
- @Override
- public boolean hasMoreElements() {
- return false;
- }
-
- @Override
- public Object nextElement() {
- return null;
- }
-
- }
-}
+++ /dev/null
-package org.argeo.cms.internal.useradmin;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jcr.Repository;
-import javax.jcr.Session;
-
-import org.argeo.ArgeoException;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.internal.useradmin.jackrabbit.JackrabbitUserAdminService;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.jcr.NewUserDetails;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.useradmin.Authorization;
-import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.service.useradmin.UserAdminEvent;
-import org.osgi.service.useradmin.UserAdminListener;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-
-/**
- * Incomplete implementation of {@link UserAdmin} wrapping the supported
- * {@link UserAdminService} for the time being.
- */
-public class JcrUserAdmin implements UserAdmin {
- private final BundleContext bundleContext;
- private JackrabbitUserAdminService userAdminService;
-
- private final Session session;
-
- public JcrUserAdmin(BundleContext bundleContext, Repository node) {
- try {
- this.bundleContext = bundleContext;
- this.session = node.login();
- } catch (Exception e) {
- throw new ArgeoException("Cannot initialize user admin", e);
- }
- }
-
- public void destroy() {
- JcrUtils.logoutQuietly(session);
- }
-
- @Override
- public Role createRole(String name, int type) {
- if (Role.USER == type) {
- NewUserDetails userDetails = new NewUserDetails(name, null);
- userAdminService().createUser(userDetails);
- return new JcrEndUser((JcrUserDetails) userAdminService()
- .loadUserByUsername(name));
- } else if (Role.GROUP == type) {
- userAdminService().newRole(name);
- return new JcrGroup(name);
- } else {
- throw new ArgeoException("Unsupported role type " + type);
- }
- }
-
- @Override
- public boolean removeRole(String name) {
- Role role = getRole(name);
- if (role == null)
- return false;
- if (role instanceof JcrEndUser)
- userAdminService().deleteUser(role.getName());
- else if (role instanceof JcrGroup)
- userAdminService().deleteRole(role.getName());
- else
- return false;
- return true;
- }
-
- @Override
- public Role getRole(String name) {
- try {
- JcrUserDetails userDetails = (JcrUserDetails) userAdminService()
- .loadUserByUsername(name);
- return new JcrEndUser(userDetails);
- } catch (UsernameNotFoundException e) {
- if (userAdminService().listEditableRoles().contains(name))
- return new JcrGroup(name);
- else
- return null;
- }
- }
-
- @Override
- public Role[] getRoles(String filter) throws InvalidSyntaxException {
- if (filter != null)
- throw new ArgeoException("Filtering not yet implemented");
- List<String> roles = new ArrayList<String>(userAdminService()
- .listEditableRoles());
- List<String> users = new ArrayList<String>(userAdminService()
- .listUsers());
- Role[] res = new Role[users.size() + roles.size()];
- for (int i = 0; i < roles.size(); i++)
- res[i] = new JcrGroup(roles.get(i));
- for (int i = 0; i < users.size(); i++)
- res[roles.size() + i] = new JcrEndUser(
- (JcrUserDetails) userAdminService().loadUserByUsername(
- users.get(i)));
- return res;
- }
-
- @Override
- public User getUser(String key, String value) {
- throw new CmsException("Property based search not yet implemented");
- }
-
- @Override
- public Authorization getAuthorization(User user) {
- return new JcrAuthorization(((JcrEndUser) user).getUserDetails());
- }
-
- private synchronized UserAdminService userAdminService() {
- return userAdminService;
- }
-
- public void setUserAdminService(JackrabbitUserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-
- protected synchronized void notifyEvent(UserAdminEvent event) {
- try {
- Collection<ServiceReference<UserAdminListener>> sr = bundleContext
- .getServiceReferences(UserAdminListener.class, null);
- for (Iterator<ServiceReference<UserAdminListener>> it = sr
- .iterator(); it.hasNext();) {
- UserAdminListener listener = bundleContext
- .getService(it.next());
- listener.roleChanged(event);
- }
- } catch (InvalidSyntaxException e) {
- throw new ArgeoException("Cannot notify listeners", e);
- }
- }
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-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;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-
-/**
- * Dummy user service to be used when running as a single OS user (typically
- * desktop). TODO integrate with JCR user / groups
- */
-public class OsJcrUserAdminService implements UserAdminService {
- private Repository repository;
-
- /** In memory roles provided by applications. */
- private List<String> roles = new ArrayList<String>();
-
- // private Session adminSession;
-
- public void init() {
- // try {
- // adminSession = repository.login();
- // } catch (RepositoryException e) {
- // throw new ArgeoException("Cannot initialize", e);
- // }
- }
-
- public void destroy() {
- // JcrUtils.logoutQuietly(adminSession);
- }
-
- /** <b>Unsupported</b> */
- public void createUser(UserDetails user) {
- throw new UnsupportedOperationException();
- }
-
- /** Does nothing */
- public void updateUser(UserDetails user) {
-
- }
-
- /** <b>Unsupported</b> */
- public void deleteUser(String username) {
- throw new UnsupportedOperationException();
- }
-
- /** <b>Unsupported</b> */
- public void changePassword(String oldPassword, String newPassword) {
- throw new UnsupportedOperationException();
- }
-
- public boolean userExists(String username) {
- if (getSPropertyUsername().equals(username))
- return true;
- else
- return false;
- }
-
- public UserDetails loadUserByUsername(String username)
- throws UsernameNotFoundException, DataAccessException {
- if (getSPropertyUsername().equals(username)) {
- UserDetails userDetails;
- if (repository != null) {
- Session adminSession = null;
- try {
- adminSession = repository.login();
- Node userProfile = UserJcrUtils.getUserProfile(
- adminSession, username);
- userDetails = new JcrUserDetails(userProfile, "",
- OsJcrAuthenticationProvider.getBaseAuthorities());
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Cannot retrieve user profile for " + username, e);
- } finally {
- JcrUtils.logoutQuietly(adminSession);
- }
- } else {
- userDetails = new User(username, "", true, true, true, true,
- OsJcrAuthenticationProvider.getBaseAuthorities());
- }
- return userDetails;
- } else {
- throw new UnsupportedOperationException();
- }
- }
-
- protected final String getSPropertyUsername() {
- return System.getProperty("user.name");
- }
-
- public Set<String> listUsers() {
- Set<String> set = new HashSet<String>();
- set.add(getSPropertyUsername());
- return set;
- }
-
- public Set<String> listUsersInRole(String role) {
- Set<String> set = new HashSet<String>();
- set.add(getSPropertyUsername());
- return set;
- }
-
- /** Does nothing */
- public void synchronize() {
- }
-
- /** <b>Unsupported</b> */
- public void newRole(String role) {
- roles.add(role);
- }
-
- public Set<String> listEditableRoles() {
- return new HashSet<String>(roles);
- }
-
- /** <b>Unsupported</b> */
- public void deleteRole(String role) {
- roles.remove(role);
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin;
-
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.security.Privilege;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.core.security.user.UserAccessControlProvider;
-import org.argeo.ArgeoException;
-import org.argeo.cms.internal.auth.JcrSecurityModel;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-
-/**
- * Manages data expected by the Argeo security model, such as user home and
- * profile.
- */
-public class SimpleJcrSecurityModel implements JcrSecurityModel {
- private final static Log log = LogFactory
- .getLog(SimpleJcrSecurityModel.class);
- // ArgeoNames not implemented as interface in order to ease derivation by
- // Jackrabbit bundles
-
- /** The home base path. */
- private String homeBasePath = "/home";
- private String peopleBasePath = ArgeoJcrConstants.PEOPLE_BASE_PATH;
-
- @Override
- public void init(Session adminSession) throws RepositoryException {
- JcrUtils.mkdirs(adminSession, homeBasePath);
- JcrUtils.mkdirs(adminSession, peopleBasePath);
- adminSession.save();
-
- JcrUtils.addPrivilege(adminSession, homeBasePath,
- UserAccessControlProvider.USER_ADMIN_GROUP_NAME,
- Privilege.JCR_READ);
- JcrUtils.addPrivilege(adminSession, peopleBasePath,
- UserAccessControlProvider.USER_ADMIN_GROUP_NAME,
- Privilege.JCR_ALL);
- }
-
- public synchronized Node sync(Session session, String username,
- List<String> roles) {
- // TODO check user name validity (e.g. should not start by ROLE_)
-
- try {
- Node userHome = UserJcrUtils.getUserHome(session, username);
- if (userHome == null) {
- String homePath = generateUserPath(homeBasePath, username);
- userHome = JcrUtils.mkdirs(session, homePath);
- // userHome = JcrUtils.mkfolders(session, homePath);
- userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
- userHome.setProperty(ArgeoNames.ARGEO_USER_ID, username);
- session.save();
-
- JcrUtils.clearAccessControList(session, homePath, username);
- JcrUtils.addPrivilege(session, homePath, username,
- Privilege.JCR_ALL);
- } else {
- // for backward compatibility with pre 1.0 security model
- if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE)) {
- userHome.getNode(ArgeoNames.ARGEO_PROFILE).remove();
- userHome.getSession().save();
- }
- }
-
- // Remote roles
- if (roles != null) {
- // writeRemoteRoles(userHome, roles);
- }
-
- Node userProfile = UserJcrUtils.getUserProfile(session, username);
- // new user
- if (userProfile == null) {
- String personPath = generateUserPath(peopleBasePath, username);
- Node personBase = JcrUtils.mkdirs(session, personPath);
- userProfile = personBase.addNode(ArgeoNames.ARGEO_PROFILE);
- userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
- userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username);
- userProfile.setProperty(ArgeoNames.ARGEO_ENABLED, true);
- userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED,
- true);
- userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED,
- true);
- userProfile.setProperty(
- ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED, true);
- session.save();
-
- JcrUtils.clearAccessControList(session, userProfile.getPath(),
- username);
- JcrUtils.addPrivilege(session, userProfile.getPath(), username,
- Privilege.JCR_READ);
- }
-
- // Remote roles
- if (roles != null) {
- writeRemoteRoles(userProfile, roles);
- }
- return userProfile;
- } catch (RepositoryException e) {
- JcrUtils.discardQuietly(session);
- throw new ArgeoException("Cannot sync node security model for "
- + username, e);
- }
- }
-
- /** Generate path for a new user home */
- protected String generateUserPath(String base, String username) {
- int atIndex = username.indexOf('@');
- if (atIndex > 0) {
- String domain = username.substring(0, atIndex);
- String name = username.substring(atIndex + 1);
- return base + '/' + JcrUtils.firstCharsToPath(domain, 2) + '/'
- + domain + '/' + JcrUtils.firstCharsToPath(name, 2) + '/'
- + name;
- } else if (atIndex == 0 || atIndex == (username.length() - 1)) {
- throw new ArgeoException("Unsupported username " + username);
- } else {
- return base + '/' + JcrUtils.firstCharsToPath(username, 2) + '/'
- + username;
- }
- }
-
- /** Write remote roles used by remote access in the home directory */
- protected void writeRemoteRoles(Node userHome, List<String> roles)
- throws RepositoryException {
- boolean writeRoles = false;
- if (userHome.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
- Value[] remoteRoles = userHome.getProperty(
- ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
- if (remoteRoles.length != roles.size())
- writeRoles = true;
- else
- for (int i = 0; i < remoteRoles.length; i++)
- if (!remoteRoles[i].getString().equals(roles.get(i)))
- writeRoles = true;
- } else
- writeRoles = true;
-
- if (writeRoles) {
- userHome.getSession().getWorkspace().getVersionManager()
- .checkout(userHome.getPath());
- String[] roleIds = roles.toArray(new String[roles.size()]);
- userHome.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds);
- JcrUtils.updateLastModified(userHome);
- userHome.getSession().save();
- userHome.getSession().getWorkspace().getVersionManager()
- .checkin(userHome.getPath());
- if (log.isDebugEnabled())
- log.debug("Wrote remote roles " + roles + " for "
- + userHome.getProperty(ArgeoNames.ARGEO_USER_ID));
- }
-
- }
-
- public void setHomeBasePath(String homeBasePath) {
- this.homeBasePath = homeBasePath;
- }
-
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin.jackrabbit;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.JackrabbitSession;
-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;
-
-/** Make sure that user authorizable exists before syncing user directories. */
-public class JackrabbitSecurityModel extends SimpleJcrSecurityModel {
- private final static Log log = LogFactory
- .getLog(JackrabbitSecurityModel.class);
-
- @Override
- public synchronized Node sync(Session session, String username,
- List<String> roles) {
- if (!(session instanceof JackrabbitSession))
- return super.sync(session, username, roles);
-
- try {
- UserManager userManager = ((JackrabbitSession) session)
- .getUserManager();
- User user = (User) userManager.getAuthorizable(username);
- if (user != null) {
- String principalName = user.getPrincipal().getName();
- if (!principalName.equals(username)) {
- log.warn("Jackrabbit principal is '" + principalName
- + "' but username is '" + username
- + "'. Recreating...");
- user.remove();
- user = userManager.createUser(username, "");
- }
- } else {
- // create new principal
- user = userManager.createUser(username, "");
- log.info(username + " added as Jackrabbit user " + user);
- }
-
- // generic JCR sync
- Node userProfile = super.sync(session, username, roles);
-
- Boolean enabled = userProfile.getProperty(ArgeoNames.ARGEO_ENABLED)
- .getBoolean();
- if (enabled && user.isDisabled())
- user.disable(null);
- else if (!enabled && !user.isDisabled())
- user.disable(userProfile.getPath() + " is disabled");
-
- // Sync Jackrabbit roles
- if (roles != null)
- syncRoles(userManager, user, roles);
-
- return userProfile;
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Cannot perform Jackrabbit specific operations", e);
- }
- }
-
- /** Make sure Jackrabbit roles are in line with authentication */
- void syncRoles(UserManager userManager, User user, List<String> roles)
- throws RepositoryException {
- List<String> userGroupIds = new ArrayList<String>();
- for (String role : roles) {
- Group group = (Group) userManager.getAuthorizable(role);
- if (group == null) {
- group = userManager.createGroup(role);
- log.info(role + " added as " + group);
- }
- if (!group.isMember(user))
- group.addMember(user);
- userGroupIds.add(role);
- }
-
- // check if user has not been removed from some groups
- for (Iterator<Group> it = user.declaredMemberOf(); it.hasNext();) {
- Group group = it.next();
- if (!userGroupIds.contains(group.getID()))
- group.removeMember(user);
- }
- }
-}
+++ /dev/null
-package org.argeo.cms.internal.useradmin.jackrabbit;
-
-import static org.argeo.cms.KernelHeader.ROLE_ADMIN;
-import static org.argeo.cms.KernelHeader.USERNAME_ADMIN;
-import static org.argeo.cms.KernelHeader.USERNAME_DEMO;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-import javax.jcr.version.VersionManager;
-
-import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.security.user.Authorizable;
-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.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials;
-import org.apache.jackrabbit.core.security.user.UserAccessControlProvider;
-import org.argeo.ArgeoException;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.KernelHeader;
-import org.argeo.cms.internal.auth.GrantedAuthorityPrincipal;
-import org.argeo.cms.internal.auth.JcrSecurityModel;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.security.NodeAuthenticationToken;
-import org.argeo.security.SecurityUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.jcr.NewUserDetails;
-import org.springframework.dao.DataAccessException;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-
-/**
- * An implementation of {@link UserAdminService} which closely wraps Jackrabbits
- * implementation. Roles are implemented with Groups.
- */
-public class JackrabbitUserAdminService implements UserAdminService,
- AuthenticationProvider {
- private final static String JACKR_ADMINISTRATORS = "administrators";
- private final static String REP_PRINCIPAL_NAME = "rep:principalName";
- // private final static String REP_PASSWORD = "rep:password";
-
- private Repository repository;
- private JcrSecurityModel securityModel;
-
- private JackrabbitSession adminSession = null;
-
- private String initialPassword = "demo";
-
- public void init() throws RepositoryException {
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- authentication.getName();
- adminSession = (JackrabbitSession) repository.login();
- Authorizable adminGroup = getUserManager().getAuthorizable(ROLE_ADMIN);
- if (adminGroup == null) {
- adminGroup = getUserManager().createGroup(ROLE_ADMIN);
- adminSession.save();
- }
-
- // create superuser
- Authorizable superUser = getUserManager().getAuthorizable(
- USERNAME_ADMIN);
- if (superUser == null) {
- superUser = getUserManager().createUser(USERNAME_ADMIN,
- initialPassword);
- ((Group) adminGroup).addMember(superUser);
- securityModel.sync(adminSession, USERNAME_ADMIN, null);
- adminSession.save();
-
- // create demo user only at initialisation
- Authorizable demoUser = getUserManager().getAuthorizable(
- USERNAME_DEMO);
- if (demoUser != null)
- throw new CmsException("There is already a demo user");
- demoUser = getUserManager().createUser(USERNAME_DEMO,
- initialPassword);
- securityModel.sync(adminSession, USERNAME_DEMO, null);
- adminSession.save();
- }
- securityModel.init(adminSession);
- }
-
- public void destroy() throws RepositoryException {
- JcrUtils.logoutQuietly(adminSession);
- }
-
- private UserManager getUserManager() throws RepositoryException {
- return adminSession.getUserManager();
- }
-
- @Override
- public void createUser(UserDetails user) {
- try {
- // if (getUserManager().getAuthorizable(user.getUsername()) == null)
- // {
- getUserManager().createUser(user.getUsername(), user.getPassword());
- Node userProfile = securityModel.sync(adminSession,
- user.getUsername(), null);
- if (user instanceof NewUserDetails)
- ((NewUserDetails) user).mapToProfileNode(userProfile);
- userProfile.getSession().save();
-
- // check in node
- VersionManager versionManager = userProfile.getSession()
- .getWorkspace().getVersionManager();
- if (versionManager.isCheckedOut(userProfile.getPath()))
- versionManager.checkin(userProfile.getPath());
- // }
- updateUser(user);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot create user " + user, e);
- }
- }
-
- @Override
- public void updateUser(UserDetails userDetails) {
- try {
- String username = userDetails.getUsername();
- User user = (User) getUserManager().getAuthorizable(username);
- if (user == null)
- throw new ArgeoException("No user " + userDetails.getUsername());
-
- // new password
- String newPassword = userDetails.getPassword();
- if (!newPassword.trim().equals("")) {
- if (newPassword.startsWith("{SHA-256}")) {
- // Already hashed password
- throw new CmsException("Cannot import hashed password");
- // Value v = adminSession.getValueFactory().createValue(
- // newPassword);
- // user.setProperty(REP_PASSWORD, v);
- // TODO find a way to deal w/ protected property
- // see
- // http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/core/security/user/UserImporter.html
- } else {
- SimpleCredentials sp = new SimpleCredentials(
- userDetails.getUsername(),
- newPassword.toCharArray());
- CryptedSimpleCredentials credentials = (CryptedSimpleCredentials) user
- .getCredentials();
-
- if (!credentials.matches(sp))
- user.changePassword(new String(newPassword));
- }
- }
-
- List<String> roles = new ArrayList<String>();
- for (GrantedAuthority ga : userDetails.getAuthorities()) {
- if (ga.getAuthority().equals(KernelHeader.ROLE_USER))
- continue;
- roles.add(ga.getAuthority());
- }
-
- groups: for (Iterator<Group> it = user.memberOf(); it.hasNext();) {
- Group group = it.next();
- String groupName = group.getPrincipal().getName();
- String role = groupNameToRole(groupName);
- if (role == null)
- continue groups;
-
- if (roles.contains(role))
- roles.remove(role);
- else {
- group.removeMember(user);
- if (role.equals(KernelHeader.ROLE_ADMIN)) {
- Group administratorsGroup = ((Group) getUserManager()
- .getAuthorizable(JACKR_ADMINISTRATORS));
- if (administratorsGroup.isDeclaredMember(user))
- administratorsGroup.removeMember(user);
- }
- }
- }
-
- // remaining (new memberships)
- for (String role : roles) {
- String groupName = roleToGroupName(role);
- Group group = (Group) getUserManager().getAuthorizable(
- groupName);
- if (group == null)
- throw new ArgeoException("Group " + role
- + " does not exist,"
- + " whereas it was granted to user " + userDetails);
- group.addMember(user);
-
- // add to Jackrabbit administrators
- if (role.equals(KernelHeader.ROLE_ADMIN)) {
- Group administratorsGroup = (Group) getUserManager()
- .getAuthorizable(JACKR_ADMINISTRATORS);
- administratorsGroup.addMember(user);
- }
-
- }
- } catch (Exception e) {
- throw new ArgeoException("Cannot update user details", e);
- }
-
- }
-
- @Override
- public void deleteUser(String username) {
- try {
- getUserManager().getAuthorizable(username).remove();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot remove user " + username, e);
- }
- }
-
- @Override
- public void changePassword(String oldPassword, String newPassword) {
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- String username = authentication.getName();
- try {
- SimpleCredentials sp = new SimpleCredentials(username,
- oldPassword.toCharArray());
- User user = (User) getUserManager().getAuthorizable(username);
- CryptedSimpleCredentials credentials = (CryptedSimpleCredentials) user
- .getCredentials();
- if (credentials.matches(sp))
- user.changePassword(newPassword);
- else
- throw new BadCredentialsException("Bad credentials provided");
- } catch (Exception e) {
- throw new ArgeoException("Cannot change password for user "
- + username, e);
- }
- }
-
- @Override
- public boolean userExists(String username) {
- try {
- Authorizable authorizable = getUserManager().getAuthorizable(
- username);
- if (authorizable != null && authorizable instanceof User)
- return true;
- return false;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot check whether user " + username
- + " exists ", e);
- }
- }
-
- @Override
- public Set<String> listUsers() {
- LinkedHashSet<String> res = new LinkedHashSet<String>();
- try {
- Iterator<Authorizable> users = getUserManager().findAuthorizables(
- "rep:principalName", null, UserManager.SEARCH_TYPE_USER);
- while (users.hasNext()) {
- res.add(users.next().getPrincipal().getName());
- }
- return res;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot list users", e);
- }
- }
-
- @Override
- public Set<String> listUsersInRole(String role) {
- LinkedHashSet<String> res = new LinkedHashSet<String>();
- try {
- Group group = (Group) getUserManager().getAuthorizable(role);
- Iterator<Authorizable> users = group.getMembers();
- // NB: not recursive
- while (users.hasNext()) {
- res.add(users.next().getPrincipal().getName());
- }
- return res;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot list users in role " + role, e);
- }
- }
-
- @Override
- public void synchronize() {
- }
-
- @Override
- public void newRole(String role) {
- try {
- getUserManager().createGroup(role);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot create role " + role, e);
- }
- }
-
- @Override
- public Set<String> listEditableRoles() {
- LinkedHashSet<String> res = new LinkedHashSet<String>();
- try {
- Iterator<Authorizable> groups = getUserManager().findAuthorizables(
- REP_PRINCIPAL_NAME, null, UserManager.SEARCH_TYPE_GROUP);
- while (groups.hasNext()) {
- Group group = (Group) groups.next();
- String groupName = group.getPrincipal().getName();
- String role = groupNameToRole(groupName);
- if (role != null
- && !role.equals(KernelHeader.ROLE_GROUP_ADMIN)
- && !(role.equals(KernelHeader.ROLE_ADMIN) && !SecurityUtils
- .hasCurrentThreadAuthority(KernelHeader.ROLE_ADMIN)))
- res.add(role);
- }
- return res;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot list groups", e);
- }
- }
-
- @Override
- public void deleteRole(String role) {
- try {
- getUserManager().getAuthorizable(role).remove();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot remove role " + role, e);
- }
- }
-
- protected String roleToGroupName(String role) {
- String groupName;
- if (role.equals(KernelHeader.ROLE_USER_ADMIN))
- groupName = UserAccessControlProvider.USER_ADMIN_GROUP_NAME;
- else if (role.equals(KernelHeader.ROLE_GROUP_ADMIN))
- groupName = UserAccessControlProvider.GROUP_ADMIN_GROUP_NAME;
- else
- groupName = role;
- return groupName;
- }
-
- protected String groupNameToRole(String groupName) {
- String role;
- if (groupName.equals(UserAccessControlProvider.USER_ADMIN_GROUP_NAME)) {
- role = KernelHeader.ROLE_USER_ADMIN;
- } else if (groupName
- .equals(UserAccessControlProvider.GROUP_ADMIN_GROUP_NAME)) {
- role = KernelHeader.ROLE_GROUP_ADMIN;
- } else if (groupName.equals(JACKR_ADMINISTRATORS)) {
- return null;
- } else {
- role = groupName;
- }
- return role;
- }
-
- @Override
- public UserDetails loadUserByUsername(String username)
- throws UsernameNotFoundException, DataAccessException {
- try {
- User user = (User) getUserManager().getAuthorizable(username);
- if (user == null)
- throw new UsernameNotFoundException("User " + username
- + " cannot be found");
- return loadJcrUserDetails(adminSession, username);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot load user " + username, e);
- }
- }
-
- protected JcrUserDetails loadJcrUserDetails(Session session, String username)
- throws RepositoryException {
- if (username == null)
- username = session.getUserID();
- User user = (User) getUserManager().getAuthorizable(username);
-
- ArrayList<GrantedAuthorityPrincipal> authorities = new ArrayList<GrantedAuthorityPrincipal>();
- authorities.add(new GrantedAuthorityPrincipal(KernelHeader.ROLE_USER));
-
- Group adminGroup = (Group) getUserManager().getAuthorizable(
- KernelHeader.ROLE_ADMIN);
-
- Iterator<? extends Authorizable> groups;
- if (username.equals(KernelHeader.USERNAME_ADMIN)
- || adminGroup.isDeclaredMember(user)) {
- groups = getUserManager().findAuthorizables(REP_PRINCIPAL_NAME,
- null, UserManager.SEARCH_TYPE_GROUP);
- } else {
- groups = user.declaredMemberOf();
- }
-
- while (groups.hasNext()) {
- Authorizable group = groups.next();
- String groupName = group.getPrincipal().getName();
- String role = groupNameToRole(groupName);
- if (role != null)
- authorities.add(new GrantedAuthorityPrincipal(role));
- }
-
- Node userProfile = UserJcrUtils.getUserProfile(session, username);
- JcrUserDetails userDetails = new JcrUserDetails(userProfile, "",
- authorities);
- return userDetails;
- }
-
- // AUTHENTICATION PROVIDER
- public synchronized Authentication authenticate(
- Authentication authentication) throws AuthenticationException {
- NodeAuthenticationToken siteAuth = (NodeAuthenticationToken) authentication;
- String username = siteAuth.getName();
- if (!(siteAuth.getCredentials() instanceof char[]))
- throw new ArgeoException("Only char array passwords are supported");
- char[] password = (char[]) siteAuth.getCredentials();
- try {
- SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
- password);
- User user = (User) getUserManager().getAuthorizable(username);
- if (user == null)
- throw new BadCredentialsException("Bad credentials");
- CryptedSimpleCredentials credentials = (CryptedSimpleCredentials) user
- .getCredentials();
- // String providedPassword = siteAuth.getCredentials().toString();
- if (!credentials.matches(sp))
- throw new BadCredentialsException("Bad credentials");
-
- // session = repository.login(sp, null);
-
- Node userProfile = UserJcrUtils.getUserProfile(adminSession,
- username);
- JcrUserDetails.checkAccountStatus(userProfile);
- } catch (BadCredentialsException e) {
- throw e;
- } catch (Exception e) {
- throw new BadCredentialsException(
- "Cannot authenticate " + siteAuth, e);
- } finally {
- Arrays.fill(password, '*');
- }
-
- try {
- JcrUserDetails userDetails = loadJcrUserDetails(adminSession,
- username);
- NodeAuthenticationToken authenticated = new NodeAuthenticationToken(
- siteAuth, userDetails.getAuthorities());
- authenticated.setDetails(userDetails);
- return authenticated;
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected exception when authenticating " + siteAuth, e);
- }
- }
-
- @SuppressWarnings("rawtypes")
- public boolean supports(Class authentication) {
- return UsernamePasswordAuthenticationToken.class
- .isAssignableFrom(authentication);
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
- public void setSecurityModel(JcrSecurityModel securityModel) {
- this.securityModel = securityModel;
- }
-
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin.jackrabbit;
-
-import java.io.Serializable;
-
-import javax.jcr.LoginException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.JcrUtils;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-
-/**
- * Session provider assuming a single workspace and a short life cycle,
- * typically a Spring bean of scope (web) 'session'.
- */
-public class ScopedSessionProvider implements SessionProvider, Serializable {
- private static final long serialVersionUID = 6589775984177317058L;
- private static final Log log = LogFactory
- .getLog(ScopedSessionProvider.class);
- private transient HttpSession httpSession = null;
- private transient Session jcrSession = null;
-
- private transient String currentRepositoryName = null;
- private transient String currentWorkspaceName = null;
- private transient String currentJcrUser = null;
-
- // private transient String anonymousUserId = "anonymous";
-
- public Session getSession(HttpServletRequest request, Repository rep,
- String workspace) throws LoginException, ServletException,
- RepositoryException {
-
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- if (authentication == null)
- throw new ArgeoException(
- "Request not authenticated by Spring Security");
- String springUser = authentication.getName();
-
- // HTTP
- String requestJcrRepository = (String) request
- .getAttribute(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
-
- // HTTP session
- if (httpSession != null
- && !httpSession.getId().equals(request.getSession().getId()))
- throw new ArgeoException(
- "Only session scope is supported in this mode");
- if (httpSession == null)
- httpSession = request.getSession();
-
- // Initializes current values
- if (currentRepositoryName == null)
- currentRepositoryName = requestJcrRepository;
- if (currentWorkspaceName == null)
- currentWorkspaceName = workspace;
- if (currentJcrUser == null)
- currentJcrUser = springUser;
-
- // logout if there was a change in session coordinates
- if (jcrSession != null)
- if (!currentRepositoryName.equals(requestJcrRepository)) {
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from repository '"
- + currentRepositoryName + "' to '"
- + requestJcrRepository
- + "', logging out cached JCR session.");
- logout();
- } else if (!currentWorkspaceName.equals(workspace)) {
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from workspace '"
- + currentWorkspaceName + "' to '" + workspace
- + "', logging out cached JCR session.");
- logout();
- } else if (!currentJcrUser.equals(springUser)) {
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from user '"
- + currentJcrUser + "' to '" + springUser
- + "', logging out cached JCR session.");
- logout();
- }
-
- // login if needed
- if (jcrSession == null)
- try {
- Session session = login(rep, workspace);
- if (!session.getUserID().equals(springUser)) {
- JcrUtils.logoutQuietly(session);
- throw new ArgeoException("Spring Security user '"
- + springUser + "' not in line with JCR user '"
- + session.getUserID() + "'");
- }
- currentRepositoryName = requestJcrRepository;
- // do not use workspace variable which may be null
- currentWorkspaceName = session.getWorkspace().getName();
- currentJcrUser = session.getUserID();
-
- jcrSession = session;
- return jcrSession;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot open session to workspace "
- + workspace, e);
- }
-
- // returns cached session
- return jcrSession;
- }
-
- protected Session login(Repository repository, String workspace)
- throws RepositoryException {
- Session session = repository.login(workspace);
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " User '" + session.getUserID()
- + "' logged in workspace '"
- + session.getWorkspace().getName() + "' of repository '"
- + currentRepositoryName + "'");
- return session;
- }
-
- public void releaseSession(Session session) {
- if (log.isTraceEnabled())
- log.trace(getHttpSessionId() + " Releasing JCR session " + session);
- }
-
- protected void logout() {
- JcrUtils.logoutQuietly(jcrSession);
- jcrSession = null;
- }
-
- protected final String getHttpSessionId() {
- return httpSession != null ? httpSession.getId() : "<null>";
- }
-
- public void init() {
- }
-
- public void destroy() {
- logout();
- if (getHttpSessionId() != null)
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId()
- + " Cleaned up provider for web session ");
- httpSession = null;
- }
-
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin.ldap;
-
-import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
-
-/**
- * {@link LdapShaPasswordEncoder} allowing to configure the usage of salt (APache
- * Directory Server 1.0 does not support bind with SSHA)
- */
-public class ArgeoLdapShaPasswordEncoder extends LdapShaPasswordEncoder {
- private Boolean useSalt = true;
-
- @Override
- public String encodePassword(String rawPass, Object salt) {
- return super.encodePassword(rawPass, useSalt ? salt : null);
- }
-
- public void setUseSalt(Boolean useSalt) {
- this.useSalt = useSalt;
- }
-
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin.ldap;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.argeo.ArgeoException;
-import org.argeo.security.UserAdminService;
-import org.springframework.ldap.core.ContextSource;
-import org.springframework.security.authentication.encoding.PasswordEncoder;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-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";
- private ArgeoUserAdminDaoLdap userAdminDao;
- private PasswordEncoder passwordEncoder;
- private final Random random;
-
- public ArgeoLdapUserDetailsManager(ContextSource contextSource) {
- super(contextSource);
- this.random = createRandom();
- }
-
- private static Random createRandom() {
- try {
- return SecureRandom.getInstance("SHA1PRNG");
- } catch (NoSuchAlgorithmException e) {
- return new Random(System.currentTimeMillis());
- }
- }
-
- @Override
- public void changePassword(String oldPassword, String newPassword) {
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- if (authentication == null)
- throw new ArgeoException(
- "Cannot change password without authentication");
- String username = authentication.getName();
- UserDetails userDetails = loadUserByUsername(username);
- String currentPassword = userDetails.getPassword();
- if (currentPassword == null)
- throw new ArgeoException("Cannot access current password");
- if (!passwordEncoder
- .isPasswordValid(currentPassword, oldPassword, null))
- throw new ArgeoException("Old password invalid");
- // Spring Security LDAP 2.0 is buggy when used with OpenLDAP and called
- // with oldPassword argument
- super.changePassword(null, encodePassword(newPassword));
- }
-
- public void newRole(String role) {
- userAdminDao.createRole(role, superUsername);
- }
-
- public void synchronize() {
- for (String username : userAdminDao.listUsers())
- loadUserByUsername(username);
- // TODO: find a way to remove from JCR
- }
-
- public void deleteRole(String role) {
- userAdminDao.deleteRole(role);
- }
-
- public Set<String> listUsers() {
- return userAdminDao.listUsers();
- }
-
- public Set<String> listUsersInRole(String role) {
- Set<String> lst = new TreeSet<String>(
- userAdminDao.listUsersInRole(role));
- Iterator<String> it = lst.iterator();
- while (it.hasNext()) {
- if (it.next().equals(superUsername)) {
- it.remove();
- break;
- }
- }
- return lst;
- }
-
- public List<String> listUserRoles(String username) {
- UserDetails userDetails = loadUserByUsername(username);
- List<String> roles = new ArrayList<String>();
- for (GrantedAuthority ga : userDetails.getAuthorities()) {
- roles.add(ga.getAuthority());
- }
- return Collections.unmodifiableList(roles);
- }
-
- public Set<String> listEditableRoles() {
- return userAdminDao.listEditableRoles();
- }
-
- protected String encodePassword(String password) {
- if (!password.startsWith("{")) {
- byte[] salt = new byte[16];
- random.nextBytes(salt);
- return passwordEncoder.encodePassword(password, salt);
- } else {
- return password;
- }
- }
-
- public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
- this.passwordEncoder = passwordEncoder;
- }
-
- public void setSuperUsername(String superUsername) {
- this.superUsername = superUsername;
- }
-
- public void setUserAdminDao(ArgeoUserAdminDaoLdap userAdminDao) {
- this.userAdminDao = userAdminDao;
- }
-
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin.ldap;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-
-import org.springframework.ldap.core.ContextExecutor;
-import org.springframework.ldap.core.ContextMapper;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.ldap.core.LdapTemplate;
-import org.springframework.ldap.core.support.BaseLdapPathContextSource;
-import org.springframework.security.ldap.LdapUsernameToDnMapper;
-import org.springframework.security.ldap.LdapUtils;
-
-/**
- * Wraps low-level LDAP operation on user and roles, used by
- * {@link ArgeoLdapUserDetailsManager}
- */
-public class ArgeoUserAdminDaoLdap {
- private String userBase;
- private String usernameAttribute;
- private String groupBase;
- private String[] groupClasses;
-
- private String groupRoleAttribute;
- private String groupMemberAttribute;
- private String defaultRole;
- private String rolePrefix;
-
- private final LdapTemplate ldapTemplate;
- private LdapUsernameToDnMapper usernameMapper;
-
- /**
- * Standard constructor, using the LDAP context source shared with Spring
- * Security components.
- */
- public ArgeoUserAdminDaoLdap(BaseLdapPathContextSource contextSource) {
- this.ldapTemplate = new LdapTemplate(contextSource);
- }
-
- @SuppressWarnings("unchecked")
- public synchronized Set<String> listUsers() {
- List<String> usernames = (List<String>) ldapTemplate.listBindings(
- new DistinguishedName(userBase), new ContextMapper() {
- public Object mapFromContext(Object ctxArg) {
- DirContextAdapter ctx = (DirContextAdapter) ctxArg;
- return ctx.getStringAttribute(usernameAttribute);
- }
- });
-
- return Collections
- .unmodifiableSortedSet(new TreeSet<String>(usernames));
- }
-
- @SuppressWarnings("unchecked")
- public Set<String> listEditableRoles() {
- return Collections.unmodifiableSortedSet(new TreeSet<String>(
- ldapTemplate.listBindings(groupBase, new ContextMapper() {
- public Object mapFromContext(Object ctxArg) {
- String groupName = ((DirContextAdapter) ctxArg)
- .getStringAttribute(groupRoleAttribute);
- String roleName = convertGroupToRole(groupName);
- return roleName;
- }
- })));
- }
-
- @SuppressWarnings("unchecked")
- public Set<String> listUsersInRole(String role) {
- return (Set<String>) ldapTemplate.lookup(
- buildGroupDn(convertRoleToGroup(role)), new ContextMapper() {
- public Object mapFromContext(Object ctxArg) {
- DirContextAdapter ctx = (DirContextAdapter) ctxArg;
- String[] userDns = ctx
- .getStringAttributes(groupMemberAttribute);
- TreeSet<String> set = new TreeSet<String>();
- for (String userDn : userDns) {
- DistinguishedName dn = new DistinguishedName(userDn);
- String username = dn.getValue(usernameAttribute);
- set.add(username);
- }
- return Collections.unmodifiableSortedSet(set);
- }
- });
- }
-
- public void createRole(String role, final String superuserName) {
- String group = convertRoleToGroup(role);
- DistinguishedName superuserDn = (DistinguishedName) ldapTemplate
- .executeReadWrite(new ContextExecutor() {
- public Object executeWithContext(DirContext ctx)
- throws NamingException {
- return LdapUtils.getFullDn(
- usernameMapper.buildDn(superuserName), ctx);
- }
- });
-
- Name groupDn = buildGroupDn(group);
- DirContextAdapter context = new DirContextAdapter();
- context.setAttributeValues("objectClass", groupClasses);
- context.setAttributeValue("cn", group);
- // Add superuser because cannot create empty group
- context.setAttributeValue(groupMemberAttribute, superuserDn.toString());
- ldapTemplate.bind(groupDn, context, null);
- }
-
- public void deleteRole(String role) {
- String group = convertRoleToGroup(role);
- Name dn = buildGroupDn(group);
- ldapTemplate.unbind(dn);
- }
-
- /** Maps a role (ROLE_XXX) to the related LDAP group (xxx) */
- protected String convertRoleToGroup(String role) {
- String group = role;
- if (group.startsWith(rolePrefix)) {
- group = group.substring(rolePrefix.length());
- group = group.toLowerCase();
- }
- return group;
- }
-
- /** Maps anLDAP group (xxx) to the related role (ROLE_XXX) */
- protected String convertGroupToRole(String groupName) {
- groupName = groupName.toUpperCase();
-
- return rolePrefix + groupName;
- }
-
- protected Name buildGroupDn(String name) {
- return new DistinguishedName(groupRoleAttribute + "=" + name + ","
- + groupBase);
- }
-
- public void setUserBase(String userBase) {
- this.userBase = userBase;
- }
-
- public void setUsernameAttribute(String usernameAttribute) {
- this.usernameAttribute = usernameAttribute;
- }
-
- public void setGroupBase(String groupBase) {
- this.groupBase = groupBase;
- }
-
- public void setGroupRoleAttribute(String groupRoleAttributeName) {
- this.groupRoleAttribute = groupRoleAttributeName;
- }
-
- public void setGroupMemberAttribute(String groupMemberAttributeName) {
- this.groupMemberAttribute = groupMemberAttributeName;
- }
-
- public void setDefaultRole(String defaultRole) {
- this.defaultRole = defaultRole;
- }
-
- public void setRolePrefix(String rolePrefix) {
- this.rolePrefix = rolePrefix;
- }
-
- public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
- this.usernameMapper = usernameMapper;
- }
-
- public String getDefaultRole() {
- return defaultRole;
- }
-
- public void setGroupClasses(String[] groupClasses) {
- this.groupClasses = groupClasses;
- }
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin.ldap;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.SortedSet;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-import javax.jcr.version.VersionManager;
-import javax.naming.Name;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.DirContext;
-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.auth.JcrSecurityModel;
-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.JcrUserDetails;
-import org.springframework.ldap.core.ContextMapper;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.ldap.core.LdapTemplate;
-import org.springframework.security.authentication.encoding.PasswordEncoder;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-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);
-
- // LDAP
- private LdapTemplate ldapTemplate;
- /**
- * LDAP template whose context source has an object factory set to null. see
- * <a href=
- * "http://forum.springsource.org/showthread.php?55955-Persistent-search-with-spring-ldap"
- * >this</a>
- */
- // private LdapTemplate rawLdapTemplate;
-
- private String userBase;
- private String usernameAttribute;
- private String passwordAttribute;
- private String[] userClasses;
- // private String defaultUserRole ="ROLE_USER";
-
- // private NamingListener ldapUserListener;
- // private SearchControls subTreeSearchControls;
- private LdapUsernameToDnMapper usernameMapper;
-
- private PasswordEncoder passwordEncoder;
- private final Random random;
-
- // JCR
- /** Admin session on the main workspace */
- private Session nodeSession;
- private Repository repository;
-
- // private JcrProfileListener jcrProfileListener;
- private JcrSecurityModel jcrSecurityModel = new SimpleJcrSecurityModel();
-
- // Mapping
- private Map<String, String> propertyToAttributes = new HashMap<String, String>();
-
- public JcrLdapSynchronizer() {
- random = createRandom();
- }
-
- public void init() {
- try {
- nodeSession = repository.login();
-
- // TODO put this in a different thread, and poll the LDAP server
- // until it is up
- try {
- synchronize();
-
- // LDAP
- // subTreeSearchControls = new SearchControls();
- // subTreeSearchControls
- // .setSearchScope(SearchControls.SUBTREE_SCOPE);
- // LDAP listener
- // ldapUserListener = new LdapUserListener();
- // rawLdapTemplate.executeReadOnly(new ContextExecutor() {
- // public Object executeWithContext(DirContext ctx)
- // throws NamingException {
- // EventDirContext ectx = (EventDirContext) ctx.lookup("");
- // ectx.addNamingListener(userBase, "("
- // + usernameAttribute + "=*)",
- // subTreeSearchControls, ldapUserListener);
- // return null;
- // }
- // });
- } catch (Exception e) {
- log.error("Could not synchronize and listen to LDAP,"
- + " probably because the LDAP server is not available."
- + " Restart the system as soon as possible.", e);
- }
-
- // JCR
- // String[] nodeTypes = { ArgeoTypes.ARGEO_USER_PROFILE };
- // jcrProfileListener = new JcrProfileListener();
- // noLocal is used so that we are not notified when we modify JCR
- // from LDAP
- // nodeSession
- // .getWorkspace()
- // .getObservationManager()
- // .addEventListener(jcrProfileListener,
- // Event.PROPERTY_CHANGED | Event.NODE_ADDED, "/",
- // true, null, nodeTypes, true);
- } catch (Exception e) {
- JcrUtils.logoutQuietly(nodeSession);
- throw new ArgeoException("Cannot initialize LDAP/JCR synchronizer",
- e);
- }
- }
-
- public void destroy() {
- // JcrUtils.removeListenerQuietly(nodeSession, jcrProfileListener);
- JcrUtils.logoutQuietly(nodeSession);
- // try {
- // rawLdapTemplate.executeReadOnly(new ContextExecutor() {
- // public Object executeWithContext(DirContext ctx)
- // throws NamingException {
- // EventDirContext ectx = (EventDirContext) ctx.lookup("");
- // ectx.removeNamingListener(ldapUserListener);
- // return null;
- // }
- // });
- // } catch (Exception e) {
- // // silent (LDAP server may have been shutdown already)
- // if (log.isTraceEnabled())
- // log.trace("Cannot remove LDAP listener", e);
- // }
- }
-
- /*
- * LDAP TO JCR
- */
- /** Full synchronization between LDAP and JCR. LDAP has priority. */
- protected void synchronize() {
- try {
- Name userBaseName = new DistinguishedName(userBase);
- // TODO subtree search?
- @SuppressWarnings("unchecked")
- List<String> userPaths = (List<String>) ldapTemplate.listBindings(
- userBaseName, new ContextMapper() {
- public Object mapFromContext(Object ctxObj) {
- try {
- return mapLdapToJcr((DirContextAdapter) ctxObj);
- } catch (Exception e) {
- // do not break process because of error
- log.error(
- "Could not LDAP->JCR synchronize user "
- + ctxObj, e);
- return null;
- }
- }
- });
-
- // create accounts which are not in LDAP
- Query query = nodeSession
- .getWorkspace()
- .getQueryManager()
- .createQuery(
- "select * from [" + ArgeoTypes.ARGEO_USER_PROFILE
- + "]", Query.JCR_SQL2);
- NodeIterator it = query.execute().getNodes();
- while (it.hasNext()) {
- Node userProfile = it.nextNode();
- String path = userProfile.getPath();
- try {
- if (!userPaths.contains(path)) {
- String username = userProfile
- .getProperty(ARGEO_USER_ID).getString();
- // GrantedAuthority[] authorities = {new
- // GrantedAuthorityImpl(defaultUserRole)};
- List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
- JcrUserDetails userDetails = new JcrUserDetails(
- userProfile, username, authorities);
- String dn = createLdapUser(userDetails);
- log.warn("Created ldap entry '" + dn + "' for user '"
- + username + "'");
-
- // if(!userProfile.getProperty(ARGEO_ENABLED).getBoolean()){
- // continue profiles;
- // }
- //
- // log.warn("Path "
- // + path
- // + " not found in LDAP, disabling user "
- // + userProfile.getProperty(ArgeoNames.ARGEO_USER_ID)
- // .getString());
-
- // Temporary hack to repair previous behaviour
- if (!userProfile.getProperty(ARGEO_ENABLED)
- .getBoolean()) {
- VersionManager versionManager = nodeSession
- .getWorkspace().getVersionManager();
- versionManager.checkout(userProfile.getPath());
- userProfile.setProperty(ArgeoNames.ARGEO_ENABLED,
- true);
- nodeSession.save();
- versionManager.checkin(userProfile.getPath());
- }
- }
- } catch (Exception e) {
- log.error("Cannot process " + path, e);
- }
- }
- } catch (Exception e) {
- JcrUtils.discardQuietly(nodeSession);
- log.error("Cannot synchronize LDAP and JCR", e);
- // throw new ArgeoException("Cannot synchronize LDAP and JCR", e);
- }
- }
-
- private String createLdapUser(UserDetails user) {
- DirContextAdapter ctx = new DirContextAdapter();
- mapUserToContext(user, ctx);
- DistinguishedName dn = usernameMapper.buildDn(user.getUsername());
- ldapTemplate.bind(dn, ctx, null);
- return dn.toString();
- }
-
- /** Called during authentication in order to retrieve user details */
- public UserDetails mapUserFromContext(final DirContextOperations ctx,
- final String username,
- Collection<? extends GrantedAuthority> authorities) {
- if (ctx == null)
- throw new ArgeoException("No LDAP information for user " + username);
-
- String ldapUsername = ctx.getStringAttribute(usernameAttribute);
- if (!ldapUsername.equals(username))
- throw new ArgeoException("Logged in with username " + username
- + " but LDAP user is " + ldapUsername);
-
- Node userProfile = jcrSecurityModel.sync(nodeSession, username,
- SecurityUtils.authoritiesToStringList(authorities));
- // JcrUserDetails.checkAccountStatus(userProfile);
-
- // password
- SortedSet<?> passwordAttributes = ctx
- .getAttributeSortedStringSet(passwordAttribute);
- String password;
- if (passwordAttributes == null || passwordAttributes.size() == 0) {
- // throw new ArgeoException("No password found for user " +
- // username);
- password = "NULL";
- } else {
- byte[] arr = (byte[]) passwordAttributes.first();
- password = new String(arr);
- // erase password
- Arrays.fill(arr, (byte) 0);
- }
-
- try {
- return new JcrUserDetails(userProfile, password, authorities);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot retrieve user details for "
- + username, e);
- }
- }
-
- /**
- * Writes an LDAP context to the JCR user profile.
- *
- * @return path to user profile
- */
- protected synchronized String mapLdapToJcr(DirContextAdapter ctx) {
- Session session = nodeSession;
- try {
- // process
- String username = ctx.getStringAttribute(usernameAttribute);
-
- Node userProfile = jcrSecurityModel.sync(session, username, null);
- Map<String, String> modifications = new HashMap<String, String>();
- for (String jcrProperty : propertyToAttributes.keySet())
- ldapToJcr(userProfile, jcrProperty, ctx, modifications);
-
- int modifCount = modifications.size();
- if (modifCount > 0) {
- session.getWorkspace().getVersionManager()
- .checkout(userProfile.getPath());
- for (String prop : modifications.keySet())
- userProfile.setProperty(prop, modifications.get(prop));
- JcrUtils.updateLastModified(userProfile);
- session.save();
- session.getWorkspace().getVersionManager()
- .checkin(userProfile.getPath());
- if (log.isDebugEnabled())
- log.debug("Mapped " + modifCount + " LDAP modification"
- + (modifCount == 1 ? "" : "s") + " from "
- + ctx.getDn() + " to " + userProfile);
- }
- return userProfile.getPath();
- } catch (Exception e) {
- JcrUtils.discardQuietly(session);
- throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
- }
- }
-
- /** Maps an LDAP property to a JCR property */
- protected void ldapToJcr(Node userProfile, String jcrProperty,
- DirContextOperations ctx, Map<String, String> modifications) {
- // TODO do we really need DirContextOperations?
- try {
- String ldapAttribute;
- if (propertyToAttributes.containsKey(jcrProperty))
- ldapAttribute = propertyToAttributes.get(jcrProperty);
- else
- throw new ArgeoException(
- "No LDAP attribute mapped for JCR proprty "
- + jcrProperty);
-
- String value = ctx.getStringAttribute(ldapAttribute);
- String jcrValue = userProfile.hasProperty(jcrProperty) ? userProfile
- .getProperty(jcrProperty).getString() : null;
- if (value != null && jcrValue != null) {
- if (!value.equals(jcrValue))
- modifications.put(jcrProperty, value);
- } else if (value != null && jcrValue == null) {
- modifications.put(jcrProperty, value);
- } else if (value == null && jcrValue != null) {
- modifications.put(jcrProperty, value);
- }
- } catch (Exception e) {
- throw new ArgeoException("Cannot map JCR property " + jcrProperty
- + " from LDAP", e);
- }
- }
-
- /*
- * JCR to LDAP
- */
-
- public void mapUserToContext(UserDetails user, final DirContextAdapter ctx) {
- if (!(user instanceof JcrUserDetails))
- throw new ArgeoException("Unsupported user details: "
- + user.getClass());
-
- ctx.setAttributeValues("objectClass", userClasses);
- ctx.setAttributeValue(usernameAttribute, user.getUsername());
- ctx.setAttributeValue(passwordAttribute,
- encodePassword(user.getPassword()));
-
- final JcrUserDetails jcrUserDetails = (JcrUserDetails) user;
- try {
- Node userProfile = nodeSession
- .getNode(jcrUserDetails.getHomePath()).getNode(
- ARGEO_PROFILE);
- for (String jcrProperty : propertyToAttributes.keySet()) {
- if (userProfile.hasProperty(jcrProperty)) {
- ModificationItem mi = jcrToLdap(jcrProperty, userProfile
- .getProperty(jcrProperty).getString());
- if (mi != null)
- ctx.setAttribute(mi.getAttribute());
- }
- }
- if (log.isTraceEnabled())
- log.trace("Mapped " + userProfile + " to " + ctx.getDn());
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
- }
-
- }
-
- /** Maps a JCR property to an LDAP property */
- protected ModificationItem jcrToLdap(String jcrProperty, String value) {
- // TODO do we really need DirContextOperations?
- try {
- String ldapAttribute;
- if (propertyToAttributes.containsKey(jcrProperty))
- ldapAttribute = propertyToAttributes.get(jcrProperty);
- else
- return null;
-
- // fix issue with empty 'sn' in LDAP
- if (ldapAttribute.equals("sn") && (value.trim().equals("")))
- return null;
- // fix issue with empty 'description' in LDAP
- if (ldapAttribute.equals("description") && value.trim().equals(""))
- return null;
- BasicAttribute attr = new BasicAttribute(
- propertyToAttributes.get(jcrProperty), value);
- ModificationItem mi = new ModificationItem(
- DirContext.REPLACE_ATTRIBUTE, attr);
- return mi;
- } catch (Exception e) {
- throw new ArgeoException("Cannot map JCR property " + jcrProperty
- + " from LDAP", e);
- }
- }
-
- /*
- * UTILITIES
- */
- protected String encodePassword(String password) {
- if (!password.startsWith("{")) {
- byte[] salt = new byte[16];
- random.nextBytes(salt);
- return passwordEncoder.encodePassword(password, salt);
- } else {
- return password;
- }
- }
-
- private static Random createRandom() {
- try {
- return SecureRandom.getInstance("SHA1PRNG");
- } catch (NoSuchAlgorithmException e) {
- return new Random(System.currentTimeMillis());
- }
- }
-
- /*
- * DEPENDENCY INJECTION
- */
-
- public void setLdapTemplate(LdapTemplate ldapTemplate) {
- this.ldapTemplate = ldapTemplate;
- }
-
- public void setRawLdapTemplate(LdapTemplate rawLdapTemplate) {
- // this.rawLdapTemplate = rawLdapTemplate;
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
- public void setUserBase(String userBase) {
- this.userBase = userBase;
- }
-
- public void setUsernameAttribute(String usernameAttribute) {
- this.usernameAttribute = usernameAttribute;
- }
-
- public void setPropertyToAttributes(Map<String, String> propertyToAttributes) {
- this.propertyToAttributes = propertyToAttributes;
- }
-
- public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
- this.usernameMapper = usernameMapper;
- }
-
- public void setPasswordAttribute(String passwordAttribute) {
- this.passwordAttribute = passwordAttribute;
- }
-
- public void setUserClasses(String[] userClasses) {
- this.userClasses = userClasses;
- }
-
- public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
- this.passwordEncoder = passwordEncoder;
- }
-
- public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
- this.jcrSecurityModel = jcrSecurityModel;
- }
-
- /** Listen to LDAP */
- // class LdapUserListener implements ObjectChangeListener,
- // NamespaceChangeListener, UnsolicitedNotificationListener {
- //
- // public void namingExceptionThrown(NamingExceptionEvent evt) {
- // evt.getException().printStackTrace();
- // }
- //
- // public void objectChanged(NamingEvent evt) {
- // Binding user = evt.getNewBinding();
- // // TODO find a way not to be called when JCR is the source of the
- // // modification
- // DirContextAdapter ctx = (DirContextAdapter) ldapTemplate
- // .lookup(user.getName());
- // mapLdapToJcr(ctx);
- // }
- //
- // public void objectAdded(NamingEvent evt) {
- // Binding user = evt.getNewBinding();
- // DirContextAdapter ctx = (DirContextAdapter) ldapTemplate
- // .lookup(user.getName());
- // mapLdapToJcr(ctx);
- // }
- //
- // public void objectRemoved(NamingEvent evt) {
- // if (log.isDebugEnabled())
- // log.debug(evt);
- // }
- //
- // public void objectRenamed(NamingEvent evt) {
- // if (log.isDebugEnabled())
- // log.debug(evt);
- // }
- //
- // public void notificationReceived(UnsolicitedNotificationEvent evt) {
- // UnsolicitedNotification notification = evt.getNotification();
- // NamingException ne = notification.getException();
- // String msg = "LDAP notification " + "ID=" + notification.getID()
- // + ", referrals=" + notification.getReferrals();
- // if (ne != null) {
- // if (log.isTraceEnabled())
- // log.trace(msg + ", exception= " + ne, ne);
- // else
- // log.warn(msg + ", exception= " + ne);
- // } else if (log.isDebugEnabled()) {
- // log.debug("Unsollicited LDAP notification " + msg);
- // }
- // }
- //
- // }
-
- /** Listen to JCR */
- // class JcrProfileListener implements EventListener {
- //
- // public void onEvent(EventIterator events) {
- // try {
- // final Map<Name, List<ModificationItem>> modifications = new HashMap<Name,
- // List<ModificationItem>>();
- // while (events.hasNext()) {
- // Event event = events.nextEvent();
- // try {
- // if (Event.PROPERTY_CHANGED == event.getType()) {
- // Property property = (Property) nodeSession
- // .getItem(event.getPath());
- // String propertyName = property.getName();
- // Node userProfile = property.getParent();
- // String username = userProfile.getProperty(
- // ARGEO_USER_ID).getString();
- // if (propertyToAttributes.containsKey(propertyName)) {
- // Name name = usernameMapper.buildDn(username);
- // if (!modifications.containsKey(name))
- // modifications.put(name,
- // new ArrayList<ModificationItem>());
- // String value = property.getString();
- // ModificationItem mi = jcrToLdap(propertyName,
- // value);
- // if (mi != null)
- // modifications.get(name).add(mi);
- // }
- // } else if (Event.NODE_ADDED == event.getType()) {
- // Node userProfile = nodeSession.getNode(event
- // .getPath());
- // String username = userProfile.getProperty(
- // ARGEO_USER_ID).getString();
- // Name name = usernameMapper.buildDn(username);
- // for (String propertyName : propertyToAttributes
- // .keySet()) {
- // if (!modifications.containsKey(name))
- // modifications.put(name,
- // new ArrayList<ModificationItem>());
- // String value = userProfile.getProperty(
- // propertyName).getString();
- // ModificationItem mi = jcrToLdap(propertyName,
- // value);
- // if (mi != null)
- // modifications.get(name).add(mi);
- // }
- // }
- // } catch (RepositoryException e) {
- // throw new ArgeoException("Cannot process event "
- // + event, e);
- // }
- // }
- //
- // for (Name name : modifications.keySet()) {
- // List<ModificationItem> userModifs = modifications.get(name);
- // int modifCount = userModifs.size();
- // ldapTemplate.modifyAttributes(name, userModifs
- // .toArray(new ModificationItem[modifCount]));
- // if (log.isDebugEnabled())
- // log.debug("Mapped " + modifCount + " JCR modification"
- // + (modifCount == 1 ? "" : "s") + " to " + name);
- // }
- // } catch (Exception e) {
- // // if (log.isDebugEnabled())
- // // e.printStackTrace();
- // throw new ArgeoException("Cannot process JCR events ("
- // + e.getMessage() + ")", e);
- // }
- // }
- //
- // }
-}
+++ /dev/null
-/*
- * 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.cms.internal.useradmin.ldap;
-
-import java.util.Collection;
-import java.util.UUID;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
-
-/** @deprecated Read only mapping from LDAP to user details */
-@Deprecated
-public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
- ArgeoNames {
- /** Admin session on the security workspace */
- private Session securitySession;
- private Repository repository;
- private String securityWorkspace = "security";
-
- public void init() {
- try {
- securitySession = repository.login(securityWorkspace);
- } catch (RepositoryException e) {
- JcrUtils.logoutQuietly(securitySession);
- throw new ArgeoException(
- "Cannot initialize LDAP/JCR user details context mapper", e);
- }
- }
-
- public void destroy() {
- JcrUtils.logoutQuietly(securitySession);
- }
-
- /** Called during authentication in order to retrieve user details */
- public UserDetails mapUserFromContext(final DirContextOperations ctx,
- final String username,
- Collection<? extends GrantedAuthority> authorities) {
- if (ctx == null)
- throw new ArgeoException("No LDAP information for user " + username);
- Node userHome = UserJcrUtils.getUserHome(securitySession, username);
- if (userHome == null)
- throw new ArgeoException("No JCR information for user " + username);
-
- // password
- // SortedSet<?> passwordAttributes = ctx
- // .getAttributeSortedStringSet(passwordAttribute);
- // String password;
- // if (passwordAttributes == null || passwordAttributes.size() == 0) {
- // throw new ArgeoException("No password found for user " + username);
- // } else {
- // byte[] arr = (byte[]) passwordAttributes.first();
- // password = new String(arr);
- // // erase password
- // Arrays.fill(arr, (byte) 0);
- // }
-
- try {
- // we don't have access to password, so let's not pretend
- String password = UUID.randomUUID().toString();
- return new JcrUserDetails(userHome.getNode(ARGEO_PROFILE),
- password, authorities);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot retrieve user details for "
- + username, e);
- }
- }
-
- public void mapUserToContext(UserDetails user, final DirContextAdapter ctx) {
- throw new UnsupportedOperationException("LDAP access is read-only");
- }
-
-}
Bundle-ActivationPolicy: lazy
Import-Package:org.bouncycastle.*;resolution:=optional,\
-org.springframework.util,\
javax.jcr.security,\
org.apache.commons.codec,\
org.apache.commons.codec.digest,\
+org.springframework.core,\
*
source.. = src/,\
ext/test/
additional.bundles = org.junit,\
- org.slf4j.commons.logging,\
- org.springframework.security.core
+ org.slf4j.commons.logging
+++ /dev/null
-/*
- * 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;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.binary.Hex;
-import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
-
-public class PasswordSandbox {
- public static void main(String[] args) {
- try {
- // Tested password
- String pwdPlain = "demo";
-
- // Check Java generated values
- LdapShaPasswordEncoder lspe = new LdapShaPasswordEncoder();
- String pwdLdapShaBase64 = lspe.encodePassword(pwdPlain, null);
- System.out.println("pwdLdapShaBase64:\t\t" + pwdLdapShaBase64);
-
- String pwdShaBase64 = pwdLdapShaBase64.substring("{SHA}".length());
- System.out.println("pwdShaBase64:\t\t\t" + pwdShaBase64);
-
- byte[] pwdShaArray = Base64.decodeBase64(pwdShaBase64.getBytes());
- String pwdShaHex = new String(Hex.encodeHex(pwdShaArray));
- System.out.println("pwdShaHex:\t\t\t" + pwdShaHex);
-
- // Check that we can use JavaScript generated values in Hex
- String jsShaHex = "89e495e7941cf9e40e6980d14a16bf023ccd4c91";
- System.out.println("jsShaHex:\t\t\t" + pwdShaHex);
- System.out.println("pwdShaHex==jsShaHex:\t\t"
- + (pwdShaHex.equals(jsShaHex)));
-
- byte[] jsShaArray = Hex.decodeHex(jsShaHex.toCharArray());
- String jsShaBase64 = new String(Base64.encodeBase64(jsShaArray));
- System.out.println("jsShaBase64:\t\t\t" + jsShaBase64);
- System.out.println("pwdShaBase64==jsShaBase64:\t"
- + (pwdShaBase64.equals(jsShaBase64)));
- } catch (DecoderException e) {
- e.printStackTrace();
- }
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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;
-
-import java.util.Collection;
-
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-
-/** Credentials required for the authentication to a node. */
-public class NodeAuthenticationToken extends
- UsernamePasswordAuthenticationToken {
- private static final long serialVersionUID = 1955222132884795213L;
- private final String url;
-
- /** Non authenticated local constructor */
- public NodeAuthenticationToken(Object principal, Object credentials) {
- super(principal, credentials);
- this.url = null;
- }
-
- /** Non authenticated remote constructor */
- public NodeAuthenticationToken(Object principal, Object credentials,
- String url) {
- super(principal, credentials);
- this.url = url;
- }
-
- /** Authenticated constructor */
- public NodeAuthenticationToken(NodeAuthenticationToken sat,
- Collection<? extends GrantedAuthority> authorities) {
- super(sat.getPrincipal(), sat.getCredentials(), authorities);
- this.url = sat.getUrl();
- }
-
- public String getUrl() {
- return url;
- }
-
- public Boolean isRemote() {
- return url != null;
- }
-
- public String toString() {
- String username = getName();
- StringBuilder buf = new StringBuilder("groups=");
- for (GrantedAuthority ga : getAuthorities()) {
- if (!ga.getAuthority().equals(username)) {
- buf.append(ga.getAuthority());
- buf.append(',');
- }
- }
- buf.deleteCharAt(buf.length() - 1);
- return "uid=" + getName() + " " + buf.toString();
- }
-}
+++ /dev/null
-/*
- * 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;
-
-import java.security.AccessController;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-
-import org.argeo.ArgeoException;
-import org.argeo.OperatingSystem;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-/** Abstracts principals provided by com.sun.security.auth.module login modules. */
-public class OsAuthenticationToken implements Authentication {
- private static final long serialVersionUID = -7544626794250917244L;
-
- final Class<? extends Principal> osUserPrincipalClass;
- final Class<? extends Principal> osUserIdPrincipalClass;
- final Class<? extends Principal> osGroupIdPrincipalClass;
-
- private List<GrantedAuthority> grantedAuthorities;
-
- private UserDetails details;
-
- /** Request */
- public OsAuthenticationToken(
- Collection<? extends GrantedAuthority> authorities) {
- this.grantedAuthorities = new ArrayList<GrantedAuthority>(authorities);
- ClassLoader cl = getClass().getClassLoader();
- switch (OperatingSystem.os) {
- case OperatingSystem.WINDOWS:
- osUserPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.NTUserPrincipal");
- osUserIdPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.NTSidUserPrincipal");
- osGroupIdPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.NTSidGroupPrincipal");
- break;
- case OperatingSystem.NIX:
- osUserPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.UnixPrincipal");
- osUserIdPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.UnixNumericUserPrincipal");
- osGroupIdPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.UnixNumericGroupPrincipal");
- break;
- case OperatingSystem.SOLARIS:
- osUserPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.SolarisPrincipal");
- osUserIdPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.SolarisNumericUserPrincipal");
- osGroupIdPrincipalClass = getPrincipalClass(cl,
- "com.sun.security.auth.SolarisNumericGroupPrincipal");
- break;
-
- default:
- throw new ArgeoException("Unsupported operating system "
- + OperatingSystem.os);
- }
-
- }
-
- /** Authenticated */
- public OsAuthenticationToken() {
- this(new ArrayList<GrantedAuthority>());
- }
-
- /** @return the name, or null if not yet logged */
- public String getName() {
- Subject subject = Subject.getSubject(AccessController.getContext());
- if (subject == null)
- return null;
- return getUser().getName();
- }
-
- /**
- * Should not be called during authentication since group IDs are not yet
- * available {@link Subject} has been set
- */
- public Collection<? extends GrantedAuthority> getAuthorities() {
- // grantedAuthorities should not be null at this stage
- List<GrantedAuthority> gas = new ArrayList<GrantedAuthority>(
- grantedAuthorities);
- for (Principal groupPrincipal : getGroupsIds()) {
- gas.add(new SimpleGrantedAuthority("OSGROUP_"
- + groupPrincipal.getName()));
- }
- return gas;
- }
-
- public UserDetails getDetails() {
- return details;
- }
-
- public void setDetails(UserDetails details) {
- this.details = details;
- }
-
- public boolean isAuthenticated() {
- return grantedAuthorities != null;
- }
-
- public void setAuthenticated(boolean isAuthenticated)
- throws IllegalArgumentException {
- if (grantedAuthorities != null)
- grantedAuthorities.clear();
- grantedAuthorities = null;
- }
-
- @SuppressWarnings("unchecked")
- protected static Class<? extends Principal> getPrincipalClass(
- ClassLoader cl, String className) {
- try {
- return (Class<? extends Principal>) cl.loadClass(className);
- } catch (ClassNotFoundException e) {
- throw new ArgeoException("Cannot load principal class", e);
- }
- }
-
- public Object getPrincipal() {
- return getUser();
- }
-
- public Principal getUser() {
- Subject subject = getSubject();
- Set<? extends Principal> userPrincipals = subject
- .getPrincipals(osUserPrincipalClass);
- if (userPrincipals == null || userPrincipals.size() == 0)
- throw new ArgeoException("No OS principal");
- if (userPrincipals.size() > 1)
- throw new ArgeoException("More than one OS principal");
- Principal user = userPrincipals.iterator().next();
- return user;
- }
-
- public Principal getUserId() {
- Subject subject = getSubject();
- Set<? extends Principal> userIdsPrincipals = subject
- .getPrincipals(osUserIdPrincipalClass);
- if (userIdsPrincipals == null || userIdsPrincipals.size() == 0)
- throw new ArgeoException("No user id principal");
- if (userIdsPrincipals.size() > 1)
- throw new ArgeoException("More than one user id principal");
- Principal userId = userIdsPrincipals.iterator().next();
- return userId;
- }
-
- public Set<? extends Principal> getGroupsIds() {
- Subject subject = getSubject();
- return (Set<? extends Principal>) subject
- .getPrincipals(osGroupIdPrincipalClass);
- }
-
- /** @return the subject always non null */
- protected Subject getSubject() {
- Subject subject = Subject.getSubject(AccessController.getContext());
- if (subject == null)
- throw new ArgeoException("No subject in JAAS context");
- return subject;
- }
-
- public Object getCredentials() {
- return "";
- }
-
-}
*/
package org.argeo.security;
-import java.util.ArrayList;
-import java.util.Collection;
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.acl.Group;
import java.util.Collections;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
-import org.springframework.security.authentication.AnonymousAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+
+import org.argeo.ArgeoException;
/** Static utilities */
public final class SecurityUtils {
/** Whether the current thread has the admin role */
public static boolean hasCurrentThreadAuthority(String authority) {
- SecurityContext securityContext = SecurityContextHolder.getContext();
- if (securityContext != null) {
- Authentication authentication = securityContext.getAuthentication();
- if (authentication != null) {
- for (GrantedAuthority ga : authentication.getAuthorities())
- if (ga.getAuthority().equals(authority))
- return true;
- }
- }
- return false;
+ return roles().contains(authority);
}
/**
* anonymous
*/
public static String getCurrentThreadUsername() {
- SecurityContext securityContext = SecurityContextHolder.getContext();
- if (securityContext != null) {
- Authentication authentication = securityContext.getAuthentication();
- if (authentication != null) {
- if (authentication instanceof AnonymousAuthenticationToken) {
- return null;
- }
- return authentication.getName();
- }
- }
- return null;
+ return getUsername();
}
- /**
- * Returns the display name of the user details (by calling toString() on
- * it)
- */
- public static String getUserDetailsDisplayName() {
- SecurityContext securityContext = SecurityContextHolder.getContext();
- if (securityContext != null) {
- Authentication authentication = securityContext.getAuthentication();
- if (authentication != null) {
- if (authentication instanceof AnonymousAuthenticationToken) {
- return null;
- }
- Object details = authentication.getDetails();
- if (details != null)
- return details.toString();
- return authentication.getName();
- }
- }
- return null;
+ public final static String getUsername() {
+ Subject subject = Subject.getSubject(AccessController.getContext());
+ if (subject == null)
+ return null;
+ if (subject.getPrincipals(X500Principal.class).size() != 1)
+ return null;
+ Principal principal = subject.getPrincipals(X500Principal.class)
+ .iterator().next();
+ return principal.getName();
+
}
- /**
- * Converts an array of Spring Security {@link GrantedAuthority} to a
- * read-only list of strings, for portability and integration
- */
- public static List<String> authoritiesToStringList(
- Collection<? extends GrantedAuthority> authorities) {
- List<String> lst = new ArrayList<String>();
- for (GrantedAuthority ga : authorities)
- lst.add(ga.getAuthority());
- return Collections.unmodifiableList(lst);
+ public final static Set<String> roles() {
+ Set<String> roles = Collections.synchronizedSet(new HashSet<String>());
+ Subject subject = Subject.getSubject(AccessController.getContext());
+ if (subject == null)
+ throw new ArgeoException("Not authenticated.");
+ X500Principal userPrincipal = subject
+ .getPrincipals(X500Principal.class).iterator().next();
+ roles.add(userPrincipal.getName());
+ for (Principal group : subject.getPrincipals(Group.class)) {
+ roles.add(group.getName());
+ }
+ return roles;
}
}
+++ /dev/null
-/*
- * 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;
-
-/**
- * Marks a system authentication, that is which did not require a login process.
- */
-public interface SystemAuthentication {
- /** 'admin' for consistency with JCR */
- public final static String USERNAME_SYSTEM = "admin";
- public final static String ROLE_SYSTEM = "ROLE_SYSTEM";
- public final static String SYSTEM_KEY_PROPERTY = "argeo.security.systemKey";
-}
+++ /dev/null
-/*
- * 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;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Future;
-
-/**
- * Allows to execute code authenticated as a system user (that is not a real
- * person). The {@link Executor} interface is not used directly in order to
- * allow future extension of this interface and to simplify its publication
- * (e.g. as an OSGi service) and interception.
- */
-public interface SystemExecutionService extends Executor {
- /**
- * Executes this {@link Runnable} within a system authenticated context.
- * Implementations should make sure that this method is properly secured via
- * Java permissions since it could access everything without credentials.
- */
- public void execute(Runnable runnable);
-
- /**
- * Executes this {@link Callable} within a system authenticated context.
- * Implementations should make sure that this method is properly secured via
- * Java permissions since it could access everything without credentials.
- */
- public <T> Future<T> submit(Callable<T> task);
-}
+++ /dev/null
-/*
- * 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;
-
-import java.util.Set;
-
-import org.springframework.security.provisioning.UserDetailsManager;
-
-/** Enrich {@link UserDetailsManager} in order to provide roles semantics. */
-public interface UserAdminService extends UserDetailsManager {
- /**
- * Usernames must match this regexp pattern ({@value #USERNAME_PATTERN}).
- * Thanks to <a href=
- * "http://www.mkyong.com/regular-expressions/how-to-validate-username-with-regular-expression/"
- * >this tip</a> (modified to add upper-case, add '@')
- */
- //public final static String USERNAME_PATTERN = "^[a-zA-Z0-9_-@]{3,64}$";
-
- /**
- * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}.
- * Thanks to <a href=
- * "http://www.mkyong.com/regular-expressions/how-to-validate-email-address-with-regular-expression/"
- * >this tip</a>.
- */
- public final static String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
-
- /*
- * USERS
- */
- /** List all users. */
- public Set<String> listUsers();
-
- /** List users having this role (except the super user). */
- public Set<String> listUsersInRole(String role);
-
- /** Synchronize with the underlying DAO. */
- public void synchronize();
-
- /*
- * ROLES
- */
- public void newRole(String role);
-
- public Set<String> listEditableRoles();
-
- public void deleteRole(String role);
-}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
-import org.springframework.security.authentication.AuthenticationManager;
/** Provides base method for executing code with system authorization. */
public abstract class AbstractSystemExecution {
private final static Log log = LogFactory
.getLog(AbstractSystemExecution.class);
- // private AuthenticationManager authenticationManager;
private final Subject subject = new Subject();
- // private String systemAuthenticationKey;
private final String loginModule = "SYSTEM";
- /** Whether the current thread was authenticated by this component. */
- // private ThreadLocal<Boolean> authenticatedBySelf = new
- // ThreadLocal<Boolean>() {
- // protected Boolean initialValue() {
- // return false;
- // }
- // };
-
/**
* Authenticate the calling thread to the underlying
* {@link AuthenticationManager}
} catch (LoginException e) {
throw new ArgeoException("Cannot login as system", e);
}
- // if (authenticatedBySelf.get())
- // return;
- // SecurityContext securityContext = SecurityContextHolder.getContext();
- // Authentication currentAuth = securityContext.getAuthentication();
- // if (currentAuth != null) {
- // if (!(currentAuth instanceof SystemAuthentication))
- // throw new ArgeoException(
- // "System execution on an already authenticated thread: "
- // + currentAuth + ", THREAD="
- // + Thread.currentThread().getId());
- // return;
- // }
- //
- // String key = systemAuthenticationKey != null ?
- // systemAuthenticationKey
- // : System.getProperty(
- // SystemAuthentication.SYSTEM_KEY_PROPERTY,
- // InternalAuthentication.SYSTEM_KEY_DEFAULT);
- // if (key == null)
- // throw new ArgeoException("No system key defined");
- // 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");
}
protected Subject getSubject() {
return subject;
}
-
- // /**
- // * Whether the current thread was authenticated by this component or a
- // * parent thread.
- // */
- // protected Boolean isAuthenticatedBySelf() {
- // return authenticatedBySelf.get();
- // }
- //
- public void setAuthenticationManager(
- AuthenticationManager authenticationManager) {
- log.warn("Use of authenticationManager is deprecated, remove this property from the configuration.");
- }
-
- public void setSystemAuthenticationKey(String systemAuthenticationKey) {
- log.warn("Use of systemAuthenticationKey is deprecated, remove this property from the configuration.");
- // this.systemAuthenticationKey = systemAuthenticationKey;
- }
}
+++ /dev/null
-/*
- * 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.core;
-
-import org.argeo.security.SystemExecutionService;
-import org.springframework.core.task.SimpleAsyncTaskExecutor;
-
-/**
- * Asynchronous Spring TaskExecutor (for use in JMS for example) wrapping a
- * {@link SystemExecutionService}.
- */
-public class AsyncSystemTaskExecutor extends SimpleAsyncTaskExecutor {
- private static final long serialVersionUID = -8035527542087963068L;
-
- private SystemExecutionService systemExecutionService;
-
- public AsyncSystemTaskExecutor() {
- super();
- }
-
- public AsyncSystemTaskExecutor(String threadNamePrefix) {
- super(threadNamePrefix);
- }
-
- @Override
- public Thread createThread(final Runnable runnable) {
- Runnable systemExecutionRunnable = new Runnable() {
-
- public void run() {
- systemExecutionService.execute(runnable);
-
- }
- };
- return super.createThread(systemExecutionRunnable);
- }
-
- public void setSystemExecutionService(
- SystemExecutionService systemExecutionService) {
- this.systemExecutionService = systemExecutionService;
- }
-
-}
*/
package org.argeo.security.core;
-import java.beans.PropertyDescriptor;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor;
import org.springframework.beans.BeansException;
-import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.beans.factory.support.SecurityContextProvider;
import org.springframework.beans.factory.support.SimpleSecurityContextProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ApplicationEvent;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextRefreshedEvent;
/**
* Executes with a system authentication the instantiation and initialization
* methods of the application context where it has been defined.
*/
public class AuthenticatedApplicationContextInitialization extends
- AbstractSystemExecution implements DependencyInitializationAwareBeanPostProcessor,
- ApplicationListener<ApplicationEvent>, ApplicationContextAware {
- // private Log log = LogFactory
- // .getLog(AuthenticatedApplicationContextInitialization.class);
+ AbstractSystemExecution implements
+ DependencyInitializationAwareBeanPostProcessor, ApplicationContextAware {
/** If non empty, restricts to these beans */
private List<String> beanNames = new ArrayList<String>();
-// @SuppressWarnings("rawtypes")
-// public Object postProcessBeforeInstantiation(Class beanClass,
-// String beanName) throws BeansException {
-// // we authenticate when any bean is instantiated
-// // we will deauthenticate only when the application context has been
-// // refreshed in order to be able to deal with factory beans has well
-// // if (!isAuthenticatedBySelf()) {
-// // if (beanNames.size() == 0)
-// // authenticateAsSystem();
-// // else if (beanNames.contains(beanName))
-// // authenticateAsSystem();
-// // }
-// return null;
-// }
-//
-// public boolean postProcessAfterInstantiation(Object bean, String beanName)
-// throws BeansException {
-// return true;
-// }
-//
-// public PropertyValues postProcessPropertyValues(PropertyValues pvs,
-// PropertyDescriptor[] pds, Object bean, String beanName)
-// throws BeansException {
-// return pvs;
-// }
-
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if (beanNames.size() == 0 || beanNames.contains(beanName))
authenticateAsSystem();
- // try {
- // if (beanNames.size() == 0 || beanNames.contains(beanName)) {
- // LoginContext lc = new LoginContext("INIT", subject);
- // lc.login();
- // }
- // } catch (LoginException e) {
- // throw new ArgeoException("Cannot login as initialization", e);
- // }
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
- // NOTE: in case there was an exception in on the initialization method
- // we expect the underlying thread to die and thus the system
- // authentication to be lost. We have currently no way to catch the
- // exception and perform the deauthentication by ourselves.
if (beanNames.size() == 0 || beanNames.contains(beanName))
deauthenticateAsSystem();
- // try {
- // if (beanNames.size() == 0 || beanNames.contains(beanName)) {
- // LoginContext lc = new LoginContext("INIT", subject);
- // lc.logout();
- // }
- // } catch (LoginException e) {
- // // TODO Auto-generated catch block
- // e.printStackTrace();
- // }
return bean;
}
- public void onApplicationEvent(ApplicationEvent event) {
- if (event instanceof ContextRefreshedEvent) {
- // make sure that we have deauthenticated after the application
- // context was initialized/refreshed
- // deauthenticateAsSystem();
- }
- }
-
public void setBeanNames(List<String> beanNames) {
this.beanNames = beanNames;
}
+++ /dev/null
-/*
- * 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.core;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.InitializingBean;
-
-/**
- * Maintains a list of authentication providers injected in to a provider
- * manager, in order to avoid issues with OSGi services and use packages.
- */
-@Deprecated
-public class AuthenticationProvidersRegister implements InitializingBean {
- private Log log = LogFactory.getLog(AuthenticationProvidersRegister.class);
-
- private List<Object> providers = new ArrayList<Object>();
- private List<Object> defaultProviders = new ArrayList<Object>();
-
- public void register(Object authenticationProvider,
- Map<String, String> parameters) {
- providers.add(authenticationProvider);
- if (log.isTraceEnabled())
- log.trace("Registered authentication provider " + parameters);
- }
-
- public void unregister(Object authenticationProvider,
- Map<String, String> parameters) {
- providers.remove(authenticationProvider);
- if (log.isTraceEnabled())
- log.trace("Unregistered authentication provider " + parameters);
- }
-
- public List<Object> getProviders() {
- return providers;
- }
-
- public void setDefaultProviders(
- List<Object> defaultProviders) {
- this.defaultProviders = defaultProviders;
- }
-
- public void afterPropertiesSet() throws Exception {
- providers.addAll(defaultProviders);
- }
-
-}
+++ /dev/null
-/*
- * 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.core;
-
-import java.util.Collections;
-
-import org.argeo.security.SystemAuthentication;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-
-/** A token base on a system key used to request a system authentication. */
-public class InternalAuthentication extends UsernamePasswordAuthenticationToken
- implements SystemAuthentication {
- private static final long serialVersionUID = -6783376375615949315L;
- public final static String SYSTEM_KEY_DEFAULT = "argeo";
-
- public InternalAuthentication(String key, String systemUsername,
- String systemRole) {
- super(systemUsername, key, Collections
- .singleton(new SimpleGrantedAuthority(systemRole)));
- }
-
- public InternalAuthentication(String key) {
- this(key, SystemAuthentication.USERNAME_SYSTEM, SystemAuthentication.ROLE_SYSTEM);
- }
-
-}
+++ /dev/null
-package org.argeo.security.core;
-
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-
-public class InternalAuthenticationProvider implements AuthenticationProvider {
- private String key;
-
- public InternalAuthenticationProvider() {
- }
-
- public InternalAuthenticationProvider(String key) {
- this.key = key;
- }
-
- @Override
- public Authentication authenticate(Authentication arg0)
- throws AuthenticationException {
- InternalAuthentication authentication = (InternalAuthentication) arg0;
- if (authentication.getCredentials().toString().equals(key))
- return authentication;
- return null;
- }
-
- public void setKey(String key) {
- this.key = key;
- }
-
- @Override
- public boolean supports(Class<?> authentication) {
- return InternalAuthentication.class.isAssignableFrom(authentication);
- }
-
-}
+++ /dev/null
-/*
- * 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.core;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.FutureTask;
-
-import org.argeo.ArgeoException;
-import org.argeo.security.SystemExecutionService;
-
-/**
- * Implementation of a {@link SystemExecutionService} using a key-based
- * {@link InternalAuthentication}
- */
-public class KeyBasedSystemExecutionService extends AbstractSystemExecution
- implements SystemExecutionService {
- public void execute(Runnable runnable) {
- try {
- wrapWithSystemAuthentication(Executors.callable(runnable)).call();
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new ArgeoException(
- "Exception when running system authenticated task", e);
- }
- }
-
- public <T> Future<T> submit(Callable<T> task) {
- FutureTask<T> future = new FutureTask<T>(
- wrapWithSystemAuthentication(task));
- future.run();
- return future;
- }
-
- protected <T> Callable<T> wrapWithSystemAuthentication(
- final Callable<T> runnable) {
- return new Callable<T>() {
-
- public T call() throws Exception {
- authenticateAsSystem();
- try {
- return runnable.call();
- } finally {
-// deauthenticateAsSystem();
- }
- }
- };
- }
-}
+++ /dev/null
-/*
- * 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.core;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.springframework.core.io.Resource;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.GrantedAuthorityImpl;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
-
-/** @deprecated */
-@Deprecated
-public class MatchingAuthenticationProvider extends
- AbstractUserDetailsAuthenticationProvider {
-
- private Resource mapping;
- private Properties properties;
-
- private List<String> defaultRoles = new ArrayList<String>();
-
- @Override
- protected void doAfterPropertiesSet() throws Exception {
- properties = new Properties();
- InputStream propIn = mapping.getInputStream();
- try {
- properties.load(propIn);
- } finally {
- propIn.close();
- }
- }
-
- @Override
- protected void additionalAuthenticationChecks(UserDetails userDetails,
- UsernamePasswordAuthenticationToken authentication)
- throws AuthenticationException {
- if (!userDetails.getPassword().equals(authentication.getCredentials()))
- throw new BadCredentialsException(
- "Invalid credentails provided by "
- + authentication.getName());
- }
-
- @Override
- protected UserDetails retrieveUser(String username,
- UsernamePasswordAuthenticationToken authentication)
- throws AuthenticationException {
- String value = properties.getProperty(username);
- if (value == null)
- throw new BadCredentialsException("User " + username
- + " is not registered");
- List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
- for (String role : defaultRoles)
- grantedAuthorities.add(new GrantedAuthorityImpl(role));
- return new User(username, value, true, true, true, true,
- grantedAuthorities);
- }
-
- public void setMapping(Resource mapping) {
- this.mapping = mapping;
- }
-
- public void setDefaultRoles(List<String> defaultRoles) {
- this.defaultRoles = defaultRoles;
- }
-
-}
+++ /dev/null
-/*
- * 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.core;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.argeo.security.OsAuthenticationToken;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-
-/**
- * Validates an OS authentication. The id is that it will always be
- * authenticated since we are always runnign within an OS, but the fact that the
- * {@link Authentication} works properly depends on the proper OS login module
- * having been called as well. TODO make it more configurable (base roles, is
- * admin)
- */
-public class OsAuthenticationProvider implements AuthenticationProvider {
- final static String osUserRole = "ROLE_OS_USER";
- final static String userRole = "ROLE_USER";
- final static String adminRole = "ROLE_ADMIN";
-
- final static Boolean isAdmin = true;
-
- public Authentication authenticate(Authentication authentication)
- throws AuthenticationException {
- return new OsAuthenticationToken(getBaseAuthorities());
- }
-
- public static Collection<? extends GrantedAuthority> getBaseAuthorities() {
- List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
- auths.add(new SimpleGrantedAuthority(osUserRole));
- auths.add(new SimpleGrantedAuthority(userRole));
- if (isAdmin)
- auths.add(new SimpleGrantedAuthority(adminRole));
- return auths;
- }
-
- @SuppressWarnings("rawtypes")
- public boolean supports(Class authentication) {
- return OsAuthenticationToken.class.isAssignableFrom(authentication);
- }
-
-}
+++ /dev/null
-/*
- * 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.jcr;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.UserJcrUtils;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.DisabledException;
-import org.springframework.security.authentication.LockedException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.User;
-
-/** User details based on a user profile node. */
-public class JcrUserDetails extends User implements ArgeoNames {
- private static final long serialVersionUID = -8142764995842559646L;
- private final String homePath;
- private final String securityWorkspace;
-
- /** Human readable user name */
- private String displayName;
-
- protected JcrUserDetails(String securityWorkspace, String homePath,
- String username, String password, boolean enabled,
- boolean accountNonExpired, boolean credentialsNonExpired,
- boolean accountNonLocked,
- Collection<? extends GrantedAuthority> authorities)
- throws IllegalArgumentException {
- super(username, password, enabled, accountNonExpired,
- credentialsNonExpired, accountNonLocked, authorities);
- this.homePath = homePath;
- this.securityWorkspace = securityWorkspace;
- }
-
- public JcrUserDetails(Node userProfile, String password,
- Collection<? extends GrantedAuthority> authorities)
- throws RepositoryException {
- super(
- userProfile.getProperty(ARGEO_USER_ID).getString(),
- password,
- userProfile.getProperty(ARGEO_ENABLED).getBoolean(),
- userProfile.getProperty(ARGEO_ACCOUNT_NON_EXPIRED).getBoolean(),
- userProfile.getProperty(ARGEO_CREDENTIALS_NON_EXPIRED)
- .getBoolean(), userProfile.getProperty(
- ARGEO_ACCOUNT_NON_LOCKED).getBoolean(), authorities);
- // human readable name
- if (userProfile.hasProperty(Property.JCR_TITLE)) {
- displayName = userProfile.getProperty(Property.JCR_TITLE)
- .getString();
- if (displayName.trim().equals(""))
- displayName = null;
- }
- if (displayName == null)
- displayName = userProfile.getProperty(ARGEO_USER_ID).getString();
- // home is defined as the parent of the profile
- homePath = userProfile.getParent().getPath();
- securityWorkspace = userProfile.getSession().getWorkspace().getName();
- }
-
- /**
- * Convenience constructor
- *
- * @param session
- * the security session
- * @param username
- * the username
- * @param password
- * the password, can be null
- * @param authorities
- * the granted authorities
- */
- public JcrUserDetails(Session session, String username, String password,
- Collection<? extends GrantedAuthority> authorities)
- throws RepositoryException {
- this(UserJcrUtils.getUserProfile(session, username),
- password != null ? password : "", authorities);
- }
-
- /**
- * Check the account status in JCR, throwing the exceptions expected by
- * Spring security if needed.
- */
- public static void checkAccountStatus(Node userProfile) {
- try {
- if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean())
- throw new DisabledException(userProfile.getPath()
- + " is disabled");
- if (!userProfile.getProperty(ARGEO_ACCOUNT_NON_LOCKED).getBoolean())
- throw new LockedException(userProfile.getPath() + " is locked");
- } catch (RepositoryException e) {
- throw new BadCredentialsException("Cannot check account status", e);
- }
- }
-
- /** Clone immutable with new roles */
- public JcrUserDetails cloneWithNewRoles(List<String> roles) {
- List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
- for (String role : roles) {
- authorities.add(new SimpleGrantedAuthority(role));
- }
- return new JcrUserDetails(securityWorkspace, homePath, getUsername(),
- getPassword(), isEnabled(), isAccountNonExpired(),
- isAccountNonExpired(), isAccountNonLocked(), authorities);
- }
-
- /** Clone immutable with new password */
- public JcrUserDetails cloneWithNewPassword(String password) {
- return new JcrUserDetails(securityWorkspace, homePath, getUsername(),
- password, isEnabled(), isAccountNonExpired(),
- isAccountNonExpired(), isAccountNonLocked(), getAuthorities());
- }
-
- public String getHomePath() {
- return homePath;
- }
-
- /** Not yet API */
- public String getSecurityWorkspace() {
- return securityWorkspace;
- }
-
- /** The human readable name of this user */
- public String getDisplayName() {
- return displayName;
- }
-
- @Override
- public String toString() {
- return getDisplayName();
- }
-
-}
+++ /dev/null
-package org.argeo.security.jcr;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.User;
-
-/** Used to create a new user */
-public class NewUserDetails extends User {
- private static final long serialVersionUID = -8331941336984083297L;
-
- public NewUserDetails(String username, char[] password) {
- this(username, password, null);
- }
-
- public NewUserDetails(String username, char[] password, String[] roles) {
- super(username, new String(password), false, false, false, false,
- rolesToAuthorities(roles));
- }
-
- /** To be overriden */
- public void mapToProfileNode(Node userProfile) throws RepositoryException {
- // does nothing by default
- }
-
- private static Collection<GrantedAuthority> rolesToAuthorities(
- String[] roles) {
- List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
- if (roles != null)
- for (String role : roles) {
- authorities.add(new SimpleGrantedAuthority(role));
- }
- return authorities;
- }
-}
+++ /dev/null
-/*
- * 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.jcr;
-
-import javax.jcr.Credentials;
-import javax.jcr.LoginException;
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrUtils;
-import org.argeo.jcr.JcrRepositoryWrapper;
-import org.argeo.security.NodeAuthenticationToken;
-import org.argeo.security.SystemAuthentication;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-
-/**
- * Wrapper around a remote Jackrabbit repository which allows to simplify
- * configuration and intercept some actions. It exposes itself as a
- * {@link Repository}.
- */
-public class RemoteJcrRepositoryWrapper extends JcrRepositoryWrapper {
- private final static Log log = LogFactory
- .getLog(RemoteJcrRepositoryWrapper.class);
-
- private String uri = null;
-
- private RepositoryFactory repositoryFactory;
-
- // remote
- private Credentials remoteSystemCredentials = null;
-
- /**
- * Empty constructor, {@link #init()} should be called after properties have
- * been set
- */
- public RemoteJcrRepositoryWrapper() {
- }
-
- /**
- * Embedded constructor, calling the {@link #init()} method.
- *
- * @param alias
- * if not null the repository will be published under this alias
- */
- public RemoteJcrRepositoryWrapper(RepositoryFactory repositoryFactory,
- String uri, Credentials remoteSystemCredentials) {
- this.repositoryFactory = repositoryFactory;
- this.uri = uri;
- this.remoteSystemCredentials = remoteSystemCredentials;
- init();
- }
-
- public void init() {
- Repository repository = createJackrabbitRepository();
- setRepository(repository);
- }
-
- /** Actually creates the new repository. */
- protected Repository createJackrabbitRepository() {
- long begin = System.currentTimeMillis();
- try {
- if (uri == null || uri.trim().equals(""))
- throw new ArgeoException("Remote URI not set");
-
- Repository repository = ArgeoJcrUtils.getRepositoryByUri(
- repositoryFactory, uri);
- if (repository == null)
- throw new ArgeoException("Remote JCR repository " + uri
- + " not found");
- double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
- log.info("Created remote JCR repository in " + duration
- + " s from URI " + uri);
- // we assume that the data model of the remote repository has
- // been properly initialized
- return repository;
- } catch (Exception e) {
- throw new ArgeoException("Cannot create remote JCR repository "
- + uri, e);
- }
- }
-
- /** Shutdown the repository */
- public void destroy() throws Exception {
- super.destroy();
- }
-
- /** Central login method */
- public Session login(Credentials credentials, String workspaceName)
- throws LoginException, NoSuchWorkspaceException,
- RepositoryException {
-
- // retrieve credentials for remote
- if (credentials == null) {
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- if (authentication != null) {
- if (authentication instanceof UsernamePasswordAuthenticationToken) {
- UsernamePasswordAuthenticationToken upat = (UsernamePasswordAuthenticationToken) authentication;
- credentials = new SimpleCredentials(upat.getName(), upat
- .getCredentials().toString().toCharArray());
- } else if ((authentication instanceof SystemAuthentication)
- || (authentication instanceof NodeAuthenticationToken)) {
- credentials = remoteSystemCredentials;
- }
- }
- }
-
- return super.login(credentials, workspaceName);
- }
-
- public void setUri(String uri) {
- this.uri = uri;
- }
-
- public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
- this.repositoryFactory = repositoryFactory;
- }
-
- public void setRemoteSystemCredentials(Credentials remoteSystemCredentials) {
- this.remoteSystemCredentials = remoteSystemCredentials;
- }
-
-}
+++ /dev/null
-/*
- * 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.jcr;
-
-import javax.jcr.Session;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.spring.ThreadBoundSession;
-import org.springframework.security.core.Authentication;
-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);
-
- @Override
- protected Session preCall(Session session) {
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- if (authentication != null) {
- String userID = session.getUserID();
- String currentUserName = authentication.getName();
- if (currentUserName != null) {
- if (!userID.equals(currentUserName)) {
- log.warn("Current session has user ID " + userID
- + " while logged is user is " + currentUserName
- + "(authentication=" + authentication + ")"
- + ". Re-login.");
- // TODO throw an exception
- return login();
- }
- }
- }
- return super.preCall(session);
- }
-
-}
+++ /dev/null
-/*
- * 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.jackrabbit;
-
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.Credentials;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-
-import org.apache.jackrabbit.core.security.AnonymousPrincipal;
-import org.apache.jackrabbit.core.security.authentication.AbstractLoginModule;
-import org.apache.jackrabbit.core.security.authentication.Authentication;
-import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
-import org.springframework.security.authentication.AnonymousAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-
-/** Jackrabbit login mechanism based on Spring Security */
-public class ArgeoLoginModule extends AbstractLoginModule {
- private String adminRole = "ROLE_ADMIN";
- private String systemRole = "ROLE_SYSTEM";
-
- /**
- * Returns the Spring {@link org.springframework.security.Authentication}
- * (which can be null)
- */
- @Override
- protected Principal getPrincipal(Credentials credentials) {
- return SecurityContextHolder.getContext().getAuthentication();
- }
-
- protected Set<Principal> getPrincipals() {
- // use linked HashSet instead of HashSet in order to maintain the order
- // of principals (as in the Subject).
- org.springframework.security.core.Authentication authen = (org.springframework.security.core.Authentication) principal;
-
- Set<Principal> principals = new LinkedHashSet<Principal>();
- principals.add(authen);
-
- // if (authen instanceof SystemAuthentication) {
- // principals.add(new AdminPrincipal(authen.getName()));
- // // principals.add(new ArgeoSystemPrincipal(authen.getName()));
- // } else
- if (authen instanceof AnonymousAuthenticationToken) {
- principals.add(new AnonymousPrincipal());
- } else {
- for (GrantedAuthority ga : authen.getAuthorities()) {
- if (ga instanceof Principal)
- principals.add((Principal) ga);
- // FIXME: make it more generic
- String authority = ga.getAuthority();
- if (adminRole.equals(authority) || systemRole.equals(authority))
- principals.add(new AdminPrincipal(authen.getName()));
- }
- }
-
- // remove previous credentials
- // Set<SimpleCredentials> thisCredentials = subject
- // .getPublicCredentials(SimpleCredentials.class);
- // if (thisCredentials != null)
- // thisCredentials.clear();
-
- return principals;
- }
-
- /**
- * Super implementation removes all {@link Principal}, the Spring
- * {@link org.springframework.security.Authentication} as well. Here we
- * simply clear Jackrabbit related {@link Principal}s.
- */
- // @Override
- // public boolean logout() throws LoginException {
- // Set<Principal> principals = subject.getPrincipals();
- // for (Principal principal : subject.getPrincipals()) {
- // if ((principal instanceof AdminPrincipal)
- // || (principal instanceof ArgeoSystemPrincipal)
- // || (principal instanceof AnonymousPrincipal)
- // || (principal instanceof GrantedAuthority)) {
- // principals.remove(principal);
- // }
- // }
- // // clearPrincipals(AdminPrincipal.class);
- // // clearPrincipals(ArgeoSystemPrincipal.class);
- // // clearPrincipals(AnonymousPrincipal.class);
- // // clearPrincipals(GrantedAuthority.class);
- // return true;
- // }
-
- // private <T extends Principal> void clearPrincipals(Class<T> clss) {
- // Set<T> principals = subject.getPrincipals(clss);
- // if (principals != null)
- // principals.clear();
- // }
-
- @SuppressWarnings("rawtypes")
- @Override
- protected void doInit(CallbackHandler callbackHandler, Session session,
- Map options) throws LoginException {
- }
-
- @Override
- protected boolean impersonate(Principal principal, Credentials credentials)
- throws RepositoryException, LoginException {
- throw new UnsupportedOperationException(
- "Impersonation is not yet supported");
- }
-
- @Override
- protected Authentication getAuthentication(final Principal principal,
- Credentials creds) throws RepositoryException {
- if (principal instanceof Group) {
- return null;
- }
- return new Authentication() {
- public boolean canHandle(Credentials credentials) {
- return principal instanceof org.springframework.security.core.Authentication;
- }
-
- public boolean authenticate(Credentials credentials)
- throws RepositoryException {
- return ((org.springframework.security.core.Authentication) principal)
- .isAuthenticated();
- }
- };
- }
-
-}
org.eclipse.ui.services,\
org.osgi.framework,\
org.springframework.core,\
-org.springframework.dao,\
-org.springframework.security.provisioning,\
*
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.jcr.ArgeoNames;
-import org.argeo.security.UserAdminService;
import org.argeo.security.ui.admin.SecurityAdminPlugin;
import org.argeo.security.ui.admin.internal.UiAdminUtils;
import org.argeo.security.ui.admin.internal.UserAdminConstants;
/** Open a wizard that enables creation of a new user. */
public class NewUser extends AbstractHandler {
+ /**
+ * Email addresses must match this regexp pattern ({@value #EMAIL_PATTERN}.
+ * Thanks to <a href=
+ * "http://www.mkyong.com/regular-expressions/how-to-validate-email-address-with-regular-expression/"
+ * >this tip</a>.
+ */
+ public final static String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
// private final static Log log = LogFactory.getLog(NewUser.class);
public final static String ID = SecurityAdminPlugin.PLUGIN_ID + ".newUser";
.getRole(getDn(name));
if (role != null)
return "User " + name + " already exists";
- if (!primaryMailTxt.getText().matches(
- UserAdminService.EMAIL_PATTERN))
+ if (!primaryMailTxt.getText().matches(EMAIL_PATTERN))
return "Not a valid email address";
if (lastNameTxt.getText().trim().equals(""))
return "Specify a last name";
+++ /dev/null
-/*
- * 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.admin.internal.parts;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.version.VersionManager;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.ArgeoMonitor;
-import org.argeo.eclipse.ui.EclipseArgeoMonitor;
-import org.argeo.eclipse.ui.parts.UsersTable;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.ui.PrivilegedJob;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.IPageChangeProvider;
-import org.eclipse.jface.dialogs.IPageChangedListener;
-import org.eclipse.jface.dialogs.PageChangedEvent;
-import org.eclipse.jface.wizard.IWizardContainer;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-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;
-
-/** Wizard to update users */
-public class UserBatchUpdateWizard extends Wizard {
- private final static Log log = LogFactory
- .getLog(UserBatchUpdateWizard.class);
- private Session session;
- private UserAdminService userAdminService;
-
- // pages
- private ChooseCommandWizardPage chooseCommandPage;
- private ChooseUsersWizardPage userListPage;
- private ValidateAndLaunchWizardPage validatePage;
-
- // /////////////////////////////////////////////////
- // / Definition of the various implemented commands
- private final static String CMD_UPDATE_PASSWORD = "resetPassword";
- private final static String CMD_GROUP_MEMBERSHIP = "groupMembership";
-
- private final Map<String, String> commands = new HashMap<String, String>() {
- private static final long serialVersionUID = 1L;
- {
- put("Enable user(s)", ArgeoNames.ARGEO_ENABLED);
- put("Expire credentials", ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED);
- put("Expire account(s)", ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED);
- put("Lock account(s)", ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED);
- put("Reset password(s)", CMD_UPDATE_PASSWORD);
- // TODO implement role / group management
- // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP);
- }
- };
-
- public UserBatchUpdateWizard(Session session,
- UserAdminService userAdminService) {
- this.session = session;
- this.userAdminService = userAdminService;
- }
-
- @Override
- public void addPages() {
- chooseCommandPage = new ChooseCommandWizardPage();
- addPage(chooseCommandPage);
- userListPage = new ChooseUsersWizardPage(session);
- addPage(userListPage);
- validatePage = new ValidateAndLaunchWizardPage(session);
- addPage(validatePage);
- }
-
- @Override
- public boolean performFinish() {
- if (!canFinish())
- return false;
-
- UpdateJob job = null;
- if (ArgeoNames.ARGEO_ENABLED.equals(chooseCommandPage.getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_ENABLED,
- chooseCommandPage.getBoleanValue());
- } else if (ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED
- .equals(chooseCommandPage.getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED,
- chooseCommandPage.getBoleanValue());
- } else if (ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED
- .equals(chooseCommandPage.getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED,
- chooseCommandPage.getBoleanValue());
- } else if (ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED.equals(chooseCommandPage
- .getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED,
- chooseCommandPage.getBoleanValue());
- } else if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) {
- String newValue = chooseCommandPage.getPwdValue();
- if (newValue == null)
- throw new ArgeoException(
- "Password cannot be null or an empty string");
- job = new ResetPassword(session, userAdminService,
- userListPage.getSelectedUsers(), newValue);
- }
-
- if (job != null)
- job.schedule();
- return true;
- }
-
- public void setSession(Session session) {
- this.session = session;
- }
-
- public boolean canFinish() {
- if (this.getContainer().getCurrentPage() == validatePage)
- return true;
- return false;
- }
-
- // /////////////////////////
- // REEL UPDATE JOB
- private class UpdateBoolean extends UpdateJob {
- private String propertyName;
- private boolean value;
-
- public UpdateBoolean(Session session, List<Node> nodesToUpdate,
- String propertyName, boolean value) {
- super(session, nodesToUpdate);
- this.propertyName = propertyName;
- this.value = value;
- }
-
- protected void doUpdate(Node node) {
- try {
- node.setProperty(propertyName, value);
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unable to update boolean value for node " + node, re);
- }
- }
- }
-
- private class ResetPassword extends UpdateJob {
- private String newValue;
- private UserAdminService userAdminService;
-
- public ResetPassword(Session session,
- UserAdminService userAdminService, List<Node> nodesToUpdate,
- String newValue) {
- super(session, nodesToUpdate);
- this.newValue = newValue;
- this.userAdminService = userAdminService;
- }
-
- protected void doUpdate(Node node) {
- try {
- String userId = node.getProperty(ArgeoNames.ARGEO_USER_ID)
- .getString();
- if (userAdminService.userExists(userId)) {
- JcrUserDetails userDetails = (JcrUserDetails) userAdminService
- .loadUserByUsername(userId);
- userAdminService.updateUser(userDetails
- .cloneWithNewPassword(newValue));
- }
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unable to update boolean value for node " + node, re);
- }
- }
- }
-
- @SuppressWarnings("unused")
- private class AddToGroup extends UpdateJob {
- private String groupID;
- private Session session;
-
- public AddToGroup(Session session, List<Node> nodesToUpdate,
- String groupID) {
- super(session, nodesToUpdate);
- this.session = session;
- this.groupID = groupID;
- }
-
- protected void doUpdate(Node node) {
- log.info("Add/Remove to group actions are not yet implemented");
- // TODO implement this
- // try {
- // throw new ArgeoException("Not yet implemented");
- // } catch (RepositoryException re) {
- // throw new ArgeoException(
- // "Unable to update boolean value for node " + node, re);
- // }
- }
- }
-
- /**
- * Base privileged job that will be run asynchronously to perform the batch
- * update
- */
- private abstract class UpdateJob extends PrivilegedJob {
-
- private final Session currSession;
- private final List<Node> nodesToUpdate;
-
- protected abstract void doUpdate(Node node);
-
- public UpdateJob(Session session, List<Node> nodesToUpdate) {
- super("Perform update");
- try {
- this.currSession = session.getRepository().login();
- // "move" nodes to update in the new session
- // the "old" session will be closed by the calling command
- // before the job has effectively ran
- // TODO there must be a cleaner way to do.
- List<Node> nodes = new ArrayList<Node>();
- for (Node node : nodesToUpdate) {
- nodes.add(currSession.getNode(node.getPath()));
- }
- this.nodesToUpdate = nodes;
- } catch (RepositoryException e) {
- throw new ArgeoException("Error while dupplicating "
- + "session for job", e);
- }
- }
-
- @Override
- protected IStatus doRun(IProgressMonitor progressMonitor) {
- try {
- ArgeoMonitor monitor = new EclipseArgeoMonitor(progressMonitor);
- VersionManager vm = currSession.getWorkspace()
- .getVersionManager();
- int total = nodesToUpdate.size();
- monitor.beginTask("Performing change", total);
- for (Node node : nodesToUpdate) {
- String path = node.getPath();
- vm.checkout(path);
- doUpdate(node);
- currSession.save();
- vm.checkin(path);
- monitor.worked(1);
- }
- } catch (Exception e) {
- log.error("Cannot perform batch update on users", e);
- // e.printStackTrace();
-
- // Dig exception to find the root cause that will enable the
- // user to understand the problem
- Throwable cause = e;
- Throwable originalCause = e;
- while (cause != null) {
- if (log.isTraceEnabled())
- log.trace("Parent Cause message : "
- + cause.getMessage());
- originalCause = cause;
- cause = cause.getCause();
- }
- return new Status(IStatus.ERROR, SecurityAdminPlugin.PLUGIN_ID,
- "Cannot perform updates.", originalCause);
- } finally {
- JcrUtils.logoutQuietly(currSession);
- }
- return Status.OK_STATUS;
- }
- }
-
- // //////////////////////
- // Pages definition
- /** Displays a combo box that enables user to choose which action to perform */
- private class ChooseCommandWizardPage extends WizardPage {
- private static final long serialVersionUID = 1L;
-
- private Combo chooseCommandCmb;
- private Button trueChk;
- private Text valueTxt;
- private Text pwdTxt;
- private Text pwd2Txt;
-
- public ChooseCommandWizardPage() {
- super("Choose a command to run.");
- setTitle("Choose a command to run.");
- }
-
- @Override
- public void createControl(Composite parent) {
- GridLayout gl = new GridLayout();
- Composite container = new Composite(parent, SWT.NO_FOCUS);
- container.setLayout(gl);
-
- chooseCommandCmb = new Combo(container, SWT.NO_FOCUS);
- String[] values = commands.keySet().toArray(
- new String[commands.size()]);
- chooseCommandCmb.setItems(values);
- chooseCommandCmb.setLayoutData(new GridData(SWT.FILL, SWT.TOP,
- true, false));
-
- final Composite bottomPart = new Composite(container, SWT.NO_FOCUS);
- gl = new GridLayout();
- gl.horizontalSpacing = gl.marginWidth = gl.verticalSpacing = 0;
- bottomPart.setLayout(gl);
- bottomPart.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
- true));
-
- chooseCommandCmb.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (getCommand().equals(CMD_UPDATE_PASSWORD))
- populatePasswordCmp(bottomPart);
- else if (getCommand().equals(CMD_GROUP_MEMBERSHIP))
- populateGroupCmp(bottomPart);
- else
- populateBooleanFlagCmp(bottomPart);
- bottomPart.pack(true);
- bottomPart.layout();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
-
- setControl(container);
- }
-
- private void cleanParent(Composite parent) {
- if (parent.getChildren().length > 0) {
- for (Control control : parent.getChildren())
- control.dispose();
- }
- }
-
- private void populateBooleanFlagCmp(Composite parent) {
- cleanParent(parent);
- trueChk = new Button(parent, SWT.CHECK);
- trueChk.setText("Do it. (It will to the contrary if unchecked)");
- trueChk.setSelection(true);
- trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
- }
-
- private void populatePasswordCmp(Composite parent) {
- cleanParent(parent);
- Composite body = new Composite(parent, SWT.NO_FOCUS);
- body.setLayout(new GridLayout(2, false));
- body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- pwdTxt = createLP(body, "New password", "");
- pwd2Txt = createLP(body, "Repeat password", "");
- }
-
- /** Creates label and password. */
- protected Text createLP(Composite body, String label, String value) {
- Label lbl = new Label(body, SWT.NONE);
- lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
- lbl.setText(label);
- Text text = new Text(body, SWT.BORDER | SWT.PASSWORD);
- text.setText(value);
- text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- return text;
- }
-
- private void populateGroupCmp(Composite parent) {
- if (parent.getChildren().length > 0) {
- for (Control control : parent.getChildren())
- control.dispose();
- }
- trueChk = new Button(parent, SWT.CHECK);
- trueChk.setText("Add to group. (It will remove user(s) from the "
- + "corresponding group if unchecked)");
- trueChk.setSelection(true);
- trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
- }
-
- protected String getCommand() {
- return commands.get(chooseCommandCmb.getItem(chooseCommandCmb
- .getSelectionIndex()));
- }
-
- protected String getCommandLbl() {
- return chooseCommandCmb.getItem(chooseCommandCmb
- .getSelectionIndex());
- }
-
- protected boolean getBoleanValue() {
- // FIXME this is not consistent and will lead to errors.
- if (ArgeoNames.ARGEO_ENABLED.equals(getCommand()))
- return trueChk.getSelection();
- else
- return !trueChk.getSelection();
- }
-
- @SuppressWarnings("unused")
- protected String getStringValue() {
- String value = null;
- if (valueTxt != null) {
- value = valueTxt.getText();
- if ("".equals(value.trim()))
- value = null;
- }
- return value;
- }
-
- protected String getPwdValue() {
- String newPwd = null;
- if (pwdTxt == null || pwd2Txt == null)
- return null;
- if (!pwdTxt.getText().equals("") || !pwd2Txt.getText().equals("")) {
- if (pwdTxt.getText().equals(pwd2Txt.getText())) {
- newPwd = pwdTxt.getText();
- pwdTxt.setText("");
- pwd2Txt.setText("");
- } else {
- pwdTxt.setText("");
- pwd2Txt.setText("");
- throw new ArgeoException("Passwords are not equals");
- }
- }
- return newPwd;
- }
- }
-
- /**
- * Displays a list of users with a check box to be able to choose some of
- * them
- */
- private class ChooseUsersWizardPage extends WizardPage implements
- IPageChangedListener {
- private static final long serialVersionUID = 1L;
- private UsersTable userTableCmp;
- private Composite container;
- private Session session;
-
- public ChooseUsersWizardPage(Session session) {
- super("Choose Users");
- this.session = session;
- setTitle("Select users who will be impacted");
- }
-
- @Override
- public void createControl(Composite parent) {
- container = new Composite(parent, SWT.NONE);
- container.setLayout(new FillLayout());
- userTableCmp = new MyUserTableCmp(container, SWT.NO_FOCUS, session);
- userTableCmp.populate(true, true);
- setControl(container);
-
- // Add listener to update message when shown
- final IWizardContainer container = this.getContainer();
- if (container instanceof IPageChangeProvider) {
- ((IPageChangeProvider) container).addPageChangedListener(this);
- }
-
- }
-
- @Override
- public void pageChanged(PageChangedEvent event) {
- if (event.getSelectedPage() == this) {
- String msg = "Chosen batch action: "
- + chooseCommandPage.getCommandLbl();
- ((WizardPage) event.getSelectedPage()).setMessage(msg);
- }
- }
-
- protected List<Node> getSelectedUsers() {
- return userTableCmp.getSelectedUsers();
- }
-
- private class MyUserTableCmp extends UsersTable {
-
- private static final long serialVersionUID = 1L;
-
- public MyUserTableCmp(Composite parent, int style, Session session) {
- super(parent, style, session);
- }
-
- @Override
- protected void refreshFilteredList() {
- List<Node> nodes = new ArrayList<Node>();
- try {
- NodeIterator ni = listFilteredElements(session,
- getFilterString());
-
- users: while (ni.hasNext()) {
- Node currNode = ni.nextNode();
- String username = currNode.hasProperty(ARGEO_USER_ID) ? currNode
- .getProperty(ARGEO_USER_ID).getString() : "";
- if (username.equals(session.getUserID()))
- continue users;
- else
- nodes.add(currNode);
- }
- getTableViewer().setInput(nodes.toArray());
- } catch (RepositoryException e) {
- throw new ArgeoException("Unable to list users", e);
- }
- }
- }
- }
-
- /**
- * Recapitulation of input data before running real update
- */
- private class ValidateAndLaunchWizardPage extends WizardPage implements
- IPageChangedListener {
- private static final long serialVersionUID = 1L;
- private UsersTable userTableCmp;
- private Session session;
-
- public ValidateAndLaunchWizardPage(Session session) {
- super("Validate and launch");
- this.session = session;
- setTitle("Validate and launch");
- }
-
- @Override
- public void createControl(Composite parent) {
- Composite mainCmp = new Composite(parent, SWT.NO_FOCUS);
- mainCmp.setLayout(new FillLayout());
-
- // Add listener to update user list when shown
- final IWizardContainer container = this.getContainer();
- if (container instanceof IPageChangeProvider) {
- ((IPageChangeProvider) container).addPageChangedListener(this);
- }
-
- userTableCmp = new UsersTable(mainCmp, SWT.NO_FOCUS, session);
- userTableCmp.populate(false, false);
- setControl(mainCmp);
- }
-
- @Override
- public void pageChanged(PageChangedEvent event) {
- if (event.getSelectedPage() == this) {
- @SuppressWarnings({ "unchecked", "rawtypes" })
- Object[] values = ((ArrayList) userListPage.getSelectedUsers())
- .toArray(new Object[userListPage.getSelectedUsers()
- .size()]);
- userTableCmp.getTableViewer().setInput(values);
- String msg = "Following batch action: ["
- + chooseCommandPage.getCommandLbl()
- + "] will be perfomed on the users listed below.\n"
- + "Are you sure you want to proceed?";
- ((WizardPage) event.getSelectedPage()).setMessage(msg);
- }
- }
-
- // private class MyUserTableCmp extends UserTableComposite {
- // public MyUserTableCmp(Composite parent, int style, Session session) {
- // super(parent, style, session);
- // }
- //
- // @Override
- // protected void refreshFilteredList() {
- // @SuppressWarnings({ "unchecked", "rawtypes" })
- //
- // setFilteredList(values);
- // }
- //
- // @Override
- // public void setVisible(boolean visible) {
- // super.setVisible(visible);
- // if (visible)
- // refreshFilteredList();
- // }
- // }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.admin.internal.parts;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.CheckboxCellEditor;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.ui.forms.AbstractFormPart;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-/**
- * Display/edit the roles of a user.
- */
-public class UserRolesPage extends FormPage implements ArgeoNames {
- final static String ID = "argeoUserEditor.rolesPage";
-
- private final static Log log = LogFactory.getLog(UserRolesPage.class);
- private final static Image ROLE_CHECKED = SecurityAdminPlugin
- .getImageDescriptor("icons/security.gif").createImage();
-
- private TableViewer rolesViewer;
- private UserAdminService userAdminService;
- private List<String> roles;
-
- public UserRolesPage(FormEditor editor, UserDetails userDetails,
- UserAdminService userAdminService) {
- super(editor, ID, "Roles");
- setUserDetails(userDetails);
- this.userAdminService = userAdminService;
- }
-
- public void setUserDetails(UserDetails userDetails) {
- this.roles = new ArrayList<String>();
- for (GrantedAuthority ga : userDetails.getAuthorities())
- roles.add(ga.getAuthority());
- if (rolesViewer != null)
- rolesViewer.refresh();
- }
-
- protected void createFormContent(final IManagedForm mf) {
- ScrolledForm form = mf.getForm();
- form.setText("Roles");
- FillLayout mainLayout = new FillLayout();
- // ColumnLayout mainLayout = new ColumnLayout();
- // mainLayout.minNumColumns = 1;
- // mainLayout.maxNumColumns = 4;
- // mainLayout.topMargin = 0;
- // mainLayout.bottomMargin = 5;
- // mainLayout.leftMargin = mainLayout.rightMargin =
- // mainLayout.horizontalSpacing = mainLayout.verticalSpacing = 10;
- form.getBody().setLayout(mainLayout);
- createRolesPart(form.getBody());
- }
-
- /** Creates the role section */
- protected void createRolesPart(Composite parent) {
- Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-
- AbstractFormPart part = new AbstractFormPart() {
- public void commit(boolean onSave) {
- // roles have already been modified in editing
- super.commit(onSave);
- if (log.isTraceEnabled())
- log.trace("Role part committed");
- }
- };
- getManagedForm().addPart(part);
-
- // GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
- // gridData.verticalSpan = 20;
- // table.setLayoutData(gridData);
- table.setLinesVisible(true);
- table.setHeaderVisible(false);
- rolesViewer = new TableViewer(table);
-
- // check column
- TableViewerColumn column = createTableViewerColumn(rolesViewer,
- "checked", 20);
- column.setLabelProvider(new ColumnLabelProvider() {
- private static final long serialVersionUID = -1354458151271666525L;
-
- public String getText(Object element) {
- return null;
- }
-
- public Image getImage(Object element) {
- String role = element.toString();
- if (roles.contains(role)) {
- return ROLE_CHECKED;
- } else {
- return null;
- }
- }
- });
- column.setEditingSupport(new RoleEditingSupport(rolesViewer, part));
-
- // role column
- column = createTableViewerColumn(rolesViewer, "Role", 200);
- column.setLabelProvider(new ColumnLabelProvider() {
- private static final long serialVersionUID = 2968056181744306838L;
-
- public String getText(Object element) {
- return element.toString();
- }
-
- public Image getImage(Object element) {
- return null;
- }
- });
- rolesViewer.setContentProvider(new RolesContentProvider());
- rolesViewer.setInput(getEditorSite());
- }
-
- protected TableViewerColumn createTableViewerColumn(TableViewer viewer,
- String title, int bound) {
- final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
- SWT.NONE);
- final TableColumn column = viewerColumn.getColumn();
- column.setText(title);
- column.setWidth(bound);
- column.setResizable(true);
- column.setMoveable(true);
- return viewerColumn;
-
- }
-
- public List<String> getRoles() {
- return roles;
- }
-
- public void refresh() {
- rolesViewer.refresh();
- }
-
- private class RolesContentProvider implements IStructuredContentProvider {
- private static final long serialVersionUID = -1882254608698512781L;
-
- public Object[] getElements(Object inputElement) {
- return userAdminService.listEditableRoles().toArray();
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
- }
-
- /** Select the columns by editing the checkbox in the first column */
- class RoleEditingSupport extends EditingSupport {
- private static final long serialVersionUID = 4041402007711754376L;
- private final TableViewer viewer;
- private final AbstractFormPart formPart;
-
- public RoleEditingSupport(TableViewer viewer, AbstractFormPart formPart) {
- super(viewer);
- this.viewer = viewer;
- this.formPart = formPart;
- }
-
- @Override
- protected CellEditor getCellEditor(Object element) {
- return new CheckboxCellEditor(null, SWT.CHECK | SWT.READ_ONLY);
-
- }
-
- @Override
- protected boolean canEdit(Object element) {
- return true;
- }
-
- @Override
- protected Object getValue(Object element) {
- String role = element.toString();
- return roles.contains(role);
-
- }
-
- @Override
- protected void setValue(Object element, Object value) {
- Boolean inRole = (Boolean) value;
- String role = element.toString();
- if (inRole && !roles.contains(role)) {
- roles.add(role);
- formPart.markDirty();
- } else if (!inRole && roles.contains(role)) {
- roles.remove(role);
- formPart.markDirty();
- }
- viewer.refresh();
- }
- }
-
-}
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.CredentialNotFoundException;
+import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.x500.X500Principal;
import org.eclipse.rap.rwt.application.EntryPoint;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
-import org.springframework.security.authentication.BadCredentialsException;
/**
* RAP entry point with login capabilities. Once the user has been
if (log.isDebugEnabled())
log.debug("Authenticated " + subject);
+ } catch (FailedLoginException e) {
+ MessageDialog.openInformation(display.getActiveShell(),
+ "Bad Credentials", e.getMessage());
+ // retry login
+ continue tryLogin;
} catch (LoginException e) {
- BadCredentialsException bce = wasCausedByBadCredentials(e);
- if (bce != null) {
- MessageDialog.openInformation(display.getActiveShell(),
- "Bad Credentials", bce.getMessage());
- // retry login
- continue tryLogin;
- }
return processLoginDeath(display, e);
}
}
}
- /** Recursively look for {@link BadCredentialsException} in the root causes. */
- private BadCredentialsException wasCausedByBadCredentials(Throwable t) {
- if (t instanceof BadCredentialsException)
- return (BadCredentialsException) t;
-
- if (t instanceof CredentialNotFoundException)
- return new BadCredentialsException("Login canceled");
-
- if (t.getCause() != null)
- return wasCausedByBadCredentials(t.getCause());
- else
- return null;
- }
-
/**
* If there is a {@link ThreadDeath} in the root causes, rethrow it
* (important for RAP cleaning mechanism)
package org.argeo.security.ui;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
/**
* Propagate authentication to an eclipse job. Typically to execute a privileged
* action outside the UI thread
*/
public abstract class PrivilegedJob extends Job {
-
- private final Authentication authentication;
- private Subject subject;
+ private final Subject subject;
public PrivilegedJob(String jobName) {
+ this(jobName, AccessController.getContext());
+ }
+
+ public PrivilegedJob(String jobName,
+ AccessControlContext accessControlContext) {
super(jobName);
- authentication = SecurityContextHolder.getContext().getAuthentication();
- subject = Subject.getSubject(AccessController.getContext());
+ subject = Subject.getSubject(accessControlContext);
// Must be called *before* the job is scheduled,
// it is required for the progress window to appear
protected IStatus run(final IProgressMonitor progressMonitor) {
PrivilegedAction<IStatus> privilegedAction = new PrivilegedAction<IStatus>() {
public IStatus run() {
- SecurityContextHolder.getContext().setAuthentication(
- authentication);
return doRun(progressMonitor);
}
};
*/
package org.argeo.security.ui.internal;
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Collections;
-import java.util.HashSet;
import java.util.Set;
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
-
-import org.argeo.ArgeoException;
+import org.argeo.security.SecurityUtils;
/**
* Retrieves information about the current user. Not an API, can change without
*/
public class CurrentUser {
public final static String getUsername() {
- Subject subject = getSubject();
- if (subject == null)
- return null;
- Principal principal = subject.getPrincipals(X500Principal.class)
- .iterator().next();
- return principal.getName();
-
+ return SecurityUtils.getUsername();
}
public final static Set<String> roles() {
- Set<String> roles = Collections.synchronizedSet(new HashSet<String>());
- // roles.add("ROLE_USER");
- Subject subject = getSubject();
- X500Principal userPrincipal = subject
- .getPrincipals(X500Principal.class).iterator().next();
- roles.add(userPrincipal.getName());
- for (Principal group : subject.getPrincipals(Group.class)) {
- roles.add(group.getName());
- }
- return roles;
- }
-
- // public final static String getUsername() {
- // return getAuthentication().getName();
- // }
-
- // public final static Set<String> roles() {
- // Set<String> roles = Collections.synchronizedSet(new HashSet<String>());
- // Authentication authentication = getAuthentication();
- // for (GrantedAuthority ga : authentication.getAuthorities()) {
- // roles.add(ga.getAuthority());
- // }
- // return Collections.unmodifiableSet(roles);
- // }
- //
- // public final static Authentication getAuthentication() {
- // return SecurityContextHolder.getContext().getAuthentication();
- // }
-
- // public final static Authentication getAuthentication() {
- // Set<Authentication> authens = getSubject().getPrincipals(
- // Authentication.class);
- // if (authens != null && !authens.isEmpty()) {
- // Principal principal = authens.iterator().next();
- // Authentication authentication = (Authentication) principal;
- // return authentication;
- // }
- // throw new ArgeoException("No authentication found");
- // }
-
- public final static Subject getSubject() {
- Subject subject = Subject.getSubject(AccessController.getContext());
- if (subject == null)
- throw new ArgeoException("Not authenticated.");
- return subject;
+ return SecurityUtils.roles();
}
}
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.argeo.commons</groupId>
<artifactId>argeo-commons</artifactId>
<artifactId>argeo-tp</artifactId>
<version>${version.argeo-distribution}</version>
<scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.argeo.tp.spring</groupId>
+ <artifactId>org.springframework.ldap</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.argeo.tp.spring.security</groupId>
+ <artifactId>org.springframework.security.acls</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.argeo.tp.spring.security</groupId>
+ <artifactId>org.springframework.security.aspects</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.argeo.tp.spring.security</groupId>
+ <artifactId>org.springframework.security.config</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.argeo.tp.spring.security</groupId>
+ <artifactId>org.springframework.security.core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.argeo.tp.spring.security</groupId>
+ <artifactId>org.springframework.security.ldap</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.argeo.tp.spring.security</groupId>
+ <artifactId>org.springframework.security.web</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
</dependencies>
<repositories>