Skip to content

Commit 4f2226a

Browse files
First runnable version
1 parent d9e1e1f commit 4f2226a

4 files changed

Lines changed: 304 additions & 0 deletions

File tree

pom.xml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>org.cryptomator</groupId>
4+
<artifactId>cli</artifactId>
5+
<version>0.1.0-SNAPSHOT</version>
6+
<name>Cryptomator CLI</name>
7+
<description>Command line program to access encrypted files via WebDAV.</description>
8+
<url>https://github.com/cryptomator/cli</url>
9+
10+
<properties>
11+
<java.version>1.8</java.version>
12+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13+
</properties>
14+
15+
<licenses>
16+
<license>
17+
<name>GNU Affero General Public License (AGPL) version 3.0</name>
18+
<url>https://www.gnu.org/licenses/agpl.txt</url>
19+
<distribution>repo</distribution>
20+
</license>
21+
</licenses>
22+
23+
<developers>
24+
<developer>
25+
<name>Sebastian Stenzel</name>
26+
<email>sebastian.stenzel@gmail.com</email>
27+
<timezone>+1</timezone>
28+
<organization>cryptomator.org</organization>
29+
<organizationUrl>http://cryptomator.org</organizationUrl>
30+
</developer>
31+
</developers>
32+
33+
<dependencies>
34+
<dependency>
35+
<groupId>org.cryptomator</groupId>
36+
<artifactId>cryptofs</artifactId>
37+
<version>0.1.5</version>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.cryptomator</groupId>
41+
<artifactId>webdav-nio-adapter</artifactId>
42+
<version>0.1.0</version>
43+
</dependency>
44+
45+
<!-- Commons -->
46+
<dependency>
47+
<groupId>commons-cli</groupId>
48+
<artifactId>commons-cli</artifactId>
49+
<version>1.3.1</version>
50+
</dependency>
51+
52+
<!-- Logging -->
53+
<dependency>
54+
<groupId>org.apache.logging.log4j</groupId>
55+
<artifactId>log4j-slf4j-impl</artifactId>
56+
<version>2.7</version>
57+
</dependency>
58+
<dependency>
59+
<groupId>org.apache.logging.log4j</groupId>
60+
<artifactId>log4j-core</artifactId>
61+
<version>2.7</version>
62+
</dependency>
63+
</dependencies>
64+
65+
<build>
66+
<plugins>
67+
<plugin>
68+
<groupId>org.apache.maven.plugins</groupId>
69+
<artifactId>maven-compiler-plugin</artifactId>
70+
<version>3.5.1</version>
71+
<configuration>
72+
<source>${java.version}</source>
73+
<target>${java.version}</target>
74+
<showWarnings>true</showWarnings>
75+
</configuration>
76+
</plugin>
77+
78+
<plugin>
79+
<artifactId>maven-assembly-plugin</artifactId>
80+
<executions>
81+
<execution>
82+
<id>make-assembly</id>
83+
<phase>package</phase>
84+
<goals>
85+
<goal>single</goal>
86+
</goals>
87+
</execution>
88+
</executions>
89+
<configuration>
90+
<finalName>cryptomator-cli-${project.version}</finalName>
91+
<descriptorRefs>
92+
<descriptorRef>jar-with-dependencies</descriptorRef>
93+
</descriptorRefs>
94+
<appendAssemblyId>false</appendAssemblyId>
95+
<archive>
96+
<manifestEntries>
97+
<Main-Class>org.cryptomator.cli.CryptomatorCli</Main-Class>
98+
<Implementation-Version>${project.version}</Implementation-Version>
99+
</manifestEntries>
100+
</archive>
101+
</configuration>
102+
</plugin>
103+
</plugins>
104+
</build>
105+
</project>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2016 Sebastian Stenzel and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the accompanying LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Sebastian Stenzel - initial API and implementation
8+
*******************************************************************************/
9+
package org.cryptomator.cli;
10+
11+
import java.util.Properties;
12+
import java.util.Set;
13+
import java.util.stream.Collectors;
14+
15+
import org.apache.commons.cli.CommandLine;
16+
import org.apache.commons.cli.DefaultParser;
17+
import org.apache.commons.cli.HelpFormatter;
18+
import org.apache.commons.cli.Option;
19+
import org.apache.commons.cli.Options;
20+
import org.apache.commons.cli.ParseException;
21+
22+
/**
23+
* Parses program arguments. Does not validate them.
24+
*/
25+
public class Args {
26+
27+
private static final String USAGE = "java -jar cryptomator-cli.jar" //
28+
+ " --vault mySecretVault=/path/to/vault --password mySecretVault=FooBar3000" //
29+
+ " --vault myOtherVault=/path/to/other/vault --password myOtherVault=BarFoo4000";
30+
private static final Options OPTIONS = new Options();
31+
static {
32+
OPTIONS.addOption(Option.builder() //
33+
.longOpt("port") //
34+
.argName("WebDAV port") //
35+
.desc("TCP port, the WebDAV server should listen on.") //
36+
.hasArg() //
37+
.build());
38+
OPTIONS.addOption(Option.builder() //
39+
.longOpt("vault") //
40+
.argName("Path of a vault") //
41+
.desc("Format must be vaultName=/path/to/vault") //
42+
.valueSeparator() //
43+
.hasArgs() //
44+
.build());
45+
OPTIONS.addOption(Option.builder() //
46+
.longOpt("password") //
47+
.argName("Password of a vault") //
48+
.desc("Format must be vaultName=password") //
49+
.valueSeparator() //
50+
.hasArgs() //
51+
.build());
52+
}
53+
54+
private final int port;
55+
private final Properties vaultPaths;
56+
private final Properties vaultPasswords;
57+
58+
public Args(CommandLine commandLine) throws ParseException {
59+
this.port = Integer.parseInt(commandLine.getOptionValue("port", "0"));
60+
this.vaultPaths = commandLine.getOptionProperties("vault");
61+
this.vaultPasswords = commandLine.getOptionProperties("password");
62+
}
63+
64+
public int getPort() {
65+
return port;
66+
}
67+
68+
public Set<String> getVaultNames() {
69+
return vaultPaths.keySet().stream().filter(vaultPasswords::containsKey).map(String.class::cast).collect(Collectors.toSet());
70+
}
71+
72+
public String getVaultPath(String vaultName) {
73+
return vaultPaths.getProperty(vaultName);
74+
}
75+
76+
public String getVaultPassword(String vaultName) {
77+
return vaultPasswords.getProperty(vaultName);
78+
}
79+
80+
public static Args parse(String[] arguments) throws ParseException {
81+
CommandLine commandLine = new DefaultParser().parse(OPTIONS, arguments);
82+
return new Args(commandLine);
83+
}
84+
85+
public static void printUsage() {
86+
new HelpFormatter().printHelp(USAGE, OPTIONS);
87+
}
88+
89+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2016 Sebastian Stenzel and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the accompanying LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Sebastian Stenzel - initial API and implementation
8+
*******************************************************************************/
9+
package org.cryptomator.cli;
10+
11+
import java.io.IOException;
12+
import java.nio.file.Files;
13+
import java.nio.file.Path;
14+
import java.nio.file.Paths;
15+
16+
import org.apache.commons.cli.ParseException;
17+
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
18+
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
19+
import org.cryptomator.frontend.webdav.WebDavServer;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
23+
public class CryptomatorCli {
24+
25+
private static final Logger LOG = LoggerFactory.getLogger(CryptomatorCli.class);
26+
27+
public static void main(String[] rawArgs) throws IOException {
28+
try {
29+
Args args = Args.parse(rawArgs);
30+
validate(args);
31+
startup(args);
32+
} catch (ParseException e) {
33+
LOG.error("Invalid or missing arguments", e);
34+
Args.printUsage();
35+
} catch (IllegalArgumentException e) {
36+
LOG.error(e.getMessage());
37+
Args.printUsage();
38+
}
39+
}
40+
41+
private static void validate(Args args) throws IllegalArgumentException {
42+
if (args.getPort() < 0 || args.getPort() > 65536) {
43+
throw new IllegalArgumentException("Invalid WebDAV Port.");
44+
}
45+
46+
if (args.getVaultNames().size() == 0) {
47+
throw new IllegalArgumentException("No vault specified.");
48+
}
49+
50+
for (String vaultName : args.getVaultNames()) {
51+
Path vaultPath = Paths.get(args.getVaultPath(vaultName));
52+
if (!Files.isDirectory(vaultPath)) {
53+
throw new IllegalArgumentException("Not a directory: " + vaultPath);
54+
}
55+
}
56+
}
57+
58+
private static void startup(Args args) throws IOException {
59+
WebDavServer server = WebDavServer.create(args.getPort());
60+
server.start();
61+
62+
for (String vaultName : args.getVaultNames()) {
63+
Path vaultPath = Paths.get(args.getVaultPath(vaultName));
64+
LOG.info("Unlocking vault \"{}\" located at {}", vaultName, vaultPath);
65+
String vaultPassword = args.getVaultPassword(vaultName);
66+
CryptoFileSystemProperties properties = CryptoFileSystemProperties.cryptoFileSystemProperties().withPassphrase(vaultPassword).build();
67+
Path vaultRoot = CryptoFileSystemProvider.newFileSystem(vaultPath, properties).getPath("/");
68+
server.startWebDavServlet(vaultRoot, vaultName);
69+
}
70+
71+
waitForShutdown(() -> {
72+
LOG.info("Shutting down...");
73+
try {
74+
server.stop();
75+
LOG.info("Shutdown successful.");
76+
} catch (Throwable e) {
77+
LOG.error("Error during shutdown", e);
78+
}
79+
});
80+
}
81+
82+
private static void waitForShutdown(Runnable runnable) {
83+
Runtime.getRuntime().addShutdownHook(new Thread(runnable));
84+
LOG.info("Server started. Press Ctrl+C to terminate.");
85+
}
86+
87+
}

src/main/resources/log4j2.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<Configuration status="WARN" packages="org.cryptomator">
3+
4+
<Appenders>
5+
<Console name="StdOut" target="SYSTEM_OUT">
6+
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
7+
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT" />
8+
</Console>
9+
<Console name="StdErr" target="SYSTEM_ERR">
10+
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
11+
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY" />
12+
</Console>
13+
</Appenders>
14+
15+
<Loggers>
16+
<!-- defaults: -->
17+
<Root level="INFO">
18+
<AppenderRef ref="StdOut" />
19+
<AppenderRef ref="StdErr" />
20+
</Root>
21+
</Loggers>
22+
23+
</Configuration>

0 commit comments

Comments
 (0)