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
The following commit(s) were added to refs/heads/master by this push:
new a3648c7 [SSHD-1030] Added a NoneFileSystemFactory implementation
a3648c7 is described below
commit a3648c7e4f310f95ab7a47620aa047b4e47873ef
Author: Lyor Goldstein <[email protected]>
AuthorDate: Sun Jul 5 19:49:00 2020 +0300
[SSHD-1030] Added a NoneFileSystemFactory implementation
---
CHANGES.md | 1 +
docs/commands.md | 3 +-
.../sshd/common/file/nonefs/NoneFileSystem.java | 102 +++++++++++++
.../common/file/nonefs/NoneFileSystemFactory.java | 51 +++++++
.../common/file/nonefs/NoneFileSystemProvider.java | 157 +++++++++++++++++++++
.../java/org/apache/sshd/common/util/OsUtils.java | 4 +-
.../file/nonefs/NoneFileSystemFactoryTest.java | 51 +++++++
7 files changed, 367 insertions(+), 2 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 929dde1..6df3175 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -19,6 +19,7 @@
## Minor code helpers
* [SSHD-1040](https://issues.apache.org/jira/browse/SSHD-1040) Make server key
available after KEX completed.
+* [SSHD-1030](https://issues.apache.org/jira/browse/SSHD-1030) Added a
NoneFileSystemFactory implementation
## Behavioral changes and enhancements
diff --git a/docs/commands.md b/docs/commands.md
index 2d0f6f9..50bfaf4 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -24,7 +24,8 @@ file system where the logged-in user can access only the
files under the specifi
The usage of a `FileSystemFactory` is not limited though to the server only -
the `ScpClient` implementation also uses
it in order to retrieve the *local* path for upload/download-ing
files/folders. This means that the client side can also
-be tailored to present different views for different clients
+be tailored to present different views for different clients. A special
"empty" `NoneFileSystemFactory` is provided in case
+no files are expected to be accessed by the server.
## `ExecutorService`-s
diff --git
a/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystem.java
b/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystem.java
new file mode 100644
index 0000000..407f7eb
--- /dev/null
+++
b/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystem.java
@@ -0,0 +1,102 @@
+/*
+ * 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.file.nonefs;
+
+import java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.WatchService;
+import java.nio.file.attribute.UserPrincipalLookupService;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a>
+ */
+public class NoneFileSystem extends FileSystem {
+ public static final NoneFileSystem INSTANCE = new NoneFileSystem();
+
+ public NoneFileSystem() {
+ super();
+ }
+
+ @Override
+ public FileSystemProvider provider() {
+ return NoneFileSystemProvider.INSTANCE;
+ }
+
+ @Override
+ public void close() throws IOException {
+ // ignored
+ }
+
+ @Override
+ public boolean isOpen() {
+ return true;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ @Override
+ public String getSeparator() {
+ return "/";
+ }
+
+ @Override
+ public Iterable<Path> getRootDirectories() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Iterable<FileStore> getFileStores() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Set<String> supportedFileAttributeViews() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Path getPath(String first, String... more) {
+ throw new UnsupportedOperationException("No paths available");
+ }
+
+ @Override
+ public PathMatcher getPathMatcher(String syntaxAndPattern) {
+ return p -> false;
+ }
+
+ @Override
+ public UserPrincipalLookupService getUserPrincipalLookupService() {
+ throw new UnsupportedOperationException("UserPrincipalLookupService
N/A");
+ }
+
+ @Override
+ public WatchService newWatchService() throws IOException {
+ throw new UnsupportedOperationException("WatchService N/A");
+ }
+}
diff --git
a/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystemFactory.java
b/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystemFactory.java
new file mode 100644
index 0000000..4775c43
--- /dev/null
+++
b/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystemFactory.java
@@ -0,0 +1,51 @@
+/*
+ * 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.file.nonefs;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+
+import org.apache.sshd.common.file.FileSystemFactory;
+import org.apache.sshd.common.session.SessionContext;
+
+/**
+ * Provides an "empty" file system that has no files/folders and
throws exceptions on any attempt to access a
+ * file/folder on it
+ *
+ * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a>
+ */
+public class NoneFileSystemFactory implements FileSystemFactory {
+ public static final NoneFileSystemFactory INSTANCE = new
NoneFileSystemFactory();
+
+ public NoneFileSystemFactory() {
+ super();
+ }
+
+ @Override
+ public Path getUserHomeDir(SessionContext session) throws IOException {
+ return null;
+ }
+
+ @Override
+ public FileSystem createFileSystem(SessionContext session) throws
IOException {
+ return NoneFileSystem.INSTANCE;
+ }
+}
diff --git
a/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystemProvider.java
b/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystemProvider.java
new file mode 100644
index 0000000..486af88
--- /dev/null
+++
b/sshd-common/src/main/java/org/apache/sshd/common/file/nonefs/NoneFileSystemProvider.java
@@ -0,0 +1,157 @@
+/*
+ * 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.file.nonefs;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.AccessMode;
+import java.nio.file.CopyOption;
+import java.nio.file.DirectoryStream;
+import java.nio.file.DirectoryStream.Filter;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystem;
+import java.nio.file.LinkOption;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Provides an "empty" {@link FileSystemProvider} that has no files
of any type.
+ *
+ * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a>
+ */
+public class NoneFileSystemProvider extends FileSystemProvider {
+ public static final String SCHEME = "none";
+
+ public static final NoneFileSystemProvider INSTANCE = new
NoneFileSystemProvider();
+
+ public NoneFileSystemProvider() {
+ super();
+ }
+
+ @Override
+ public String getScheme() {
+ return SCHEME;
+ }
+
+ @Override
+ public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws
IOException {
+ return getFileSystem(uri);
+ }
+
+ @Override
+ public FileSystem getFileSystem(URI uri) {
+ if (!Objects.equals(getScheme(), uri.getScheme())) {
+ throw new IllegalArgumentException("Mismatched FS scheme");
+ }
+
+ return NoneFileSystem.INSTANCE;
+ }
+
+ @Override
+ public Path getPath(URI uri) {
+ if (!Objects.equals(getScheme(), uri.getScheme())) {
+ throw new IllegalArgumentException("Mismatched FS scheme");
+ }
+
+ throw new UnsupportedOperationException("No paths available");
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path path, Set<? extends
OpenOption> options, FileAttribute<?>... attrs)
+ throws IOException {
+ throw new NoSuchFileException(path.toString());
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Path dir, Filter<? super
Path> filter) throws IOException {
+ throw new NoSuchFileException(dir.toString());
+ }
+
+ @Override
+ public void createDirectory(Path dir, FileAttribute<?>... attrs) throws
IOException {
+ throw new NoSuchFileException(dir.toString());
+ }
+
+ @Override
+ public void delete(Path path) throws IOException {
+ throw new NoSuchFileException(path.toString());
+ }
+
+ @Override
+ public void copy(Path source, Path target, CopyOption... options) throws
IOException {
+ throw new NoSuchFileException(source.toString(), target.toString(),
"N/A");
+
+ }
+
+ @Override
+ public void move(Path source, Path target, CopyOption... options) throws
IOException {
+ throw new NoSuchFileException(source.toString(), target.toString(),
"N/A");
+ }
+
+ @Override
+ public boolean isSameFile(Path path1, Path path2) throws IOException {
+ throw new NoSuchFileException(path1.toString(), path2.toString(),
"N/A");
+ }
+
+ @Override
+ public boolean isHidden(Path path) throws IOException {
+ throw new NoSuchFileException(path.toString());
+ }
+
+ @Override
+ public FileStore getFileStore(Path path) throws IOException {
+ throw new NoSuchFileException(path.toString());
+ }
+
+ @Override
+ public void checkAccess(Path path, AccessMode... modes) throws IOException
{
+ throw new NoSuchFileException(path.toString());
+ }
+
+ @Override
+ public <V extends FileAttributeView> V getFileAttributeView(Path path,
Class<V> type, LinkOption... options) {
+ return null;
+ }
+
+ @Override
+ public <A extends BasicFileAttributes> A readAttributes(Path path,
Class<A> type, LinkOption... options)
+ throws IOException {
+ throw new NoSuchFileException(path.toString());
+ }
+
+ @Override
+ public Map<String, Object> readAttributes(Path path, String attributes,
LinkOption... options) throws IOException {
+ throw new NoSuchFileException(path.toString());
+ }
+
+ @Override
+ public void setAttribute(Path path, String attribute, Object value,
LinkOption... options) throws IOException {
+ throw new NoSuchFileException(path.toString());
+ }
+}
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/OsUtils.java
b/sshd-common/src/main/java/org/apache/sshd/common/util/OsUtils.java
index 4f98d7d..54ca86b 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/OsUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/OsUtils.java
@@ -104,7 +104,7 @@ public final class OsUtils {
}
/**
- * @return The O/S type string value (lowercase)
+ * @return The resolved O/S type string if not already set (lowercase)
*/
private static String getOS() {
String typeValue;
@@ -113,10 +113,12 @@ public final class OsUtils {
if (typeValue != null) { // is it the 1st time
return typeValue;
}
+
String value = System.getProperty(OS_TYPE_OVERRIDE_PROP,
System.getProperty("os.name"));
typeValue = GenericUtils.trimToEmpty(value).toLowerCase();
OS_TYPE_HOLDER.set(typeValue);
}
+
return typeValue;
}
diff --git
a/sshd-common/src/test/java/org/apache/sshd/common/file/nonefs/NoneFileSystemFactoryTest.java
b/sshd-common/src/test/java/org/apache/sshd/common/file/nonefs/NoneFileSystemFactoryTest.java
new file mode 100644
index 0000000..854de5a
--- /dev/null
+++
b/sshd-common/src/test/java/org/apache/sshd/common/file/nonefs/NoneFileSystemFactoryTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.file.nonefs;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.spi.FileSystemProvider;
+
+import org.apache.sshd.util.test.JUnitTestSupport;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+/**
+ * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class NoneFileSystemFactoryTest extends JUnitTestSupport {
+ public NoneFileSystemFactoryTest() {
+ super();
+ }
+
+ @Test
+ public void testFileSystemCreation() throws IOException {
+ FileSystem fs = NoneFileSystemFactory.INSTANCE.createFileSystem(null);
+ FileSystemProvider provider = fs.provider();
+ assertEquals("Mismatched provider scheme",
NoneFileSystemProvider.SCHEME, provider.getScheme());
+ }
+
+ @Test
+ public void testUserHomeDirectory() throws IOException {
+ assertNull(NoneFileSystemFactory.INSTANCE.getUserHomeDir(null));
+ }
+}