This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 7fefebb5356d02fb52965e1686b8497ade94fb53
Author: Lyor Goldstein <lgoldst...@apache.org>
AuthorDate: Thu Feb 17 08:41:47 2022 +0200

    [SSHD-1246] Moved user HOME directory detection and usage to PathUtils
---
 CHANGES.md                                         |  4 ++
 .../sshd/client/config/hosts/HostConfigEntry.java  | 32 ++-------
 .../sshd/common/config/keys/IdentityUtils.java     | 20 ------
 .../sshd/common/config/keys/PublicKeyEntry.java    |  3 +-
 .../org/apache/sshd/common/util/io/PathUtils.java  | 73 ++++++++++++++++++++
 .../apache/sshd/common/util/io/PathUtilsTest.java  | 78 ++++++++++++++++++++++
 .../java/org/apache/sshd/openpgp/PGPUtils.java     |  4 +-
 7 files changed, 163 insertions(+), 51 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 4571d35..894d234 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -57,6 +57,10 @@ to make sure the requested value does not exceed 
`Integer#MAX_VALUE` (sometimes
 or malformed packets. It is important to bear in mind that in the vast 
majority of the cases we do not want to be able to allocate arrays
 or lists having billions of elements as it would almost definitely cause 
out-of-memory issues.
 
+## User HOME directory resolution and usage have been moved to *PathUtils*
+
+Was originally in *HostConfigEntry*.
+
 ## Minor code helpers
 
 ## Behavioral changes and enhancements
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
 
b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
index 31a62c2..5f4d33d 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
@@ -48,7 +48,6 @@ import java.util.TreeMap;
 
 import org.apache.sshd.common.auth.MutableUserHolder;
 import org.apache.sshd.common.config.ConfigFileReaderSupport;
-import org.apache.sshd.common.config.keys.IdentityUtils;
 import org.apache.sshd.common.config.keys.PublicKeyEntry;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.MapEntryUtils;
@@ -56,6 +55,7 @@ import 
org.apache.sshd.common.util.MapEntryUtils.NavigableMapBuilder;
 import org.apache.sshd.common.util.OsUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.io.IoUtils;
+import org.apache.sshd.common.util.io.PathUtils;
 import org.apache.sshd.common.util.io.input.NoCloseInputStream;
 import org.apache.sshd.common.util.io.input.NoCloseReader;
 import org.apache.sshd.common.util.io.output.NoCloseOutputStream;
@@ -114,7 +114,6 @@ public class HostConfigEntry extends HostPatternsHolder 
implements MutableUserHo
 
     public static final String MULTI_VALUE_SEPARATORS = " ,";
 
-    public static final char HOME_TILDE_CHAR = '~';
     public static final char PATH_MACRO_CHAR = '%';
     public static final char LOCAL_HOME_MACRO = 'd';
     public static final char LOCAL_USER_MACRO = 'u';
@@ -1148,9 +1147,9 @@ public class HostConfigEntry extends HostPatternsHolder 
implements MutableUserHo
 
             for (int curPos = 0; curPos < elem.length(); curPos++) {
                 char ch = elem.charAt(curPos);
-                if (ch == HOME_TILDE_CHAR) {
+                if (ch == PathUtils.HOME_TILDE_CHAR) {
                     ValidateUtils.checkTrue((curPos == 0) && (index == 0), 
"Home tilde must be first: %s", id);
-                    appendUserHome(sb);
+                    PathUtils.appendUserHome(sb);
                 } else if (ch == PATH_MACRO_CHAR) {
                     curPos++;
                     ValidateUtils.checkTrue(curPos < elem.length(), "Missing 
macro modifier in %s", id);
@@ -1161,7 +1160,7 @@ public class HostConfigEntry extends HostPatternsHolder 
implements MutableUserHo
                             break;
                         case LOCAL_HOME_MACRO:
                             ValidateUtils.checkTrue((curPos == 1) && (index == 
0), "Home macro must be first: %s", id);
-                            appendUserHome(sb);
+                            PathUtils.appendUserHome(sb);
                             break;
                         case LOCAL_USER_MACRO:
                             
sb.append(ValidateUtils.checkNotNullAndNotEmpty(OsUtils.getCurrentUser(),
@@ -1194,29 +1193,6 @@ public class HostConfigEntry extends HostPatternsHolder 
implements MutableUserHo
         return sb.toString();
     }
 
-    public static StringBuilder appendUserHome(StringBuilder sb) {
-        return appendUserHome(sb, IdentityUtils.getUserHomeFolder());
-    }
-
-    public static StringBuilder appendUserHome(StringBuilder sb, Path 
userHome) {
-        return appendUserHome(sb, Objects.requireNonNull(userHome, "No user 
home folder").toString());
-    }
-
-    public static StringBuilder appendUserHome(StringBuilder sb, String 
userHome) {
-        if (GenericUtils.isEmpty(userHome)) {
-            return sb;
-        }
-
-        sb.append(userHome);
-        // strip any ending separator since we add our own
-        int len = sb.length();
-        if (sb.charAt(len - 1) == File.separatorChar) {
-            sb.setLength(len - 1);
-        }
-
-        return sb;
-    }
-
     /**
      * @return The default {@link Path} location of the OpenSSH hosts entries 
configuration file
      */
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java
index b353dbc..f727165 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java
@@ -23,7 +23,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.OpenOption;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.util.Collections;
@@ -48,25 +47,6 @@ public final class IdentityUtils {
         throw new UnsupportedOperationException("No instance");
     }
 
-    private static final class LazyDefaultUserHomeFolderHolder {
-        private static final Path PATH
-                = 
Paths.get(ValidateUtils.checkNotNullAndNotEmpty(System.getProperty("user.home"),
 "No user home"))
-                        .toAbsolutePath()
-                        .normalize();
-
-        private LazyDefaultUserHomeFolderHolder() {
-            throw new UnsupportedOperationException("No instance allowed");
-        }
-    }
-
-    /**
-     * @return The {@link Path} to the currently running user home
-     */
-    @SuppressWarnings("synthetic-access")
-    public static Path getUserHomeFolder() {
-        return LazyDefaultUserHomeFolderHolder.PATH;
-    }
-
     /**
      * @param  prefix The file name prefix - ignored if {@code null}/empty
      * @param  type   The identity type - ignored if {@code null}/empty
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
index 8dc634c..882daa7 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
@@ -42,6 +42,7 @@ import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.NumberUtils;
 import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.io.PathUtils;
 
 /**
  * <P>
@@ -498,7 +499,7 @@ public class PublicKeyEntry implements Serializable, 
KeyTypeIndicator {
     }
 
     private static final class LazyDefaultKeysFolderHolder {
-        private static final Path PATH = 
IdentityUtils.getUserHomeFolder().resolve(STD_KEYFILE_FOLDER_NAME);
+        private static final Path PATH = 
PathUtils.getUserHomeFolder().resolve(STD_KEYFILE_FOLDER_NAME);
 
         private LazyDefaultKeysFolderHolder() {
             throw new UnsupportedOperationException("No instance allowed");
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/io/PathUtils.java 
b/sshd-common/src/main/java/org/apache/sshd/common/util/io/PathUtils.java
index 52fec23..cd9ab9c 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/io/PathUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/io/PathUtils.java
@@ -19,11 +19,14 @@
 
 package org.apache.sshd.common.util.io;
 
+import java.io.File;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Comparator;
 import java.util.Objects;
 
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.functors.UnaryEquator;
 
 /**
@@ -43,6 +46,19 @@ public final class PathUtils {
     public static final UnaryEquator<Path> EQ_CASE_SENSITIVE_FILENAME
             = (p1, p2) -> BY_CASE_SENSITIVE_FILENAME.compare(p1, p2) == 0;
 
+    private static final class LazyDefaultUserHomeFolderHolder {
+        private static final Path PATH
+                = 
Paths.get(ValidateUtils.checkNotNullAndNotEmpty(System.getProperty("user.home"),
 "No user home"))
+                        .toAbsolutePath()
+                        .normalize();
+
+        private LazyDefaultUserHomeFolderHolder() {
+            throw new UnsupportedOperationException("No instance allowed");
+        }
+    }
+
+    public static final char HOME_TILDE_CHAR = '~';
+
     /**
      * Private Constructor
      */
@@ -73,4 +89,61 @@ public final class PathUtils {
         String n2 = Objects.toString(p2.getFileName(), null);
         return GenericUtils.safeCompare(n1, n2, caseSensitive);
     }
+
+    /**
+     * <UL>
+     *      <LI>Replaces <U>leading</U> '~' with user's HOME directory</LI>
+     *      <LI>Replaces any forward slashes with the O/S directory 
separator</LI>
+     * </UL>
+     *
+     * @param path Input path - ignored if {@code null}/empty/blank
+     * @return Adjusted path
+     */
+    public static String normalizePath(String path) {
+        if (GenericUtils.isBlank(path)) {
+            return path;
+        }
+
+        if (path.charAt(0) == HOME_TILDE_CHAR) {
+            Path homeDir = Objects.requireNonNull(getUserHomeFolder(), "No 
user home folder available");
+            if (path.length() > 1) {
+                path = homeDir + path.substring(1);
+            } else {
+                path = homeDir.toString();
+            }
+        }
+
+        return path.replace('/', File.separatorChar);
+    }
+
+    /**
+     * @return The {@link Path} to the currently running user home
+     */
+    @SuppressWarnings("synthetic-access")
+    public static Path getUserHomeFolder() {
+        return LazyDefaultUserHomeFolderHolder.PATH;
+    }
+
+    public static StringBuilder appendUserHome(StringBuilder sb) {
+        return appendUserHome(sb, getUserHomeFolder());
+    }
+
+    public static StringBuilder appendUserHome(StringBuilder sb, Path 
userHome) {
+        return appendUserHome(sb, Objects.requireNonNull(userHome, "No user 
home folder").toString());
+    }
+
+    public static StringBuilder appendUserHome(StringBuilder sb, String 
userHome) {
+        if (GenericUtils.isEmpty(userHome)) {
+            return sb;
+        }
+
+        sb.append(userHome);
+        // strip any ending separator since we add our own
+        int len = sb.length();
+        if (sb.charAt(len - 1) == File.separatorChar) {
+            sb.setLength(len - 1);
+        }
+
+        return sb;
+    }
 }
diff --git 
a/sshd-common/src/test/java/org/apache/sshd/common/util/io/PathUtilsTest.java 
b/sshd-common/src/test/java/org/apache/sshd/common/util/io/PathUtilsTest.java
new file mode 100644
index 0000000..32c0480
--- /dev/null
+++ 
b/sshd-common/src/test/java/org/apache/sshd/common/util/io/PathUtilsTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.util.io;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import org.apache.sshd.util.test.JUnitTestSupport;
+import org.apache.sshd.util.test.NoIoTestCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runners.MethodSorters;
+
+/**
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Category({ NoIoTestCase.class })
+public class PathUtilsTest extends JUnitTestSupport {
+    public PathUtilsTest() {
+        super();
+    }
+
+    @Test
+    public void testNormalizeUserHomeOnlyPath() {
+        Path expected = PathUtils.getUserHomeFolder();
+        String actual = 
PathUtils.normalizePath(Character.toString(PathUtils.HOME_TILDE_CHAR));
+        assertEquals(expected.toString(), actual);
+    }
+
+    @Test
+    public void testNormalizeLeadingUserHomePath() {
+        Path expected = PathUtils.getUserHomeFolder()
+                .resolve(getClass().getSimpleName())
+                .resolve(getCurrentTestName())
+                ;
+        String actual = PathUtils.normalizePath(PathUtils.HOME_TILDE_CHAR
+            + File.separator + getClass().getSimpleName()
+            + File.separator + getCurrentTestName());
+        assertEquals(expected.toString(), actual);
+    }
+
+    @Test
+    public void testNormalizeStandardPath() {
+        String expected = detectTargetFolder().toString();
+        String actual = PathUtils.normalizePath(expected);
+        assertSame(expected, actual);
+    }
+
+    @Test
+    public void testNormalizeForwardSlash() {
+        String expected = detectTargetFolder().toString();
+        String actual = 
PathUtils.normalizePath(expected.replace(File.separatorChar, '/'));
+        if (File.separatorChar == '/') {
+            assertSame(expected, actual);
+        } else {
+            assertEquals(expected, actual);
+        }
+    }
+}
diff --git a/sshd-openpgp/src/main/java/org/apache/sshd/openpgp/PGPUtils.java 
b/sshd-openpgp/src/main/java/org/apache/sshd/openpgp/PGPUtils.java
index d061b6e..9159d79 100644
--- a/sshd-openpgp/src/main/java/org/apache/sshd/openpgp/PGPUtils.java
+++ b/sshd-openpgp/src/main/java/org/apache/sshd/openpgp/PGPUtils.java
@@ -28,10 +28,10 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.sshd.common.PropertyResolverUtils;
-import org.apache.sshd.common.config.keys.IdentityUtils;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.OsUtils;
 import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.io.PathUtils;
 import org.c02e.jpgpj.CompressionAlgorithm;
 import org.c02e.jpgpj.EncryptionAlgorithm;
 import org.c02e.jpgpj.Key;
@@ -161,7 +161,7 @@ public final class PGPUtils {
     }
 
     private static final class LazyDefaultPgpKeysFolderHolder {
-        private static final Path PATH = IdentityUtils.getUserHomeFolder()
+        private static final Path PATH = PathUtils.getUserHomeFolder()
                 .resolve(OsUtils.isUNIX() ? STD_LINUX_PGP_FOLDER_NAME : 
STD_WINDOWS_PGP_FOLDER_NAME);
 
         private LazyDefaultPgpKeysFolderHolder() {

Reply via email to