Refactor deploy properties and move legacy CMS exception.
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 30 Jun 2022 09:39:55 +0000 (11:39 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 30 Jun 2022 09:39:55 +0000 (11:39 +0200)
78 files changed:
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/CmsE4Utils.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/OsgiFilterContextFunction.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/addons/AuthAddon.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/files/NodeFsBrowserView.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/CloseWorkbench.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrE4DClickListener.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/Browse.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/monitoring/OsgiConfigurationsView.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java
eclipse/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserAdminAbstractLP.java
eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/InternalHttpConstants.java [deleted file]
eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java
eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/JettyHttpConstants.java [new file with mode: 0644]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/CmsException.java [new file with mode: 0644]
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/auth/CmsLogin.java
eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/auth/LocaleChoice.java
eclipse/org.argeo.ext.equinox.jetty/src/org/argeo/equinox/jetty/CmsJettyCustomizer.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java [deleted file]
jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsJcrDeployment.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsPaths.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryContextsFactory.java
jcr/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormUtils.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/CmsFsBrowser.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/JcrContentProvider.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/util/SimpleCmsHeader.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/util/SimpleDynamicPages.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/util/StyleSheetResourceLoader.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/util/SystemNotifications.java
jcr/org.argeo.cms.ui/src/org/argeo/cms/ui/util/UserMenu.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsConstants.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsDeployment.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsState.java
org.argeo.cms/src/org/argeo/cms/ArgeoNames.java
org.argeo.cms/src/org/argeo/cms/ArgeoTypes.java
org.argeo.cms/src/org/argeo/cms/CmsDeployProperty.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/CmsException.java [deleted file]
org.argeo.cms/src/org/argeo/cms/LocaleUtils.java
org.argeo.cms/src/org/argeo/cms/acr/CmsContentRepository.java
org.argeo.cms/src/org/argeo/cms/acr/CmsContentSession.java
org.argeo.cms/src/org/argeo/cms/acr/SingleUserContentRepository.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/internal/http/client/SpnegoAuthScheme.java
org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsOsgiLogger.java
org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java
org.argeo.cms/src/org/argeo/cms/internal/osgi/NodeUserAdmin.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsContextImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsUserAdmin.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/InitUtils.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/runtime/KernelConstants.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/KernelUtils.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/PkiUtils.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/security/AbstractKeyring.java
org.argeo.cms/src/org/argeo/cms/security/ChecksumFactory.java
org.argeo.cms/src/org/argeo/cms/security/PkiUtils.java [deleted file]
org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java [deleted file]
org.argeo.util/src/org/argeo/osgi/metatype/EnumOCD.java [deleted file]
org.argeo.util/src/org/argeo/osgi/metatype/package-info.java [deleted file]
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptApp.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/AbstractCmsEntryPoint.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleApp.java
rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleErgonomics.java
rcp/org.argeo.cms.e4.rcp/src/org/argeo/cms/e4/rcp/CmsE4Application.java

index 21abf5828b90d589ec03d4690317c98f411666b3..a997de748875446664865e251abb910811af64f2 100644 (file)
@@ -2,7 +2,7 @@ package org.argeo.cms.e4;
 
 import java.util.List;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.e4.ui.model.application.MApplication;
 import org.eclipse.e4.ui.model.application.commands.MCommand;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
index c42a02a147ab64ccf468c3383d7a057a04e5778e..1e3e75cecfba32247dc3397aac1490285ab14a6d 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.e4;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.e4.core.contexts.ContextFunction;
 import org.eclipse.e4.core.contexts.IEclipseContext;
 import org.eclipse.e4.core.di.IInjector;
index 3d57e1659934ca429e35b602f3b69860e4e21ca9..e84b18c0b164828251602d4c2e8ecc139e516d68 100644 (file)
@@ -8,8 +8,8 @@ import javax.security.auth.Subject;
 import javax.servlet.http.HttpServletRequest;
 
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.e4.ui.model.application.MApplication;
 import org.eclipse.e4.ui.model.application.ui.MElementContainer;
 import org.eclipse.e4.ui.model.application.ui.MUIElement;
index cb9f9b97a474e68bf5fd3215067f8be0cccba967..579d35d6a6e0a15beb8e9a4743c6ec1087842fbc 100644 (file)
@@ -9,8 +9,8 @@ import java.nio.file.spi.FileSystemProvider;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import org.argeo.cms.CmsException;
 import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.eclipse.ui.fs.AdvancedFsBrowser;
 import org.argeo.eclipse.ui.fs.SimpleFsBrowser;
 import org.eclipse.swt.SWT;
index a6cdcf620af3e25f94376c11c5524c58405d37bf..7ef8c59da89dadbcfcc454dde65c482688ad5dec 100644 (file)
@@ -12,9 +12,9 @@ import javax.inject.Inject;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.security.CryptoKeyring;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.dialogs.CmsMessageDialog;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.util.transaction.WorkTransaction;
index a365f3d7d13f40fda6beedd3602701c7e59073a9..c2ae4bff7c8b32cb7562c4a28607216276205182 100644 (file)
@@ -4,8 +4,8 @@ import java.security.AccessController;
 
 import javax.security.auth.Subject;
 
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.workbench.IWorkbench;
 
index 46e1b6507c53ff784b7fe9a26b290e5c9f2053f8..0b77c0732a51cdf63dde604cd1b48a12d2eb9be2 100644 (file)
@@ -17,9 +17,9 @@ import javax.jcr.observation.EventListener;
 import javax.jcr.observation.ObservationManager;
 
 import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.security.CryptoKeyring;
 import org.argeo.cms.security.Keyring;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.ui.jcr.JcrBrowserUtils;
 import org.argeo.cms.ui.jcr.NodeContentProvider;
index ad6a547da64214ad9a5c8b8f067ddd18b09c536a..f4ee2e8da0b9091042a288fa2b69bff4c4cf9058 100644 (file)
@@ -3,7 +3,7 @@ package org.argeo.cms.e4.jcr;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.ui.jcr.JcrDClickListener;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
index 40a3c4e8bb8f039dcc1e8a4f6b9f5138f40bedac..a536da0660af495cfd2e62da26fce2445d75dfea 100644 (file)
@@ -16,7 +16,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 
 import org.argeo.api.cms.ux.Cms2DSize;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.util.CmsLink;
index 759b3e9558848c6855284442090e9293ee618bb8..5db8bd151a069dff316e94eded0e65b5122f776f 100644 (file)
@@ -9,7 +9,7 @@ import java.util.List;
 
 import javax.annotation.PostConstruct;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.util.LangUtils;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
 import org.eclipse.jface.viewers.ITreeContentProvider;
index ddad34fd1e59b2bad78a96618d109ab29b0e2837..3bf48918db8cd1b65f5e8adc5aba4c676288f157 100644 (file)
@@ -9,12 +9,12 @@ import javax.inject.Inject;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.e4.users.providers.CommonNameLP;
 import org.argeo.cms.e4.users.providers.DomainNameLP;
 import org.argeo.cms.e4.users.providers.RoleIconLP;
 import org.argeo.cms.e4.users.providers.UserDragListener;
+import org.argeo.cms.swt.CmsException;
 //import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
 //import org.argeo.cms.ui.workbench.internal.useradmin.UiUserAdminListener;
 //import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper;
index 1e0fc6eb33b99558cab7ba8db364bee242d43079..d120ae9a289b8494e62372e28a5f607edc08f8d1 100644 (file)
@@ -9,7 +9,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.osgi.useradmin.UserDirectory;
 import org.argeo.util.directory.DirectoryConf;
 import org.argeo.util.transaction.WorkTransaction;
index 01ccc7d73221d7732f4ccf26bb106ec9067ce36f..4fc59d30d5c47e1754bdcb0ef7002f248507c914 100644 (file)
@@ -7,13 +7,13 @@ import java.util.Map;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.UserAdminUtils;
 import org.argeo.cms.e4.users.providers.CommonNameLP;
 import org.argeo.cms.e4.users.providers.DomainNameLP;
 import org.argeo.cms.e4.users.providers.MailLP;
 import org.argeo.cms.e4.users.providers.UserNameLP;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
index 877a925c6d4371d7396cc1de8737a7e34c26e74d..720945c4ca144dcef475b424d7c18b89055e51c1 100644 (file)
@@ -8,13 +8,13 @@ import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
 import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.e4.users.providers.CommonNameLP;
 import org.argeo.cms.e4.users.providers.DomainNameLP;
 import org.argeo.cms.e4.users.providers.MailLP;
 import org.argeo.cms.e4.users.providers.UserDragListener;
 import org.argeo.cms.e4.users.providers.UserNameLP;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
index f02a26b1c29a3b465aeaf53cc796f974241f357b..41e14e09733cb38d8bd779ac1ee60caae896fec8 100644 (file)
@@ -5,8 +5,8 @@ import java.util.Map;
 
 import javax.inject.Inject;
 
-import org.argeo.cms.CmsException;
 import org.argeo.cms.e4.users.UserAdminWrapper;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.util.directory.DirectoryConf;
index 24f7e6250ee27c9c81c035892d7f1ced7649189b..40a4460061f97dca4ae35e0194d3bc998c862df8 100644 (file)
@@ -9,10 +9,10 @@ import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.UserAdminUtils;
 import org.argeo.cms.e4.users.UiAdminUtils;
 import org.argeo.cms.e4.users.UserAdminWrapper;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.util.directory.DirectoryConf;
index e33b1531db6344301b8922c4fd1c9fb99c345785..29873db2fa9d626a525cf701cbe9c42a75fc5600 100644 (file)
@@ -3,8 +3,8 @@ package org.argeo.cms.e4.users.providers;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.UserAdminUtils;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
 import org.eclipse.swt.SWT;
diff --git a/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/InternalHttpConstants.java b/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/InternalHttpConstants.java
deleted file mode 100644 (file)
index 462bf7a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.argeo.cms.servlet.internal.jetty;
-
-/** Compatible with Jetty. */
-public interface InternalHttpConstants {
-       static final String HTTP_ENABLED = "http.enabled";
-       static final String HTTP_PORT = "http.port";
-       static final String HTTP_HOST = "http.host";
-       static final String HTTPS_ENABLED = "https.enabled";
-       static final String HTTPS_HOST = "https.host";
-       static final String HTTPS_PORT = "https.port";
-       static final String SSL_KEYSTORE = "ssl.keystore";
-       static final String SSL_PASSWORD = "ssl.password";
-       static final String SSL_KEYPASSWORD = "ssl.keypassword";
-       static final String SSL_NEEDCLIENTAUTH = "ssl.needclientauth";
-       static final String SSL_WANTCLIENTAUTH = "ssl.wantclientauth";
-       static final String SSL_PROTOCOL = "ssl.protocol";
-       static final String SSL_ALGORITHM = "ssl.algorithm";
-       static final String SSL_KEYSTORETYPE = "ssl.keystoretype";
-       static final String JETTY_PROPERTY_PREFIX = "org.eclipse.equinox.http.jetty.";
-       // Argeo specific
-       static final String WEBSOCKET_ENABLED = "websocket.enabled";
-
-}
index ad93fad61e759ca19a2e7542b3c7e061866e349d..64e33d3ecd5147a99175922e699a94dc97b37c36 100644 (file)
@@ -1,11 +1,5 @@
 package org.argeo.cms.servlet.internal.jetty;
 
-import java.io.IOException;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.KeyStore;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.Map;
@@ -18,7 +12,7 @@ import javax.websocket.server.ServerEndpointConfig;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsState;
-import org.argeo.cms.security.PkiUtils;
+import org.argeo.cms.CmsDeployProperty;
 import org.argeo.cms.websocket.javax.server.CmsWebSocketConfigurator;
 import org.argeo.cms.websocket.javax.server.TestEndpoint;
 import org.argeo.util.LangUtils;
@@ -32,13 +26,13 @@ public class JettyConfig {
        private final static CmsLog log = CmsLog.getLog(JettyConfig.class);
 
        final static String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
-       // Argeo specific
-       final static String WEBSOCKET_ENABLED = "websocket.enabled";
 
        private CmsState cmsState;
 
        private final BundleContext bc = FrameworkUtil.getBundle(JettyConfig.class).getBundleContext();
 
+       //private static final String JETTY_PROPERTY_PREFIX = "org.eclipse.equinox.http.jetty.";
+
        public void start() {
                // We need to start asynchronously so that Jetty bundle get started by lazy init
                // due to the non-configurable behaviour of its activator
@@ -103,10 +97,10 @@ public class JettyConfig {
                        config.put("customizer.class", CMS_JETTY_CUSTOMIZER_CLASS);
 
                        // TODO centralise with Jetty extender
-                       Object webSocketEnabled = config.get(WEBSOCKET_ENABLED);
+                       Object webSocketEnabled = config.get(CmsDeployProperty.WEBSOCKET_ENABLED.getProperty());
                        if (webSocketEnabled != null && webSocketEnabled.toString().equals("true")) {
                                bc.registerService(ServerEndpointConfig.Configurator.class, new CmsWebSocketConfigurator(), null);
-                               config.put(WEBSOCKET_ENABLED, "true");
+                               // config.put(WEBSOCKET_ENABLED, "true");
                        }
                }
 
@@ -117,8 +111,8 @@ public class JettyConfig {
                                        // FIXME deal with multiple ids
                                        JettyConfigurator.startServer(CmsConstants.DEFAULT, new Hashtable<>(config));
 
-                                       Object httpPort = config.get(InternalHttpConstants.HTTP_PORT);
-                                       Object httpsPort = config.get(InternalHttpConstants.HTTPS_PORT);
+                                       Object httpPort = config.get(JettyHttpConstants.HTTP_PORT);
+                                       Object httpsPort = config.get(JettyHttpConstants.HTTPS_PORT);
                                        log.info(httpPortsMsg(httpPort, httpsPort));
 
                                        // Explicitly starts Jetty OSGi HTTP bundle, so that it gets triggered if OSGi
@@ -148,94 +142,57 @@ public class JettyConfig {
 
        /** Override the provided config with the framework properties */
        public Dictionary<String, Object> getHttpServerConfig() {
-               String httpPort = getFrameworkProp("org.osgi.service.http.port");
-               String httpsPort = getFrameworkProp("org.osgi.service.http.port.secure");
+               String httpPort = getFrameworkProp(CmsDeployProperty.HTTP_PORT);
+               String httpsPort = getFrameworkProp(CmsDeployProperty.HTTPS_PORT);
                /// TODO make it more generic
-               String httpHost = getFrameworkProp(
-                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTP_HOST);
-               String httpsHost = getFrameworkProp(
-                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTPS_HOST);
-               String webSocketEnabled = getFrameworkProp(
-                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.WEBSOCKET_ENABLED);
+               String httpHost = getFrameworkProp(CmsDeployProperty.HOST);
+//             String httpsHost = getFrameworkProp(
+//                             JettyConfig.JETTY_PROPERTY_PREFIX + CmsHttpConstants.HTTPS_HOST);
+               String webSocketEnabled = getFrameworkProp(CmsDeployProperty.WEBSOCKET_ENABLED);
 
                final Hashtable<String, Object> props = new Hashtable<String, Object>();
                // try {
                if (httpPort != null || httpsPort != null) {
                        boolean httpEnabled = httpPort != null;
-                       props.put(InternalHttpConstants.HTTP_ENABLED, httpEnabled);
+                       props.put(JettyHttpConstants.HTTP_ENABLED, httpEnabled);
                        boolean httpsEnabled = httpsPort != null;
-                       props.put(InternalHttpConstants.HTTPS_ENABLED, httpsEnabled);
+                       props.put(JettyHttpConstants.HTTPS_ENABLED, httpsEnabled);
 
                        if (httpEnabled) {
-                               props.put(InternalHttpConstants.HTTP_PORT, httpPort);
+                               props.put(JettyHttpConstants.HTTP_PORT, httpPort);
                                if (httpHost != null)
-                                       props.put(InternalHttpConstants.HTTP_HOST, httpHost);
+                                       props.put(JettyHttpConstants.HTTP_HOST, httpHost);
                        }
 
                        if (httpsEnabled) {
-                               props.put(InternalHttpConstants.HTTPS_PORT, httpsPort);
-                               if (httpsHost != null)
-                                       props.put(InternalHttpConstants.HTTPS_HOST, httpsHost);
-
-                               // server certificate
-                               Path keyStorePath = cmsState.getDataPath(PkiUtils.DEFAULT_KEYSTORE_PATH);
-                               Path pemKeyPath = cmsState.getDataPath(PkiUtils.DEFAULT_PEM_KEY_PATH);
-                               Path pemCertPath = cmsState.getDataPath(PkiUtils.DEFAULT_PEM_CERT_PATH);
-                               String keyStorePasswordStr = getFrameworkProp(
-                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_PASSWORD);
-                               char[] keyStorePassword;
-                               if (keyStorePasswordStr == null)
-                                       keyStorePassword = "changeit".toCharArray();
-                               else
-                                       keyStorePassword = keyStorePasswordStr.toCharArray();
-
-                               // if PEM files both exists, update the PKCS12 file
-                               if (Files.exists(pemCertPath) && Files.exists(pemKeyPath)) {
-                                       // TODO check certificate update time? monitor changes?
-                                       KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
-                                       try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
-                                                       Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
-                                               PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
-                                               PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
-                                               if (log.isDebugEnabled())
-                                                       log.debug("PEM certificate stored in " + keyStorePath);
-                                       } catch (IOException e) {
-                                               log.error("Cannot read PEM files " + pemKeyPath + " and " + pemCertPath, e);
-                                       }
-                               }
-
-                               if (!Files.exists(keyStorePath))
-                                       PkiUtils.createSelfSignedKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
-                               props.put(InternalHttpConstants.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
-                               props.put(InternalHttpConstants.SSL_KEYSTORE, keyStorePath.toString());
-                               props.put(InternalHttpConstants.SSL_PASSWORD, new String(keyStorePassword));
+                               props.put(JettyHttpConstants.HTTPS_PORT, httpsPort);
+                               if (httpHost != null)
+                                       props.put(JettyHttpConstants.HTTPS_HOST, httpHost);
 
-//                             props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
-//                             props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
-//                             props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
+                               props.put(JettyHttpConstants.SSL_KEYSTORETYPE,  getFrameworkProp(CmsDeployProperty.SSL_KEYSTORETYPE));
+                               props.put(JettyHttpConstants.SSL_KEYSTORE, getFrameworkProp(CmsDeployProperty.SSL_KEYSTORE));
+                               props.put(JettyHttpConstants.SSL_PASSWORD, getFrameworkProp(CmsDeployProperty.SSL_PASSWORD));
 
                                // client certificate authentication
-                               String wantClientAuth = getFrameworkProp(
-                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_WANTCLIENTAUTH);
+                               String wantClientAuth = getFrameworkProp(CmsDeployProperty.SSL_WANTCLIENTAUTH);
                                if (wantClientAuth != null)
-                                       props.put(InternalHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
-                               String needClientAuth = getFrameworkProp(
-                                               InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_NEEDCLIENTAUTH);
+                                       props.put(JettyHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
+                               String needClientAuth = getFrameworkProp(CmsDeployProperty.SSL_NEEDCLIENTAUTH);
                                if (needClientAuth != null)
-                                       props.put(InternalHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
+                                       props.put(JettyHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
                        }
 
                        // web socket
                        if (webSocketEnabled != null && webSocketEnabled.equals("true"))
-                               props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true);
+                               props.put(CmsDeployProperty.WEBSOCKET_ENABLED.getProperty(), true);
 
                        props.put(CmsConstants.CN, CmsConstants.DEFAULT);
                }
                return props;
        }
 
-       private String getFrameworkProp(String key) {
-               return cmsState.getDeployProperty(key);
+       private String getFrameworkProp(CmsDeployProperty deployProperty) {
+               return cmsState.getDeployProperty(deployProperty.getProperty());
        }
 
        public void setCmsState(CmsState cmsState) {
diff --git a/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/JettyHttpConstants.java b/eclipse/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/jetty/JettyHttpConstants.java
new file mode 100644 (file)
index 0000000..155e6c8
--- /dev/null
@@ -0,0 +1,19 @@
+package org.argeo.cms.servlet.internal.jetty;
+
+/** Compatible with Jetty. */
+interface JettyHttpConstants {
+       static final String HTTP_ENABLED = "http.enabled";
+       static final String HTTP_PORT = "http.port";
+       static final String HTTP_HOST = "http.host";
+       static final String HTTPS_ENABLED = "https.enabled";
+       static final String HTTPS_HOST = "https.host";
+       static final String HTTPS_PORT = "https.port";
+       static final String SSL_KEYSTORE = "ssl.keystore";
+       static final String SSL_PASSWORD = "ssl.password";
+       static final String SSL_KEYPASSWORD = "ssl.keypassword";
+       static final String SSL_NEEDCLIENTAUTH = "ssl.needclientauth";
+       static final String SSL_WANTCLIENTAUTH = "ssl.wantclientauth";
+       static final String SSL_PROTOCOL = "ssl.protocol";
+       static final String SSL_ALGORITHM = "ssl.algorithm";
+       static final String SSL_KEYSTORETYPE = "ssl.keystoretype";
+}
diff --git a/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/CmsException.java b/eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/CmsException.java
new file mode 100644 (file)
index 0000000..874ea96
--- /dev/null
@@ -0,0 +1,16 @@
+package org.argeo.cms.swt;
+
+/** @deprecated Use standard Java {@link RuntimeException} instead. */
+@Deprecated
+public class CmsException extends RuntimeException {
+       private static final long serialVersionUID = -5341764743356771313L;
+
+       public CmsException(String message) {
+               super(message);
+       }
+
+       public CmsException(String message, Throwable e) {
+               super(message, e);
+       }
+
+}
index afd1b54997f09a5f69af41ac953d9d0fce8f592f..b313222d516374e67b60ff9114b98fd9a1992530 100644 (file)
@@ -4,9 +4,24 @@ import static org.argeo.cms.CmsMsg.password;
 import static org.argeo.cms.CmsMsg.username;
 
 import java.io.IOException;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandler;
+import java.net.http.HttpResponse.BodyHandlers;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedAction;
+import java.security.cert.X509Certificate;
 import java.util.List;
 import java.util.Locale;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
@@ -24,6 +39,7 @@ import org.argeo.api.cms.ux.CmsView;
 import org.argeo.cms.CmsMsg;
 import org.argeo.cms.LocaleUtils;
 import org.argeo.cms.auth.RemoteAuthCallback;
+import org.argeo.cms.auth.RemoteAuthUtils;
 import org.argeo.cms.servlet.ServletHttpRequest;
 import org.argeo.cms.servlet.ServletHttpResponse;
 import org.argeo.cms.swt.CmsStyles;
@@ -277,6 +293,11 @@ public class CmsLogin implements CmsStyles, CallbackHandler {
                        else
                                loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, this);
                        loginContext.login();
+//                     try {
+//                             openHttpClient(loginContext.getSubject(), "id-internal.work.argeo.net");
+//                     } catch (Exception e) {
+//                             e.printStackTrace();
+//                     }
                        cmsView.authChange(loginContext);
                        return true;
                } catch (LoginException e) {
@@ -299,6 +320,70 @@ public class CmsLogin implements CmsStyles, CallbackHandler {
                // }
        }
 
+       private static HttpClient openHttpClient(Subject subject, String server) {
+               try {
+                       String domain = "WORK.ARGEO.ORG";
+                       // disable https check
+                       // jdk.internal.httpclient.disableHostnameVerification=true
+                       HttpClient client = HttpClient.newBuilder().sslContext(insecureContext())
+                                       .authenticator(new Authenticator() {
+                                               public PasswordAuthentication getPasswordAuthentication() {
+                                                       // I haven't checked getRequestingScheme() here, since for NTLM
+                                                       // and Negotiate, the usrname and password are all the same.
+                                                       System.err.println("Feeding username and password for " + getRequestingScheme());
+                                                       return (new PasswordAuthentication("mbaudier@" + domain, null));
+                                               }
+
+                                       }).build();
+
+                       String token = RemoteAuthUtils.getGssToken(subject, "HTTP/" + server + "@" + domain);
+
+                       HttpRequest request = HttpRequest.newBuilder(URI.create("https://" + server + "/ipa/session/json")).GET()
+                                       .header("Authorization", "Negotiate " + token).build();
+                       BodyHandler<String> bodyHandler = BodyHandlers.ofString();
+                       HttpResponse<String> response = client.send(request, bodyHandler);
+                       System.out.println(response.body());
+                       return client;
+
+                       // return client;
+//                     AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
+//                     HttpParams params = DefaultHttpParams.getDefaultParams();
+//                     ArrayList<String> schemes = new ArrayList<>();
+//                     schemes.add(SpnegoAuthScheme.NAME);
+//                     params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
+//                     params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
+//                     HttpClient httpClient = new HttpClient();
+//                     httpClient.executeMethod(new GetMethod(("https://" + server + "/ipa/session/json")));
+//                     return httpClient;
+               } catch (
+
+               Exception e) {
+                       throw new IllegalStateException("Cannot open client to IPA server " + server, e);
+               }
+
+       }
+
+       private static SSLContext insecureContext() {
+               TrustManager[] noopTrustManager = new TrustManager[] { new X509TrustManager() {
+                       public void checkClientTrusted(X509Certificate[] xcs, String string) {
+                       }
+
+                       public void checkServerTrusted(X509Certificate[] xcs, String string) {
+                       }
+
+                       public X509Certificate[] getAcceptedIssuers() {
+                               return null;
+                       }
+               } };
+               try {
+                       SSLContext sc = SSLContext.getInstance("ssl");
+                       sc.init(null, noopTrustManager, null);
+                       return sc;
+               } catch (KeyManagementException | NoSuchAlgorithmException e) {
+                       throw new IllegalStateException("Cannot create insecure SSL context ", e);
+               }
+       }
+
        protected void logout() {
                cmsView.logout();
                cmsView.navigateTo("~");
index e98e390eeaf8cb6eabaa0d4e99a3bf05e58d33ee..3ce5ae5169ca95343060647000f20206009247d5 100644 (file)
@@ -6,10 +6,10 @@ import java.util.Locale;
 
 import javax.security.auth.callback.LanguageCallback;
 
-import org.argeo.cms.CmsException;
-import org.argeo.cms.LocaleUtils;
+import org.argeo.cms.swt.CmsException;
 
 /** Choose in a list of locales. TODO: replace with {@link LanguageCallback} */
+@Deprecated
 public class LocaleChoice {
        private final List<Locale> locales;
 
@@ -36,13 +36,13 @@ public class LocaleChoice {
                this.selectedIndex = defaultIndex;
        }
 
-       /**
-        * Convenience constructor based on a comma separated list of iso codes (en,
-        * en_US, fr_CA, etc.). Default selection is default locale.
-        */
-       public LocaleChoice(String locales, Locale defaultLocale) {
-               this(LocaleUtils.asLocaleList(locales), defaultLocale);
-       }
+//     /**
+//      * Convenience constructor based on a comma separated list of iso codes (en,
+//      * en_US, fr_CA, etc.). Default selection is default locale.
+//      */
+//     public LocaleChoice(String locales, Locale defaultLocale) {
+//             this(LocaleUtils.asLocaleList(locales), defaultLocale);
+//     }
 
        public String[] getSupportedLocalesLabels() {
                String[] labels = new String[locales.size()];
index 8ad95c9e350713833fd0081550be8e598f950ad1..9d15143d790a56a4c4eb1981d530bd2ff835940f 100644 (file)
@@ -17,7 +17,7 @@ import org.osgi.framework.FrameworkUtil;
 public class CmsJettyCustomizer extends JettyCustomizer {
        private BundleContext bc = FrameworkUtil.getBundle(CmsJettyCustomizer.class).getBundleContext();
 
-       public final static String WEBSOCKET_ENABLED = "websocket.enabled";
+       public final static String WEBSOCKET_ENABLED = "argeo.websocket.enabled";
 
        @Override
        public Object customizeContext(Object context, Dictionary<String, ?> settings) {
diff --git a/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java b/jcr/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java
deleted file mode 100644 (file)
index a1cba1a..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.argeo.cms.internal.jcr;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-
-import org.argeo.api.cms.CmsDeployment;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
-import org.argeo.jcr.JcrException;
-import org.argeo.util.naming.LdapAttrs;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkUtil;
-
-/** JCR specific init utilities. */
-@Deprecated
-public class JcrInitUtils {
-       private final static CmsLog log = CmsLog.getLog(JcrInitUtils.class);
-       private final static BundleContext bundleContext = FrameworkUtil.getBundle(JcrInitUtils.class).getBundleContext();
-
-//     public static void addToDeployment(CmsDeployment nodeDeployment) {
-//             // node repository
-////           Dictionary<String, Object> provided = null;
-//             Dictionary<String, Object> provided = nodeDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID,
-//                             CmsConstants.NODE);
-//             Dictionary<String, Object> nodeConfig = JcrInitUtils.getNodeRepositoryConfig(provided);
-//             // node repository is mandatory
-//             nodeDeployment.addFactoryDeployConfig(CmsConstants.NODE_REPOS_FACTORY_PID, nodeConfig);
-//
-//             // additional repositories
-////           dataModels: for (DataModels.DataModel dataModel : dataModels.getNonAbstractDataModels()) {
-////                   if (NodeConstants.NODE_REPOSITORY.equals(dataModel.getName()))
-////                           continue dataModels;
-////                   Dictionary<String, Object> config = JcrInitUtils.getRepositoryConfig(dataModel.getName(),
-////                                   getProps(NodeConstants.NODE_REPOS_FACTORY_PID, dataModel.getName()));
-////                   if (config.size() != 0)
-////                           putFactoryDeployConfig(NodeConstants.NODE_REPOS_FACTORY_PID, config);
-////           }
-//
-//     }
-
-       /** Override the provided config with the framework properties */
-       public static Dictionary<String, Object> getNodeRepositoryConfig(Dictionary<String, Object> provided) {
-               Dictionary<String, Object> props = provided != null ? provided : new Hashtable<String, Object>();
-               for (RepoConf repoConf : RepoConf.values()) {
-                       Object value = getFrameworkProp(CmsConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
-                       if (value != null) {
-                               props.put(repoConf.name(), value);
-                               if (log.isDebugEnabled())
-                                       log.debug("Set node repo configuration " + repoConf.name() + " to " + value);
-                       }
-               }
-               props.put(CmsConstants.CN, CmsConstants.NODE_REPOSITORY);
-               return props;
-       }
-
-//     public static Dictionary<String, Object> getRepositoryConfig(String dataModelName,
-//                     Dictionary<String, Object> provided) {
-//             if (dataModelName.equals(CmsConstants.NODE_REPOSITORY) || dataModelName.equals(CmsConstants.EGO_REPOSITORY))
-//                     throw new IllegalArgumentException("Data model '" + dataModelName + "' is reserved.");
-//             Dictionary<String, Object> props = provided != null ? provided : new Hashtable<String, Object>();
-//             for (RepoConf repoConf : RepoConf.values()) {
-//                     Object value = getFrameworkProp(
-//                                     CmsConstants.NODE_REPOS_PROP_PREFIX + dataModelName + '.' + repoConf.name());
-//                     if (value != null) {
-//                             props.put(repoConf.name(), value);
-//                             if (log.isDebugEnabled())
-//                                     log.debug("Set " + dataModelName + " repo configuration " + repoConf.name() + " to " + value);
-//                     }
-//             }
-//             if (props.size() != 0)
-//                     props.put(CmsConstants.CN, dataModelName);
-//             return props;
-//     }
-
-       private static void registerRemoteInit(String uri) {
-               try {
-                       Repository repository = createRemoteRepository(new URI(uri));
-                       Hashtable<String, Object> properties = new Hashtable<>();
-                       properties.put(CmsConstants.CN, CmsConstants.NODE_INIT);
-                       properties.put(LdapAttrs.labeledURI.name(), uri);
-                       properties.put(Constants.SERVICE_RANKING, -1000);
-                       bundleContext.registerService(Repository.class, repository, properties);
-               } catch (RepositoryException e) {
-                       throw new JcrException(e);
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException(e);
-               }
-       }
-
-       private static Repository createRemoteRepository(URI uri) throws RepositoryException {
-               RepositoryFactory repositoryFactory = new ClientDavexRepositoryFactory();
-               Map<String, String> params = new HashMap<String, String>();
-               params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString());
-               // TODO make it configurable
-               params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, CmsConstants.SYS_WORKSPACE);
-               return repositoryFactory.getRepository(params);
-       }
-
-       private static String getFrameworkProp(String key, String def) {
-               String value;
-               if (bundleContext != null)
-                       value = bundleContext.getProperty(key);
-               else
-                       value = System.getProperty(key);
-               if (value == null)
-                       return def;
-               return value;
-       }
-
-       private static String getFrameworkProp(String key) {
-               return getFrameworkProp(key, null);
-       }
-
-}
index a45656cf567bda2e83e405f5080e5d5a42ca0dd5..336ec8239bbd7c45770cc09a9aa59edd4d7af28a 100644 (file)
@@ -1,11 +1,9 @@
 package org.argeo.cms.internal.jcr;
 
 import org.argeo.api.cms.CmsConstants;
-import org.argeo.osgi.metatype.EnumAD;
-import org.argeo.osgi.metatype.EnumOCD;
 
 /** JCR repository configuration */
-public enum RepoConf implements EnumAD {
+public enum RepoConf {
        /** Repository type */
        type("h2"),
        /** Default workspace */
@@ -41,10 +39,8 @@ public enum RepoConf implements EnumAD {
 
        /** The default value. */
        private Object def;
-       private String oid;
 
        RepoConf(String oid, Object def) {
-               this.oid = oid;
                this.def = def;
        }
 
@@ -56,17 +52,4 @@ public enum RepoConf implements EnumAD {
                return def;
        }
 
-       @Override
-       public String getID() {
-               if (oid != null)
-                       return oid;
-               return EnumAD.super.getID();
-       }
-
-       public static class OCD extends EnumOCD<RepoConf> {
-               public OCD(String locale) {
-                       super(RepoConf.class, locale);
-               }
-       }
-
 }
index 6fdd2009ba773e190a8a86cb63a330d2c2c80b65..ca25ddbdfd086fcf387ece13a62cb1cc9ccbfdd1 100644 (file)
@@ -12,15 +12,12 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.jcr.NamespaceRegistry;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
@@ -30,14 +27,10 @@ import javax.servlet.Servlet;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.core.RepositoryContext;
 import org.apache.jackrabbit.core.RepositoryImpl;
-import org.argeo.api.acr.spi.ProvidedRepository;
 import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsDeployment;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.ArgeoNames;
-import org.argeo.cms.internal.jcr.JcrInitUtils;
 import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.jcr.acr.JcrContentProvider;
 import org.argeo.cms.jcr.internal.servlet.CmsRemotingServlet;
 import org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet;
 import org.argeo.cms.jcr.internal.servlet.JcrHttpUtils;
@@ -48,7 +41,6 @@ import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.util.LangUtils;
-import org.argeo.util.naming.LdapAttrs;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -165,23 +157,23 @@ public class CmsJcrDeployment {
 //             }
 
                // init from repository
-               Collection<ServiceReference<Repository>> initRepositorySr;
-               try {
-                       initRepositorySr = bc.getServiceReferences(Repository.class,
-                                       "(" + CmsConstants.CN + "=" + CmsConstants.NODE_INIT + ")");
-               } catch (InvalidSyntaxException e1) {
-                       throw new IllegalArgumentException(e1);
-               }
-               Iterator<ServiceReference<Repository>> it = initRepositorySr.iterator();
-               while (it.hasNext()) {
-                       ServiceReference<Repository> sr = it.next();
-                       Object labeledUri = sr.getProperties().get(LdapAttrs.labeledURI.name());
-                       Repository initRepository = bc.getService(sr);
-                       if (log.isDebugEnabled())
-                               log.debug("Found init repository " + labeledUri + ", copying it...");
-                       initFromRepository(deployedNodeRepository, initRepository);
-                       log.info("Node repository initialised from " + labeledUri);
-               }
+//             Collection<ServiceReference<Repository>> initRepositorySr;
+//             try {
+//                     initRepositorySr = bc.getServiceReferences(Repository.class,
+//                                     "(" + CmsConstants.CN + "=" + CmsConstants.NODE_INIT + ")");
+//             } catch (InvalidSyntaxException e1) {
+//                     throw new IllegalArgumentException(e1);
+//             }
+//             Iterator<ServiceReference<Repository>> it = initRepositorySr.iterator();
+//             while (it.hasNext()) {
+//                     ServiceReference<Repository> sr = it.next();
+//                     Object labeledUri = sr.getProperties().get(LdapAttrs.labeledURI.name());
+//                     Repository initRepository = bc.getService(sr);
+//                     if (log.isDebugEnabled())
+//                             log.debug("Found init repository " + labeledUri + ", copying it...");
+//                     initFromRepository(deployedNodeRepository, initRepository);
+//                     log.info("Node repository initialised from " + labeledUri);
+//             }
        }
 
        /** Init from a (typically remote) repository. */
index e7f5a55af0084f2f01e540ac4c62695f05be49b0..090ec67ef3e21fd04291596ae3387b7e66f6f341 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.cms.jcr.internal;
 import java.nio.file.Path;
 
 /** Centralises access to the default node deployment directories. */
+@Deprecated
 public class CmsPaths {
        public static Path getRepoDirPath(String cn) {
                return KernelUtils.getOsgiInstancePath(KernelConstants.DIR_REPOS + '/' + cn);
index 29802509617bcc0545f4db86596dee380c491046..abf1a641802fe7f04d3f47d412b3a8145c34369f 100644 (file)
@@ -19,7 +19,6 @@ import javax.security.auth.login.LoginContext;
 
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrRepositoryWrapper;
@@ -28,7 +27,7 @@ import org.argeo.jcr.JcrUtils;
 /**
  * Make sure each user has a home directory available.
  */
-class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
+class EgoRepository extends JcrRepositoryWrapper {
 
        /** The home base path. */
 //     private String homeBasePath = KernelConstants.DEFAULT_HOME_BASE_PATH;
@@ -145,7 +144,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
 //                     JcrUtils.addPrivilege(adminSession, groupsBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
                        adminSession.save();
                } catch (RepositoryException e) {
-                       throw new CmsException("Cannot initialize home repository", e);
+                       throw new JcrException("Cannot initialize home repository", e);
                } finally {
                        JcrUtils.logoutQuietly(adminSession);
                }
@@ -197,7 +196,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
                try {
                        dn = new LdapName(username);
                } catch (InvalidNameException e) {
-                       throw new CmsException("Invalid name " + username, e);
+                       throw new IllegalArgumentException("Invalid name " + username, e);
                }
                String userId = dn.getRdn(dn.size() - 1).getValue().toString();
                return '/' + userId;
@@ -214,7 +213,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
                try {
                        dn = new LdapName(username);
                } catch (InvalidNameException e) {
-                       throw new CmsException("Invalid name " + username, e);
+                       throw new IllegalArgumentException("Invalid name " + username, e);
                }
                String userId = dn.getRdn(dn.size() - 1).getValue().toString();
                return userId;
@@ -233,7 +232,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
                Node newWorkgroup = CmsJcrUtils.getGroupHome(adminSession, cn);
                if (newWorkgroup != null) {
                        JcrUtils.logoutQuietly(adminSession);
-                       throw new CmsException("Workgroup " + newWorkgroup + " already exists for " + dn);
+                       throw new IllegalStateException("Workgroup " + newWorkgroup + " already exists for " + dn);
                }
                try {
                        // TODO enhance transformation of cn to a valid node name
@@ -251,7 +250,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants {
                        JcrUtils.addPrivilege(adminSession, newWorkgroup.getPath(), dn.toString(), Privilege.JCR_ALL);
                        adminSession.save();
                } catch (RepositoryException e) {
-                       throw new CmsException("Cannot create workgroup", e);
+                       throw new JcrException("Cannot create workgroup", e);
                } finally {
                        JcrUtils.logoutQuietly(adminSession);
                }
index 11e9a9e92bc0e064cf2fa9d3483251afcc7fd600..f3a099b08f7f64f670108d1f3566f1b8f596b4d2 100644 (file)
@@ -16,6 +16,7 @@ import org.apache.jackrabbit.core.RepositoryContext;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsState;
+import org.argeo.cms.CmsDeployProperty;
 import org.argeo.cms.internal.jcr.RepoConf;
 import org.argeo.cms.internal.jcr.RepositoryBuilder;
 import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
@@ -25,6 +26,7 @@ import org.osgi.service.cm.ManagedServiceFactory;
 /** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */
 public class RepositoryContextsFactory {
        private final static CmsLog log = CmsLog.getLog(RepositoryContextsFactory.class);
+       private final static String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
 //     private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext();
 
 //     private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
@@ -68,8 +70,11 @@ public class RepositoryContextsFactory {
        /** Override the provided config with the framework properties */
        private Dictionary<String, Object> getNodeRepositoryConfig() {
                Dictionary<String, Object> props = new Hashtable<String, Object>();
+               addDeployProperty(CmsDeployProperty.DB_URL, RepoConf.dburl, props);
+               addDeployProperty(CmsDeployProperty.DB_USER, RepoConf.dbuser, props);
+               addDeployProperty(CmsDeployProperty.DB_PASSWORD, RepoConf.dbpassword, props);
                for (RepoConf repoConf : RepoConf.values()) {
-                       Object value = getFrameworkProp(CmsConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
+                       Object value = getFrameworkProp(NODE_REPO_PROP_PREFIX + repoConf.name());
                        if (value != null) {
                                props.put(repoConf.name(), value);
                                if (log.isDebugEnabled())
@@ -80,6 +85,15 @@ public class RepositoryContextsFactory {
                return props;
        }
 
+       private void addDeployProperty(CmsDeployProperty deployProperty, RepoConf repoConf,
+                       Dictionary<String, Object> props) {
+               String value = getFrameworkProp(deployProperty.getProperty());
+               if (value != null) {
+                       props.put(repoConf.name(), value);
+               }
+
+       }
+
 //     @Override
 //     public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
        protected void deployRepository(Dictionary<String, Object> properties) {
index 62cdc5f6b08d92ce58fdc60e1d76193cbed9100d..be5684acccc1e439d79c623460d0257e023cdd1f 100644 (file)
@@ -27,7 +27,6 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.jcr.CmsJcrUtils;
 import org.argeo.jcr.JcrUtils;
 import org.osgi.framework.BundleContext;
@@ -137,7 +136,7 @@ public class LinkServlet extends HttpServlet {
                        response.setHeader("Content-Type", "text/html");
                        writer.flush();
                } catch (Exception e) {
-                       throw new CmsException("Cannot write canonical answer", e);
+                       throw new IllegalStateException("Cannot write canonical answer", e);
                } finally {
                        JcrUtils.logoutQuietly(session);
                }
@@ -190,7 +189,7 @@ public class LinkServlet extends HttpServlet {
                                buf.append(':').append(url.getPort());
                        return buf;
                } catch (MalformedURLException e) {
-                       throw new CmsException("Cannot extract server base URL from " + request.getRequestURL(), e);
+                       throw new IllegalArgumentException("Cannot extract server base URL from " + request.getRequestURL(), e);
                }
        }
 
@@ -200,7 +199,7 @@ public class LinkServlet extends HttpServlet {
                        buf.append(CmsJcrUtils.getDataPath(CmsConstants.EGO_REPOSITORY, node));
                        return new URL(buf.toString()).toString();
                } catch (MalformedURLException e) {
-                       throw new CmsException("Cannot build data URL for " + node, e);
+                       throw new IllegalArgumentException("Cannot build data URL for " + node, e);
                }
        }
 
@@ -238,7 +237,7 @@ public class LinkServlet extends HttpServlet {
                        buf.append('/').append('!').append(node.getPath());
                        return new URL(buf.toString()).toString();
                } catch (MalformedURLException e) {
-                       throw new CmsException("Cannot build data URL for " + node, e);
+                       throw new IllegalArgumentException("Cannot build data URL for " + node, e);
                }
                // return request.getRequestURL().append('!').append(node.getPath())
                // .toString();
@@ -252,7 +251,7 @@ public class LinkServlet extends HttpServlet {
                        lc.login();
                        return subject;
                } catch (LoginException e) {
-                       throw new CmsException("Cannot login as anonymous", e);
+                       throw new IllegalStateException("Cannot login as anonymous", e);
                }
        }
 
index d5914d209478cc1cb0e4092d798b665eb9df0c32..ef49c8ae5652e5c351b8b5113c304673f4470711 100644 (file)
@@ -11,7 +11,7 @@ import javax.jcr.RepositoryException;
 
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.ux.CmsView;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.eclipse.jface.fieldassist.ControlDecoration;
index 5a5ecdb8bf4be58e19c0476e779d16d4cad2e6a2..d9c1c1221e0b3d92cdb0d3919a9f7474434edbae 100644 (file)
@@ -18,9 +18,9 @@ import javax.jcr.Node;
 import javax.jcr.Repository;
 import javax.jcr.Session;
 
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
index c548e2aa0b0cfdd25bf7ffcce158d9334886ba3c..1fb3c2a05a59696e3242085025ee6c84adea596c 100644 (file)
@@ -16,7 +16,7 @@ import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.SingleValue;
index 44885b1ca04b5eb25497ee179d2995abfd515874..ea0abdf5da1903409476751792f7ab0d96445770 100644 (file)
@@ -6,7 +6,7 @@ import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
index e8bf66297e26a9d551f37cd32296e40dfeecded9..ab6a29f7dfa8950cf546849e8dc2736b9d1c4955 100644 (file)
@@ -6,7 +6,7 @@ import java.util.List;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsStyles;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.ui.CmsUiProvider;
index 8e0e7c1795d0752f53188f8269c29c020f4bcbde..c61a2fc9efa64000badbde494372ebeb894f5fba 100644 (file)
@@ -11,7 +11,7 @@ import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.jcr.JcrUtils;
 import org.eclipse.rap.rwt.RWT;
index ad1523c1a0809fba689460c20fe6a1221481122a..1e17dc930e418a9cc131e63086e4235bf9b8e7a9 100644 (file)
@@ -9,7 +9,7 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.rap.rwt.service.ResourceLoader;
 import org.osgi.framework.Bundle;
 
index 156a6082f5322c83648467ad21e799b161b3c566..5a00781635374aae5293861fd231582351761e75 100644 (file)
@@ -8,7 +8,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 
 import org.apache.commons.io.IOUtils;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsStyles;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.eclipse.rap.rwt.RWT;
index 008ec2c161da3ded1feadafcf9b91b9f669a006e..09aeff60f412a20282ac23096db47ceef6fc6c6e 100644 (file)
@@ -2,7 +2,7 @@ package org.argeo.cms.ui.util;
 
 import javax.jcr.Node;
 
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.auth.CmsLoginShell;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ShellAdapter;
index 8fe9846f41f272f1a956ee29fd3099748ea66513..7b89813fd32c56845f03e71e247e0515ea11edc5 100644 (file)
@@ -82,31 +82,31 @@ public interface CmsConstants {
        /*
         * INIT FRAMEWORK PROPERTIES
         */
-       String NODE_INIT = "argeo.node.init";
-       String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale";
-       String I18N_LOCALES = "argeo.i18n.locales";
+//     String NODE_INIT = "argeo.node.init";
+//     String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale";
+//     String I18N_LOCALES = "argeo.i18n.locales";
        // Node Security
-       String ROLES_URI = "argeo.node.roles.uri";
-       String TOKENS_URI = "argeo.node.tokens.uri";
-       /** URI to an LDIF file or LDAP server used as initialization or backend */
-       String USERADMIN_URIS = "argeo.node.useradmin.uris";
+//     String ROLES_URI = "argeo.node.roles.uri";
+//     String TOKENS_URI = "argeo.node.tokens.uri";
+//     /** URI to an LDIF file or LDAP server used as initialization or backend */
+//     String USERADMIN_URIS = "argeo.node.useradmin.uris";
        // Transaction manager
-       String TRANSACTION_MANAGER = "argeo.node.transaction.manager";
-       String TRANSACTION_MANAGER_SIMPLE = "simple";
-       String TRANSACTION_MANAGER_BITRONIX = "bitronix";
+//     String TRANSACTION_MANAGER = "argeo.node.transaction.manager";
+//     String TRANSACTION_MANAGER_SIMPLE = "simple";
+//     String TRANSACTION_MANAGER_BITRONIX = "bitronix";
        // Node
-       /** Properties configuring the node repository */
-       String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
-       /** Additional standalone repositories, related to data models. */
-       String NODE_REPOS_PROP_PREFIX = "argeo.node.repos.";
+//     /** Properties configuring the node repository */
+//     String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
+//     /** Additional standalone repositories, related to data models. */
+//     String NODE_REPOS_PROP_PREFIX = "argeo.node.repos.";
        // HTTP
-       String HTTP_PORT = "org.osgi.service.http.port";
-       String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure";
-       /**
-        * The HTTP header used to convey the DN of a client verified by a reverse
-        * proxy. Typically SSL_CLIENT_S_DN for Apache.
-        */
-       String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn";
+//     String HTTP_PORT = "org.osgi.service.http.port";
+//     String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure";
+//     /**
+//      * The HTTP header used to convey the DN of a client verified by a reverse
+//      * proxy. Typically SSL_CLIENT_S_DN for Apache.
+//      */
+//     String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn";
 
        /*
         * PIDs
index c69be8eeb7f50f59c4375b8009b9cdd2ca5eb544..d557816cb1a3bc927d449c2ae7232b307fef726b 100644 (file)
@@ -1,7 +1,5 @@
 package org.argeo.api.cms;
 
-import java.util.Dictionary;
-
 /** A configured node deployment. */
 public interface CmsDeployment {
 
index 3e0e8b75725f8d1982f63ec0a1da04f22050d3b5..181e4b9c661f716424f0d183bf97514431680b51 100644 (file)
@@ -1,6 +1,7 @@
 package org.argeo.api.cms;
 
 import java.nio.file.Path;
+import java.util.List;
 import java.util.UUID;
 
 /** A running node process. */
@@ -11,7 +12,13 @@ public interface CmsState {
 
        UUID getUuid();
 
-       String getDeployProperty(String key);
-       
+       String getDeployProperty(String property);
+
+       /**
+        * A list of size of the max count for this property, with null values when the
+        * property is not set, or an empty list (size 0) if this property is unknown.
+        */
+       List<String> getDeployProperties(String property);
+
        Path getDataPath(String relativePath);
 }
index 90260c314e1a252ceaec94f8daad09d0eaabccf6..4e869b7fd532df762bfccd7b607ccd96153d8763 100644 (file)
@@ -1,6 +1,7 @@
 package org.argeo.cms;
 
 /** JCR names in the http://www.argeo.org/argeo namespace */
+@Deprecated
 public interface ArgeoNames {
        public final static String ARGEO_NAMESPACE = "http://www.argeo.org/ns/argeo";
 
index ce043910238ad4a95f9a92f3b13cf29088d3093b..9995725d80ea29473cd77eb10ce97c6e0b8977e3 100644 (file)
@@ -1,9 +1,10 @@
 package org.argeo.cms;
 
 /** JCR types in the http://www.argeo.org/argeo namespace */
+@Deprecated
 public interface ArgeoTypes {
        public final static String ARGEO_REMOTE_REPOSITORY = "argeo:remoteRepository";
-       
+
        // tabular
        public final static String ARGEO_TABLE = "argeo:table";
        public final static String ARGEO_COLUMN = "argeo:column";
diff --git a/org.argeo.cms/src/org/argeo/cms/CmsDeployProperty.java b/org.argeo.cms/src/org/argeo/cms/CmsDeployProperty.java
new file mode 100644 (file)
index 0000000..ef1edcc
--- /dev/null
@@ -0,0 +1,147 @@
+package org.argeo.cms;
+
+import java.util.Objects;
+
+/** A property that can be used to configure a CMS node deployment. */
+public enum CmsDeployProperty {
+       //
+       // DIRECTORY
+       //
+       DIRECTORY("argeo.directory", 64),
+       //
+       // DATABASE
+       //
+       /** URL of the database backend. */
+       DB_URL("argeo.db.url"),
+       /** DB user of the database backend. */
+       DB_USER("argeo.db.user"),
+       /** DB user password of the database backend. */
+       DB_PASSWORD("argeo.db.password"),
+       //
+       // NETWORK
+       //
+       /** Either a host or an IP address. Restricts all servers to it. */
+       HOST("argeo.host"),
+       //
+       // HTTP
+       //
+       /** Request an HTTP server on this port. */
+       HTTP_PORT("argeo.http.port"),
+       /** Request an HTTPS server on this port. */
+       HTTPS_PORT("argeo.https.port"),
+       /**
+        * The HTTP header used to convey the DN of a client verified by a reverse
+        * proxy. Typically SSL_CLIENT_S_DN for Apache.
+        */
+       HTTP_PROXY_SSL_HEADER_DN("argeo.http.proxy.ssl.header.dn"),
+       //
+       // SSL
+       //
+       /** SSL keystore for the system. */
+       SSL_KEYSTORE("argeo.ssl.keystore"),
+       /** SSL keystore password for the system. */
+       SSL_PASSWORD("argeo.ssl.password"),
+       /** SSL keystore type password for the system. */
+       SSL_KEYSTORETYPE("argeo.ssl.keystoretype"),
+       /** SSL password for the private key. */
+       SSL_KEYPASSWORD("argeo.ssl.keypassword"),
+       /** Whether a client certificate is required. */
+       SSL_NEEDCLIENTAUTH("argeo.ssl.needclientauth"),
+       /** Whether a client certificate can be used. */
+       SSL_WANTCLIENTAUTH("argeo.ssl.wantclientauth"),
+       /** SSL protocol to use. */
+       SSL_PROTOCOL("argeo.ssl.protocol"),
+       /** SSL algorithm to use. */
+       SSL_ALGORITHM("argeo.ssl.algorithm"),
+       //
+       // WEBSOCKET
+       //
+       /** Whether web socket should be enables in web server. */
+       WEBSOCKET_ENABLED("argeo.websocket.enabled"),
+       //
+       // INTERNATIONALIZATION
+       //
+       /** Locales enabled for this system, the first one is considered the default. */
+       LOCALE("argeo.locale", 256),
+       //
+       // NODE
+       //
+       /** Directories to copy to the data area during the first initialisation. */
+       NODE_INIT("argeo.node.init", 64),
+       //
+       // JAVA
+       //
+       /** Custom JAAS config. */
+       JAVA_LOGIN_CONFIG("java.security.auth.login.config", true),
+       //
+       // OSGi
+       //
+       /** OSGi writable data area. */
+       OSGI_INSTANCE_AREA("osgi.instance.area"),
+       /** OSGi writable configuration area. */
+       OSGI_CONFIGURATION_AREA("osgi.configuration.area"),
+       //
+       ;
+
+       private String property;
+       private boolean systemPropertyOnly = false;
+
+       private int maxCount = 1;
+
+       CmsDeployProperty(String property) {
+               this(property, 1, false);
+       }
+
+       CmsDeployProperty(String property, int maxCount) {
+               this(property, maxCount, false);
+       }
+
+       CmsDeployProperty(String property, boolean systemPropertyOnly) {
+               this.property = property;
+       }
+
+       CmsDeployProperty(String property, int maxCount, boolean systemPropertyOnly) {
+               this.property = property;
+               this.systemPropertyOnly = systemPropertyOnly;
+               this.maxCount = maxCount;
+       }
+
+       public String getProperty() {
+               return property;
+       }
+
+       public boolean isSystemPropertyOnly() {
+               return systemPropertyOnly;
+       }
+
+       public int getMaxCount() {
+               return maxCount;
+       }
+
+       public static CmsDeployProperty find(String property) {
+               int index = getPropertyIndex(property);
+               String propertyName = index == 0 ? property : property.substring(0, property.lastIndexOf('.'));
+               for (CmsDeployProperty deployProperty : values()) {
+                       if (deployProperty.getProperty().equals(propertyName))
+                               return deployProperty;
+               }
+               return null;
+       }
+
+       public static int getPropertyIndex(String property) {
+               Objects.requireNonNull(property);
+               int lastDot = property.lastIndexOf('.');
+               if (lastDot <= 0 || lastDot == (property.length() - 1)) {
+                       throw new IllegalArgumentException("Property " + property + " is not qualified (must contain a dot).");
+               }
+               String lastSegment = property.substring(lastDot + 1);
+               int index;
+               try {
+                       index = Integer.parseInt(lastSegment);
+               } catch (NumberFormatException e) {
+                       index = 0;
+               }
+               return index;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/CmsException.java b/org.argeo.cms/src/org/argeo/cms/CmsException.java
deleted file mode 100644 (file)
index 09d55c2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.argeo.cms;
-
-/** @deprecated Use standard Java {@link RuntimeException} instead. */
-@Deprecated
-public class CmsException extends RuntimeException {
-       private static final long serialVersionUID = -5341764743356771313L;
-
-       public CmsException(String message) {
-               super(message);
-       }
-
-       public CmsException(String message, Throwable e) {
-               super(message, e);
-       }
-
-}
index f02e6a2b4439f57a3e5a23f69aaecbda3dcf1c46..415a0954dff41d4526e39ccf5b8413c3b7573b79 100644 (file)
@@ -1,13 +1,8 @@
 package org.argeo.cms;
 
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Locale;
 import java.util.ResourceBundle;
 
-import javax.security.auth.Subject;
-
 import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.auth.CurrentUser;
 
@@ -102,7 +97,7 @@ public class LocaleUtils {
 
        static Locale getCurrentLocale() {
                Locale currentLocale = null;
-               if (Subject.getSubject(AccessController.getContext()) != null)
+               if (CurrentUser.isAvailable())
                        currentLocale = CurrentUser.locale();
                else if (threadLocale.get() != null) {
                        currentLocale = threadLocale.get();
@@ -118,26 +113,4 @@ public class LocaleUtils {
                // return Locale.getDefault();
        }
 
-       /** Returns null if argument is null. */
-       public static List<Locale> asLocaleList(Object locales) {
-               if (locales == null)
-                       return null;
-               ArrayList<Locale> availableLocales = new ArrayList<Locale>();
-               String[] codes = locales.toString().split(",");
-               for (int i = 0; i < codes.length; i++) {
-                       String code = codes[i];
-                       // variant not supported
-                       int indexUnd = code.indexOf("_");
-                       Locale locale;
-                       if (indexUnd > 0) {
-                               String language = code.substring(0, indexUnd);
-                               String country = code.substring(indexUnd + 1);
-                               locale = new Locale(language, country);
-                       } else {
-                               locale = new Locale(code);
-                       }
-                       availableLocales.add(locale);
-               }
-               return availableLocales;
-       }
 }
index 3e01aee8b235ff9d1d0a94d30174d1afa6d6e6f4..6285710e8a0eff395acf8ab73a3877f66ae05c73 100644 (file)
@@ -45,7 +45,7 @@ public class CmsContentRepository extends AbstractContentRepository {
                CmsContentSession contentSession = userSessions.get(cmsSession);
                if (contentSession == null) {
                        final CmsContentSession newContentSession = new CmsContentSession(this, cmsSession.getUuid(),
-                                       cmsSession.getSubject(), locale);
+                                       cmsSession.getSubject(), locale, uuidFactory);
                        cmsSession.addOnCloseCallback((c) -> {
                                newContentSession.close();
                                userSessions.remove(cmsSession);
@@ -65,8 +65,8 @@ public class CmsContentRepository extends AbstractContentRepository {
                        throw new RuntimeException("Could not login as data admin", e1);
                } finally {
                }
-               return new CmsContentSession(this, getCmsState().getUuid(), loginContext.getSubject(),
-                               Locale.getDefault());
+               return new CmsContentSession(this, getCmsState().getUuid(), loginContext.getSubject(), Locale.getDefault(),
+                               uuidFactory);
        }
 
        protected CmsState getCmsState() {
index b82507d6f75025528cb4f29c69dc2b9b6637fd91..f811642c7f7f4971b379ac2aca0c709c104b61cb 100644 (file)
@@ -1,27 +1,23 @@
 package org.argeo.cms.acr;
 
-import java.util.Iterator;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
 import java.util.function.Consumer;
-import java.util.stream.Collectors;
 
 import javax.security.auth.Subject;
 
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.ContentSession;
 import org.argeo.api.acr.CrName;
-import org.argeo.api.acr.NamespaceUtils;
-import org.argeo.api.acr.RuntimeNamespaceContext;
 import org.argeo.api.acr.spi.ContentProvider;
 import org.argeo.api.acr.spi.ProvidedContent;
 import org.argeo.api.acr.spi.ProvidedRepository;
 import org.argeo.api.acr.spi.ProvidedSession;
+import org.argeo.api.uuid.UuidFactory;
 import org.argeo.cms.acr.xml.DomContentProvider;
 
 /** Implements {@link ProvidedSession}. */
@@ -32,6 +28,8 @@ class CmsContentSession implements ProvidedSession {
        private Subject subject;
        private Locale locale;
 
+       private UuidFactory uuidFactory;
+
        private CompletableFuture<ProvidedSession> closed = new CompletableFuture<>();
 
        private CompletableFuture<ContentSession> edition;
@@ -40,12 +38,13 @@ class CmsContentSession implements ProvidedSession {
 
        private Content sessionRunDir;
 
-       public CmsContentSession(AbstractContentRepository contentRepository, UUID uuid, Subject subject, Locale locale) {
+       public CmsContentSession(AbstractContentRepository contentRepository, UUID uuid, Subject subject, Locale locale,
+                       UuidFactory uuidFactory) {
                this.contentRepository = contentRepository;
                this.subject = subject;
                this.locale = locale;
                this.uuid = uuid;
-
+               this.uuidFactory = uuidFactory;
        }
 
        public void close() {
@@ -99,6 +98,10 @@ class CmsContentSession implements ProvidedSession {
                return contentRepository;
        }
 
+       public UuidFactory getUuidFactory() {
+               return uuidFactory;
+       }
+
        /*
         * MOUNT MANAGEMENT
         */
index cac407495a70be147447e9c27986ccecf448cbe4..8125555f9912890258cba87b35daf723e6fef1e3 100644 (file)
@@ -11,6 +11,8 @@ import javax.security.auth.x500.X500Principal;
 
 import org.argeo.api.acr.ContentSession;
 import org.argeo.api.acr.spi.ProvidedRepository;
+import org.argeo.api.uuid.MacAddressUuidFactory;
+import org.argeo.api.uuid.UuidFactory;
 import org.argeo.cms.acr.fs.FsContentProvider;
 import org.argeo.util.naming.LdapAttrs;
 
@@ -24,6 +26,8 @@ public class SingleUserContentRepository extends AbstractContentRepository {
 
        private UUID uuid;
 
+       private UuidFactory uuidFactory = MacAddressUuidFactory.DEFAULT;
+
        // the single session
        private CmsContentSession contentSession;
 
@@ -51,7 +55,7 @@ public class SingleUserContentRepository extends AbstractContentRepository {
                initRootContentProvider(null);
                if (contentSession != null)
                        throw new IllegalStateException("Repository is already started, stop it first.");
-               contentSession = new CmsContentSession(this, uuid, subject, locale);
+               contentSession = new CmsContentSession(this, uuid, subject, locale, uuidFactory);
        }
 
        @Override
@@ -76,7 +80,7 @@ public class SingleUserContentRepository extends AbstractContentRepository {
 
        @Override
        protected CmsContentSession newSystemSession() {
-               return new CmsContentSession(this, uuid, subject, Locale.getDefault());
+               return new CmsContentSession(this, uuid, subject, Locale.getDefault(), uuidFactory);
        }
 
        public static void main(String... args) {
index 13b54a549a83eac180c3116f017eb204bc0856dc..68ea5ff28243543112cbd586e5dbdd467b412acb 100644 (file)
@@ -138,11 +138,18 @@ public final class CurrentUser {
                return CmsContextImpl.getCmsContext().getCmsSessionByUuid(cmsSessionId.getUuid());
        }
 
+       public static boolean isAvailable() {
+               return CurrentSubject.current() != null;
+       }
+
        /*
         * HELPERS
         */
        private static Subject currentSubject() {
-               return CurrentSubject.current();
+               Subject subject = CurrentSubject.current();
+               if (subject == null)
+                       throw new IllegalStateException("Cannot find related subject");
+               return subject;
        }
 
        private static Authorization getAuthorization(Subject subject) {
index 6274bb146e736165214fcabd52f49c20edb3e5d8..0bb199dfdbfddcf4fb93eda4e4363834f9afa77b 100644 (file)
@@ -3,12 +3,19 @@ package org.argeo.cms.auth;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Base64;
 import java.util.function.Supplier;
 
 import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosTicket;
 
 import org.argeo.api.cms.CmsSession;
 import org.argeo.cms.internal.runtime.CmsContextImpl;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
 
 /** Remote authentication utilities. */
 public class RemoteAuthUtils {
@@ -59,4 +66,50 @@ public class RemoteAuthUtils {
                CmsSession cmsSession = CmsContextImpl.getCmsContext().getCmsSession(subject);
                return cmsSession;
        }
+
+       private final static Oid KERBEROS_OID;
+       static {
+               try {
+                       KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
+               } catch (GSSException e) {
+                       throw new IllegalStateException("Cannot create Kerberos OID", e);
+               }
+       }
+
+       public static String getGssToken(Subject subject, String serverPrinc) {
+               if (subject.getPrivateCredentials(KerberosTicket.class).isEmpty())
+                       throw new IllegalArgumentException("Subject " + subject + " is not GSS authenticated.");
+               return Subject.doAs(subject, (PrivilegedAction<String>) () -> {
+                       GSSContext context = null;
+                       String tokenStr = null;
+
+                       try {
+                               // Get service's principal name
+                               GSSManager manager = GSSManager.getInstance();
+                               GSSName serverName = manager.createName(serverPrinc, GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID);
+
+                               // Get the context for authentication
+                               context = manager.createContext(serverName, KERBEROS_OID, null, GSSContext.DEFAULT_LIFETIME);
+                               // context.requestMutualAuth(true); // Request mutual authentication
+                               // context.requestConf(true); // Request confidentiality
+                               context.requestCredDeleg(true);
+
+                               byte[] token = new byte[0];
+
+                               // token is ignored on the first call
+                               token = context.initSecContext(token, 0, token.length);
+
+                               // Send a token to the server if one was generated by
+                               // initSecContext
+                               if (token != null) {
+                                       tokenStr = Base64.getEncoder().encodeToString(token);
+                                       // complete=true;
+                               }
+                               return tokenStr;
+
+                       } catch (GSSException e) {
+                               throw new IllegalStateException("Cannot authenticate to " + serverPrinc, e);
+                       }
+               });
+       }
 }
index 05c5cf4422de810d817e3c919b4cfd66ee96b9de..3abcf8c9483d52176d9cb058723577f9c1a7963a 100644 (file)
@@ -16,8 +16,10 @@ import javax.security.auth.spi.LoginModule;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.CmsDeployProperty;
 import org.argeo.cms.internal.auth.CmsSessionImpl;
 import org.argeo.cms.internal.runtime.CmsContextImpl;
+import org.argeo.cms.internal.runtime.CmsStateImpl;
 import org.osgi.service.http.HttpContext;
 import org.osgi.service.useradmin.Authorization;
 
@@ -210,8 +212,8 @@ public class RemoteSessionLoginModule implements LoginModule {
                        if (log.isDebugEnabled())
                                log.debug("Client certificate " + certDn + " verified by servlet container");
                } // Reverse proxy verified the client certificate
-               String clientDnHttpHeader = CmsContextImpl.getCmsContext().getCmsState()
-                               .getDeployProperty(CmsConstants.HTTP_PROXY_SSL_DN);
+               String clientDnHttpHeader = CmsStateImpl.getDeployProperty(CmsContextImpl.getCmsContext().getCmsState(),
+                               CmsDeployProperty.HTTP_PROXY_SSL_HEADER_DN);
                if (clientDnHttpHeader != null) {
                        String certDn = req.getHeader(clientDnHttpHeader);
                        // TODO retrieve more cf. https://httpd.apache.org/docs/current/mod/mod_ssl.html
index 4abdd145830a2b8d5ce19809a6b97cec3ad12d36..27ed2ec3e6407a34c5635f9bf51762473b35aa68 100644 (file)
@@ -20,7 +20,6 @@ import org.apache.commons.httpclient.auth.MalformedChallengeException;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.params.DefaultHttpParams;
 import org.apache.commons.httpclient.params.HttpParams;
-import org.argeo.cms.internal.runtime.KernelConstants;
 import org.ietf.jgss.GSSContext;
 import org.ietf.jgss.GSSException;
 import org.ietf.jgss.GSSManager;
@@ -41,6 +40,8 @@ public class SpnegoAuthScheme implements AuthScheme {
                }
        }
 
+       private final static String DEFAULT_KERBEROS_SERVICE = "HTTP";
+
        private boolean complete = false;
        private String realm;
 
@@ -100,7 +101,7 @@ public class SpnegoAuthScheme implements AuthScheme {
                } catch (URIException e1) {
                        throw new IllegalStateException("Cannot authenticate", e1);
                }
-               String serverPrinc = KernelConstants.DEFAULT_KERBEROS_SERVICE + "@" + hostname;
+               String serverPrinc = DEFAULT_KERBEROS_SERVICE + "@" + hostname;
 
                try {
                        // Get service's principal name
index c167af0250cada2eaa0651e21a44990268e4d3f1..2936df28a52af1c9c0091ad058dd065bef3a51e0 100644 (file)
@@ -25,9 +25,7 @@ import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.ArgeoLogListener;
 import org.argeo.cms.ArgeoLogger;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.internal.runtime.KernelConstants;
 import org.argeo.util.directory.DirectoryConf;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
@@ -40,6 +38,9 @@ import org.osgi.service.log.LogReaderService;
 
 /** Not meant to be used directly in standard log4j config */
 public class CmsOsgiLogger implements ArgeoLogger, LogListener {
+       private final static String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern";
+       private final static String CONTEXT_NAME_PROP = "contextName";
+
        /** Internal debug for development purposes. */
        private static Boolean debug = false;
 
@@ -120,7 +121,7 @@ public class CmsOsgiLogger implements ArgeoLogger, LogListener {
                        logDispatcherThread = new LogDispatcherThread();
                        logDispatcherThread.start();
                } catch (Exception e) {
-                       throw new CmsException("Cannot initialize log4j");
+                       throw new IllegalStateException("Cannot initialize log4j");
                }
        }
 
@@ -203,19 +204,18 @@ public class CmsOsgiLogger implements ArgeoLogger, LogListener {
                        // sb.append(" " + Constants.SERVICE_PID + ": " + servicePid);
                        // }
                        // servlets
-                       Object whiteBoardPattern = sr.getProperty(KernelConstants.WHITEBOARD_PATTERN_PROP);
+                       Object whiteBoardPattern = sr.getProperty(WHITEBOARD_PATTERN_PROP);
                        if (whiteBoardPattern != null) {
                                if (whiteBoardPattern instanceof String) {
-                                       sb.append(" " + KernelConstants.WHITEBOARD_PATTERN_PROP + ": " + whiteBoardPattern);
+                                       sb.append(" " + WHITEBOARD_PATTERN_PROP + ": " + whiteBoardPattern);
                                } else {
-                                       sb.append(" " + KernelConstants.WHITEBOARD_PATTERN_PROP + ": "
-                                                       + arrayToString((String[]) whiteBoardPattern));
+                                       sb.append(" " + WHITEBOARD_PATTERN_PROP + ": " + arrayToString((String[]) whiteBoardPattern));
                                }
                        }
                        // RWT
-                       Object contextName = sr.getProperty(KernelConstants.CONTEXT_NAME_PROP);
+                       Object contextName = sr.getProperty(CONTEXT_NAME_PROP);
                        if (contextName != null)
-                               sb.append(" " + KernelConstants.CONTEXT_NAME_PROP + ": " + contextName);
+                               sb.append(" " + CONTEXT_NAME_PROP + ": " + contextName);
 
                        // user directories
                        Object baseDn = sr.getProperty(DirectoryConf.baseDn.name());
@@ -254,7 +254,7 @@ public class CmsOsgiLogger implements ArgeoLogger, LogListener {
        public synchronized void register(ArgeoLogListener listener, Integer numberOfPreviousEvents) {
                String username = CurrentUser.getUsername();
                if (username == null)
-                       throw new CmsException("Only authenticated users can register a log listener");
+                       throw new IllegalStateException("Only authenticated users can register a log listener");
 
                if (!userListeners.containsKey(username)) {
                        List<ArgeoLogListener> lst = Collections.synchronizedList(new ArrayList<ArgeoLogListener>());
index e5a5048893a987ca1fae567ea59f5aecbc127aaf..7f8db5a062cd3fca9bd110cf7ff5e250a91a6505 100644 (file)
@@ -23,9 +23,6 @@ import javax.naming.ldap.Rdn;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.internal.runtime.InitUtils;
-import org.argeo.cms.internal.runtime.KernelConstants;
-import org.argeo.cms.internal.runtime.KernelUtils;
 import org.argeo.util.directory.DirectoryConf;
 import org.argeo.util.directory.ldap.AttributesDictionary;
 import org.argeo.util.directory.ldap.LdifParser;
@@ -42,7 +39,7 @@ public class DeployConfig {
        private final CmsLog log = CmsLog.getLog(getClass());
 //     private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
 
-       private static Path deployConfigPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH);
+       private static Path deployConfigPath;// = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH);
        private SortedMap<LdapName, Attributes> deployConfigs = new TreeMap<>();
 //     private final DataModels dataModels;
 
@@ -57,7 +54,7 @@ public class DeployConfig {
                Files.createDirectories(deployConfigPath.getParent());
 
                // FirstInit firstInit = new FirstInit();
-               InitUtils.prepareFirstInitInstanceArea();
+               //InitUtils.prepareFirstInitInstanceArea();
 
                if (!Files.exists(deployConfigPath))
                        deployConfigs = new TreeMap<>();
index e534d9fe36fa9c6fc92481371aaeb8a4d68dc38a..da67c733d0f1c3f0ce5249016b19aa426b7dbee0 100644 (file)
@@ -8,7 +8,6 @@ import java.util.Map;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.runtime.CmsUserAdmin;
-import org.argeo.cms.internal.runtime.KernelConstants;
 import org.argeo.osgi.useradmin.UserDirectory;
 import org.argeo.util.directory.DirectoryConf;
 import org.osgi.framework.Constants;
@@ -20,7 +19,8 @@ import org.osgi.service.useradmin.UserAdmin;
  * Aggregates multiple {@link UserDirectory} and integrates them with system
  * roles.
  */
-public class NodeUserAdmin extends CmsUserAdmin implements ManagedServiceFactory, KernelConstants {
+@Deprecated
+public class NodeUserAdmin extends CmsUserAdmin implements ManagedServiceFactory {
        private final static CmsLog log = CmsLog.getLog(NodeUserAdmin.class);
 
        // OSGi
index 2a81b6a7d11db963e7f8319f5e9761b9451dbad9..e14b21e7073cd39241250fa0ec337a2a795a83e8 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.cms.internal.runtime;
 import static java.util.Locale.ENGLISH;
 
 import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -13,8 +14,6 @@ import java.util.concurrent.ExecutionException;
 
 import javax.security.auth.Subject;
 
-import org.argeo.api.acr.spi.ProvidedContent;
-import org.argeo.api.acr.spi.ProvidedRepository;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsContext;
 import org.argeo.api.cms.CmsDeployment;
@@ -23,6 +22,7 @@ import org.argeo.api.cms.CmsSession;
 import org.argeo.api.cms.CmsSessionId;
 import org.argeo.api.cms.CmsState;
 import org.argeo.api.uuid.UuidFactory;
+import org.argeo.cms.CmsDeployProperty;
 import org.argeo.cms.LocaleUtils;
 import org.argeo.cms.internal.auth.CmsSessionImpl;
 import org.ietf.jgss.GSSCredential;
@@ -56,10 +56,14 @@ public class CmsContextImpl implements CmsContext {
 //     }
 
        public void start() {
-               Object defaultLocaleValue = KernelUtils.getFrameworkProp(CmsConstants.I18N_DEFAULT_LOCALE);
-               defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
-                               : new Locale(ENGLISH.getLanguage());
-               locales = LocaleUtils.asLocaleList(KernelUtils.getFrameworkProp(CmsConstants.I18N_LOCALES));
+               List<String> codes = CmsStateImpl.getDeployProperties(cmsState, CmsDeployProperty.LOCALE);
+               locales = getLocaleList(codes);
+               if (locales.size() == 0)
+                       throw new IllegalStateException("At least one locale must be set");
+               defaultLocale = locales.get(0);
+//             Object defaultLocaleValue = KernelUtils.getFrameworkProp(CmsConstants.I18N_DEFAULT_LOCALE);
+//             defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
+//                             : new Locale(ENGLISH.getLanguage());
                // node repository
 //             new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
 //                     @Override
@@ -145,6 +149,29 @@ public class CmsContextImpl implements CmsContext {
                throw new UnsupportedOperationException();
        }
 
+       /** Returns null if argument is null. */
+       private static List<Locale> getLocaleList(List<String> codes) {
+               if (codes == null)
+                       return null;
+               ArrayList<Locale> availableLocales = new ArrayList<Locale>();
+               for (String code : codes) {
+                       if (code == null)
+                               continue;
+                       // variant not supported
+                       int indexUnd = code.indexOf("_");
+                       Locale locale;
+                       if (indexUnd > 0) {
+                               String language = code.substring(0, indexUnd);
+                               String country = code.substring(indexUnd + 1);
+                               locale = new Locale(language, country);
+                       } else {
+                               locale = new Locale(code);
+                       }
+                       availableLocales.add(locale);
+               }
+               return availableLocales;
+       }
+
        public void setCmsDeployment(CmsDeployment cmsDeployment) {
                this.cmsDeployment = cmsDeployment;
        }
index d01bc8554c68ea38af30a14913d97af7f5525bc9..2353250c5bf88284aab165b54109122e79c03770 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.cms.internal.runtime;
 import org.argeo.api.cms.CmsDeployment;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsState;
+import org.argeo.cms.CmsDeployProperty;
 import org.osgi.service.http.HttpService;
 
 /** Implementation of a CMS deployment. */
@@ -64,8 +65,8 @@ public class CmsDeploymentImpl implements CmsDeployment {
 
        public void setCmsState(CmsState cmsState) {
                this.cmsState = cmsState;
-               String httpPort = this.cmsState.getDeployProperty("org.osgi.service.http.port");
-               String httpsPort = this.cmsState.getDeployProperty("org.osgi.service.http.port.secure");
+               String httpPort = this.cmsState.getDeployProperty(CmsDeployProperty.HTTP_PORT.getProperty());
+               String httpsPort = this.cmsState.getDeployProperty(CmsDeployProperty.HTTPS_PORT.getProperty());
                httpExpected = httpPort != null || httpsPort != null;
        }
 
index b3ef895f145c3f0190176eb173ca1cc465c4a8fd..7928857562e5a54ebc6c1388216afb82ca457ec3 100644 (file)
@@ -1,23 +1,36 @@
 package org.argeo.cms.internal.runtime;
 
+import java.io.File;
+import java.io.FileFilter;
 import java.io.IOException;
-import java.io.InputStream;
+import java.io.Reader;
 import java.net.InetAddress;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.TreeMap;
+import java.security.KeyStore;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.StringJoiner;
 import java.util.UUID;
 
 import javax.security.auth.login.Configuration;
 
+import org.apache.commons.io.FileUtils;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsState;
 import org.argeo.api.uuid.UuidFactory;
+import org.argeo.cms.CmsDeployProperty;
 import org.argeo.cms.auth.ident.IdentClient;
-import org.argeo.util.directory.ldap.LdifParser;
 
 /**
  * Implementation of a {@link CmsState}, initialising the required services.
@@ -34,6 +47,16 @@ public class CmsStateImpl implements CmsState {
 
        private UuidFactory uuidFactory;
 
+       private final Map<CmsDeployProperty, String> deployPropertyDefaults;
+
+       public CmsStateImpl() {
+               Map<CmsDeployProperty, String> deployPropertyDefaults = new HashMap<>();
+               deployPropertyDefaults.put(CmsDeployProperty.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
+               deployPropertyDefaults.put(CmsDeployProperty.NODE_INIT, "../../init");
+               deployPropertyDefaults.put(CmsDeployProperty.LOCALE, Locale.getDefault().toString());
+               this.deployPropertyDefaults = Collections.unmodifiableMap(deployPropertyDefaults);
+       }
+
        public void start() {
 //             Runtime.getRuntime().addShutdownHook(new CmsShutdown());
 
@@ -55,11 +78,27 @@ public class CmsStateImpl implements CmsState {
                        }
 
                        availableSince = System.currentTimeMillis();
-                       if (log.isDebugEnabled())
+                       if (log.isDebugEnabled()) {
                                // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? "
                                // (clean state) " : " "));
-                               log.debug("## CMS starting... (" + uuid + ")");
-
+                               StringJoiner sb = new StringJoiner("\n");
+                               CmsDeployProperty[] deployProperties = CmsDeployProperty.values();
+                               Arrays.sort(deployProperties, (o1, o2) -> o1.name().compareTo(o2.name()));
+                               for (CmsDeployProperty deployProperty : deployProperties) {
+                                       List<String> values = getDeployProperties(deployProperty);
+                                       for (int i = 0; i < values.size(); i++) {
+                                               String value = values.get(i);
+                                               if (value != null) {
+                                                       boolean isDefault = deployPropertyDefaults.containsKey(deployProperty)
+                                                                       && value.equals(deployPropertyDefaults.get(deployProperty));
+                                                       String line = deployProperty.getProperty() + (i == 0 ? "" : "." + i) + "=" + value
+                                                                       + (isDefault ? " (default)" : "");
+                                                       sb.add(line);
+                                               }
+                                       }
+                               }
+                               log.debug("## CMS starting... (" + uuid + ")\n" + sb + "\n");
+                       }
 
 //             initI18n();
 //             initServices();
@@ -73,7 +112,7 @@ public class CmsStateImpl implements CmsState {
        }
 
        private void initSecurity() {
-               if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
+               if (getDeployProperty(CmsDeployProperty.JAVA_LOGIN_CONFIG) == null) {
                        String jaasConfig = KernelConstants.JAAS_CONFIG;
                        URL url = getClass().getResource(jaasConfig);
                        // System.setProperty(KernelConstants.JAAS_CONFIG_PROP,
@@ -82,6 +121,50 @@ public class CmsStateImpl implements CmsState {
                }
                // explicitly load JAAS configuration
                Configuration.getConfiguration();
+
+               boolean initSsl = getDeployProperty(CmsDeployProperty.HTTPS_PORT) != null;
+               if (initSsl) {
+                       initCertificates();
+               }
+       }
+
+       private void initCertificates() {
+               // server certificate
+               Path keyStorePath = getDataPath(PkiUtils.DEFAULT_KEYSTORE_PATH);
+               Path pemKeyPath = getDataPath(PkiUtils.DEFAULT_PEM_KEY_PATH);
+               Path pemCertPath = getDataPath(PkiUtils.DEFAULT_PEM_CERT_PATH);
+               String keyStorePasswordStr = doGetDeployProperty(CmsDeployProperty.SSL_PASSWORD.getProperty());
+               char[] keyStorePassword;
+               if (keyStorePasswordStr == null)
+                       keyStorePassword = "changeit".toCharArray();
+               else
+                       keyStorePassword = keyStorePasswordStr.toCharArray();
+
+               // if PEM files both exists, update the PKCS12 file
+               if (Files.exists(pemCertPath) && Files.exists(pemKeyPath)) {
+                       // TODO check certificate update time? monitor changes?
+                       KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
+                       try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
+                                       Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
+                               PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
+                               PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
+                               if (log.isDebugEnabled())
+                                       log.debug("PEM certificate stored in " + keyStorePath);
+                       } catch (IOException e) {
+                               log.error("Cannot read PEM files " + pemKeyPath + " and " + pemCertPath, e);
+                       }
+               }
+
+               if (!Files.exists(keyStorePath))
+                       PkiUtils.createSelfSignedKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
+//             props.put(JettyHttpConstants.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
+//             props.put(JettyHttpConstants.SSL_KEYSTORE, keyStorePath.toString());
+//             props.put(JettyHttpConstants.SSL_PASSWORD, new String(keyStorePassword));
+
+//             props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
+//             props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
+//             props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
+
        }
 
        public void stop() {
@@ -94,13 +177,116 @@ public class CmsStateImpl implements CmsState {
 
        private void firstInit() throws IOException {
                log.info("## FIRST INIT ##");
-               // FirstInit firstInit = new FirstInit();
-               InitUtils.prepareFirstInitInstanceArea();
+               List<String> nodeInits = getDeployProperties(CmsDeployProperty.NODE_INIT);
+//             if (nodeInits == null)
+//                     nodeInits = "../../init";
+               CmsStateImpl.prepareFirstInitInstanceArea(nodeInits);
        }
 
        @Override
-       public String getDeployProperty(String key) {
-               return KernelUtils.getFrameworkProp(key);
+       public String getDeployProperty(String property) {
+               CmsDeployProperty deployProperty = CmsDeployProperty.find(property);
+               if (deployProperty == null) {
+                       // legacy
+                       if (property.startsWith("argeo.node.")) {
+                               return doGetDeployProperty(property);
+                       }
+                       if (property.equals("argeo.i18n.locales")) {
+                               String value = doGetDeployProperty(property);
+                               if (value != null) {
+                                       log.warn("Property " + property + " was ignored (value=" + value + ")");
+
+                               }
+                               return null;
+                       }
+                       throw new IllegalArgumentException("Unsupported deploy property " + property);
+               }
+               int index = CmsDeployProperty.getPropertyIndex(property);
+               return getDeployProperty(deployProperty, index);
+       }
+
+       @Override
+       public List<String> getDeployProperties(String property) {
+               CmsDeployProperty deployProperty = CmsDeployProperty.find(property);
+               if (deployProperty == null)
+                       return new ArrayList<>();
+               return getDeployProperties(deployProperty);
+       }
+
+       public static List<String> getDeployProperties(CmsState cmsState, CmsDeployProperty deployProperty) {
+               return ((CmsStateImpl) cmsState).getDeployProperties(deployProperty);
+       }
+
+       public List<String> getDeployProperties(CmsDeployProperty deployProperty) {
+               List<String> res = new ArrayList<>(deployProperty.getMaxCount());
+               for (int i = 0; i < deployProperty.getMaxCount(); i++) {
+                       // String propertyName = i == 0 ? deployProperty.getProperty() :
+                       // deployProperty.getProperty() + "." + i;
+                       String value = getDeployProperty(deployProperty, i);
+                       res.add(i, value);
+               }
+               return res;
+       }
+
+       public static String getDeployProperty(CmsState cmsState, CmsDeployProperty deployProperty) {
+               return ((CmsStateImpl) cmsState).getDeployProperty(deployProperty);
+       }
+
+       public String getDeployProperty(CmsDeployProperty deployProperty) {
+               String value = getDeployProperty(deployProperty, 0);
+               return value;
+       }
+
+       public String getDeployProperty(CmsDeployProperty deployProperty, int index) {
+               String propertyName = deployProperty.getProperty() + (index == 0 ? "" : "." + index);
+               String value = doGetDeployProperty(propertyName);
+               if (value == null && index == 0) {
+                       // try defaults
+                       if (deployPropertyDefaults.containsKey(deployProperty)) {
+                               value = deployPropertyDefaults.get(deployProperty);
+                       }
+                       // try legacy properties
+                       String legacyProperty = switch (deployProperty) {
+                       case DIRECTORY -> "argeo.node.useradmin.uris";
+                       case DB_URL -> "argeo.node.dburl";
+                       case DB_USER -> "argeo.node.dbuser";
+                       case DB_PASSWORD -> "argeo.node.dbpassword";
+                       case HTTP_PORT -> "org.osgi.service.http.port";
+                       case HTTPS_PORT -> "org.osgi.service.http.port.secure";
+                       case HOST -> "org.eclipse.equinox.http.jetty.http.host";
+                       case LOCALE -> "argeo.i18n.defaultLocale";
+
+                       default -> null;
+                       };
+                       if (legacyProperty != null) {
+                               value = doGetDeployProperty(legacyProperty);
+                               if (value != null) {
+                                       log.warn("Retrieved deploy property " + deployProperty.getProperty()
+                                                       + " through deprecated property " + legacyProperty);
+                               }
+                       }
+               }
+               if (index == 0 && deployProperty.isSystemPropertyOnly()) {
+                       String systemPropertyValue = System.getProperty(deployProperty.getProperty());
+                       if (!Objects.equals(value, systemPropertyValue))
+                               throw new IllegalStateException(
+                                               "Property " + deployProperty + " must be a ssystem property, but its value is " + value
+                                                               + ", while the system property value is " + systemPropertyValue);
+               }
+               return value != null ? value.toString() : null;
+       }
+
+       protected String getLegacyProperty(String legacyProperty, CmsDeployProperty deployProperty) {
+               String value = doGetDeployProperty(legacyProperty);
+               if (value != null) {
+                       log.warn("Retrieved deploy property " + deployProperty.getProperty() + " through deprecated property "
+                                       + legacyProperty + ".");
+               }
+               return value;
+       }
+
+       protected String doGetDeployProperty(String property) {
+               return KernelUtils.getFrameworkProp(property);
        }
 
        @Override
@@ -129,6 +315,47 @@ public class CmsStateImpl implements CmsState {
                this.uuidFactory = uuidFactory;
        }
 
+       /**
+        * Called before node initialisation, in order populate OSGi instance are with
+        * some files (typically LDIF, etc).
+        */
+       public static void prepareFirstInitInstanceArea(List<String> nodeInits) {
+
+               for (String nodeInit : nodeInits) {
+
+                       if (nodeInit.startsWith("http")) {
+                               // TODO reconnect it
+                               // registerRemoteInit(nodeInit);
+                       } else {
+
+                               // TODO use java.nio.file
+                               File initDir;
+                               if (nodeInit.startsWith("."))
+                                       initDir = KernelUtils.getExecutionDir(nodeInit);
+                               else
+                                       initDir = new File(nodeInit);
+                               // TODO also uncompress archives
+                               if (initDir.exists())
+                                       try {
+                                               // TODO use NIO utilities
+                                               FileUtils.copyDirectory(initDir, KernelUtils.getOsgiInstancePath("").toFile(),
+                                                               new FileFilter() {
+
+                                                                       @Override
+                                                                       public boolean accept(File pathname) {
+                                                                               if (pathname.getName().equals(".svn") || pathname.getName().equals(".git"))
+                                                                                       return false;
+                                                                               return true;
+                                                                       }
+                                                               });
+                                               log.info("CMS initialized from " + initDir.getCanonicalPath());
+                                       } catch (IOException e) {
+                                               throw new RuntimeException("Cannot initialize from " + initDir, e);
+                                       }
+                       }
+               }
+       }
+
        /*
         * STATIC
         */
index e73d96f65ec7ab80c5abe7f14d13faa05c8028d5..9ebc429178ce0276f7a83ae37eba2ebb083c96cf 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.cms.internal.runtime;
 
+import java.io.File;
 import java.io.IOException;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -30,10 +31,12 @@ import org.apache.commons.httpclient.auth.CredentialsProvider;
 import org.apache.commons.httpclient.params.DefaultHttpParams;
 import org.apache.commons.httpclient.params.HttpMethodParams;
 import org.apache.commons.httpclient.params.HttpParams;
+import org.apache.commons.io.FileUtils;
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsState;
+import org.argeo.cms.CmsDeployProperty;
 import org.argeo.cms.internal.http.client.HttpCredentialProvider;
 import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
 import org.argeo.osgi.useradmin.AggregatingUserAdmin;
@@ -76,7 +79,7 @@ public class CmsUserAdmin extends AggregatingUserAdmin {
 
        public void start() {
                super.start();
-               List<Dictionary<String, Object>> configs = InitUtils.getUserDirectoryConfigs();
+               List<Dictionary<String, Object>> configs = getUserDirectoryConfigs();
                for (Dictionary<String, Object> config : configs) {
                        UserDirectory userDirectory = enableUserDirectory(config);
                        if (userDirectory.getRealm().isPresent())
@@ -92,6 +95,106 @@ public class CmsUserAdmin extends AggregatingUserAdmin {
                super.stop();
        }
 
+       protected List<Dictionary<String, Object>> getUserDirectoryConfigs() {
+               List<Dictionary<String, Object>> res = new ArrayList<>();
+               File nodeBaseDir = cmsState.getDataPath(KernelConstants.DIR_NODE).toFile();
+               List<String> uris = new ArrayList<>();
+
+               // node roles
+               String nodeRolesUri = null;// getFrameworkProp(CmsConstants.ROLES_URI);
+               String baseNodeRoleDn = CmsConstants.ROLES_BASEDN;
+               if (nodeRolesUri == null) {
+                       nodeRolesUri = baseNodeRoleDn + ".ldif";
+                       File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri);
+                       if (!nodeRolesFile.exists())
+                               try {
+                                       FileUtils.copyInputStreamToFile(CmsUserAdmin.class.getResourceAsStream(baseNodeRoleDn + ".ldif"),
+                                                       nodeRolesFile);
+                               } catch (IOException e) {
+                                       throw new RuntimeException("Cannot copy demo resource", e);
+                               }
+                       // nodeRolesUri = nodeRolesFile.toURI().toString();
+               }
+               uris.add(nodeRolesUri);
+
+               // node tokens
+               String nodeTokensUri = null;// getFrameworkProp(CmsConstants.TOKENS_URI);
+               String baseNodeTokensDn = CmsConstants.TOKENS_BASEDN;
+               if (nodeTokensUri == null) {
+                       nodeTokensUri = baseNodeTokensDn + ".ldif";
+                       File nodeTokensFile = new File(nodeBaseDir, nodeTokensUri);
+                       if (!nodeTokensFile.exists())
+                               try {
+                                       FileUtils.copyInputStreamToFile(CmsUserAdmin.class.getResourceAsStream(baseNodeTokensDn + ".ldif"),
+                                                       nodeTokensFile);
+                               } catch (IOException e) {
+                                       throw new RuntimeException("Cannot copy demo resource", e);
+                               }
+                       // nodeRolesUri = nodeRolesFile.toURI().toString();
+               }
+               uris.add(nodeTokensUri);
+
+               // Business roles
+//             String userAdminUris = getFrameworkProp(CmsConstants.USERADMIN_URIS);
+               List<String> userAdminUris = CmsStateImpl.getDeployProperties(cmsState, CmsDeployProperty.DIRECTORY);// getFrameworkProp(CmsConstants.USERADMIN_URIS);
+               for (String userAdminUri : userAdminUris) {
+                       if (userAdminUri == null)
+                               continue;
+//                     if (!userAdminUri.trim().equals(""))
+                       uris.add(userAdminUri);
+               }
+
+               if (uris.size() == 0) {
+                       // TODO put this somewhere else
+                       String demoBaseDn = "dc=example,dc=com";
+                       String userAdminUri = demoBaseDn + ".ldif";
+                       File businessRolesFile = new File(nodeBaseDir, userAdminUri);
+                       File systemRolesFile = new File(nodeBaseDir, "ou=roles,ou=node.ldif");
+                       if (!businessRolesFile.exists())
+                               try {
+                                       FileUtils.copyInputStreamToFile(CmsUserAdmin.class.getResourceAsStream(demoBaseDn + ".ldif"),
+                                                       businessRolesFile);
+                                       if (!systemRolesFile.exists())
+                                               FileUtils.copyInputStreamToFile(
+                                                               CmsUserAdmin.class.getResourceAsStream("example-ou=roles,ou=node.ldif"),
+                                                               systemRolesFile);
+                               } catch (IOException e) {
+                                       throw new RuntimeException("Cannot copy demo resources", e);
+                               }
+                       // userAdminUris = businessRolesFile.toURI().toString();
+                       log.warn("## DEV Using dummy base DN " + demoBaseDn);
+                       // TODO downgrade security level
+               }
+
+               // Interprets URIs
+               for (String uri : uris) {
+                       URI u;
+                       try {
+                               u = new URI(uri);
+                               if (u.getPath() == null)
+                                       throw new IllegalArgumentException(
+                                                       "URI " + uri + " must have a path in order to determine base DN");
+                               if (u.getScheme() == null) {
+                                       if (uri.startsWith("/") || uri.startsWith("./") || uri.startsWith("../"))
+                                               u = new File(uri).getCanonicalFile().toURI();
+                                       else if (!uri.contains("/")) {
+                                               // u = KernelUtils.getOsgiInstanceUri(KernelConstants.DIR_NODE + '/' + uri);
+                                               u = new URI(uri);
+                                       } else
+                                               throw new IllegalArgumentException("Cannot interpret " + uri + " as an uri");
+                               } else if (u.getScheme().equals(DirectoryConf.SCHEME_FILE)) {
+                                       u = new File(u).getCanonicalFile().toURI();
+                               }
+                       } catch (Exception e) {
+                               throw new RuntimeException("Cannot interpret " + uri + " as an uri", e);
+                       }
+                       Dictionary<String, Object> properties = DirectoryConf.uriAsProperties(u.toString());
+                       res.add(properties);
+               }
+
+               return res;
+       }
+
        public UserDirectory enableUserDirectory(Dictionary<String, ?> properties) {
                String uri = (String) properties.get(DirectoryConf.uri.name());
                Object realm = properties.get(DirectoryConf.realm.name());
@@ -224,7 +327,7 @@ public class CmsUserAdmin extends AggregatingUserAdmin {
        }
 
        private void loadIpaJaasConfiguration() {
-               if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
+               if (CmsStateImpl.getDeployProperty(cmsState, CmsDeployProperty.JAVA_LOGIN_CONFIG) == null) {
                        String jaasConfig = KernelConstants.JAAS_CONFIG_IPA;
                        URL url = getClass().getClassLoader().getResource(jaasConfig);
                        KernelUtils.setJaasConfiguration(url);
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/InitUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/InitUtils.java
deleted file mode 100644 (file)
index f634e43..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-package org.argeo.cms.internal.runtime;
-
-import static org.argeo.cms.internal.runtime.KernelUtils.getFrameworkProp;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.commons.io.FileUtils;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.util.directory.DirectoryConf;
-
-/**
- * Interprets framework properties in order to generate the initial deploy
- * configuration.
- */
-public class InitUtils {
-       private final static CmsLog log = CmsLog.getLog(InitUtils.class);
-
-       /** Override the provided config with the framework properties */
-//     public static Dictionary<String, Object> getHttpServerConfig(Dictionary<String, Object> provided) {
-//             String httpPort = getFrameworkProp("org.osgi.service.http.port");
-//             String httpsPort = getFrameworkProp("org.osgi.service.http.port.secure");
-//             /// TODO make it more generic
-//             String httpHost = getFrameworkProp(
-//                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTP_HOST);
-//             String httpsHost = getFrameworkProp(
-//                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.HTTPS_HOST);
-//             String webSocketEnabled = getFrameworkProp(
-//                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.WEBSOCKET_ENABLED);
-//
-//             final Hashtable<String, Object> props = new Hashtable<String, Object>();
-//             // try {
-//             if (httpPort != null || httpsPort != null) {
-//                     boolean httpEnabled = httpPort != null;
-//                     props.put(InternalHttpConstants.HTTP_ENABLED, httpEnabled);
-//                     boolean httpsEnabled = httpsPort != null;
-//                     props.put(InternalHttpConstants.HTTPS_ENABLED, httpsEnabled);
-//
-//                     if (httpEnabled) {
-//                             props.put(InternalHttpConstants.HTTP_PORT, httpPort);
-//                             if (httpHost != null)
-//                                     props.put(InternalHttpConstants.HTTP_HOST, httpHost);
-//                     }
-//
-//                     if (httpsEnabled) {
-//                             props.put(InternalHttpConstants.HTTPS_PORT, httpsPort);
-//                             if (httpsHost != null)
-//                                     props.put(InternalHttpConstants.HTTPS_HOST, httpsHost);
-//
-//                             // server certificate
-//                             Path keyStorePath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_KEYSTORE_PATH);
-//                             Path pemKeyPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_PEM_KEY_PATH);
-//                             Path pemCertPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_PEM_CERT_PATH);
-//                             String keyStorePasswordStr = getFrameworkProp(
-//                                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_PASSWORD);
-//                             char[] keyStorePassword;
-//                             if (keyStorePasswordStr == null)
-//                                     keyStorePassword = "changeit".toCharArray();
-//                             else
-//                                     keyStorePassword = keyStorePasswordStr.toCharArray();
-//
-//                             // if PEM files both exists, update the PKCS12 file
-//                             if (Files.exists(pemCertPath) && Files.exists(pemKeyPath)) {
-//                                     // TODO check certificate update time? monitor changes?
-//                                     KeyStore keyStore = PkiUtils.getKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
-//                                     try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
-//                                                     Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
-//                                             PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
-//                                             PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
-//                                             if (log.isDebugEnabled())
-//                                                     log.debug("PEM certificate stored in " + keyStorePath);
-//                                     } catch (IOException e) {
-//                                             log.error("Cannot read PEM files " + pemKeyPath + " and " + pemCertPath, e);
-//                                     }
-//                             }
-//
-//                             if (!Files.exists(keyStorePath))
-//                                     createSelfSignedKeyStore(keyStorePath, keyStorePassword, PkiUtils.PKCS12);
-//                             props.put(InternalHttpConstants.SSL_KEYSTORETYPE, PkiUtils.PKCS12);
-//                             props.put(InternalHttpConstants.SSL_KEYSTORE, keyStorePath.toString());
-//                             props.put(InternalHttpConstants.SSL_PASSWORD, new String(keyStorePassword));
-//
-////                           props.put(InternalHttpConstants.SSL_KEYSTORETYPE, "PKCS11");
-////                           props.put(InternalHttpConstants.SSL_KEYSTORE, "../../nssdb");
-////                           props.put(InternalHttpConstants.SSL_PASSWORD, keyStorePassword);
-//
-//                             // client certificate authentication
-//                             String wantClientAuth = getFrameworkProp(
-//                                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_WANTCLIENTAUTH);
-//                             if (wantClientAuth != null)
-//                                     props.put(InternalHttpConstants.SSL_WANTCLIENTAUTH, Boolean.parseBoolean(wantClientAuth));
-//                             String needClientAuth = getFrameworkProp(
-//                                             InternalHttpConstants.JETTY_PROPERTY_PREFIX + InternalHttpConstants.SSL_NEEDCLIENTAUTH);
-//                             if (needClientAuth != null)
-//                                     props.put(InternalHttpConstants.SSL_NEEDCLIENTAUTH, Boolean.parseBoolean(needClientAuth));
-//                     }
-//
-//                     // web socket
-//                     if (webSocketEnabled != null && webSocketEnabled.equals("true"))
-//                             props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true);
-//
-//                     props.put(CmsConstants.CN, CmsConstants.DEFAULT);
-//             }
-//             return props;
-//     }
-
-       public static List<Dictionary<String, Object>> getUserDirectoryConfigs() {
-               List<Dictionary<String, Object>> res = new ArrayList<>();
-               File nodeBaseDir = KernelUtils.getOsgiInstancePath(KernelConstants.DIR_NODE).toFile();
-               List<String> uris = new ArrayList<>();
-
-               // node roles
-               String nodeRolesUri = getFrameworkProp(CmsConstants.ROLES_URI);
-               String baseNodeRoleDn = CmsConstants.ROLES_BASEDN;
-               if (nodeRolesUri == null) {
-                       nodeRolesUri = baseNodeRoleDn + ".ldif";
-                       File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri);
-                       if (!nodeRolesFile.exists())
-                               try {
-                                       FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(baseNodeRoleDn + ".ldif"),
-                                                       nodeRolesFile);
-                               } catch (IOException e) {
-                                       throw new RuntimeException("Cannot copy demo resource", e);
-                               }
-                       // nodeRolesUri = nodeRolesFile.toURI().toString();
-               }
-               uris.add(nodeRolesUri);
-
-               // node tokens
-               String nodeTokensUri = getFrameworkProp(CmsConstants.TOKENS_URI);
-               String baseNodeTokensDn = CmsConstants.TOKENS_BASEDN;
-               if (nodeTokensUri == null) {
-                       nodeTokensUri = baseNodeTokensDn + ".ldif";
-                       File nodeTokensFile = new File(nodeBaseDir, nodeTokensUri);
-                       if (!nodeTokensFile.exists())
-                               try {
-                                       FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(baseNodeTokensDn + ".ldif"),
-                                                       nodeTokensFile);
-                               } catch (IOException e) {
-                                       throw new RuntimeException("Cannot copy demo resource", e);
-                               }
-                       // nodeRolesUri = nodeRolesFile.toURI().toString();
-               }
-               uris.add(nodeTokensUri);
-
-               // Business roles
-               String userAdminUris = getFrameworkProp(CmsConstants.USERADMIN_URIS);
-               if (userAdminUris == null) {
-                       String demoBaseDn = "dc=example,dc=com";
-                       userAdminUris = demoBaseDn + ".ldif";
-                       File businessRolesFile = new File(nodeBaseDir, userAdminUris);
-                       File systemRolesFile = new File(nodeBaseDir, "ou=roles,ou=node.ldif");
-                       if (!businessRolesFile.exists())
-                               try {
-                                       FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(demoBaseDn + ".ldif"),
-                                                       businessRolesFile);
-                                       if (!systemRolesFile.exists())
-                                               FileUtils.copyInputStreamToFile(
-                                                               InitUtils.class.getResourceAsStream("example-ou=roles,ou=node.ldif"), systemRolesFile);
-                               } catch (IOException e) {
-                                       throw new RuntimeException("Cannot copy demo resources", e);
-                               }
-                       // userAdminUris = businessRolesFile.toURI().toString();
-                       log.warn("## DEV Using dummy base DN " + demoBaseDn);
-                       // TODO downgrade security level
-               }
-               for (String userAdminUri : userAdminUris.split(" "))
-                       if (!userAdminUri.trim().equals(""))
-                               uris.add(userAdminUri);
-
-               // Interprets URIs
-               for (String uri : uris) {
-                       URI u;
-                       try {
-                               u = new URI(uri);
-                               if (u.getPath() == null)
-                                       throw new IllegalArgumentException(
-                                                       "URI " + uri + " must have a path in order to determine base DN");
-                               if (u.getScheme() == null) {
-                                       if (uri.startsWith("/") || uri.startsWith("./") || uri.startsWith("../"))
-                                               u = new File(uri).getCanonicalFile().toURI();
-                                       else if (!uri.contains("/")) {
-                                               // u = KernelUtils.getOsgiInstanceUri(KernelConstants.DIR_NODE + '/' + uri);
-                                               u = new URI(uri);
-                                       } else
-                                               throw new IllegalArgumentException("Cannot interpret " + uri + " as an uri");
-                               } else if (u.getScheme().equals(DirectoryConf.SCHEME_FILE)) {
-                                       u = new File(u).getCanonicalFile().toURI();
-                               }
-                       } catch (Exception e) {
-                               throw new RuntimeException("Cannot interpret " + uri + " as an uri", e);
-                       }
-                       Dictionary<String, Object> properties = DirectoryConf.uriAsProperties(u.toString());
-                       res.add(properties);
-               }
-
-               return res;
-       }
-
-       /**
-        * Called before node initialisation, in order populate OSGi instance are with
-        * some files (typically LDIF, etc).
-        */
-       public static void prepareFirstInitInstanceArea() {
-               String nodeInits = getFrameworkProp(CmsConstants.NODE_INIT);
-               if (nodeInits == null)
-                       nodeInits = "../../init";
-
-               for (String nodeInit : nodeInits.split(",")) {
-
-                       if (nodeInit.startsWith("http")) {
-                               // TODO reconnect it
-                               // registerRemoteInit(nodeInit);
-                       } else {
-
-                               // TODO use java.nio.file
-                               File initDir;
-                               if (nodeInit.startsWith("."))
-                                       initDir = KernelUtils.getExecutionDir(nodeInit);
-                               else
-                                       initDir = new File(nodeInit);
-                               // TODO also uncompress archives
-                               if (initDir.exists())
-                                       try {
-                                               // TODO use NIO utilities
-                                               FileUtils.copyDirectory(initDir, KernelUtils.getOsgiInstancePath("").toFile(),
-                                                               new FileFilter() {
-
-                                                                       @Override
-                                                                       public boolean accept(File pathname) {
-                                                                               if (pathname.getName().equals(".svn") || pathname.getName().equals(".git"))
-                                                                                       return false;
-                                                                               return true;
-                                                                       }
-                                                               });
-                                               log.info("CMS initialized from " + initDir.getCanonicalPath());
-                                       } catch (IOException e) {
-                                               throw new RuntimeException("Cannot initialize from " + initDir, e);
-                                       }
-                       }
-               }
-       }
-
-}
index a02c557f2a79b8b51e021b1e38efc34c35b81d2e..1a1c076c23e4656bcd7fd4025d0c1d2fc46ad698 100644 (file)
@@ -1,17 +1,15 @@
 package org.argeo.cms.internal.runtime;
 
-import org.argeo.api.cms.CmsConstants;
-
 /** Internal CMS constants. */
-public interface KernelConstants {
+interface KernelConstants {
        // Directories
        String DIR_NODE = "node";
-       String DIR_REPOS = "repos";
-       String DIR_INDEXES = "indexes";
-       String DIR_TRANSACTIONS = "transactions";
+//     String DIR_REPOS = "repos";
+//     String DIR_INDEXES = "indexes";
+//     String DIR_TRANSACTIONS = "transactions";
 
        // Files
-       String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif";
+//     String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif";
        String NODE_KEY_TAB_PATH = DIR_NODE + "/krb5.keytab";
 
        // Security
@@ -19,12 +17,12 @@ public interface KernelConstants {
        String JAAS_CONFIG_IPA = "/org/argeo/cms/internal/runtime/jaas-ipa.cfg";
 
        // Java
-       String JAAS_CONFIG_PROP = "java.security.auth.login.config";
+//     String JAAS_CONFIG_PROP = "java.security.auth.login.config";
 
        // DEFAULTS JCR PATH
-       String DEFAULT_HOME_BASE_PATH = "/home";
-       String DEFAULT_USERS_BASE_PATH = "/users";
-       String DEFAULT_GROUPS_BASE_PATH = "/groups";
+//     String DEFAULT_HOME_BASE_PATH = "/home";
+//     String DEFAULT_USERS_BASE_PATH = "/users";
+//     String DEFAULT_GROUPS_BASE_PATH = "/groups";
        
        // KERBEROS
        String DEFAULT_KERBEROS_SERVICE = "HTTP";
@@ -37,14 +35,12 @@ public interface KernelConstants {
        // String PATH_WORKBENCH_PUBLIC = PATH_WORKBENCH + "/public";
 
 //     String JETTY_FACTORY_PID = "org.eclipse.equinox.http.jetty.config";
-       String JETTY_FACTORY_PID = "org.argeo.equinox.jetty.config";
-       String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern";
+//     String JETTY_FACTORY_PID = "org.argeo.equinox.jetty.config";
        // default Jetty server configured via JettyConfigurator
-       String DEFAULT_JETTY_SERVER = "default";
-       String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
+//     String DEFAULT_JETTY_SERVER = "default";
+//     String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
 
        // avoid dependencies
-       String CONTEXT_NAME_PROP = "contextName";
-       String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
-       String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
+//     String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
+//     String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
 }
index 5635bccfed34a9e5dff34999b84430ce267c6b7d..2ada3c7269e2625e25bd78e6f28507c1889c11d5 100644 (file)
@@ -19,7 +19,7 @@ import org.argeo.api.cms.CmsLog;
 import org.argeo.cms.internal.osgi.CmsActivator;
 
 /** Package utilities */
-public class KernelUtils implements KernelConstants {
+class KernelUtils implements KernelConstants {
        final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
        final static String OSGI_CONFIGURATION_AREA = "osgi.configuration.area";
 
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/PkiUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/PkiUtils.java
new file mode 100644 (file)
index 0000000..a90d598
--- /dev/null
@@ -0,0 +1,299 @@
+package org.argeo.cms.internal.runtime;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.InputDecryptorProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
+import org.bouncycastle.pkcs.PKCSException;
+
+/**
+ * Utilities around private keys and certificate, mostly wrapping BouncyCastle
+ * implementations.
+ */
+class PkiUtils {
+       private final static CmsLog log = CmsLog.getLog(PkiUtils.class);
+
+       public final static String PKCS12 = "PKCS12";
+       public static final String DEFAULT_KEYSTORE_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".p12";
+
+       public static final String DEFAULT_PEM_KEY_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".key";
+
+       public static final String DEFAULT_PEM_CERT_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".crt";
+
+       private final static String SECURITY_PROVIDER;
+       static {
+               Security.addProvider(new BouncyCastleProvider());
+               SECURITY_PROVIDER = "BC";
+       }
+
+       public static X509Certificate generateSelfSignedCertificate(KeyStore keyStore, X500Principal x500Principal,
+                       int keySize, char[] keyPassword) {
+               try {
+                       KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", SECURITY_PROVIDER);
+                       kpGen.initialize(keySize, new SecureRandom());
+                       KeyPair pair = kpGen.generateKeyPair();
+                       Date notBefore = new Date(System.currentTimeMillis() - 10000);
+                       Date notAfter = new Date(System.currentTimeMillis() + 365 * 24L * 3600 * 1000);
+                       BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());
+                       X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(x500Principal, serial, notBefore,
+                                       notAfter, x500Principal, pair.getPublic());
+                       ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(SECURITY_PROVIDER)
+                                       .build(pair.getPrivate());
+                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
+                                       .getCertificate(certGen.build(sigGen));
+                       cert.checkValidity(new Date());
+                       cert.verify(cert.getPublicKey());
+
+                       keyStore.setKeyEntry(x500Principal.getName(), pair.getPrivate(), keyPassword, new Certificate[] { cert });
+                       return cert;
+               } catch (GeneralSecurityException | OperatorCreationException e) {
+                       throw new RuntimeException("Cannot generate self-signed certificate", e);
+               }
+       }
+
+       public static KeyStore getKeyStore(Path keyStoreFile, char[] keyStorePassword, String keyStoreType) {
+               try {
+                       KeyStore store = KeyStore.getInstance(keyStoreType, SECURITY_PROVIDER);
+                       if (Files.exists(keyStoreFile)) {
+                               try (InputStream fis = Files.newInputStream(keyStoreFile)) {
+                                       store.load(fis, keyStorePassword);
+                               }
+                       } else {
+                               store.load(null);
+                       }
+                       return store;
+               } catch (GeneralSecurityException | IOException e) {
+                       throw new RuntimeException("Cannot load keystore " + keyStoreFile, e);
+               }
+       }
+
+       public static void saveKeyStore(Path keyStoreFile, char[] keyStorePassword, KeyStore keyStore) {
+               try {
+                       try (OutputStream fis = Files.newOutputStream(keyStoreFile)) {
+                               keyStore.store(fis, keyStorePassword);
+                       }
+               } catch (GeneralSecurityException | IOException e) {
+                       throw new RuntimeException("Cannot save keystore " + keyStoreFile, e);
+               }
+       }
+
+//     public static byte[] pemToPKCS12(final String keyFile, final String cerFile, final String password)
+//                     throws Exception {
+//             // Get the private key
+//             FileReader reader = new FileReader(keyFile);
+//
+//             PEMReader pem = new PemReader(reader, new PasswordFinder() {
+//                     @Override
+//                     public char[] getPassword() {
+//                             return password.toCharArray();
+//                     }
+//             });
+//
+//             PrivateKey key = ((KeyPair) pem.readObject()).getPrivate();
+//
+//             pem.close();
+//             reader.close();
+//
+//             // Get the certificate
+//             reader = new FileReader(cerFile);
+//             pem = new PEMReader(reader);
+//
+//             X509Certificate cert = (X509Certificate) pem.readObject();
+//
+//             pem.close();
+//             reader.close();
+//
+//             // Put them into a PKCS12 keystore and write it to a byte[]
+//             ByteArrayOutputStream bos = new ByteArrayOutputStream();
+//             KeyStore ks = KeyStore.getInstance("PKCS12");
+//             ks.load(null);
+//             ks.setKeyEntry("alias", (Key) key, password.toCharArray(), new java.security.cert.Certificate[] { cert });
+//             ks.store(bos, password.toCharArray());
+//             bos.close();
+//             return bos.toByteArray();
+//     }
+
+       public static void loadPem(KeyStore keyStore, Reader key, char[] keyPassword, Reader cert) {
+               PrivateKey privateKey = loadPemPrivateKey(key, keyPassword);
+               X509Certificate certificate = loadPemCertificate(cert);
+               try {
+                       keyStore.setKeyEntry(certificate.getSubjectX500Principal().getName(), privateKey, keyPassword,
+                                       new java.security.cert.Certificate[] { certificate });
+               } catch (KeyStoreException e) {
+                       throw new RuntimeException("Cannot store PEM certificate", e);
+               }
+       }
+
+       public static PrivateKey loadPemPrivateKey(Reader reader, char[] keyPassword) {
+               try (PEMParser pemParser = new PEMParser(reader)) {
+                       JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
+                       Object object = pemParser.readObject();
+                       PrivateKeyInfo privateKeyInfo;
+                       if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
+                               if (keyPassword == null)
+                                       throw new IllegalArgumentException("A key password is required");
+                               InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(keyPassword);
+                               privateKeyInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decProv);
+                       } else if (object instanceof PrivateKeyInfo) {
+                               privateKeyInfo = (PrivateKeyInfo) object;
+                       } else {
+                               throw new IllegalArgumentException("Unsupported format for private key");
+                       }
+                       return converter.getPrivateKey(privateKeyInfo);
+               } catch (IOException | OperatorCreationException | PKCSException e) {
+                       throw new RuntimeException("Cannot read private key", e);
+               }
+       }
+
+       public static X509Certificate loadPemCertificate(Reader reader) {
+               try (PEMParser pemParser = new PEMParser(reader)) {
+                       X509CertificateHolder certHolder = (X509CertificateHolder) pemParser.readObject();
+                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
+                                       .getCertificate(certHolder);
+                       return cert;
+               } catch (IOException | CertificateException e) {
+                       throw new RuntimeException("Cannot read private key", e);
+               }
+       }
+
+       public static void main(String[] args) throws Exception {
+               final String ALGORITHM = "RSA";
+               final String provider = "BC";
+               SecureRandom secureRandom = new SecureRandom();
+               long begin = System.currentTimeMillis();
+               for (int i = 512; i < 1024; i = i + 2) {
+                       try {
+                               KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, provider);
+                               keyGen.initialize(i, secureRandom);
+                               keyGen.generateKeyPair();
+                       } catch (Exception e) {
+                               System.err.println(i + " : " + e.getMessage());
+                       }
+               }
+               System.out.println((System.currentTimeMillis() - begin) + " ms");
+
+               // // String text = "a";
+               // String text =
+               // "testtesttesttesttesttesttesttesttesttesttesttesttesttesttest";
+               // try {
+               // System.out.println(text);
+               // PrivateKey privateKey;
+               // PublicKey publicKey;
+               // char[] password = "changeit".toCharArray();
+               // String alias = "CN=test";
+               // KeyStore keyStore = KeyStore.getInstance("pkcs12");
+               // File p12file = new File("test.p12");
+               // p12file.delete();
+               // if (!p12file.exists()) {
+               // keyStore.load(null);
+               // generateSelfSignedCertificate(keyStore, new X500Principal(alias),
+               // 513, password);
+               // try (OutputStream out = new FileOutputStream(p12file)) {
+               // keyStore.store(out, password);
+               // }
+               // }
+               // try (InputStream in = new FileInputStream(p12file)) {
+               // keyStore.load(in, password);
+               // privateKey = (PrivateKey) keyStore.getKey(alias, password);
+               // publicKey = keyStore.getCertificateChain(alias)[0].getPublicKey();
+               // }
+               // // KeyPair key;
+               // // final KeyPairGenerator keyGen =
+               // // KeyPairGenerator.getInstance(ALGORITHM);
+               // // keyGen.initialize(4096, new SecureRandom());
+               // // long begin = System.currentTimeMillis();
+               // // key = keyGen.generateKeyPair();
+               // // System.out.println((System.currentTimeMillis() - begin) + " ms");
+               // // keyStore.load(null);
+               // // keyStore.setKeyEntry("test", key.getPrivate(), password, null);
+               // // try(OutputStream out=new FileOutputStream(p12file)) {
+               // // keyStore.store(out, password);
+               // // }
+               // // privateKey = key.getPrivate();
+               // // publicKey = key.getPublic();
+               //
+               // Cipher encrypt = Cipher.getInstance(ALGORITHM);
+               // encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
+               // byte[] encrypted = encrypt.doFinal(text.getBytes());
+               // String encryptedBase64 =
+               // Base64.getEncoder().encodeToString(encrypted);
+               // System.out.println(encryptedBase64);
+               // byte[] encryptedFromBase64 =
+               // Base64.getDecoder().decode(encryptedBase64);
+               //
+               // Cipher decrypt = Cipher.getInstance(ALGORITHM);
+               // decrypt.init(Cipher.DECRYPT_MODE, privateKey);
+               // byte[] decrypted = decrypt.doFinal(encryptedFromBase64);
+               // System.out.println(new String(decrypted));
+               // } catch (Exception e) {
+               // e.printStackTrace();
+               // }
+
+       }
+
+       public static void createSelfSignedKeyStore(Path keyStorePath, char[] keyStorePassword, String keyStoreType) {
+               // for (Provider provider : Security.getProviders())
+               // System.out.println(provider.getName());
+               // File keyStoreFile = keyStorePath.toFile();
+               char[] keyPwd = Arrays.copyOf(keyStorePassword, keyStorePassword.length);
+               if (!Files.exists(keyStorePath)) {
+                       try {
+                               Files.createDirectories(keyStorePath.getParent());
+                               KeyStore keyStore = getKeyStore(keyStorePath, keyStorePassword, keyStoreType);
+                               generateSelfSignedCertificate(keyStore,
+                                               new X500Principal("CN=" + InetAddress.getLocalHost().getHostName() + ",OU=UNSECURE,O=UNSECURE"),
+                                               1024, keyPwd);
+                               saveKeyStore(keyStorePath, keyStorePassword, keyStore);
+                               if (log.isDebugEnabled())
+                                       log.debug("Created self-signed unsecure keystore " + keyStorePath);
+                       } catch (Exception e) {
+                               try {
+                                       if (Files.size(keyStorePath) == 0)
+                                               Files.delete(keyStorePath);
+                               } catch (IOException e1) {
+                                       // silent
+                               }
+                               log.error("Cannot create keystore " + keyStorePath, e);
+                       }
+               } else {
+                       throw new IllegalStateException("Keystore " + keyStorePath + " already exists");
+               }
+       }
+
+}
index 08ac5493613758af5d4123f6441a83f3674b2e9e..10b583fdfa6b9e5eba23c91fe8b052a1dd96c294 100644 (file)
@@ -9,7 +9,6 @@ import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
-import java.security.AccessController;
 import java.security.Provider;
 import java.security.Security;
 import java.util.Arrays;
@@ -27,7 +26,7 @@ import javax.security.auth.login.LoginException;
 
 import org.apache.commons.io.IOUtils;
 import org.argeo.api.cms.CmsAuth;
-import org.argeo.cms.CmsException;
+import org.argeo.util.CurrentSubject;
 
 /** username / password based keyring. TODO internationalize */
 public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
@@ -65,23 +64,24 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
 
        /** Triggers lazy initialization */
        protected SecretKey getSecretKey(char[] password) {
-               Subject subject = Subject.getSubject(AccessController.getContext());
+               Subject subject = CurrentSubject.current();
+               if (subject == null)
+                       throw new IllegalStateException("Current subject cannot be null");
                // we assume only one secrete key is available
                Iterator<SecretKey> iterator = subject.getPrivateCredentials(SecretKey.class).iterator();
-               if (!iterator.hasNext() || password!=null) {// not initialized
+               if (!iterator.hasNext() || password != null) {// not initialized
                        CallbackHandler callbackHandler = password == null ? new KeyringCallbackHandler()
                                        : new PasswordProvidedCallBackHandler(password);
                        ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
                        try {
-                               LoginContext loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_KEYRING, subject,
-                                               callbackHandler);
+                               LoginContext loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_KEYRING, subject, callbackHandler);
                                loginContext.login();
                                // FIXME will login even if password is wrong
                                iterator = subject.getPrivateCredentials(SecretKey.class).iterator();
                                return iterator.next();
                        } catch (LoginException e) {
-                               throw new CmsException("Keyring login failed", e);
+                               throw new IllegalStateException("Keyring login failed", e);
                        } finally {
                                Thread.currentThread().setContextClassLoader(currentContextClassLoader);
                        }
@@ -89,7 +89,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                } else {
                        SecretKey secretKey = iterator.next();
                        if (iterator.hasNext())
-                               throw new CmsException("More than one secret key in private credentials");
+                               throw new IllegalStateException("More than one secret key in private credentials");
                        return secretKey;
                }
        }
@@ -112,7 +112,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                        IOUtils.copy(reader, writer);
                        return writer.toCharArray();
                } catch (IOException e) {
-                       throw new CmsException("Cannot decrypt to char array", e);
+                       throw new IllegalStateException("Cannot decrypt to char array", e);
                } finally {
                        // IOUtils.closeQuietly(reader);
                        // IOUtils.closeQuietly(in);
@@ -134,7 +134,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                                set(path, in);
                        }
                } catch (IOException e) {
-                       throw new CmsException("Cannot encrypt to char array", e);
+                       throw new IllegalStateException("Cannot encrypt to char array", e);
                } finally {
                        // IOUtils.closeQuietly(writer);
                        // IOUtils.closeQuietly(out);
@@ -147,7 +147,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                        setup(password);
                SecretKey secretKey = getSecretKey(password);
                if (secretKey == null)
-                       throw new CmsException("Could not unlock keyring");
+                       throw new IllegalStateException("Could not unlock keyring");
        }
 
        protected Provider getSecurityProvider() {
@@ -205,7 +205,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring {
                        char[] password = passwordCb.getPassword();
                        return password;
                } catch (Exception e) {
-                       throw new CmsException("Cannot ask for a password", e);
+                       throw new IllegalStateException("Cannot ask for a password", e);
                }
 
        }
index 69e8a08fda9b616885d4870e7c37a27530d3733d..7344f01bc25ee6ebda7b7c6cd4f5dd6c16ce7844 100644 (file)
@@ -11,11 +11,10 @@ import java.nio.file.Paths;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.Base64;
 import java.util.zip.Checksum;
 
-import org.argeo.cms.CmsException;
-
 /** Allows to fine tune how files are read. */
 public class ChecksumFactory {
        private int regionSize = 10 * 1024 * 1024;
@@ -81,8 +80,8 @@ public class ChecksumFactory {
                                        return digest;
                                }
                        }
-               } catch (Exception e) {
-                       throw new CmsException("Cannot digest " + path, e);
+               } catch (NoSuchAlgorithmException | IOException e) {
+                       throw new IllegalStateException("Cannot digest " + path, e);
                }
        }
 
@@ -113,8 +112,8 @@ public class ChecksumFactory {
                                cursor = cursor + regionSize;
                        }
                        return crc.getValue();
-               } catch (Exception e) {
-                       throw new CmsException("Cannot checksum " + path, e);
+               } catch (IOException e) {
+                       throw new IllegalStateException("Cannot checksum " + path, e);
                } finally {
                        long duration = System.currentTimeMillis() - begin;
                        System.out.println(duration / 1000 + "s");
diff --git a/org.argeo.cms/src/org/argeo/cms/security/PkiUtils.java b/org.argeo.cms/src/org/argeo/cms/security/PkiUtils.java
deleted file mode 100644 (file)
index d6f90ac..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-package org.argeo.cms.security;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Date;
-
-import javax.security.auth.x500.X500Principal;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.internal.runtime.KernelConstants;
-import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.openssl.PEMParser;
-import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
-import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.InputDecryptorProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
-import org.bouncycastle.pkcs.PKCSException;
-
-/**
- * Utilities around private keys and certificate, mostly wrapping BouncyCastle
- * implementations.
- */
-public class PkiUtils {
-       private final static CmsLog log = CmsLog.getLog(PkiUtils.class);
-
-       public final static String PKCS12 = "PKCS12";
-       public static final String DEFAULT_KEYSTORE_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".p12";
-
-       public static final String DEFAULT_PEM_KEY_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".key";
-
-       public static final String DEFAULT_PEM_CERT_PATH = KernelConstants.DIR_NODE + '/' + CmsConstants.NODE + ".crt";
-
-       private final static String SECURITY_PROVIDER;
-       static {
-               Security.addProvider(new BouncyCastleProvider());
-               SECURITY_PROVIDER = "BC";
-       }
-
-       public static X509Certificate generateSelfSignedCertificate(KeyStore keyStore, X500Principal x500Principal,
-                       int keySize, char[] keyPassword) {
-               try {
-                       KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", SECURITY_PROVIDER);
-                       kpGen.initialize(keySize, new SecureRandom());
-                       KeyPair pair = kpGen.generateKeyPair();
-                       Date notBefore = new Date(System.currentTimeMillis() - 10000);
-                       Date notAfter = new Date(System.currentTimeMillis() + 365 * 24L * 3600 * 1000);
-                       BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());
-                       X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(x500Principal, serial, notBefore,
-                                       notAfter, x500Principal, pair.getPublic());
-                       ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(SECURITY_PROVIDER)
-                                       .build(pair.getPrivate());
-                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
-                                       .getCertificate(certGen.build(sigGen));
-                       cert.checkValidity(new Date());
-                       cert.verify(cert.getPublicKey());
-
-                       keyStore.setKeyEntry(x500Principal.getName(), pair.getPrivate(), keyPassword, new Certificate[] { cert });
-                       return cert;
-               } catch (GeneralSecurityException | OperatorCreationException e) {
-                       throw new RuntimeException("Cannot generate self-signed certificate", e);
-               }
-       }
-
-       public static KeyStore getKeyStore(Path keyStoreFile, char[] keyStorePassword, String keyStoreType) {
-               try {
-                       KeyStore store = KeyStore.getInstance(keyStoreType, SECURITY_PROVIDER);
-                       if (Files.exists(keyStoreFile)) {
-                               try (InputStream fis = Files.newInputStream(keyStoreFile)) {
-                                       store.load(fis, keyStorePassword);
-                               }
-                       } else {
-                               store.load(null);
-                       }
-                       return store;
-               } catch (GeneralSecurityException | IOException e) {
-                       throw new RuntimeException("Cannot load keystore " + keyStoreFile, e);
-               }
-       }
-
-       public static void saveKeyStore(Path keyStoreFile, char[] keyStorePassword, KeyStore keyStore) {
-               try {
-                       try (OutputStream fis = Files.newOutputStream(keyStoreFile)) {
-                               keyStore.store(fis, keyStorePassword);
-                       }
-               } catch (GeneralSecurityException | IOException e) {
-                       throw new RuntimeException("Cannot save keystore " + keyStoreFile, e);
-               }
-       }
-
-//     public static byte[] pemToPKCS12(final String keyFile, final String cerFile, final String password)
-//                     throws Exception {
-//             // Get the private key
-//             FileReader reader = new FileReader(keyFile);
-//
-//             PEMReader pem = new PemReader(reader, new PasswordFinder() {
-//                     @Override
-//                     public char[] getPassword() {
-//                             return password.toCharArray();
-//                     }
-//             });
-//
-//             PrivateKey key = ((KeyPair) pem.readObject()).getPrivate();
-//
-//             pem.close();
-//             reader.close();
-//
-//             // Get the certificate
-//             reader = new FileReader(cerFile);
-//             pem = new PEMReader(reader);
-//
-//             X509Certificate cert = (X509Certificate) pem.readObject();
-//
-//             pem.close();
-//             reader.close();
-//
-//             // Put them into a PKCS12 keystore and write it to a byte[]
-//             ByteArrayOutputStream bos = new ByteArrayOutputStream();
-//             KeyStore ks = KeyStore.getInstance("PKCS12");
-//             ks.load(null);
-//             ks.setKeyEntry("alias", (Key) key, password.toCharArray(), new java.security.cert.Certificate[] { cert });
-//             ks.store(bos, password.toCharArray());
-//             bos.close();
-//             return bos.toByteArray();
-//     }
-
-       public static void loadPem(KeyStore keyStore, Reader key, char[] keyPassword, Reader cert) {
-               PrivateKey privateKey = loadPemPrivateKey(key, keyPassword);
-               X509Certificate certificate = loadPemCertificate(cert);
-               try {
-                       keyStore.setKeyEntry(certificate.getSubjectX500Principal().getName(), privateKey, keyPassword,
-                                       new java.security.cert.Certificate[] { certificate });
-               } catch (KeyStoreException e) {
-                       throw new RuntimeException("Cannot store PEM certificate", e);
-               }
-       }
-
-       public static PrivateKey loadPemPrivateKey(Reader reader, char[] keyPassword) {
-               try (PEMParser pemParser = new PEMParser(reader)) {
-                       JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
-                       Object object = pemParser.readObject();
-                       PrivateKeyInfo privateKeyInfo;
-                       if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
-                               if (keyPassword == null)
-                                       throw new IllegalArgumentException("A key password is required");
-                               InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(keyPassword);
-                               privateKeyInfo = ((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decProv);
-                       } else if (object instanceof PrivateKeyInfo) {
-                               privateKeyInfo = (PrivateKeyInfo) object;
-                       } else {
-                               throw new IllegalArgumentException("Unsupported format for private key");
-                       }
-                       return converter.getPrivateKey(privateKeyInfo);
-               } catch (IOException | OperatorCreationException | PKCSException e) {
-                       throw new RuntimeException("Cannot read private key", e);
-               }
-       }
-
-       public static X509Certificate loadPemCertificate(Reader reader) {
-               try (PEMParser pemParser = new PEMParser(reader)) {
-                       X509CertificateHolder certHolder = (X509CertificateHolder) pemParser.readObject();
-                       X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER)
-                                       .getCertificate(certHolder);
-                       return cert;
-               } catch (IOException | CertificateException e) {
-                       throw new RuntimeException("Cannot read private key", e);
-               }
-       }
-
-       public static void main(String[] args) throws Exception {
-               final String ALGORITHM = "RSA";
-               final String provider = "BC";
-               SecureRandom secureRandom = new SecureRandom();
-               long begin = System.currentTimeMillis();
-               for (int i = 512; i < 1024; i = i + 2) {
-                       try {
-                               KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, provider);
-                               keyGen.initialize(i, secureRandom);
-                               keyGen.generateKeyPair();
-                       } catch (Exception e) {
-                               System.err.println(i + " : " + e.getMessage());
-                       }
-               }
-               System.out.println((System.currentTimeMillis() - begin) + " ms");
-
-               // // String text = "a";
-               // String text =
-               // "testtesttesttesttesttesttesttesttesttesttesttesttesttesttest";
-               // try {
-               // System.out.println(text);
-               // PrivateKey privateKey;
-               // PublicKey publicKey;
-               // char[] password = "changeit".toCharArray();
-               // String alias = "CN=test";
-               // KeyStore keyStore = KeyStore.getInstance("pkcs12");
-               // File p12file = new File("test.p12");
-               // p12file.delete();
-               // if (!p12file.exists()) {
-               // keyStore.load(null);
-               // generateSelfSignedCertificate(keyStore, new X500Principal(alias),
-               // 513, password);
-               // try (OutputStream out = new FileOutputStream(p12file)) {
-               // keyStore.store(out, password);
-               // }
-               // }
-               // try (InputStream in = new FileInputStream(p12file)) {
-               // keyStore.load(in, password);
-               // privateKey = (PrivateKey) keyStore.getKey(alias, password);
-               // publicKey = keyStore.getCertificateChain(alias)[0].getPublicKey();
-               // }
-               // // KeyPair key;
-               // // final KeyPairGenerator keyGen =
-               // // KeyPairGenerator.getInstance(ALGORITHM);
-               // // keyGen.initialize(4096, new SecureRandom());
-               // // long begin = System.currentTimeMillis();
-               // // key = keyGen.generateKeyPair();
-               // // System.out.println((System.currentTimeMillis() - begin) + " ms");
-               // // keyStore.load(null);
-               // // keyStore.setKeyEntry("test", key.getPrivate(), password, null);
-               // // try(OutputStream out=new FileOutputStream(p12file)) {
-               // // keyStore.store(out, password);
-               // // }
-               // // privateKey = key.getPrivate();
-               // // publicKey = key.getPublic();
-               //
-               // Cipher encrypt = Cipher.getInstance(ALGORITHM);
-               // encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
-               // byte[] encrypted = encrypt.doFinal(text.getBytes());
-               // String encryptedBase64 =
-               // Base64.getEncoder().encodeToString(encrypted);
-               // System.out.println(encryptedBase64);
-               // byte[] encryptedFromBase64 =
-               // Base64.getDecoder().decode(encryptedBase64);
-               //
-               // Cipher decrypt = Cipher.getInstance(ALGORITHM);
-               // decrypt.init(Cipher.DECRYPT_MODE, privateKey);
-               // byte[] decrypted = decrypt.doFinal(encryptedFromBase64);
-               // System.out.println(new String(decrypted));
-               // } catch (Exception e) {
-               // e.printStackTrace();
-               // }
-
-       }
-
-       public static void createSelfSignedKeyStore(Path keyStorePath, char[] keyStorePassword, String keyStoreType) {
-               // for (Provider provider : Security.getProviders())
-               // System.out.println(provider.getName());
-               // File keyStoreFile = keyStorePath.toFile();
-               char[] keyPwd = Arrays.copyOf(keyStorePassword, keyStorePassword.length);
-               if (!Files.exists(keyStorePath)) {
-                       try {
-                               Files.createDirectories(keyStorePath.getParent());
-                               KeyStore keyStore = getKeyStore(keyStorePath, keyStorePassword, keyStoreType);
-                               generateSelfSignedCertificate(keyStore,
-                                               new X500Principal("CN=" + InetAddress.getLocalHost().getHostName() + ",OU=UNSECURE,O=UNSECURE"),
-                                               1024, keyPwd);
-                               saveKeyStore(keyStorePath, keyStorePassword, keyStore);
-                               if (log.isDebugEnabled())
-                                       log.debug("Created self-signed unsecure keystore " + keyStorePath);
-                       } catch (Exception e) {
-                               try {
-                                       if (Files.size(keyStorePath) == 0)
-                                               Files.delete(keyStorePath);
-                               } catch (IOException e1) {
-                                       // silent
-                               }
-                               log.error("Cannot create keystore " + keyStorePath, e);
-                       }
-               } else {
-                       throw new IllegalStateException("Keystore " + keyStorePath + " already exists");
-               }
-       }
-
-}
diff --git a/org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java b/org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java
deleted file mode 100644 (file)
index 0fc4f32..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.argeo.osgi.metatype;
-
-import org.argeo.util.naming.SpecifiedName;
-import org.osgi.service.metatype.AttributeDefinition;
-
-public interface EnumAD extends SpecifiedName, AttributeDefinition {
-       String name();
-
-       default Object getDefault() {
-               return null;
-       }
-
-       @Override
-       default String getName() {
-               return name();
-       }
-
-       @Override
-       default String getID() {
-               return getClass().getName() + "." + name();
-       }
-
-       @Override
-       default String getDescription() {
-               return null;
-       }
-
-       @Override
-       default int getCardinality() {
-               return 0;
-       }
-
-       @Override
-       default int getType() {
-               return STRING;
-       }
-
-       @Override
-       default String[] getOptionValues() {
-               return null;
-       }
-
-       @Override
-       default String[] getOptionLabels() {
-               return null;
-       }
-
-       @Override
-       default String validate(String value) {
-               return null;
-       }
-
-       @Override
-       default String[] getDefaultValue() {
-               Object value = getDefault();
-               if (value == null)
-                       return null;
-               return new String[] { value.toString() };
-       }
-}
diff --git a/org.argeo.util/src/org/argeo/osgi/metatype/EnumOCD.java b/org.argeo.util/src/org/argeo/osgi/metatype/EnumOCD.java
deleted file mode 100644 (file)
index 97c7d56..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.argeo.osgi.metatype;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.List;
-
-import org.osgi.service.metatype.AttributeDefinition;
-import org.osgi.service.metatype.ObjectClassDefinition;
-
-public class EnumOCD<T extends Enum<T>> implements ObjectClassDefinition {
-       private final Class<T> enumClass;
-       private String locale;
-
-       public EnumOCD(Class<T> clazz, String locale) {
-               this.enumClass = clazz;
-               this.locale = locale;
-       }
-
-       @Override
-       public String getName() {
-               return null;
-       }
-
-       public String getLocale() {
-               return locale;
-       }
-
-       @Override
-       public String getID() {
-               return enumClass.getName();
-       }
-
-       @Override
-       public String getDescription() {
-               return null;
-       }
-
-       @Override
-       public AttributeDefinition[] getAttributeDefinitions(int filter) {
-               EnumSet<T> set = EnumSet.allOf(enumClass);
-               List<AttributeDefinition> attrs = new ArrayList<>();
-               for (T key : set)
-                       attrs.add((AttributeDefinition) key);
-               return attrs.toArray(new AttributeDefinition[attrs.size()]);
-       }
-
-       @Override
-       public InputStream getIcon(int size) throws IOException {
-               return null;
-       }
-
-}
diff --git a/org.argeo.util/src/org/argeo/osgi/metatype/package-info.java b/org.argeo.util/src/org/argeo/osgi/metatype/package-info.java
deleted file mode 100644 (file)
index bca5d1f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** OSGi metatype support. */
-package org.argeo.osgi.metatype;
\ No newline at end of file
index a2b9440647b691f1ec745b3ab2d856fc7110695c..6b3a670d7974979ab1e49183d90c41bed10f1124 100644 (file)
@@ -22,7 +22,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.ux.CmsTheme;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.ui.CmsUiConstants;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.util.CmsUiUtils;
index 499840a73894244c116619b30be6f070f16a2be1..9879fb019e78b4bbef5180409e67a531d812bea0 100644 (file)
@@ -11,7 +11,7 @@ import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.eclipse.rap.rwt.application.Application;
 import org.eclipse.rap.rwt.application.ApplicationConfiguration;
 import org.osgi.framework.BundleContext;
index a909dbdd7e5f940b329b4fd654f43345a972de16..f3269f2c43356575677d8481600271598f17f83c 100644 (file)
@@ -24,12 +24,12 @@ import javax.servlet.http.HttpServletRequest;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.ux.CmsView;
 import org.argeo.api.cms.CmsAuth;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.RemoteAuthCallback;
 import org.argeo.cms.auth.RemoteAuthCallbackHandler;
 import org.argeo.cms.servlet.ServletHttpRequest;
 import org.argeo.cms.servlet.ServletHttpResponse;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsStyles;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.eclipse.ui.specific.UiContext;
index f063117ae625ca0415db3ce535c61bee294059e2..38a9b4449785ba0e1a8b1a8112c3efe041847122 100644 (file)
@@ -22,8 +22,8 @@ import javax.jcr.version.VersionManager;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.ui.CmsUiConstants;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.LifeCycleUiProvider;
index 1b50c19b7b042c20af2d2522467e9755fd6abfe4..783f6eb73d3499337f601a10dc235e2550300558 100644 (file)
@@ -10,7 +10,7 @@ import javax.jcr.RepositoryException;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.ux.CmsImageManager;
 import org.argeo.api.cms.ux.UxContext;
-import org.argeo.cms.CmsException;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsStyles;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.swt.SimpleSwtUxContext;
index a13c0170fc9a6d302ba1f217c504f64a5e5b29ea..b37a76587c1a82f0e5292ec6e650b0c33b5fd432 100644 (file)
@@ -11,8 +11,8 @@ import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.ux.CmsImageManager;
 import org.argeo.api.cms.ux.CmsView;
 import org.argeo.api.cms.ux.UxContext;
-import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsException;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.swt.SimpleSwtUxContext;
 import org.argeo.cms.swt.auth.CmsLoginShell;
@@ -55,7 +55,7 @@ public class CmsE4Application implements IApplication, CmsView {
                        }
                }
                if (CurrentUser.getUsername(getSubject()) == null)
-                       throw new CmsException("Cannot log in");
+                       throw new IllegalStateException("Cannot log in");
 
                // try {
                // CallbackHandler callbackHandler = new DefaultLoginDialog(