Allow the bytebin url to be configured

This commit is contained in:
Luck 2019-01-12 12:02:16 +00:00
parent 4b97c9419e
commit d3ae3324fa
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
16 changed files with 201 additions and 136 deletions

View File

@ -40,7 +40,6 @@ import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.web.StandardPastebin;
import me.lucko.luckperms.common.web.WebEditor;
import net.kyori.text.Component;
@ -70,7 +69,7 @@ public class HolderEditor<T extends PermissionHolder> extends SubCommand<T> {
JsonObject payload = WebEditor.formPayload(Collections.singletonList(holder), sender, label, plugin);
// upload the payload data to gist
String pasteId = StandardPastebin.BYTEBIN.postJson(payload, true).id();
String pasteId = plugin.getBytebin().postJson(payload, true).id();
if (pasteId == null) {
Message.EDITOR_UPLOAD_FAILURE.send(sender);
return CommandResult.STATE_ERROR;

View File

@ -70,7 +70,7 @@ public class ApplyEditsCommand extends SingleCommand {
return CommandResult.INVALID_ARGS;
}
JsonObject data = WebEditor.getDataFromGist(code);
JsonObject data = WebEditor.readDataFromBytebin(plugin.getBytebin(), code);
if (data == null) {
Message.APPLY_EDITS_UNABLE_TO_READ.send(sender, code);
return CommandResult.FAILURE;

View File

@ -51,8 +51,7 @@ import me.lucko.luckperms.common.util.gson.GsonProvider;
import me.lucko.luckperms.common.util.gson.JArray;
import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.web.Pastebin;
import me.lucko.luckperms.common.web.StandardPastebin;
import me.lucko.luckperms.common.web.Hastebin;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
@ -91,12 +90,12 @@ public class DebugCommand extends SingleCommand {
builder.accept("context.json", getContextData(plugin));
builder.accept("players.json", getPlayersData(plugin));
Pastebin.Paste paste = StandardPastebin.HASTEBIN.postPlain(sb.toString());
String pasteUrl = Hastebin.INSTANCE.postPlain(sb.toString()).url();
Message.DEBUG_URL.send(sender);
Component message = TextComponent.builder(paste.url()).color(TextColor.AQUA)
.clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, String.valueOf(paste.url())))
Component message = TextComponent.builder(pasteUrl).color(TextColor.AQUA)
.clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, pasteUrl))
.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to open the debugging data.").color(TextColor.GRAY)))
.build();

View File

@ -40,7 +40,6 @@ import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.common.web.StandardPastebin;
import me.lucko.luckperms.common.web.WebEditor;
import net.kyori.text.Component;
@ -107,7 +106,7 @@ public class EditorCommand extends SingleCommand {
JsonObject payload = WebEditor.formPayload(holders, sender, label, plugin);
// upload the payload data to gist
String pasteId = StandardPastebin.BYTEBIN.postJson(payload, true).id();
String pasteId = plugin.getBytebin().postJson(payload, true).id();
if (pasteId == null) {
Message.EDITOR_UPLOAD_FAILURE.send(sender);
return CommandResult.STATE_ERROR;

View File

@ -91,7 +91,7 @@ public class TreeCommand extends SingleCommand {
Message.TREE_UPLOAD_START.send(sender);
PermissionCache permissionData = user == null ? null : user.getCachedData().getPermissionData(plugin.getContextForUser(user).orElse(plugin.getContextManager().getStaticContexts()));
String id = view.uploadPasteData(sender, user, permissionData);
String id = view.uploadPasteData(plugin.getBytebin(), sender, user, permissionData);
String url = plugin.getConfiguration().get(ConfigKeys.TREE_VIEWER_URL_PATTERN) + "#" + id;
Message.TREE_URL.send(sender);

View File

@ -112,7 +112,7 @@ public class VerboseCommand extends SingleCommand {
Message.VERBOSE_OFF.send(sender);
} else {
Message.VERBOSE_UPLOAD_START.send(sender);
String id = listener.uploadPasteData();
String id = listener.uploadPasteData(plugin.getBytebin());
String url = plugin.getConfiguration().get(ConfigKeys.VERBOSE_VIEWER_URL_PATTERN) + "#" + id;
Message.VERBOSE_RESULTS_URL.send(sender);

View File

@ -517,6 +517,11 @@ public final class ConfigKeys {
*/
public static final ConfigKey<String> REDIS_PASSWORD = enduringKey(stringKey("redis.password", ""));
/**
* The URL of the bytebin instance used to upload data
*/
public static final ConfigKey<String> BYTEBIN_URL = stringKey("bytebin-url", "https://bytebin.lucko.me/");
/**
* The URL of the web editor
*/

View File

@ -53,6 +53,7 @@ import me.lucko.luckperms.common.storage.implementation.file.FileWatcher;
import me.lucko.luckperms.common.tasks.SyncTask;
import me.lucko.luckperms.common.treeview.PermissionRegistry;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import me.lucko.luckperms.common.web.Bytebin;
import java.io.IOException;
import java.util.Optional;
@ -70,6 +71,7 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
private LogDispatcher logDispatcher;
private LuckPermsConfiguration configuration;
private LocaleManager localeManager;
private Bytebin bytebin;
private FileWatcher fileWatcher = null;
private Storage storage;
private InternalMessagingService messagingService = null;
@ -108,6 +110,9 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
this.localeManager = new LocaleManager();
this.localeManager.tryLoad(this, getBootstrap().getConfigDirectory().resolve("lang.yml"));
// setup a bytebin instance
this.bytebin = new Bytebin(getConfiguration().get(ConfigKeys.BYTEBIN_URL));
// now the configuration is loaded, we can create a storage factory and load initial dependencies
StorageFactory storageFactory = new StorageFactory(this);
Set<StorageType> storageTypes = storageFactory.getRequiredTypes(StorageType.H2);
@ -274,6 +279,11 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
return this.localeManager;
}
@Override
public Bytebin getBytebin() {
return this.bytebin;
}
@Override
public Optional<FileWatcher> getFileWatcher() {
return Optional.ofNullable(this.fileWatcher);

View File

@ -53,6 +53,7 @@ import me.lucko.luckperms.common.storage.implementation.file.FileWatcher;
import me.lucko.luckperms.common.tasks.SyncTask;
import me.lucko.luckperms.common.treeview.PermissionRegistry;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import me.lucko.luckperms.common.web.Bytebin;
import java.util.Collections;
import java.util.List;
@ -222,6 +223,13 @@ public interface LuckPermsPlugin {
*/
Optional<FileWatcher> getFileWatcher();
/**
* Gets the bytebin instance in use by platform.
*
* @return the bytebin instance
*/
Bytebin getBytebin();
/**
* Gets a calculated context instance for the user using the rules of the platform.
*

View File

@ -33,7 +33,7 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.web.StandardPastebin;
import me.lucko.luckperms.common.web.Bytebin;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -116,12 +116,13 @@ public class TreeView {
/**
* Uploads the data contained in this TreeView and returns the id.
*
* @param bytebin the bytebin instance to upload to
* @param sender the sender
* @param user the reference user, or null
* @param checker the permission data instance to check against, or null
* @return the id, or null
*/
public String uploadPasteData(Sender sender, User user, PermissionCache checker) {
public String uploadPasteData(Bytebin bytebin, Sender sender, User user, PermissionCache checker) {
// only paste if there is actually data here
if (!hasData()) {
throw new IllegalStateException();
@ -168,7 +169,7 @@ public class TreeView {
)
.toJson();
return StandardPastebin.BYTEBIN.postJson(payload, true).id();
return bytebin.postJson(payload, true).id();
}
}

View File

@ -40,7 +40,7 @@ import me.lucko.luckperms.common.util.gson.JObject;
import me.lucko.luckperms.common.verbose.event.MetaCheckEvent;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.common.verbose.event.VerboseEvent;
import me.lucko.luckperms.common.web.StandardPastebin;
import me.lucko.luckperms.common.web.Bytebin;
import net.kyori.text.TextComponent;
import net.kyori.text.event.HoverEvent;
@ -229,10 +229,10 @@ public class VerboseListener {
/**
* Uploads the captured data in this listener to a paste and returns the url
*
* @param bytebin the bytebin instance to upload with
* @return the url
*/
public String uploadPasteData() {
public String uploadPasteData(Bytebin bytebin) {
// retrieve variables
long now = System.currentTimeMillis();
String startDate = DATE_FORMAT.format(new Date(this.startTime));
@ -275,7 +275,7 @@ public class VerboseListener {
.add("data", data)
.toJson();
return StandardPastebin.BYTEBIN.postJson(payload, true).id();
return bytebin.postJson(payload, true).id();
}
private static String getTristateColor(Tristate tristate) {

View File

@ -26,7 +26,6 @@
package me.lucko.luckperms.common.web;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.util.gson.GsonProvider;
@ -47,59 +46,47 @@ import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPOutputStream;
public enum StandardPastebin implements Pastebin {
BYTEBIN {
public static final String URL = "https://bytebin.lucko.me/";
private static final String POST_URL = URL + "post";
@Override
public String getPostUrl() {
return POST_URL;
}
@Override
protected String parseIdFromResult(BufferedReader reader) {
JsonObject object = GsonProvider.prettyPrinting().fromJson(reader, JsonObject.class);
return object.get("key").getAsString();
}
@Override
public String getRawUrl(String id) {
return URL + id;
}
},
HASTEBIN {
private static final String URL = "https://hastebin.com/";
private static final String RAW_URL = URL + "raw/";
private static final String POST_URL = URL + "documents";
@Override
public String getPostUrl() {
return POST_URL;
}
@Override
protected String parseIdFromResult(BufferedReader reader) {
JsonObject object = GsonProvider.prettyPrinting().fromJson(reader, JsonObject.class);
return object.get("key").getAsString();
}
@Override
public String getRawUrl(String id) {
return RAW_URL + id;
}
};
/**
* Represents a pastebin service
*/
public abstract class AbstractPastebin {
private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
private static final MediaType PLAIN_TYPE = MediaType.parse("text/plain; charset=utf-8");
/**
* Gets the URL that post requests should be made to.
*
* @return the post URL
*/
protected abstract String getPostUrl();
protected abstract String parseIdFromResult(BufferedReader reader);
@Override
public Pastebin.Paste postJson(JsonElement content, boolean compress) {
/**
* Gets the id of the resultant post from the response of an upload request
*
* @param response the response
* @param responseBody the response body
* @param responseBodyReader the response body content
* @return
*/
protected abstract String parseIdFromResult(Response response, ResponseBody responseBody, BufferedReader responseBodyReader);
/**
* Gets the raw url of a paste's data from an id
*
* @param id the id
* @return a url
*/
public abstract String getPasteUrl(String id);
/**
* Posts the given json to the pastebin
*
* @param content the json element to post
* @param compress whether to compress and post the data using gzip
* @return a paste
*/
public Paste postJson(JsonElement content, boolean compress) {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
OutputStream outputStream;
@ -122,12 +109,17 @@ public enum StandardPastebin implements Pastebin {
return post(RequestBody.create(JSON_TYPE, byteOut.toByteArray()), compress);
}
@Override
public Pastebin.Paste postPlain(String content) {
/**
* Posts "plain" content to the pastebin
*
* @param content the content
* @return a paste
*/
public Paste postPlain(String content) {
return post(RequestBody.create(PLAIN_TYPE, content), false);
}
private Pastebin.Paste post(RequestBody body, boolean compressed) {
private Paste post(RequestBody body, boolean compressed) {
Request.Builder requestBuilder = new Request.Builder()
.url(getPostUrl())
.post(body);
@ -145,8 +137,8 @@ public enum StandardPastebin implements Pastebin {
try (InputStream inputStream = responseBody.byteStream()) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
String id = parseIdFromResult(reader);
String url = getRawUrl(id);
String id = parseIdFromResult(response, responseBody, reader);
String url = getPasteUrl(id);
return new Paste(url, id);
}
}
@ -156,23 +148,35 @@ public enum StandardPastebin implements Pastebin {
}
}
private static final class Paste implements Pastebin.Paste {
/**
* Encapsulates the properties of a specific "paste" entry
*/
public static final class Paste {
private final String url;
private final String id;
private Paste(String url, String id) {
Paste(String url, String id) {
this.url = url;
this.id = id;
}
@Override
/**
* Gets the url of the paste
*
* @return the url
*/
public String url() {
return this.url;
}
@Override
/**
* Gets the unique id of the paste
*
* @return the id
*/
public String id() {
return this.id;
}
}
}

View File

@ -25,56 +25,40 @@
package me.lucko.luckperms.common.web;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
/**
* Represents a pastebin service
*/
public interface Pastebin {
import me.lucko.luckperms.common.util.gson.GsonProvider;
/**
* Posts the given json to the pastebin
*
* @param element the json element to post
* @param compress whether to compress and post the data using gzip
* @return a paste
*/
Paste postJson(JsonElement element, boolean compress);
import okhttp3.Response;
import okhttp3.ResponseBody;
/**
* Posts "plain" content to the pastebin
*
* @param content the content
* @return a paste
*/
Paste postPlain(String content);
import java.io.BufferedReader;
/**
* Gets the raw url of a paste's data from an id
*
* @param id the id
* @return a url
*/
String getRawUrl(String id);
public class Bytebin extends AbstractPastebin {
private final String url;
private final String postUrl;
/**
* Encapsulates the properties of a specific "paste" entry
*/
interface Paste {
/**
* Gets the url of the paste
*
* @return the url
*/
String url();
/**
* Gets the unique id of the paste
*
* @return the id
*/
String id();
public Bytebin(String url) {
if (!url.endsWith("/")) {
url += "/";
}
this.url = url;
this.postUrl = url + "post";
}
@Override
protected String getPostUrl() {
return this.postUrl;
}
@Override
protected String parseIdFromResult(Response response, ResponseBody responseBody, BufferedReader responseBodyReader) {
JsonObject object = GsonProvider.prettyPrinting().fromJson(responseBodyReader, JsonObject.class);
return object.get("key").getAsString();
}
@Override
public String getPasteUrl(String id) {
return this.url + id;
}
}

View File

@ -0,0 +1,63 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.web;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.util.gson.GsonProvider;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.io.BufferedReader;
public class Hastebin extends AbstractPastebin {
public static final Hastebin INSTANCE = new Hastebin();
private static final String URL = "https://hastebin.com/";
private static final String RAW_URL = URL + "raw/";
private static final String POST_URL = URL + "documents";
private Hastebin() {
}
@Override
protected String getPostUrl() {
return POST_URL;
}
@Override
protected String parseIdFromResult(Response response, ResponseBody responseBody, BufferedReader responseBodyReader) {
JsonObject object = GsonProvider.prettyPrinting().fromJson(responseBodyReader, JsonObject.class);
return object.get("key").getAsString();
}
@Override
public String getPasteUrl(String id) {
return RAW_URL + id;
}
}

View File

@ -36,21 +36,16 @@ import java.io.IOException;
/**
* Utilities for the OkHttp client
*/
public class HttpClient {
public final class HttpClient {
private static OkHttpClient client = null;
private HttpClient() {}
private static synchronized OkHttpClient getClient() {
if (client == null) {
client = new OkHttpClient.Builder()
.addInterceptor(new LuckPermsUserAgentInterceptor())
.build();
}
return client;
}
private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
.addInterceptor(new LuckPermsUserAgentInterceptor())
.build();
public static Response makeCall(Request request) throws IOException {
Response response = getClient().newCall(request).execute();
Response response = CLIENT.newCall(request).execute();
if (!response.isSuccessful()) {
throw exceptionForUnsuccessfulResponse(response);
}
@ -81,6 +76,4 @@ public class HttpClient {
}
}
private HttpClient() {}
}

View File

@ -144,9 +144,9 @@ public final class WebEditor {
}
}
public static JsonObject getDataFromGist(String id) {
public static JsonObject readDataFromBytebin(Bytebin bytebin, String id) {
Request request = new Request.Builder()
.url(StandardPastebin.BYTEBIN.getRawUrl(id))
.url(bytebin.getPasteUrl(id))
.build();
try (Response response = HttpClient.makeCall(request)) {