Move CMS session management to CMS Context.
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 20 May 2022 14:48:15 +0000 (16:48 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 20 May 2022 14:48:15 +0000 (16:48 +0200)
16 files changed:
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/EgoDashboard.java
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/app/CmsUserApp.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsApp.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsContext.java
org.argeo.cms/src/org/argeo/cms/AbstractCmsApp.java
org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java
org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java
org.argeo.cms/src/org/argeo/cms/auth/RemoteAuthUtils.java
org.argeo.cms/src/org/argeo/cms/auth/RemoteSessionLoginModule.java
org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java
org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java
org.argeo.cms/src/org/argeo/cms/internal/http/WebCmsSessionImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java
org.argeo.cms/src/org/argeo/cms/osgi/CmsOsgiUtils.java [deleted file]
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
rcp/org.argeo.cms.ui.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java

index 5a805d1e953646da314646793cb16bd87b3b58d2..f2a73f2102c08bc490a8e54e960fb66bf9db66ca 100644 (file)
@@ -1,23 +1,18 @@
 package org.argeo.cms.e4.parts;
 
-import java.security.AccessController;
 import java.time.ZonedDateTime;
 
 import javax.annotation.PostConstruct;
-import javax.security.auth.Subject;
 
 import org.argeo.api.cms.CmsSession;
 import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.osgi.CmsOsgiUtils;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
 
 /** A canonical view of the logged in user. */
 public class EgoDashboard {
-       private BundleContext bc = FrameworkUtil.getBundle(EgoDashboard.class).getBundleContext();
+//     private BundleContext bc = FrameworkUtil.getBundle(EgoDashboard.class).getBundleContext();
 
        @PostConstruct
        public void createPartControl(Composite p) {
@@ -33,14 +28,14 @@ public class EgoDashboard {
                        CmsSwtUtils.txt(p, role);
                }
 
-               Subject subject = Subject.getSubject(AccessController.getContext());
-               if (subject != null) {
-                       CmsSession cmsSession = CmsOsgiUtils.getCmsSession(bc, subject);
-                       ZonedDateTime loggedIndSince = cmsSession.getCreationTime();
-                       CmsSwtUtils.lbl(p, "Session:");
-                       CmsSwtUtils.txt(p, cmsSession.getUuid().toString());
-                       CmsSwtUtils.lbl(p, "Logged in since:");
-                       CmsSwtUtils.txt(p, loggedIndSince.toString());
-               }
+//             Subject subject = Subject.getSubject(AccessController.getContext());
+//             if (subject != null) {
+               CmsSession cmsSession = CurrentUser.getCmsSession();
+               ZonedDateTime loggedIndSince = cmsSession.getCreationTime();
+               CmsSwtUtils.lbl(p, "Session:");
+               CmsSwtUtils.txt(p, cmsSession.getUuid().toString());
+               CmsSwtUtils.lbl(p, "Logged in since:");
+               CmsSwtUtils.txt(p, loggedIndSince.toString());
+//             }
        }
 }
index 8bb3cc765fab1fb134530171f60105f1f7f40f2f..064c7e6864bf868fe6d41229820b95f541f28878 100644 (file)
@@ -17,7 +17,6 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 
 public class CmsUserApp extends AbstractCmsApp {
-       private CmsContext cmsContext;
        private ContentRepository contentRepository;
 
        @Override
@@ -35,7 +34,7 @@ public class CmsUserApp extends AbstractCmsApp {
                CmsSwtUi cmsUi = new CmsSwtUi(parent, SWT.NONE);
                if ("login".equals(uiName)) {
                        CmsView cmsView = CmsSwtUtils.getCmsView(cmsUi);
-                       CmsLogin cmsLogin = new CmsLogin(cmsView, cmsContext);
+                       CmsLogin cmsLogin = new CmsLogin(cmsView, getCmsContext());
                        cmsLogin.createUi(cmsUi);
 
                } else if ("data".equals(uiName)) {
@@ -61,8 +60,4 @@ public class CmsUserApp extends AbstractCmsApp {
                this.contentRepository = contentRepository;
        }
 
-       public void setCmsContext(CmsContext cmsContext) {
-               this.cmsContext = cmsContext;
-       }
-
 }
\ No newline at end of file
index af9665a63bdee7dd8df3f8ba44e6c758dc27f4e6..99c619c807e3756517fb9c5f509ee45502abb859 100644 (file)
@@ -30,4 +30,6 @@ public interface CmsApp {
        void addCmsAppListener(CmsAppListener listener);
 
        void removeCmsAppListener(CmsAppListener listener);
+
+       CmsContext getCmsContext();
 }
index fa26b253a2121f6f67f103966657460729fcb898..8f4161c507e2244b7b3bf52fca1647122bf2d4d6 100644 (file)
@@ -3,6 +3,8 @@ package org.argeo.api.cms;
 import java.util.List;
 import java.util.Locale;
 
+import javax.security.auth.Subject;
+
 /**
  * A logical view on this CMS instance, independently of a particular launch or
  * deployment.
@@ -20,7 +22,9 @@ public interface CmsContext {
 
        Long getAvailableSince();
 
-       
        /** Mark this group as a workgroup */
        void createWorkgroup(String groupDn);
+
+       /** Get the CMS session of this subject. */
+       CmsSession getCmsSession(Subject subject);
 }
index 7bf2c96d5a8b4a97fa05e5f2aaa3a5419a19d097..c2d52f3d0c5eb4e2ae63ccec4838e68a001d5e94 100644 (file)
@@ -8,10 +8,13 @@ import java.util.Map;
 
 import org.argeo.api.cms.CmsApp;
 import org.argeo.api.cms.CmsAppListener;
+import org.argeo.api.cms.CmsContext;
 import org.argeo.api.cms.CmsTheme;
 
 /** Base class for {@link CmsApp}s. */
 public abstract class AbstractCmsApp implements CmsApp {
+       private CmsContext cmsContext;
+       
        private Map<String, CmsTheme> themes = Collections.synchronizedMap(new HashMap<>());
 
        private List<CmsAppListener> cmsAppListeners = new ArrayList<>();
@@ -69,4 +72,15 @@ public abstract class AbstractCmsApp implements CmsApp {
                cmsAppListeners.remove(listener);
        }
 
+       @Override
+       public CmsContext getCmsContext() {
+               return cmsContext;
+       }
+
+       public void setCmsContext(CmsContext cmsContext) {
+               this.cmsContext = cmsContext;
+       }
+       
+       
+
 }
index 72676611e4e43f631429c52e8b31a6a0893e4529..46adcf8a516db80a509476947cbcb4c9ee5cd364 100644 (file)
@@ -19,6 +19,7 @@ import org.argeo.api.cms.CmsConstants;
 import org.argeo.cms.internal.auth.CmsSessionImpl;
 import org.argeo.cms.internal.auth.ImpliedByPrincipal;
 import org.argeo.cms.internal.http.WebCmsSessionImpl;
+import org.argeo.cms.internal.runtime.CmsContextImpl;
 import org.argeo.cms.security.NodeSecurityUtils;
 import org.argeo.osgi.useradmin.AuthenticatingUser;
 import org.osgi.framework.BundleContext;
@@ -136,7 +137,7 @@ class CmsAuthUtils {
                        request.setAttribute(HttpContext.AUTHORIZATION, authorization);
 
                        CmsSessionImpl cmsSession;
-                       CmsSessionImpl currentLocalSession = CmsSessionImpl.getByLocalId(httpSessId);
+                       CmsSessionImpl currentLocalSession = CmsContextImpl.getCmsContext().getCmsSessionByLocalId(httpSessId);
                        if (currentLocalSession != null) {
                                boolean currentLocalSessionAnonymous = currentLocalSession.getAuthorization().getName() == null;
                                if (!anonymous) {
@@ -165,6 +166,7 @@ class CmsAuthUtils {
                        } else {
                                // new CMS session
                                cmsSession = new WebCmsSessionImpl(subject, authorization, locale, request);
+                               CmsContextImpl.getCmsContext().registerCmsSession(cmsSession);
                        }
 
                        if (cmsSession == null)// should be dead code (cf. SuppressWarning of the method)
@@ -181,33 +183,34 @@ class CmsAuthUtils {
                        }
                } else {
                        CmsSessionImpl cmsSession = new CmsSessionImpl(subject, authorization, locale, "desktop");
+                       CmsContextImpl.getCmsContext().registerCmsSession(cmsSession);
                        CmsSessionId nodeSessionId = new CmsSessionId(cmsSession.getUuid());
                        subject.getPrivateCredentials().add(nodeSessionId);
                }
        }
 
-       public static CmsSessionImpl cmsSessionFromHttpSession(BundleContext bc, String httpSessionId) {
-               Authorization authorization = null;
-               Collection<ServiceReference<CmsSession>> sr;
-               try {
-                       sr = bc.getServiceReferences(CmsSession.class,
-                                       "(" + CmsSession.SESSION_LOCAL_ID + "=" + httpSessionId + ")");
-               } catch (InvalidSyntaxException e) {
-                       throw new IllegalArgumentException("Cannot get CMS session for id " + httpSessionId, e);
-               }
-               CmsSessionImpl cmsSession;
-               if (sr.size() == 1) {
-                       cmsSession = (CmsSessionImpl) bc.getService(sr.iterator().next());
-//                     locale = cmsSession.getLocale();
-                       authorization = cmsSession.getAuthorization();
-                       if (authorization.getName() == null)
-                               return null;// anonymous is not sufficient
-               } else if (sr.size() == 0)
-                       return null;
-               else
-                       throw new IllegalStateException(sr.size() + ">1 web sessions detected for http session " + httpSessionId);
-               return cmsSession;
-       }
+//     public static CmsSessionImpl cmsSessionFromHttpSession(BundleContext bc, String httpSessionId) {
+//             Authorization authorization = null;
+//             Collection<ServiceReference<CmsSession>> sr;
+//             try {
+//                     sr = bc.getServiceReferences(CmsSession.class,
+//                                     "(" + CmsSession.SESSION_LOCAL_ID + "=" + httpSessionId + ")");
+//             } catch (InvalidSyntaxException e) {
+//                     throw new IllegalArgumentException("Cannot get CMS session for id " + httpSessionId, e);
+//             }
+//             CmsSessionImpl cmsSession;
+//             if (sr.size() == 1) {
+//                     cmsSession = (CmsSessionImpl) bc.getService(sr.iterator().next());
+////                   locale = cmsSession.getLocale();
+//                     authorization = cmsSession.getAuthorization();
+//                     if (authorization.getName() == null)
+//                             return null;// anonymous is not sufficient
+//             } else if (sr.size() == 0)
+//                     return null;
+//             else
+//                     throw new IllegalStateException(sr.size() + ">1 web sessions detected for http session " + httpSessionId);
+//             return cmsSession;
+//     }
 
        public static <T extends Principal> T getSinglePrincipal(Subject subject, Class<T> clss) {
                Set<T> principals = subject.getPrincipals(clss);
index 86a748325ec0e0a553ab3e46d2be403a59fe5c73..cbe4286921c527651e928eebc552d610d745f90e 100644 (file)
@@ -124,7 +124,7 @@ public final class CurrentUser {
        public static CmsSession getCmsSession() {
                Subject subject = currentSubject();
                CmsSessionId cmsSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next();
-               return CmsSessionImpl.getByUuid(cmsSessionId.getUuid());
+               return CmsContextImpl.getCmsContext().getCmsSessionByUuid(cmsSessionId.getUuid());
        }
 
        /*
@@ -151,7 +151,7 @@ public final class CurrentUser {
                        nodeSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next().getUuid();
                else
                        return false;
-               CmsSessionImpl cmsSession = CmsSessionImpl.getByUuid(nodeSessionId.toString());
+               CmsSessionImpl cmsSession = CmsContextImpl.getCmsContext().getCmsSessionByUuid(nodeSessionId);
 
                // FIXME logout all views
                // TODO check why it is sometimes null
index d51997d74fca518340fc5f601e649c7e30dd6480..6274bb146e736165214fcabd52f49c20edb3e5d8 100644 (file)
@@ -8,14 +8,12 @@ import java.util.function.Supplier;
 import javax.security.auth.Subject;
 
 import org.argeo.api.cms.CmsSession;
-import org.argeo.cms.osgi.CmsOsgiUtils;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
+import org.argeo.cms.internal.runtime.CmsContextImpl;
 
 /** Remote authentication utilities. */
 public class RemoteAuthUtils {
        static final String REMOTE_USER = "org.osgi.service.http.authentication.remote.user";
-       private static BundleContext bundleContext = FrameworkUtil.getBundle(RemoteAuthUtils.class).getBundleContext();
+//     private static BundleContext bundleContext = FrameworkUtil.getBundle(RemoteAuthUtils.class).getBundleContext();
 
        /**
         * Execute this supplier, using the CMS class loader as context classloader.
@@ -58,7 +56,7 @@ public class RemoteAuthUtils {
        public static CmsSession getCmsSession(RemoteAuthRequest req) {
                Subject subject = Subject
                                .getSubject((AccessControlContext) req.getAttribute(AccessControlContext.class.getName()));
-               CmsSession cmsSession = CmsOsgiUtils.getCmsSession(bundleContext, subject);
+               CmsSession cmsSession = CmsContextImpl.getCmsContext().getCmsSession(subject);
                return cmsSession;
        }
 }
index 962094d4ace32377f3b9e4ba5da1e2ab1ce81f1a..b5734afd3221957b1fe80a7ef82ffc21f3090993 100644 (file)
@@ -17,9 +17,8 @@ import javax.security.auth.spi.LoginModule;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.auth.CmsSessionImpl;
+import org.argeo.cms.internal.runtime.CmsContextImpl;
 import org.argeo.cms.internal.runtime.KernelUtils;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
 import org.osgi.service.http.HttpContext;
 import org.osgi.service.useradmin.Authorization;
 
@@ -34,7 +33,7 @@ public class RemoteSessionLoginModule implements LoginModule {
        private RemoteAuthRequest request = null;
        private RemoteAuthResponse response = null;
 
-       private BundleContext bc;
+//     private BundleContext bc;
 
        private Authorization authorization;
        private Locale locale;
@@ -43,8 +42,8 @@ public class RemoteSessionLoginModule implements LoginModule {
        @Override
        public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
                        Map<String, ?> options) {
-               bc = FrameworkUtil.getBundle(RemoteSessionLoginModule.class).getBundleContext();
-               assert bc != null;
+//             bc = FrameworkUtil.getBundle(RemoteSessionLoginModule.class).getBundleContext();
+//             assert bc != null;
                this.subject = subject;
                this.callbackHandler = callbackHandler;
                this.sharedState = (Map<String, Object>) sharedState;
@@ -71,8 +70,8 @@ public class RemoteSessionLoginModule implements LoginModule {
                        String httpSessionId = httpSession.getId();
 //                     if (log.isTraceEnabled())
 //                             log.trace("HTTP login: " + request.getPathInfo() + " #" + httpSessionId);
-                       CmsSessionImpl cmsSession = CmsAuthUtils.cmsSessionFromHttpSession(bc, httpSessionId);
-                       if (cmsSession != null) {
+                       CmsSessionImpl cmsSession = CmsContextImpl.getCmsContext().getCmsSessionByLocalId(httpSessionId);
+                       if (cmsSession != null && !cmsSession.isAnonymous()) {
                                authorization = cmsSession.getAuthorization();
                                locale = cmsSession.getLocale();
                                if (log.isTraceEnabled())
@@ -91,8 +90,8 @@ public class RemoteSessionLoginModule implements LoginModule {
                                String httpSessionId = httpSession.getId();
 //                             if (log.isTraceEnabled())
 //                                     log.trace("HTTP login: " + request.getPathInfo() + " #" + httpSessionId);
-                               CmsSessionImpl cmsSession = CmsAuthUtils.cmsSessionFromHttpSession(bc, httpSessionId);
-                               if (cmsSession != null) {
+                               CmsSessionImpl cmsSession = CmsContextImpl.getCmsContext().getCmsSessionByLocalId(httpSessionId);
+                               if (cmsSession != null && !cmsSession.isAnonymous()) {
                                        authorization = cmsSession.getAuthorization();
                                        locale = cmsSession.getLocale();
                                        if (log.isTraceEnabled())
index 738b507e79495a5898f29098f5a0f2c4169bf8a9..ea7d1f37082bf17f335dc27b4c02a89ffc74266c 100644 (file)
@@ -80,7 +80,7 @@ public class UserAdminLoginModule implements LoginModule {
 
        @Override
        public boolean login() throws LoginException {
-               UserAdmin userAdmin = CmsContextImpl.getUserAdmin();
+               UserAdmin userAdmin = CmsContextImpl.getCmsContext().getUserAdmin();
                final String username;
                final char[] password;
                Object certificateChain = null;
@@ -212,7 +212,7 @@ public class UserAdminLoginModule implements LoginModule {
 //             if (singleUser) {
 //                     OsUserUtils.loginAsSystemUser(subject);
 //             }
-               UserAdmin userAdmin = CmsContextImpl.getUserAdmin();
+               UserAdmin userAdmin = CmsContextImpl.getCmsContext().getUserAdmin();
                Authorization authorization;
                if (callbackHandler == null) {// anonymous
                        authorization = userAdmin.getAuthorization(null);
index aa3a6ad17dd3e61fa4bd4dc751c6533a2a1f8b4a..a3670c0cb4b8cbf4313a7a8eea3aa82a26b77b57 100644 (file)
@@ -28,6 +28,7 @@ import javax.security.auth.x500.X500Principal;
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsSession;
+import org.argeo.cms.internal.runtime.CmsContextImpl;
 import org.argeo.cms.security.NodeSecurityUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -39,7 +40,7 @@ import org.osgi.service.useradmin.Authorization;
 /** 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 BundleContext bc = FrameworkUtil.getBundle(CmsSessionImpl.class).getBundleContext();
        private final static CmsLog log = CmsLog.getLog(CmsSessionImpl.class);
 
        // private final Subject initialSubject;
@@ -85,18 +86,20 @@ public class CmsSessionImpl implements CmsSession, Serializable {
                        this.userDn = NodeSecurityUtils.ROLE_ANONYMOUS_NAME;
                        this.anonymous = true;
                }
+               // TODO use time-based UUID?
                this.uuid = UUID.randomUUID();
                // register as service
-               Hashtable<String, String> props = new Hashtable<>();
-               props.put(CmsSession.USER_DN, userDn.toString());
-               props.put(CmsSession.SESSION_UUID, uuid.toString());
-               props.put(CmsSession.SESSION_LOCAL_ID, localSessionId);
-               serviceRegistration = bc.registerService(CmsSession.class, this, props);
+//             Hashtable<String, String> props = new Hashtable<>();
+//             props.put(CmsSession.USER_DN, userDn.toString());
+//             props.put(CmsSession.SESSION_UUID, uuid.toString());
+//             props.put(CmsSession.SESSION_LOCAL_ID, localSessionId);
+//             serviceRegistration = bc.registerService(CmsSession.class, this, props);
        }
 
        public void close() {
                end = ZonedDateTime.now();
-               serviceRegistration.unregister();
+               CmsContextImpl.getCmsContext().unregisterCmsSession(this);
+//             serviceRegistration.unregister();
 
                for (Consumer<CmsSession> onClose : onCloseCallbacks) {
                        onClose.accept(this);
@@ -205,59 +208,59 @@ public class CmsSessionImpl implements CmsSession, Serializable {
        }
 
        public String toString() {
-               return "CMS Session " + userDn + " local=" + localSessionId + ", uuid=" + uuid;
+               return "CMS Session " + userDn + " localId=" + localSessionId + ", uuid=" + uuid;
        }
 
-       public static CmsSessionImpl getByLocalId(String localId) {
-               Collection<ServiceReference<CmsSession>> sr;
-               try {
-                       sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_LOCAL_ID + "=" + localId + ")");
-               } catch (InvalidSyntaxException e) {
-                       throw new IllegalArgumentException("Cannot get CMS session for id " + localId, e);
-               }
-               ServiceReference<CmsSession> cmsSessionRef;
-               if (sr.size() == 1) {
-                       cmsSessionRef = sr.iterator().next();
-                       return (CmsSessionImpl) bc.getService(cmsSessionRef);
-               } else if (sr.size() == 0) {
-                       return null;
-               } else
-                       throw new IllegalStateException(sr.size() + " CMS sessions registered for " + localId);
-
-       }
-
-       public static CmsSessionImpl getByUuid(Object uuid) {
-               Collection<ServiceReference<CmsSession>> sr;
-               try {
-                       sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + uuid + ")");
-               } catch (InvalidSyntaxException e) {
-                       throw new IllegalArgumentException("Cannot get CMS session for uuid " + uuid, e);
-               }
-               ServiceReference<CmsSession> cmsSessionRef;
-               if (sr.size() == 1) {
-                       cmsSessionRef = sr.iterator().next();
-                       return (CmsSessionImpl) bc.getService(cmsSessionRef);
-               } else if (sr.size() == 0) {
-                       return null;
-               } else
-                       throw new IllegalStateException(sr.size() + " CMS sessions registered for " + uuid);
-
-       }
-
-       public static void closeInvalidSessions() {
-               Collection<ServiceReference<CmsSession>> srs;
-               try {
-                       srs = bc.getServiceReferences(CmsSession.class, null);
-                       for (ServiceReference<CmsSession> sr : srs) {
-                               CmsSession cmsSession = bc.getService(sr);
-                               if (!cmsSession.isValid()) {
-                                       ((CmsSessionImpl) cmsSession).close();
-                                       if (log.isDebugEnabled())
-                                               log.debug("Closed expired CMS session " + cmsSession);
-                               }
-                       }
-               } catch (InvalidSyntaxException e) {
-                       throw new IllegalArgumentException("Cannot get CMS sessions", e);
-               }
-       }
+//     public static CmsSessionImpl getByLocalId(String localId) {
+//             Collection<ServiceReference<CmsSession>> sr;
+//             try {
+//                     sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_LOCAL_ID + "=" + localId + ")");
+//             } catch (InvalidSyntaxException e) {
+//                     throw new IllegalArgumentException("Cannot get CMS session for id " + localId, e);
+//             }
+//             ServiceReference<CmsSession> cmsSessionRef;
+//             if (sr.size() == 1) {
+//                     cmsSessionRef = sr.iterator().next();
+//                     return (CmsSessionImpl) bc.getService(cmsSessionRef);
+//             } else if (sr.size() == 0) {
+//                     return null;
+//             } else
+//                     throw new IllegalStateException(sr.size() + " CMS sessions registered for " + localId);
+//
+//     }
+//
+//     public static CmsSessionImpl getByUuid(Object uuid) {
+//             Collection<ServiceReference<CmsSession>> sr;
+//             try {
+//                     sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + uuid + ")");
+//             } catch (InvalidSyntaxException e) {
+//                     throw new IllegalArgumentException("Cannot get CMS session for uuid " + uuid, e);
+//             }
+//             ServiceReference<CmsSession> cmsSessionRef;
+//             if (sr.size() == 1) {
+//                     cmsSessionRef = sr.iterator().next();
+//                     return (CmsSessionImpl) bc.getService(cmsSessionRef);
+//             } else if (sr.size() == 0) {
+//                     return null;
+//             } else
+//                     throw new IllegalStateException(sr.size() + " CMS sessions registered for " + uuid);
+//
+//     }
+//
+//     public static void closeInvalidSessions() {
+//             Collection<ServiceReference<CmsSession>> srs;
+//             try {
+//                     srs = bc.getServiceReferences(CmsSession.class, null);
+//                     for (ServiceReference<CmsSession> sr : srs) {
+//                             CmsSession cmsSession = bc.getService(sr);
+//                             if (!cmsSession.isValid()) {
+//                                     ((CmsSessionImpl) cmsSession).close();
+//                                     if (log.isDebugEnabled())
+//                                             log.debug("Closed expired CMS session " + cmsSession);
+//                             }
+//                     }
+//             } catch (InvalidSyntaxException e) {
+//                     throw new IllegalArgumentException("Cannot get CMS sessions", e);
+//             }
+//     }
 }
index fd51c597a4795308a6ef9591fd65cdea0a90de9c..eb6c89d37b52a49aa01963a826c09a67dacfcea8 100644 (file)
@@ -27,7 +27,7 @@ public class WebCmsSessionImpl extends CmsSessionImpl {
                return httpSession.isValid();
        }
 
-       public static CmsSessionImpl getCmsSession(RemoteAuthRequest request) {
-               return CmsSessionImpl.getByLocalId(request.getSession().getId());
-       }
+//     public static CmsSessionImpl getCmsSession(RemoteAuthRequest request) {
+//             return CmsSessionImpl.getByLocalId(request.getSession().getId());
+//     }
 }
index 8e29f667365e10870da3f4ebf36d873af2d31594..ef9f0ec9a8df203ad6a50a588a1cf9b79ec88fa3 100644 (file)
@@ -3,18 +3,25 @@ package org.argeo.cms.internal.runtime;
 import static java.util.Locale.ENGLISH;
 
 import java.lang.management.ManagementFactory;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
+import javax.security.auth.Subject;
+
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsContext;
 import org.argeo.api.cms.CmsDeployment;
 import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsSessionId;
 import org.argeo.api.cms.CmsState;
 import org.argeo.cms.LocaleUtils;
-import org.argeo.cms.internal.osgi.NodeUserAdmin;
+import org.argeo.cms.internal.auth.CmsSessionImpl;
 import org.ietf.jgss.GSSCredential;
 import org.osgi.service.useradmin.UserAdmin;
 
@@ -35,6 +42,10 @@ public class CmsContextImpl implements CmsContext {
 
        private Long availableSince;
 
+       // CMS sessions
+       private Map<UUID, CmsSessionImpl> cmsSessionsByUuid = new HashMap<>();
+       private Map<String, CmsSessionImpl> cmsSessionsByLocalId = new HashMap<>();
+
 //     public CmsContextImpl() {
 //             initTrackers();
 //     }
@@ -164,20 +175,20 @@ public class CmsContextImpl implements CmsContext {
         * STATIC
         */
 
-       public synchronized static CmsContext getCmsContext() {
+       public synchronized static CmsContextImpl getCmsContext() {
                return getInstance();
        }
 
-       /** Required by USER login module. */
-       public synchronized static UserAdmin getUserAdmin() {
-               return getInstance().userAdmin;
-       }
+//     /** Required by USER login module. */
+//     public synchronized static UserAdmin getUserAdmin() {
+//             return getInstance().userAdmin;
+//     }
 
        /** Required by SPNEGO login module. */
        @Deprecated
        public synchronized static GSSCredential getAcceptorCredentials() {
                // FIXME find a cleaner way
-               return ((NodeUserAdmin) getInstance().userAdmin).getAcceptorCredentials();
+               return ((CmsUserAdmin) getInstance().userAdmin).getAcceptorCredentials();
        }
 
        private synchronized static void setInstance(CmsContextImpl cmsContextImpl) {
@@ -198,4 +209,45 @@ public class CmsContextImpl implements CmsContext {
                }
        }
 
+       public UserAdmin getUserAdmin() {
+               return userAdmin;
+       }
+
+       /*
+        * CMS Sessions
+        */
+
+       @Override
+       public synchronized CmsSession getCmsSession(Subject subject) {
+               if (subject.getPrivateCredentials(CmsSessionId.class).isEmpty())
+                       return null;
+               CmsSessionId cmsSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next();
+               return getCmsSessionByUuid(cmsSessionId.getUuid());
+       }
+
+       public synchronized void registerCmsSession(CmsSessionImpl cmsSession) {
+               if (cmsSessionsByUuid.containsKey(cmsSession.getUuid())
+                               || cmsSessionsByLocalId.containsKey(cmsSession.getLocalId()))
+                       throw new IllegalStateException("CMS session " + cmsSession + " is already registered.");
+               cmsSessionsByUuid.put(cmsSession.getUuid(), cmsSession);
+               cmsSessionsByLocalId.put(cmsSession.getLocalId(), cmsSession);
+       }
+
+       public synchronized void unregisterCmsSession(CmsSessionImpl cmsSession) {
+               if (!cmsSessionsByUuid.containsKey(cmsSession.getUuid())
+                               || !cmsSessionsByLocalId.containsKey(cmsSession.getLocalId()))
+                       throw new IllegalStateException("CMS session " + cmsSession + " is not registered.");
+               CmsSession removed = cmsSessionsByUuid.remove(cmsSession.getUuid());
+               assert removed == cmsSession;
+               cmsSessionsByLocalId.remove(cmsSession.getLocalId());
+       }
+
+       public synchronized CmsSessionImpl getCmsSessionByUuid(UUID uuid) {
+               return cmsSessionsByUuid.get(uuid);
+       }
+
+       public synchronized CmsSessionImpl getCmsSessionByLocalId(String localId) {
+               return cmsSessionsByLocalId.get(localId);
+       }
+
 }
diff --git a/org.argeo.cms/src/org/argeo/cms/osgi/CmsOsgiUtils.java b/org.argeo.cms/src/org/argeo/cms/osgi/CmsOsgiUtils.java
deleted file mode 100644 (file)
index 424d62f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.argeo.cms.osgi;
-
-import java.util.Collection;
-
-import javax.security.auth.Subject;
-
-import org.argeo.api.cms.CmsSession;
-import org.argeo.api.cms.CmsSessionId;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-public class CmsOsgiUtils {
-
-       /** @return The {@link CmsSession} for this {@link Subject} or null. */
-       public static CmsSession getCmsSession(BundleContext bc, Subject subject) {
-               if (subject.getPrivateCredentials(CmsSessionId.class).isEmpty())
-                       return null;
-               CmsSessionId cmsSessionId = subject.getPrivateCredentials(CmsSessionId.class).iterator().next();
-               String uuid = cmsSessionId.getUuid().toString();
-               Collection<ServiceReference<CmsSession>> sr;
-               try {
-                       sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_UUID + "=" + uuid + ")");
-               } catch (InvalidSyntaxException e) {
-                       throw new IllegalArgumentException("Cannot get CMS session for uuid " + uuid, e);
-               }
-               ServiceReference<CmsSession> cmsSessionRef;
-               if (sr.size() == 1) {
-                       cmsSessionRef = sr.iterator().next();
-                       return bc.getService(cmsSessionRef);
-               } else if (sr.size() == 0) {
-                       return null;
-               } else
-                       throw new IllegalStateException(sr.size() + " CMS sessions registered for " + uuid);
-       }
-
-       /** Singleton.*/
-       private CmsOsgiUtils() {
-       }
-}
index afc07c5b0681dfa61cfd057ed3ead7ad1ffcc25e..9b0ba4019c3a49ce40cf5084d4212e6cce84bd4a 100644 (file)
@@ -15,15 +15,14 @@ import javax.security.auth.login.LoginException;
 import org.argeo.api.cms.CmsApp;
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsSession;
 import org.argeo.api.cms.CmsUi;
 import org.argeo.api.cms.CmsView;
-import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.UxContext;
 import org.argeo.cms.LocaleUtils;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.RemoteAuthCallbackHandler;
-import org.argeo.cms.osgi.CmsOsgiUtils;
 import org.argeo.cms.servlet.ServletHttpRequest;
 import org.argeo.cms.servlet.ServletHttpResponse;
 import org.argeo.cms.swt.CmsSwtUtils;
@@ -265,7 +264,7 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL
 
        @Override
        public CmsSession getCmsSession() {
-               CmsSession cmsSession = CmsOsgiUtils.getCmsSession(cmsWebApp.getBundleContext(), getSubject());
+               CmsSession cmsSession = cmsWebApp.getCmsApp().getCmsContext().getCmsSession(getSubject());
                return cmsSession;
        }
 
index 664d49d2b54896d99f0038b861cdd09bd4b5562a..ed019d706b1114f6f545319ffbf7e43dcc0649dc 100644 (file)
@@ -20,7 +20,6 @@ import org.argeo.api.cms.CmsTheme;
 import org.argeo.api.cms.CmsUi;
 import org.argeo.api.cms.CmsView;
 import org.argeo.api.cms.UxContext;
-import org.argeo.cms.osgi.CmsOsgiUtils;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.eclipse.e4.ui.css.core.engine.CSSEngine;
 import org.eclipse.e4.ui.css.core.engine.CSSErrorHandler;
@@ -158,7 +157,7 @@ public class CmsRcpApp implements CmsView {
 
        @Override
        public CmsSession getCmsSession() {
-               CmsSession cmsSession = CmsOsgiUtils.getCmsSession(bundleContext, getSubject());
+               CmsSession cmsSession = cmsApp.getCmsContext().getCmsSession(getSubject());
                return cmsSession;
        }