Improve RCP security
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 27 Mar 2011 13:39:41 +0000 (13:39 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 27 Mar 2011 13:39:41 +0000 (13:39 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4383 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

23 files changed:
eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/browser/HomeContentProvider.java [new file with mode: 0644]
eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/views/UserCentricJcrBrowser.java [new file with mode: 0644]
gis/runtime/org.argeo.gis.geotools/pom.xml
security/modules/org.argeo.security.dao.jackrabbit/META-INF/MANIFEST.MF
security/modules/org.argeo.security.dao.jackrabbit/META-INF/spring/jcrsecuritydao-osgi.xml
security/modules/org.argeo.security.dao.jackrabbit/META-INF/spring/jcrsecuritydao.xml
security/modules/org.argeo.security.dao.jackrabbit/META-INF/spring/services.xml [new file with mode: 0644]
security/modules/org.argeo.security.dao.jackrabbit/security.properties [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rcp/META-INF/jaas_default.txt
security/plugins/org.argeo.security.ui.rcp/META-INF/spring/application-osgi.xml [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rcp/META-INF/spring/application.xml [new file with mode: 0644]
security/plugins/org.argeo.security.ui.rcp/plugin.xml
security/plugins/org.argeo.security.ui.rcp/src/main/java/org/argeo/security/ui/rcp/AbstractSecureApplication.java
security/plugins/org.argeo.security.ui/META-INF/spring/osgi.xml
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/OsAuthenticationProvider.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrAuthenticationProvider.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/SecureThreadBoundSession.java
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/osgi.xml
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/spring/ThreadBoundSession.java [new file with mode: 0644]

diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/browser/HomeContentProvider.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/browser/HomeContentProvider.java
new file mode 100644 (file)
index 0000000..b3577a2
--- /dev/null
@@ -0,0 +1,14 @@
+package org.argeo.eclipse.ui.jcr.browser;
+
+import javax.jcr.Session;
+
+import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider;
+import org.argeo.jcr.JcrUtils;
+
+public class HomeContentProvider extends SimpleNodeContentProvider {
+
+       public HomeContentProvider(Session session) {
+               super(session, new String[] { JcrUtils.getUserHomePath(session) });
+       }
+
+}
diff --git a/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/views/UserCentricJcrBrowser.java b/eclipse/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/views/UserCentricJcrBrowser.java
new file mode 100644 (file)
index 0000000..c121f59
--- /dev/null
@@ -0,0 +1,158 @@
+package org.argeo.eclipse.ui.jcr.views;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider;
+import org.argeo.eclipse.ui.jcr.browser.HomeContentProvider;
+import org.argeo.eclipse.ui.jcr.browser.NodeLabelProvider;
+import org.argeo.eclipse.ui.jcr.browser.RepositoryNode;
+import org.argeo.eclipse.ui.jcr.browser.WorkspaceNode;
+import org.argeo.eclipse.ui.jcr.utils.JcrFileProvider;
+import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer;
+import org.argeo.eclipse.ui.specific.FileHandler;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.part.ViewPart;
+
+/** JCR browser organized around a user home node. */
+public class UserCentricJcrBrowser extends ViewPart {
+       // private final static Log log = LogFactory.getLog(UserBrowser.class);
+
+       private TreeViewer nodesViewer;
+
+       private Session session;
+
+       @Override
+       public void createPartControl(Composite parent) {
+
+               // Instantiate the generic object that fits for
+               // both RCP & RAP, must be final to be accessed in the double click
+               // listener.
+               // Not that in RAP, it registers a service handler that provide the
+               // access to the files.
+
+               final JcrFileProvider jfp = new JcrFileProvider();
+               final FileHandler fh = new FileHandler(jfp);
+
+               parent.setLayout(new FillLayout());
+
+               Composite top = new Composite(parent, SWT.NONE);
+               GridLayout gl = new GridLayout(1, false);
+               top.setLayout(gl);
+
+               // nodes viewer
+               nodesViewer = new TreeViewer(top, SWT.MULTI | SWT.H_SCROLL
+                               | SWT.V_SCROLL);
+               nodesViewer.getTree().setLayoutData(
+                               new GridData(SWT.FILL, SWT.FILL, true, true));
+
+               SimpleNodeContentProvider contentProvider = new HomeContentProvider(
+                               session);
+               nodesViewer.setContentProvider(contentProvider);
+               nodesViewer.setLabelProvider(new NodeLabelProvider());
+
+               nodesViewer.addDoubleClickListener(new IDoubleClickListener() {
+                       public void doubleClick(DoubleClickEvent event) {
+                               if (event.getSelection() == null
+                                               || event.getSelection().isEmpty())
+                                       return;
+                               Object obj = ((IStructuredSelection) event.getSelection())
+                                               .getFirstElement();
+                               if (obj instanceof RepositoryNode) {
+                                       RepositoryNode rpNode = (RepositoryNode) obj;
+                                       rpNode.login();
+                                       // For the file provider to be able to browse the various
+                                       // repository.
+                                       // TODO : enhanced that.
+                                       jfp.setRepositoryNode(rpNode);
+                                       nodesViewer.refresh(obj);
+
+                               } else if (obj instanceof WorkspaceNode) {
+                                       ((WorkspaceNode) obj).login();
+                                       nodesViewer.refresh(obj);
+                               } else if (obj instanceof Node) {
+                                       Node node = (Node) obj;
+
+                                       // double clic on a file node triggers its opening
+                                       try {
+                                               if (node.isNodeType("nt:file")) {
+                                                       String name = node.getName();
+                                                       String id = node.getIdentifier();
+                                                       fh.openFile(name, id);
+                                               }
+                                       } catch (RepositoryException re) {
+                                               throw new ArgeoException(
+                                                               "Repository error while getting Node file info",
+                                                               re);
+                                       }
+                               }
+                       }
+               });
+
+               // context menu
+               MenuManager menuManager = new MenuManager();
+               Menu menu = menuManager.createContextMenu(nodesViewer.getTree());
+               nodesViewer.getTree().setMenu(menu);
+               getSite().registerContextMenu(menuManager, nodesViewer);
+               getSite().setSelectionProvider(nodesViewer);
+
+               nodesViewer.setInput(session);
+
+               nodesViewer.setComparer(new NodeViewerComparer());
+
+       }
+
+       @Override
+       public void setFocus() {
+               nodesViewer.getTree().setFocus();
+       }
+
+       /**
+        * To be overidden to adapt size of form and result frames.
+        * 
+        * @return
+        */
+       protected int[] getWeights() {
+               return new int[] { 70, 30 };
+       }
+
+       /*
+        * NOTIFICATION
+        */
+       public void refresh(Object obj) {
+               nodesViewer.refresh(obj);
+       }
+
+       public void nodeAdded(Node parentNode, Node newNode) {
+               nodesViewer.refresh(parentNode);
+               nodesViewer.expandToLevel(newNode, 0);
+       }
+
+       public void nodeRemoved(Node parentNode) {
+
+               IStructuredSelection newSel = new StructuredSelection(parentNode);
+               nodesViewer.setSelection(newSel, true);
+               // Force refresh
+               IStructuredSelection tmpSel = (IStructuredSelection) nodesViewer
+                               .getSelection();
+               nodesViewer.refresh(tmpSel.getFirstElement());
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+}
index 992ddfa66b2b1c650d406cdf1709bb668ba21460..2278658fa8ab071a42351504b0349f507b3eb782 100644 (file)
                        <groupId>org.argeo.dep.osgi</groupId>
                        <artifactId>org.argeo.dep.osgi.jts</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>org.argeo.dep.osgi</groupId>
-                       <artifactId>org.argeo.dep.osgi.geoapi</artifactId>
-               </dependency>
                <dependency>
                        <groupId>org.jdom</groupId>
                        <artifactId>com.springsource.org.jdom</artifactId>
index e5b22fb3a1d1983fd2744af2c133a4f9c6e36ddb..47cec3bab3efbbc911d51458260c75666d101273 100644 (file)
@@ -2,7 +2,11 @@ Bundle-SymbolicName: org.argeo.security.dao.jackrabbit
 Bundle-Version: 0.3.2.SNAPSHOT
 Import-Package: javax.jcr;version="[2.0.0,3.0.0)",
  org.argeo.security,
+ org.argeo.security.core,
  org.argeo.security.jackrabbit.providers,
  org.argeo.security.jcr,
+ org.springframework.beans.factory.config;specification-version="2.5.6.SEC01",
+ org.springframework.security;specification-version="2.0.6.RELEASE",
+ org.springframework.security.adapters;specification-version="2.0.6.RELEASE",
  org.springframework.security.providers;specification-version="2.0.6.RELEASE"
 Bundle-Name: Security DAO Jackrabbit
index 4b15210c001bfcc753c671f1e6a728ff425f1e72..21d316f169bc883c2918840bfeb8aee0aa37d6e6 100644 (file)
                cardinality="0..1">\r
                <listener ref="jcrAuthenticationProvider" bind-method="register"\r
                        unbind-method="unregister" />\r
-<!--           <listener ref="osJcrAuthenticationProvider" bind-method="register" -->\r
-<!--                   unbind-method="unregister" /> -->\r
        </reference>\r
-<!--   <reference id="systemExecutor" interface="org.argeo.security.SystemExecutionService" /> -->\r
+       <reference id="nodeRepository" interface="javax.jcr.Repository"\r
+               filter="(argeo.jcr.repository.alias=node)" cardinality="0..1">\r
+               <listener ref="osJcrAuthenticationProvider" bind-method="register"\r
+                       unbind-method="unregister" />\r
+       </reference>\r
+\r
+       <reference id="systemExecutionServiceRef" interface="org.argeo.security.SystemExecutionService"\r
+               cardinality="0..1">\r
+               <listener ref="osJcrAuthenticationProvider" bind-method="register"\r
+                       unbind-method="unregister" />\r
+       </reference>\r
 \r
        <!-- SERVICES -->\r
-       <service ref="jcrAuthenticationProvider"\r
-               interface="org.springframework.security.providers.AuthenticationProvider" />\r
-<!--   <service ref="osJcrAuthenticationProvider" -->\r
-<!--           interface="org.springframework.security.providers.AuthenticationProvider" /> -->\r
+       <service ref="systemExecutionService" interface="org.argeo.security.SystemExecutionService" />\r
+\r
+       <service ref="authenticationManager"\r
+               interface="org.springframework.security.AuthenticationManager" />\r
+\r
 </beans:beans>
\ No newline at end of file
index ab4104f82f626fa708a6c516d8e1475989bdd35e..bbe3a165e34968f6305f7874c0e4cf7546cdd406 100644 (file)
@@ -6,7 +6,6 @@
        <bean id="jcrAuthenticationProvider"
                class="org.argeo.security.jackrabbit.providers.JackrabbitAuthenticationProvider" />
 
-<!--   <bean id="osJcrAuthenticationProvider" class="org.argeo.security.jcr.OsJcrAuthenticationProvider"> -->
-<!--           <property name="systemExecutor" ref="systemExecutor" /> -->
-<!--   </bean> -->
+       <bean id="osJcrAuthenticationProvider" class="org.argeo.security.jcr.OsJcrAuthenticationProvider">
+       </bean>
 </beans>
\ No newline at end of file
diff --git a/security/modules/org.argeo.security.dao.jackrabbit/META-INF/spring/services.xml b/security/modules/org.argeo.security.dao.jackrabbit/META-INF/spring/services.xml
new file mode 100644 (file)
index 0000000..c234843
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+       <bean
+               class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+               <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
+               <property name="locations">
+                       <value>osgibundle:security.properties</value>
+               </property>
+       </bean>
+
+       <bean id="systemExecutionService" class="org.argeo.security.core.KeyBasedSystemExecutionService">
+               <property name="systemAuthenticationKey" value="${argeo.security.systemKey}" />
+               <property name="authenticationManager" ref="authenticationManager" />
+       </bean>
+
+       <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
+               <property name="providers">
+                       <bean factory-bean="authenticationProvidersRegister"
+                               factory-method="getProviders" />
+               </property>
+       </bean>
+
+       <bean id="authenticationProvidersRegister" class="org.argeo.security.core.AuthenticationProvidersRegister">
+               <property name="defaultProviders">
+                       <list>
+                               <bean class="org.springframework.security.adapters.AuthByAdapterProvider">
+                                       <property name="key" value="${argeo.security.systemKey}" />
+                               </bean>
+                               <ref bean="jcrAuthenticationProvider" />
+                               <ref bean="osJcrAuthenticationProvider" />
+                       </list>
+               </property>
+       </bean>
+</beans>
\ No newline at end of file
diff --git a/security/modules/org.argeo.security.dao.jackrabbit/security.properties b/security/modules/org.argeo.security.dao.jackrabbit/security.properties
new file mode 100644 (file)
index 0000000..ae7aa87
--- /dev/null
@@ -0,0 +1 @@
+argeo.security.systemKey=argeo
index 5e0e4d3b2e221e1895c41a11d145939d638bae0b..96747d3ea73d1a7b2ad401a3d5c38a13a34f77d9 100644 (file)
@@ -1,3 +1,8 @@
+OS_SPRING {
+    org.eclipse.equinox.security.auth.module.ExtensionLoginModule required
+        extensionId="org.argeo.security.equinox.osSpringLoginModule";
+};
+
 NIX {
     org.eclipse.equinox.security.auth.module.ExtensionLoginModule requisite
         extensionId="org.argeo.security.equinox.unixLoginModule";
diff --git a/security/plugins/org.argeo.security.ui.rcp/META-INF/spring/application-osgi.xml b/security/plugins/org.argeo.security.ui.rcp/META-INF/spring/application-osgi.xml
new file mode 100644 (file)
index 0000000..d50070b
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+       xmlns:util="http://www.springframework.org/schema/util"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/osgi  \r
+       http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+       http://www.springframework.org/schema/beans   \r
+       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+       http://www.springframework.org/schema/util\r
+       http://www.springframework.org/schema/util/spring-util-2.5.xsd">\r
+\r
+       <!-- REFERENCE -->\r
+<!--   <reference id="authenticationManager" -->\r
+<!--           interface="org.springframework.security.AuthenticationManager" /> -->\r
+\r
+</beans:beans>
\ No newline at end of file
diff --git a/security/plugins/org.argeo.security.ui.rcp/META-INF/spring/application.xml b/security/plugins/org.argeo.security.ui.rcp/META-INF/spring/application.xml
new file mode 100644 (file)
index 0000000..dbf3680
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+       <bean id="secureUi" class="org.argeo.security.ui.rcp.SecureRcp">
+<!--           <property name="authenticationManager" ref="authenticationManager" /> -->
+       </bean>
+</beans>
\ No newline at end of file
index 39b8c848ccb02c2dd701814c621e9536af44b8b0..6a79da51082678faa38473ae31d5bfe602f9eb22 100644 (file)
@@ -27,7 +27,7 @@
          thread="main"
          visible="true">
          <run
-               class="org.argeo.security.ui.rcp.SecureRcp">
+               class="org.argeo.eclipse.spring.SpringExtensionFactory">
          </run>
       </application>
    </extension>
index 3da1bc7b4474ebfa8f6dc4bc29e4680d324282b9..26795f274ca9404f6ceb73135c47209c2d667807 100644 (file)
@@ -46,6 +46,7 @@ public abstract class AbstractSecureApplication implements IApplication {
 
                final Display display = PlatformUI.createDisplay();
 
+               // login
                Subject subject = null;
                try {
                        loginContext.login();
index a0d30b50619342b8176a1a1f81c8d186627a9ef4..9e357a36d5af331af439e1b88d0ae2c432e72393 100644 (file)
@@ -9,5 +9,6 @@
        osgi:default-timeout="30000">\r
 \r
        <reference id="userDetailsManager"\r
-               interface="org.springframework.security.userdetails.UserDetailsManager" />\r
+               interface="org.springframework.security.userdetails.UserDetailsManager"\r
+               cardinality="0..1" />\r
 </beans:beans>
\ No newline at end of file
index e9c83839f2e35c6d3ca836aa578a1913da517e89..fa70489fc4397b2f64e60358f9c185ea042cb62e 100644 (file)
@@ -1,14 +1,18 @@
 package org.argeo.security.core;
 
+import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.security.auth.Subject;
+
 import org.argeo.security.OsAuthenticationToken;
 import org.springframework.security.Authentication;
 import org.springframework.security.AuthenticationException;
 import org.springframework.security.GrantedAuthority;
 import org.springframework.security.GrantedAuthorityImpl;
 import org.springframework.security.providers.AuthenticationProvider;
+import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
 
 /** Validates an OS authentication. */
 public class OsAuthenticationProvider implements AuthenticationProvider {
@@ -20,16 +24,30 @@ public class OsAuthenticationProvider implements AuthenticationProvider {
 
        public Authentication authenticate(Authentication authentication)
                        throws AuthenticationException {
+               final OsAuthenticationToken oat;
+               // if (authentication instanceof UsernamePasswordAuthenticationToken) {
+               // Subject subject = Subject.getSubject(AccessController.getContext());
+               // if (subject == null)
+               // return null;
+               // oat = new OsAuthenticationToken();
+               // } else
                if (authentication instanceof OsAuthenticationToken) {
-                       List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
-                       auths.add(new GrantedAuthorityImpl(osUserRole));
-                       auths.add(new GrantedAuthorityImpl(userRole));
-                       if (isAdmin)
-                               auths.add(new GrantedAuthorityImpl(adminRole));
-                       return new OsAuthenticationToken(
-                                       auths.toArray(new GrantedAuthority[auths.size()]));
+                       oat = (OsAuthenticationToken) authentication;
+               } else {
+                       return null;
                }
-               return null;
+
+               // not OS authenticated
+//             if (oat.getUser() == null)
+//                     return null;
+
+               List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
+               auths.add(new GrantedAuthorityImpl(osUserRole));
+               auths.add(new GrantedAuthorityImpl(userRole));
+               if (isAdmin)
+                       auths.add(new GrantedAuthorityImpl(adminRole));
+               return new OsAuthenticationToken(
+                               auths.toArray(new GrantedAuthority[auths.size()]));
        }
 
        @SuppressWarnings("rawtypes")
index 192d2fdb2f801ee51a0beed4a77079c3d270edf4..dc47fa3831b3afc6b6f26b177e22665f017a49b4 100644 (file)
@@ -4,41 +4,44 @@ import java.util.Map;
 import java.util.concurrent.Executor;
 
 import javax.jcr.Node;
+import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 
 import org.argeo.ArgeoException;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.security.OsAuthenticationToken;
+import org.argeo.security.SystemExecutionService;
 import org.argeo.security.core.OsAuthenticationProvider;
 import org.springframework.security.Authentication;
 import org.springframework.security.AuthenticationException;
 import org.springframework.security.userdetails.UserDetails;
 
 public class OsJcrAuthenticationProvider extends OsAuthenticationProvider {
-       private RepositoryFactory repositoryFactory;
        private Executor systemExecutor;
        private String homeBasePath = "/home";
-       private String repositoryAlias = "node";
+       private Repository repository;
        private String workspace = null;
 
+       private Long timeout = 5 * 60 * 1000l;
+
        public Authentication authenticate(Authentication authentication)
                        throws AuthenticationException {
                final OsAuthenticationToken authen = (OsAuthenticationToken) super
                                .authenticate(authentication);
+               final Repository repository = getRepositoryBlocking();
                systemExecutor.execute(new Runnable() {
                        public void run() {
                                try {
-                                       Session session = JcrUtils.getRepositoryByAlias(
-                                                       repositoryFactory, repositoryAlias)
-                                                       .login(workspace);
-                                       Node userHome = JcrUtils.getUserHome(session,
-                                                       authen.getName());
+                                       Session session = repository.login(workspace);
+                                       // WARNING: at this stage we assume that teh java properties
+                                       // will have the same value
+                                       String userName = System.getProperty("user.name");
+                                       Node userHome = JcrUtils.getUserHome(session, userName);
                                        if (userHome == null)
-                                               JcrUtils.createUserHome(session, homeBasePath,
-                                                               authen.getName());
-                                       authen.setDetails(getUserDetails(userHome, authen));
+                                               userHome = JcrUtils.createUserHome(session,
+                                                               homeBasePath, userName);
+                                       //authen.setDetails(getUserDetails(userHome, authen));
                                } catch (RepositoryException e) {
                                        throw new ArgeoException(
                                                        "Unexpected exception when synchronizing OS and JCR security ",
@@ -67,26 +70,47 @@ public class OsJcrAuthenticationProvider extends OsAuthenticationProvider {
                return true;
        }
 
-       public void register(RepositoryFactory repositoryFactory,
+       protected Repository getRepositoryBlocking() {
+               long begin = System.currentTimeMillis();
+               while (repository == null) {
+                       synchronized (this) {
+                               try {
+                                       wait(500);
+                               } catch (InterruptedException e) {
+                                       // silent
+                               }
+                       }
+                       if (System.currentTimeMillis() - begin > timeout)
+                               throw new ArgeoException("No repository registered after "
+                                               + timeout + " ms");
+               }
+               return repository;
+       }
+
+       public synchronized void register(Repository repository,
                        Map<String, String> parameters) {
-               this.repositoryFactory = repositoryFactory;
+               this.repository = repository;
+               notifyAll();
        }
 
-       public void unregister(RepositoryFactory repositoryFactory,
+       public synchronized void unregister(Repository repository,
                        Map<String, String> parameters) {
-               this.repositoryFactory = null;
+               this.repository = null;
+               notifyAll();
        }
 
-       public void setSystemExecutor(Executor systemExecutor) {
+       public void register(SystemExecutionService systemExecutor,
+                       Map<String, String> parameters) {
                this.systemExecutor = systemExecutor;
        }
 
-       public void setHomeBasePath(String homeBasePath) {
-               this.homeBasePath = homeBasePath;
+       public void unregister(SystemExecutionService systemExecutor,
+                       Map<String, String> parameters) {
+               this.systemExecutor = null;
        }
 
-       public void setRepositoryAlias(String repositoryAlias) {
-               this.repositoryAlias = repositoryAlias;
+       public void setHomeBasePath(String homeBasePath) {
+               this.homeBasePath = homeBasePath;
        }
 
        public void setWorkspace(String workspace) {
index db2cfccbc692abd434386638d09b6ce6b06d47e5..dce6e549683281b8179be8868b6788c370c61df5 100644 (file)
@@ -4,10 +4,7 @@ import javax.jcr.Session;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.ThreadBoundJcrSessionFactory;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
+import org.argeo.jcr.spring.ThreadBoundSession;
 import org.springframework.security.Authentication;
 import org.springframework.security.context.SecurityContextHolder;
 import org.springframework.security.userdetails.UserDetails;
@@ -16,19 +13,10 @@ import org.springframework.security.userdetails.UserDetails;
  * Thread bounded JCR session factory which checks authentication and is
  * autoconfigured in Spring.
  */
-public class SecureThreadBoundSession extends ThreadBoundJcrSessionFactory
-               implements FactoryBean, InitializingBean, DisposableBean {
+public class SecureThreadBoundSession extends ThreadBoundSession {
        private final static Log log = LogFactory
                        .getLog(SecureThreadBoundSession.class);
 
-       public void afterPropertiesSet() throws Exception {
-               init();
-       }
-
-       public void destroy() throws Exception {
-               dispose();
-       }
-
        @Override
        protected Session preCall(Session session) {
                Authentication authentication = SecurityContextHolder.getContext()
index 1838dd05ef14741cc768eeea81a9d8062b52cf8b..bf33b8a2808369f5e0795f465aaba9620a0d3d66 100644 (file)
@@ -32,6 +32,8 @@ import org.springframework.security.GrantedAuthority;
 
 /** Intermediary class in order to have a consistent naming in config files. */
 public class ArgeoSecurityManager extends DefaultSecurityManager {
+       public final static String HOME_BASE_PATH = "/home";
+
        private Log log = LogFactory.getLog(ArgeoSecurityManager.class);
 
        @Override
@@ -61,7 +63,7 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                                        .toString(), authen, null);
                        log.info(userId + " added as " + user);
                }
-               
+
                setHomeNodeAuthorizations(user);
 
                // process groups
@@ -99,6 +101,11 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                try {
                        userId = user.getID();
                        Node userHome = JcrUtils.getUserHome(getSystemSession(), userId);
+                       // autocreate home node?
+//                     if (userHome == null)
+//                             userHome = JcrUtils.createUserHome(getSystemSession(),
+//                                             HOME_BASE_PATH, userId);
+
                        if (userHome != null) {
                                String path = userHome.getPath();
                                AccessControlPolicy policy = null;
index 0e87da8c0f35ceff64f5156dc6dcce2a50fe4748..0d0e37ec053134210cf21bf78044fba05bfead16 100644 (file)
@@ -8,7 +8,7 @@
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
        osgi:default-timeout="30000">\r
 \r
-       <set id="repositories" interface="javax.jcr.Repository">\r
+       <set id="repositories" interface="javax.jcr.Repository" cardinality="0..N">\r
                <listener ref="repositoryRegister" bind-method="register"\r
                        unbind-method="unregister" />\r
        </set>\r
index eb090514f425aa8f3ead1045ec072e78b38a7eda..6f50f735821d5821417ea871b75a5b0972788513 100644 (file)
@@ -295,7 +295,6 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                try {
                        NamespaceHelper namespaceHelper = new NamespaceHelper(session);
                        namespaceHelper.registerNamespaces(namespaces);
-
                } catch (Exception e) {
                        throw new ArgeoException("Cannot process new session", e);
                }
index bc7862f5fea23b5a3a2b4d935cfbb1bed2d13ebc..6edb854cb6d3f3df5a8458c54f057fbd86f6af53 100644 (file)
@@ -650,6 +650,24 @@ public class JcrUtils implements ArgeoJcrConstants {
                return getUserHome(session, userID);
        }
 
+       /**
+        * Returns user home has path, embedding exceptions. Contrary to
+        * {@link #getUserHome(Session)}, it never returns null but throws and
+        * exception if not found.
+        */
+       public static String getUserHomePath(Session session) {
+               String userID = session.getUserID();
+               try {
+                       Node userHome = getUserHome(session, userID);
+                       if (userHome != null)
+                               return userHome.getPath();
+                       else
+                               throw new ArgeoException("No home registered for " + userID);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot find user home path", e);
+               }
+       }
+
        /** Get the profile of the user attached to this session. */
        public static Node getUserProfile(Session session) {
                String userID = session.getUserID();
index d548b6eddaa227a63be3449994e08ba6ad6da326..88c9cf8fe8a508ffc28dfac38a0e54f1ac0c3cea 100644 (file)
@@ -37,7 +37,7 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
 
 /** Proxy JCR sessions and attach them to calling threads. */
-public class ThreadBoundJcrSessionFactory {
+public abstract class ThreadBoundJcrSessionFactory {
        private final static Log log = LogFactory
                        .getLog(ThreadBoundJcrSessionFactory.class);
 
diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/spring/ThreadBoundSession.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/spring/ThreadBoundSession.java
new file mode 100644 (file)
index 0000000..74966ea
--- /dev/null
@@ -0,0 +1,17 @@
+package org.argeo.jcr.spring;
+
+import org.argeo.jcr.ThreadBoundJcrSessionFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+
+public class ThreadBoundSession extends ThreadBoundJcrSessionFactory implements FactoryBean, InitializingBean, DisposableBean{
+       public void afterPropertiesSet() throws Exception {
+               init();
+       }
+
+       public void destroy() throws Exception {
+               dispose();
+       }
+
+}