Make Argeo data model extensions and keyring optional.
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 26 Jan 2020 08:11:12 +0000 (09:11 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 26 Jan 2020 08:11:12 +0000 (09:11 +0100)
org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java
org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java
org.argeo.cms/bnd.bnd
org.argeo.cms/ext/test/org/argeo/cms/tabular/JcrTabularTest.java
org.argeo.cms/src/org/argeo/cms/argeo.cnd [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/cms.cnd
org.argeo.cms/src/org/argeo/cms/dn.cnd [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java
org.argeo.node.api/src/org/argeo/node/node.cnd

index 7639df459dedc55f3478b9d926b412b58e68fcfb..f18f7fc87f14f2a8b5bd084fe8059252ac13d5dc 100644 (file)
@@ -46,6 +46,7 @@ import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer;
 import org.argeo.node.security.CryptoKeyring;
 import org.argeo.node.security.Keyring;
 import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.di.annotations.Optional;
 import org.eclipse.e4.ui.services.EMenuService;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
@@ -78,6 +79,7 @@ public class JcrBrowserView {
 
        /* DEPENDENCY INJECTION */
        @Inject
+       @Optional
        private Keyring keyring;
        @Inject
        private RepositoryFactory repositoryFactory;
index e51c104ef6443d4fd821ffa1b1f1e8709de3bef9..12dee13b96e21720fc177889cf7f1430f542896a 100644 (file)
@@ -36,6 +36,7 @@ import org.argeo.node.NodeConstants;
 import org.argeo.node.NodeUtils;
 import org.argeo.node.security.Keyring;
 import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.services.IServiceConstants;
 import org.eclipse.jface.dialogs.Dialog;
@@ -67,6 +68,7 @@ public class AddRemoteRepository implements ArgeoNames {
        @Inject
        private Repository nodeRepository;
        @Inject
+       @Optional
        private Keyring keyring;
 
        @Execute
index 50041e682fed7623cf51d0f99dfefba646b6fec3..f32e1fafcaa47ee96bf99b7fba19ff04addc206a 100644 (file)
@@ -9,4 +9,7 @@ org.apache.commons.httpclient.cookie;resolution:=optional,\
 !com.sun.security.jgss,\
 org.osgi.*;version=0.0.0,\
 *
-Provide-Capability: cms.datamodel;name=cms;cnd=/org/argeo/cms/cms.cnd;abstract=true
\ No newline at end of file
+
+Provide-Capability: cms.datamodel;name=argeo;cnd=/org/argeo/cms/argeo.cnd;abstract=true,\
+cms.datamodel;name=cms;cnd=/org/argeo/cms/cms.cnd;abstract=true,\
+cms.datamodel;name=dn;cnd=/org/argeo/cms/dn.cnd;abstract=true
\ No newline at end of file
index c1ca4c4b8254e1bc7f852cbb616ba4e2923b308b..9201a14fc8328c5024baa04810478e9ee484f277 100644 (file)
@@ -40,9 +40,12 @@ public class JcrTabularTest extends AbstractJackrabbitTestCase {
                InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/node/node.cnd"));
                CndImporter.registerNodeTypes(reader, session());
                reader.close();
-               reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/cms.cnd"));
+               reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/argeo.cnd"));
                CndImporter.registerNodeTypes(reader, session());
                reader.close();
+//             reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/cms.cnd"));
+//             CndImporter.registerNodeTypes(reader, session());
+//             reader.close();
 
                // write
                Integer columnCount = 15;
diff --git a/org.argeo.cms/src/org/argeo/cms/argeo.cnd b/org.argeo.cms/src/org/argeo/cms/argeo.cnd
new file mode 100644 (file)
index 0000000..c9e6ee7
--- /dev/null
@@ -0,0 +1,34 @@
+<argeo = 'http://www.argeo.org/ns/argeo'>
+
+// GENERIC TYPES
+[argeo:remoteRepository] > nt:unstructured
+- argeo:uri (STRING)
+- argeo:userID (STRING)
++ argeo:password (argeo:encrypted)
+
+// TABULAR CONTENT
+[argeo:table] > nt:file
++ * (argeo:column) *
+
+[argeo:column] > mix:title
+- jcr:requiredType (STRING) = 'STRING'
+
+[argeo:csv] > nt:resource
+
+// CRYPTO
+[argeo:encrypted]
+mixin
+// initialization vector used by some algorithms
+- argeo:iv (BINARY)
+
+[argeo:pbeKeySpec]
+mixin
+- argeo:secretKeyFactory (STRING)
+- argeo:salt (BINARY)
+- argeo:iterationCount (LONG)
+- argeo:keyLength (LONG)
+- argeo:secretKeyEncryption (STRING)
+
+[argeo:pbeSpec] > argeo:pbeKeySpec
+mixin
+- argeo:cipher (STRING)
index 955a4a3ac231c14610a92480119f22332ed2bedb..0e420f516b18278d8edf5b8c96ae83779fdf49bc 100644 (file)
@@ -1,39 +1,5 @@
-<argeo = 'http://www.argeo.org/ns/argeo'>
 <cms = 'http://www.argeo.org/ns/cms'>
 
-// GENERIC TYPES
-[argeo:remoteRepository] > nt:unstructured
-- argeo:uri (STRING)
-- argeo:userID (STRING)
-+ argeo:password (argeo:encrypted)
-
-// TABULAR CONTENT
-[argeo:table] > nt:file
-+ * (argeo:column) *
-
-[argeo:column] > mix:title
-- jcr:requiredType (STRING) = 'STRING'
-
-[argeo:csv] > nt:resource
-
-// CRYPTO
-[argeo:encrypted] > nt:base
-mixin
-// initialization vector used by some algorithms
-- argeo:iv (BINARY)
-
-[argeo:pbeKeySpec] > nt:base
-mixin
-- argeo:secretKeyFactory (STRING)
-- argeo:salt (BINARY)
-- argeo:iterationCount (LONG)
-- argeo:keyLength (LONG)
-- argeo:secretKeyEncryption (STRING)
-
-[argeo:pbeSpec] > argeo:pbeKeySpec
-mixin
-- argeo:cipher (STRING)
-
 // TEXT
 [cms:styled]
 mixin
diff --git a/org.argeo.cms/src/org/argeo/cms/dn.cnd b/org.argeo.cms/src/org/argeo/cms/dn.cnd
new file mode 100644 (file)
index 0000000..80849be
--- /dev/null
@@ -0,0 +1,10 @@
+// DN (see https://tools.ietf.org/html/rfc4514)
+<cn = 'http://www.argeo.org/ns/rfc4514/cn'>
+<l = 'http://www.argeo.org/ns/rfc4514/l'>
+<st = 'http://www.argeo.org/ns/rfc4514/st'>
+<o = 'http://www.argeo.org/ns/rfc4514/o'>
+<ou = 'http://www.argeo.org/ns/rfc4514/ou'>
+<c = 'http://www.argeo.org/ns/rfc4514/c'>
+<street = 'http://www.argeo.org/ns/rfc4514/street'>
+<dc = 'http://www.argeo.org/ns/rfc4514/dc'>
+<uid = 'http://www.argeo.org/ns/rfc4514/uid'>
index 82a6972cbf0e5660de9d6cf02728ba1e72e01aae..010000f61b5f9b1c5bc40122b2f32709762092ec 100644 (file)
@@ -17,7 +17,6 @@ import java.util.UUID;
 
 import javax.crypto.SecretKey;
 import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
index 20418ec4d21e803890e838abdfaec1b092a24337..59d8c910f9640c287d564d924ac5da48db1a378a 100644 (file)
@@ -8,6 +8,7 @@ import java.io.Reader;
 import java.lang.management.ManagementFactory;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
@@ -15,6 +16,7 @@ import java.util.Map;
 import java.util.Set;
 
 import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.security.auth.callback.CallbackHandler;
 import javax.transaction.UserTransaction;
@@ -24,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.core.RepositoryContext;
 import org.apache.jackrabbit.core.RepositoryImpl;
+import org.argeo.cms.ArgeoNames;
 import org.argeo.cms.CmsException;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.node.DataModelNamespace;
@@ -68,6 +71,8 @@ public class CmsDeployment implements NodeDeployment {
 
        private NodeHttp nodeHttp;
 
+       private boolean argeoDataModelExtensionsAvailable = false;
+
        // Readiness
        private boolean nodeAvailable = false;
        private boolean userAdminAvailable = false;
@@ -255,10 +260,22 @@ public class CmsDeployment implements NodeDeployment {
                }
 
                // home
-               prepareDataModel(NodeConstants.NODE, KernelUtils.openAdminSession(deployedNodeRepository));
+               prepareDataModel(NodeConstants.NODE, deployedNodeRepository);
        }
 
        private void prepareHomeRepository(RepositoryImpl deployedRepository) {
+               Session adminSession = KernelUtils.openAdminSession(deployedRepository);
+               try {
+                       argeoDataModelExtensionsAvailable = Arrays
+                                       .asList(adminSession.getWorkspace().getNamespaceRegistry().getURIs())
+                                       .contains(ArgeoNames.ARGEO_NAMESPACE);
+               } catch (RepositoryException e) {
+                       log.warn("Cannot check whether Argeo namespace is registered assuming it isn't.", e);
+                       argeoDataModelExtensionsAvailable = false;
+               } finally {
+                       JcrUtils.logoutQuietly(adminSession);
+               }
+
                Hashtable<String, String> regProps = new Hashtable<String, String>();
                regProps.put(NodeConstants.CN, NodeConstants.HOME);
                // regProps.put(LEGACY_JCR_REPOSITORY_ALIAS, NodeConstants.HOME);
@@ -266,23 +283,27 @@ public class CmsDeployment implements NodeDeployment {
                // register
                bc.registerService(Repository.class, homeRepository, regProps);
 
-               new ServiceTracker<CallbackHandler, CallbackHandler>(bc, CallbackHandler.class, null) {
-
-                       @Override
-                       public CallbackHandler addingService(ServiceReference<CallbackHandler> reference) {
-                               NodeKeyRing nodeKeyring = new NodeKeyRing(homeRepository);
-                               CallbackHandler callbackHandler = bc.getService(reference);
-                               nodeKeyring.setDefaultCallbackHandler(callbackHandler);
-                               bc.registerService(LangUtils.names(Keyring.class, CryptoKeyring.class, ManagedService.class),
-                                               nodeKeyring, LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_KEYRING_PID));
-                               return callbackHandler;
-                       }
+               // Keyring only if Argeo extensions are available
+               if (argeoDataModelExtensionsAvailable) {
+                       new ServiceTracker<CallbackHandler, CallbackHandler>(bc, CallbackHandler.class, null) {
+
+                               @Override
+                               public CallbackHandler addingService(ServiceReference<CallbackHandler> reference) {
+                                       NodeKeyRing nodeKeyring = new NodeKeyRing(homeRepository);
+                                       CallbackHandler callbackHandler = bc.getService(reference);
+                                       nodeKeyring.setDefaultCallbackHandler(callbackHandler);
+                                       bc.registerService(LangUtils.names(Keyring.class, CryptoKeyring.class, ManagedService.class),
+                                                       nodeKeyring, LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_KEYRING_PID));
+                                       return callbackHandler;
+                               }
 
-               }.open();
+                       }.open();
+               }
        }
 
        /** Session is logged out. */
-       private void prepareDataModel(String cn, Session adminSession) {
+       private void prepareDataModel(String cn, Repository repository) {
+               Session adminSession = KernelUtils.openAdminSession(repository);
                try {
                        Set<String> processed = new HashSet<String>();
                        bundles: for (Bundle bundle : bc.getBundles()) {
@@ -290,13 +311,13 @@ public class CmsDeployment implements NodeDeployment {
                                if (wiring == null)
                                        continue bundles;
                                if (NodeConstants.NODE.equals(cn))// process all data models
-                                       processWiring(cn, adminSession, wiring, processed);
+                                       processWiring(cn, adminSession, wiring, processed, false);
                                else {
                                        List<BundleCapability> capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
                                        for (BundleCapability capability : capabilities) {
                                                String dataModelName = (String) capability.getAttributes().get(DataModelNamespace.NAME);
                                                if (dataModelName.equals(cn))// process only own data model
-                                                       processWiring(cn, adminSession, wiring, processed);
+                                                       processWiring(cn, adminSession, wiring, processed, false);
                                        }
                                }
                        }
@@ -305,16 +326,21 @@ public class CmsDeployment implements NodeDeployment {
                }
        }
 
-       private void processWiring(String cn, Session adminSession, BundleWiring wiring, Set<String> processed) {
+       private void processWiring(String cn, Session adminSession, BundleWiring wiring, Set<String> processed,
+                       boolean importListedAbstractModels) {
                // recursively process requirements first
                List<BundleWire> requiredWires = wiring.getRequiredWires(CMS_DATA_MODEL_NAMESPACE);
                for (BundleWire wire : requiredWires) {
-                       processWiring(cn, adminSession, wire.getProviderWiring(), processed);
+                       processWiring(cn, adminSession, wire.getProviderWiring(), processed, true);
                }
 
                List<String> publishAsLocalRepo = new ArrayList<>();
                List<BundleCapability> capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE);
-               for (BundleCapability capability : capabilities) {
+               capabilities: for (BundleCapability capability : capabilities) {
+                       if (!importListedAbstractModels
+                                       && KernelUtils.asBoolean((String) capability.getAttributes().get(DataModelNamespace.ABSTRACT))) {
+                               continue capabilities;
+                       }
                        boolean publish = registerDataModelCapability(cn, adminSession, capability, processed);
                        if (publish)
                                publishAsLocalRepo.add((String) capability.getAttributes().get(DataModelNamespace.NAME));
@@ -409,7 +435,7 @@ public class CmsDeployment implements NodeDeployment {
                                        nodeAvailable = true;
                                        checkReadiness();
                                } else {
-                                       prepareDataModel(cn, KernelUtils.openAdminSession(repoContext.getRepository()));
+                                       prepareDataModel(cn, repoContext.getRepository());
                                }
                        }
                        return repoContext;
index f3d0619efc4e73a362dc9be0ba27767dcd340dc2..1a6dec5efeca9843f20d2fbc4791fe762c7c0124 100644 (file)
@@ -1,18 +1,6 @@
 <ldap = 'http://www.argeo.org/ns/ldap'>
 <node = 'http://www.argeo.org/ns/node'>
 
-// DN (see https://tools.ietf.org/html/rfc4514)
-<cn = 'http://www.argeo.org/ns/rfc4514/cn'>
-<l = 'http://www.argeo.org/ns/rfc4514/l'>
-<st = 'http://www.argeo.org/ns/rfc4514/st'>
-<o = 'http://www.argeo.org/ns/rfc4514/o'>
-<ou = 'http://www.argeo.org/ns/rfc4514/ou'>
-<c = 'http://www.argeo.org/ns/rfc4514/c'>
-<street = 'http://www.argeo.org/ns/rfc4514/street'>
-<dc = 'http://www.argeo.org/ns/rfc4514/dc'>
-<uid = 'http://www.argeo.org/ns/rfc4514/uid'>
-
-
 [node:userHome]
 mixin
 - ldap:uid (STRING) m