]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java
Introduce CMS event bus and use it in UI.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / runtime / CmsStateImpl.java
index fd2c5f9cdb47d4632ae7b9cf8464e92f3bdb94d9..c9109c8561fb2500485998c033cbb4ac4d58a419 100644 (file)
@@ -2,22 +2,32 @@ package org.argeo.cms.internal.runtime;
 
 import java.io.IOException;
 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.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
 import java.security.KeyStore;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.StringJoiner;
 import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 import javax.security.auth.login.Configuration;
 
@@ -40,13 +50,17 @@ public class CmsStateImpl implements CmsState {
 
        private UUID uuid;
 //     private final boolean cleanState;
-//     private String hostname;
+       private String hostname;
 
        private UuidFactory uuidFactory;
 
        private final Map<CmsDeployProperty, String> deployPropertyDefaults;
 
        public CmsStateImpl() {
+               this.deployPropertyDefaults = Collections.unmodifiableMap(createDeployPropertiesDefaults());
+       }
+
+       protected Map<CmsDeployProperty, String> createDeployPropertiesDefaults() {
                Map<CmsDeployProperty, String> deployPropertyDefaults = new HashMap<>();
                deployPropertyDefaults.put(CmsDeployProperty.NODE_INIT, "../../init");
                deployPropertyDefaults.put(CmsDeployProperty.LOCALE, Locale.getDefault().toString());
@@ -66,7 +80,13 @@ public class CmsStateImpl implements CmsState {
                deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTORETYPE, PkiUtils.PKCS12);
                deployPropertyDefaults.put(CmsDeployProperty.SSL_TRUSTSTOREPASSWORD, PkiUtils.DEFAULT_KEYSTORE_PASSWORD);
 
-               this.deployPropertyDefaults = Collections.unmodifiableMap(deployPropertyDefaults);
+               // SSH
+               Path authorizedKeysPath = getDataPath(KernelConstants.NODE_SSHD_AUTHORIZED_KEYS_PATH);
+               if (authorizedKeysPath != null) {
+                       deployPropertyDefaults.put(CmsDeployProperty.SSHD_AUTHORIZEDKEYS,
+                                       authorizedKeysPath.toAbsolutePath().toString());
+               }
+               return deployPropertyDefaults;
        }
 
        public void start() {
@@ -83,11 +103,27 @@ public class CmsStateImpl implements CmsState {
 //                     this.uuid = UUID.fromString(stateUuidStr);
                        this.uuid = uuidFactory.timeUUID();
 //             this.cleanState = stateUuid.equals(frameworkUuid);
-//                     try {
-//                             this.hostname = InetAddress.getLocalHost().getHostName();
-//                     } catch (UnknownHostException e) {
-//                             log.error("Cannot set hostname: " + e);
-//                     }
+
+                       // hostname
+                       this.hostname = getDeployProperty(CmsDeployProperty.HOST);
+                       // TODO verify we have access to the IP address
+                       if (hostname == null) {
+                               final String LOCALHOST_IP = "::1";
+                               ForkJoinTask<String> hostnameFJT = ForkJoinPool.commonPool().submit(() -> {
+                                       try {
+                                               String hostname = InetAddress.getLocalHost().getHostName();
+                                               return hostname;
+                                       } catch (UnknownHostException e) {
+                                               throw new IllegalStateException("Cannot get local hostname", e);
+                                       }
+                               });
+                               try {
+                                       this.hostname = hostnameFJT.get(5, TimeUnit.SECONDS);
+                               } catch (InterruptedException | ExecutionException | TimeoutException e) {
+                                       this.hostname = LOCALHOST_IP;
+                                       log.warn("Could not get local hostname, using " + this.hostname);
+                               }
+                       }
 
                        availableSince = System.currentTimeMillis();
                        if (log.isDebugEnabled()) {
@@ -112,7 +148,7 @@ public class CmsStateImpl implements CmsState {
                                log.debug("## CMS starting... (" + uuid + ")\n" + sb + "\n");
                        }
 
-                       Path nodeBase = getDataPath(CmsConstants.NODE);
+                       Path nodeBase = getDataPath(KernelConstants.DIR_PRIVATE);
                        if (nodeBase != null && !Files.exists(nodeBase)) {// first init
                                firstInit();
                        }
@@ -123,6 +159,21 @@ public class CmsStateImpl implements CmsState {
        }
 
        private void initSecurity() {
+               // private directory permissions
+               Path privateDir = KernelUtils.getOsgiInstancePath(KernelConstants.DIR_PRIVATE);
+               if (privateDir != null) {
+                       // TODO rather check whether we can read and write
+                       Set<PosixFilePermission> posixPermissions = new HashSet<>();
+                       posixPermissions.add(PosixFilePermission.OWNER_READ);
+                       posixPermissions.add(PosixFilePermission.OWNER_WRITE);
+                       posixPermissions.add(PosixFilePermission.OWNER_EXECUTE);
+                       try {
+                               Files.setPosixFilePermissions(privateDir, posixPermissions);
+                       } catch (IOException e) {
+                               log.error("Cannot set permissions on " + privateDir);
+                       }
+               }
+
                if (getDeployProperty(CmsDeployProperty.JAVA_LOGIN_CONFIG) == null) {
                        String jaasConfig = KernelConstants.JAAS_CONFIG;
                        URL url = getClass().getResource(jaasConfig);
@@ -154,7 +205,7 @@ public class CmsStateImpl implements CmsState {
                                        getDeployProperty(CmsDeployProperty.SSL_KEYSTORETYPE));
                        try (Reader key = Files.newBufferedReader(pemKeyPath, StandardCharsets.US_ASCII);
                                        Reader cert = Files.newBufferedReader(pemCertPath, StandardCharsets.US_ASCII);) {
-                               PkiUtils.loadPem(keyStore, key, keyStorePassword, cert);
+                               PkiUtils.loadPrivateCertificatePem(keyStore, CmsConstants.NODE, key, keyStorePassword, cert);
                                Files.createDirectories(keyStorePath.getParent());
                                PkiUtils.saveKeyStore(keyStorePath, keyStorePassword, keyStore);
                                if (log.isDebugEnabled())
@@ -174,7 +225,7 @@ public class CmsStateImpl implements CmsState {
                        KeyStore trustStore = PkiUtils.getKeyStore(trustStorePath, trustStorePassword,
                                        getDeployProperty(CmsDeployProperty.SSL_TRUSTSTORETYPE));
                        try (Reader cert = Files.newBufferedReader(ipaCaCertPath, StandardCharsets.US_ASCII);) {
-                               PkiUtils.loadPem(trustStore, null, trustStorePassword, cert);
+                               PkiUtils.loadTrustedCertificatePem(trustStore, trustStorePassword, cert);
                                Files.createDirectories(keyStorePath.getParent());
                                PkiUtils.saveKeyStore(trustStorePath, trustStorePassword, trustStore);
                                if (log.isDebugEnabled())
@@ -345,6 +396,10 @@ public class CmsStateImpl implements CmsState {
                this.uuidFactory = uuidFactory;
        }
 
+       public String getHostname() {
+               return hostname;
+       }
+
        /**
         * Called before node initialisation, in order populate OSGi instance are with
         * some files (typically LDIF, etc).