X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fauth%2FCmsSessionImpl.java;h=c18348385587e4ac956160779a3235f36b0626e9;hb=a4dac2851e23533c64a23a056da0d82574d8e300;hp=9b667717beaf80a60463d7f5068b87c99979798a;hpb=d66d81530f1da58e2e2c5d25e0a5dc30ad32b848;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 9b667717b..c18348385 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 @@ -3,18 +3,19 @@ package org.argeo.cms.internal.auth; 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; import java.util.UUID; +import javax.crypto.SecretKey; import javax.jcr.Repository; import javax.jcr.Session; import javax.naming.InvalidNameException; @@ -22,14 +23,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; @@ -37,6 +38,7 @@ import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.service.useradmin.Authorization; +/** Default CMS session implementation. */ public class CmsSessionImpl implements CmsSession { private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionImpl.class).getBundleContext(); private final static Log log = LogFactory.getLog(CmsSessionImpl.class); @@ -57,7 +59,9 @@ 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(); @@ -78,7 +82,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; @@ -123,10 +127,21 @@ public class CmsSessionImpl implements CmsSession { return Subject.getSubject(initialContext); } + 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 { @@ -164,8 +179,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); } } @@ -173,6 +188,8 @@ public class CmsSessionImpl implements CmsSession { if (additionalDataSessions.contains(session)) { JcrUtils.logoutQuietly(session); additionalDataSessions.remove(session); + if (log.isTraceEnabled()) + log.trace("Remove additional data session " + session); return; } String path = cn + '/' + session.getWorkspace().getName(); @@ -182,6 +199,8 @@ public class CmsSessionImpl implements CmsSession { Session registeredSession = dataSessions.get(path); if (session != registeredSession) log.warn("Data session " + path + " not consistent for " + userDn); + if (log.isTraceEnabled()) + log.trace("Released data session " + session + " for " + path); notifyAll(); } @@ -190,12 +209,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; } @@ -209,6 +234,11 @@ public class CmsSessionImpl implements CmsSession { return userDn; } + @Override + public String getUserRole() { + return new X500Principal(authorization.getName()).getName(); + } + @Override public String getLocalId() { return localSessionId; @@ -234,6 +264,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; } @@ -243,7 +281,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) { @@ -252,7 +290,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); } @@ -261,7 +299,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) { @@ -270,7 +308,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); } @@ -287,7 +325,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); } } }