Compare commits

..

3 Commits

3 changed files with 76 additions and 4 deletions

View File

@ -28,4 +28,16 @@ TODO
## How to use ## How to use
Place a `servers.json` in the Pie Cannon data directory. For GNU/Linux this is `XDG_DATA_HOME` (by default this would be `~/.local/share/piecannon`) (create this directory if it does not exist. For Android this would be the app's "externalFilesDir" (probably something like `Android/data/net.monarchpass.piecannon/files` - the app will tell you when you launch it). See `servers.example.json` for an example of such a file. Whenever you initiate a file upload, Pie Cannon will select one of your defined servers at random and upload the file. Place a `servers.json` in the Pie Cannon data directory. For GNU/Linux this is `XDG_DATA_HOME` (by default this would be `~/.local/share/piecannon`) (create this directory if it does not exist. For Android this would be the app's "externalFilesDir" (probably something like `Android/data/net.monarchpass.piecannon/files` - the app will tell you when you launch it). See `servers.example.json` for an example of such a file. Whenever you initiate a file upload, Pie Cannon will select one of your defined servers at random and upload the file.
For FTP/SFTP servers (the only supported types as of now), the `path` is relative to your home directory and should be where `url` points to. i.e. a file uploaded to `path` should be downloadable at `url`. In the future Pie Cannon should be able to get SSH credentials from your agent so you won't need to put a password in this file. #### Server Types
The `type` field in the server configuration tells Pie Cannon what type of server to use. The default value is `webdav`.
##### WebDAV (`webdav`)
For WebDAV servers, `url` is where the file is uploaded to and served from. `username` and `password`, if given, are HTTP Basic authentication credentials.
For setting this up with nginx, see [ngx_http_dav_module](https://nginx.org/en/docs/http/ngx_http_dav_module.html) documentation and also [HTTP Basic Authentication](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/) guide.
##### FTP/SFTP (`ftp`/`sftp`)
For FTP/SFTP servers, the `path` is relative to your home directory and should be where `url` points to. i.e. a file uploaded to `path` should be downloadable at `url`. In the future Pie Cannon should be able to get SSH credentials from your agent so you won't need to put a password in this file.
##### GoFile.io (`gofile`)
No configuration options are supported for this currently, however in the future there may be support for using a token. Note that it's not possible to get a direct download link for this service without visiting a page first, so Pie Cannon returns the URL for that page instead of a direct download link.

View File

@ -0,0 +1,37 @@
package net.monarchpass.piecannon.impl;
import java.io.IOException;
import java.net.URI;
import com.google.common.io.ByteSource;
import jodd.http.HttpRequest;
import lombok.Data;
import net.monarchpass.piecannon.Server;
@Data
public class WebDavServer implements Server {
private final String label;
private final URI uri;
private final String username;
private final String password;
@Override
public URI upload (String name, ByteSource source) {
try {
final URI target = URI.create(uri.toString() + "/" + name.replace(" ", "%20"));
final HttpRequest request = HttpRequest.put(target.toString())
.body(source.read(), "");
if (username != null && password != null) {
request.basicAuthentication(username, password);
}
request.send();
return target;
} catch (final IOException exception) {
throw new RuntimeException(exception);
}
}
}

View File

@ -11,11 +11,17 @@ import net.monarchpass.piecannon.Server;
import net.monarchpass.piecannon.impl.FtpServer; import net.monarchpass.piecannon.impl.FtpServer;
import net.monarchpass.piecannon.impl.GoFileServer; import net.monarchpass.piecannon.impl.GoFileServer;
import net.monarchpass.piecannon.impl.SftpServer; import net.monarchpass.piecannon.impl.SftpServer;
import net.monarchpass.piecannon.impl.WebDavServer;
public class ServerFactory implements Function<JsonObject, Server> { public class ServerFactory implements Function<JsonObject, Server> {
public Server apply (final JsonObject object) { public Server apply (final JsonObject object) {
final String type = object.getAsJsonPrimitive("type").getAsString(); final String type = Optional.ofNullable(object.getAsJsonPrimitive("type"))
if (type.equalsIgnoreCase("gofile")) { .map(JsonPrimitive::getAsString)
.orElse("webdav");
if (type.equals("webdav")) {
return makeWebDavServer(object);
} else if (type.equalsIgnoreCase("gofile")) {
return new GoFileServer(Optional.ofNullable(object.getAsJsonPrimitive("label")).map(JsonPrimitive::getAsString).orElse("GoFile")); return new GoFileServer(Optional.ofNullable(object.getAsJsonPrimitive("label")).map(JsonPrimitive::getAsString).orElse("GoFile"));
} else if (type.equalsIgnoreCase("ftp")) { } else if (type.equalsIgnoreCase("ftp")) {
return makeFtpServer(object); return makeFtpServer(object);
@ -23,9 +29,26 @@ public class ServerFactory implements Function<JsonObject, Server> {
return makeSftpServer(object); return makeSftpServer(object);
} }
throw new IllegalArgumentException("Invalid server type: " + type); throw new IllegalArgumentException("Invalid server type: " + type);
} }
private Server makeWebDavServer (final JsonObject object) {
final String label = Optional.ofNullable(object.getAsJsonPrimitive("label"))
.map(JsonPrimitive::getAsString)
.orElse("WebDav");
final String username = Optional.ofNullable(object.getAsJsonPrimitive("username"))
.map(JsonPrimitive::getAsString)
.orElse(null);
final String password = Optional.ofNullable(object.getAsJsonPrimitive("password"))
.map(JsonPrimitive::getAsString)
.orElse(null);
final String url = object.getAsJsonPrimitive("url").getAsString();
return new WebDavServer(
label, URI.create(url), username, password
);
}
private Server makeSftpServer (final JsonObject object) { private Server makeSftpServer (final JsonObject object) {
final String host = object.getAsJsonPrimitive("host").getAsString(); final String host = object.getAsJsonPrimitive("host").getAsString();
final String label = object.has("label") ? object.getAsJsonPrimitive("label").getAsString() : host; final String label = object.has("label") ? object.getAsJsonPrimitive("label").getAsString() : host;