X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fauth%2FCmsSessionImpl.java;h=f40c6fffd561d6315239c96109863fa2d9c35495;hb=ae1dc3ee291e2256ba0cdd3994f3d2deab1e4a93;hp=ce38cf0ee94514ed445661707bb9d27e180e6563;hpb=b6cad136dfd4589bc2a8f48ec9168732517f451b;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java index ce38cf0ee..f40c6fffd 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java @@ -1,15 +1,16 @@ package org.argeo.cms.internal.auth; +import java.io.Serializable; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.time.ZonedDateTime; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; -import java.util.LinkedHashSet; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -23,14 +24,14 @@ import javax.naming.ldap.LdapName; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; +import javax.security.auth.x500.X500Principal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; +import org.argeo.api.NodeConstants; +import org.argeo.api.security.NodeSecurityUtils; import org.argeo.cms.auth.CmsSession; import org.argeo.jcr.JcrUtils; -import org.argeo.node.NodeConstants; -import org.argeo.node.security.NodeSecurityUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; @@ -38,15 +39,17 @@ import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.service.useradmin.Authorization; -public class CmsSessionImpl implements CmsSession { +/** Default CMS session implementation. */ +public class CmsSessionImpl implements CmsSession, Serializable { + private static final long serialVersionUID = 1867719354246307225L; private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionImpl.class).getBundleContext(); private final static Log log = LogFactory.getLog(CmsSessionImpl.class); // private final Subject initialSubject; - private final AccessControlContext initialContext; + private transient AccessControlContext accessControlContext; private final UUID uuid; private final String localSessionId; - private final Authorization authorization; + private Authorization authorization; private final LdapName userDn; private final boolean anonymous; @@ -58,12 +61,14 @@ public class CmsSessionImpl implements CmsSession { private Map dataSessions = new HashMap<>(); private Set dataSessionsInUse = new HashSet<>(); - private LinkedHashSet additionalDataSessions = new LinkedHashSet<>(); + private Set additionalDataSessions = new HashSet<>(); + + private Map views = new HashMap<>(); public CmsSessionImpl(Subject initialSubject, Authorization authorization, Locale locale, String localSessionId) { this.creationTime = ZonedDateTime.now(); this.locale = locale; - this.initialContext = Subject.doAs(initialSubject, new PrivilegedAction() { + this.accessControlContext = Subject.doAs(initialSubject, new PrivilegedAction() { @Override public AccessControlContext run() { @@ -79,7 +84,7 @@ public class CmsSessionImpl implements CmsSession { this.userDn = new LdapName(authorization.getName()); this.anonymous = false; } catch (InvalidNameException e) { - throw new CmsException("Invalid user name " + authorization.getName(), e); + throw new IllegalArgumentException("Invalid user name " + authorization.getName(), e); } else { this.userDn = NodeSecurityUtils.ROLE_ANONYMOUS_NAME; @@ -116,26 +121,31 @@ public class CmsSessionImpl implements CmsSession { lc.logout(); } catch (LoginException e) { log.warn("Could not logout " + getSubject() + ": " + e); + } finally { + accessControlContext = null; } log.debug("Closed " + this); } private Subject getSubject() { - return Subject.getSubject(initialContext); + return Subject.getSubject(accessControlContext); } public Set getSecretKeys() { + checkValid(); return getSubject().getPrivateCredentials(SecretKey.class); } public Session newDataSession(String cn, String workspace, Repository repository) { + checkValid(); return login(repository, workspace); } public synchronized Session getDataSession(String cn, String workspace, Repository repository) { + checkValid(); // FIXME make it more robust if (workspace == null) - workspace = "main"; + workspace = NodeConstants.SYS_WORKSPACE; String path = cn + '/' + workspace; if (dataSessionsInUse.contains(path)) { try { @@ -173,8 +183,8 @@ public class CmsSessionImpl implements CmsSession { return repository.login(workspace); } }); - } catch (Exception e) { - throw new CmsException("Cannot log in " + userDn + " to JCR", e); + } catch (PrivilegedActionException e) { + throw new IllegalStateException("Cannot log in " + userDn + " to JCR", e); } } @@ -203,12 +213,18 @@ public class CmsSessionImpl implements CmsSession { return !isClosed(); } - protected boolean isClosed() { + private void checkValid() { + if (!isValid()) + throw new IllegalStateException("CMS session " + uuid + " is not valid since " + end); + } + + final protected boolean isClosed() { return getEnd() != null; } @Override public Authorization getAuthorization() { + checkValid(); return authorization; } @@ -222,6 +238,11 @@ public class CmsSessionImpl implements CmsSession { return userDn; } + @Override + public String getUserRole() { + return new X500Principal(authorization.getName()).getName(); + } + @Override public String getLocalId() { return localSessionId; @@ -247,6 +268,14 @@ public class CmsSessionImpl implements CmsSession { return end; } + @Override + public void registerView(String uid, Object view) { + checkValid(); + if (views.containsKey(uid)) + throw new IllegalArgumentException("View " + uid + " is already registered."); + views.put(uid, view); + } + public String toString() { return "CMS Session " + userDn + " local=" + localSessionId + ", uuid=" + uuid; } @@ -256,7 +285,7 @@ public class CmsSessionImpl implements CmsSession { try { sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_LOCAL_ID + "=" + localId + ")"); } catch (InvalidSyntaxException e) { - throw new CmsException("Cannot get CMS session for id " + localId, e); + throw new IllegalArgumentException("Cannot get CMS session for id " + localId, e); } ServiceReference cmsSessionRef; if (sr.size() == 1) { @@ -265,7 +294,7 @@ public class CmsSessionImpl implements CmsSession { } else if (sr.size() == 0) { return null; } else - throw new CmsException(sr.size() + " CMS sessions registered for " + localId); + throw new IllegalStateException(sr.size() + " CMS sessions registered for " + localId); } @@ -274,7 +303,7 @@ public class CmsSessionImpl implements CmsSession { try { sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + uuid + ")"); } catch (InvalidSyntaxException e) { - throw new CmsException("Cannot get CMS session for uuid " + uuid, e); + throw new IllegalArgumentException("Cannot get CMS session for uuid " + uuid, e); } ServiceReference cmsSessionRef; if (sr.size() == 1) { @@ -283,7 +312,7 @@ public class CmsSessionImpl implements CmsSession { } else if (sr.size() == 0) { return null; } else - throw new CmsException(sr.size() + " CMS sessions registered for " + uuid); + throw new IllegalStateException(sr.size() + " CMS sessions registered for " + uuid); } @@ -300,7 +329,7 @@ public class CmsSessionImpl implements CmsSession { } } } catch (InvalidSyntaxException e) { - throw new CmsException("Cannot get CMS sessions", e); + throw new IllegalArgumentException("Cannot get CMS sessions", e); } } }