Merge branch 'master' of GitHub repo
Conflicts: src/buttondevteam/website/ButtonWebsiteModule.java src/buttondevteam/website/WebUser.java
This commit is contained in:
commit
f1d21df5d8
7 changed files with 149 additions and 3 deletions
18
.travis.yml
Normal file
18
.travis.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
deploy:
|
||||
# deploy develop to the staging environment
|
||||
- provider: script
|
||||
script: chmod +x deploy.sh && sh deploy.sh staging
|
||||
on:
|
||||
branch: dev
|
||||
skip_cleanup: true
|
||||
# deploy master to production
|
||||
- provider: script
|
||||
script: chmod +x deploy.sh && sh deploy.sh production
|
||||
on:
|
||||
branch: master
|
||||
skip_cleanup: true
|
||||
notifications:
|
||||
webhooks: https://server.figytuna.com:8080/build_notifications
|
11
deploy.sh
Normal file
11
deploy.sh
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
FILENAME=$(find target/ ! -name '*original*' -name '*.jar')
|
||||
echo Found file: $FILENAME
|
||||
|
||||
if [ $1 = 'production' ]; then
|
||||
echo Production mode
|
||||
echo $UPLOAD_KEY > upload_key
|
||||
chmod 400 upload_key
|
||||
yes | scp -B -i upload_key -o StrictHostKeyChecking=no $FILENAME travis@server.figytuna.com:/minecraft/main/plugins
|
||||
fi
|
||||
|
|
@ -113,6 +113,7 @@ public class ButtonWebsiteModule extends JavaPlugin {
|
|||
addPage(new IndexPage());
|
||||
addPage(new LoginPage());
|
||||
addPage(new ProfilePage());
|
||||
addPage(new BuildNotificationsPage());
|
||||
TBMCCoreAPI.RegisterUserClass(WebUser.class);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
|
||||
this.getLogger().info("Starting webserver...");
|
||||
|
|
|
@ -17,6 +17,6 @@ public class WebUser extends ChromaGamerBase {
|
|||
}
|
||||
|
||||
public PlayerData<UUID> sessionID() {
|
||||
return data(new UUID(0, 0));
|
||||
return data(new UUID(0, 0)); //It's used with toString() directly, so can't be null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ public class IOHelper {
|
|||
public static void LoginUser(HttpExchange exchange, WebUser user) {
|
||||
Bukkit.getLogger().fine("Logging in user: " + user);
|
||||
user.sessionID().set(UUID.randomUUID());
|
||||
user.save();
|
||||
new Cookies(2).add(new Cookie("user_id", user.getUUID() + ""))
|
||||
.add(new Cookie("session_id", user.sessionID().get().toString())).SendHeaders(exchange);
|
||||
Bukkit.getLogger().fine("Logged in user.");
|
||||
|
@ -83,6 +84,7 @@ public class IOHelper {
|
|||
|
||||
public static void LogoutUser(HttpExchange exchange, WebUser user) {
|
||||
user.sessionID().set(new UUID(0, 0));
|
||||
user.save();
|
||||
SendLogoutHeaders(exchange);
|
||||
}
|
||||
|
||||
|
@ -125,7 +127,7 @@ public class IOHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get logged in user. It may also send logout headers if the cookies are invalid, or login headers to keep the user logged in.
|
||||
* Get logged in user. It may also send logout headers if the cookies are invalid, or login headers to keep the user logged in. <b>Make sure to save the user data.</b>
|
||||
*
|
||||
* @param exchange
|
||||
* @return The logged in user or null if not logged in.
|
||||
|
@ -174,4 +176,22 @@ public class IOHelper {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static HashMap<String, String> GetPOSTKeyValues(HttpExchange exchange) {
|
||||
try {
|
||||
String[] content = GetPOST(exchange).split("\\&");
|
||||
HashMap<String, String> vars = new HashMap<>();
|
||||
for (String var : content) {
|
||||
String[] spl = var.split("\\=");
|
||||
if (spl.length == 1)
|
||||
vars.put(spl[0], "");
|
||||
else
|
||||
vars.put(spl[0], URLDecoder.decode(spl[1], "utf-8"));
|
||||
}
|
||||
return vars;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
96
src/buttondevteam/website/page/BuildNotificationsPage.java
Normal file
96
src/buttondevteam/website/page/BuildNotificationsPage.java
Normal file
|
@ -0,0 +1,96 @@
|
|||
package buttondevteam.website.page;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
|
||||
import buttondevteam.lib.PluginUpdater;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.website.io.IOHelper;
|
||||
import buttondevteam.website.io.Response;
|
||||
|
||||
public class BuildNotificationsPage extends Page {
|
||||
|
||||
@Override
|
||||
public String GetName() {
|
||||
return "build_notifications";
|
||||
}
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
private static final String publickey = ((Supplier<String>) () -> {
|
||||
try {
|
||||
return fromString(TBMCCoreAPI.DownloadString("https://api.travis-ci.org/config"),
|
||||
"config.notifications.webhook.public_key").getAsString().replace("-----BEGIN PUBLIC KEY-----", "")
|
||||
.replaceAll("\n", "").replace("-----END PUBLIC KEY-----", "");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}).get();
|
||||
|
||||
@Override
|
||||
public Response handlePage(HttpExchange exchange) {
|
||||
HashMap<String, String> post = IOHelper.GetPOSTKeyValues(exchange);
|
||||
try {
|
||||
final List<String> signatures = exchange.getRequestHeaders().get("Signature");
|
||||
final String payload = post.get("payload");
|
||||
if (signatures != null && signatures.size() > 0 && post.containsKey("payload")
|
||||
&& verifySignature(payload.getBytes(StandardCharsets.UTF_8),
|
||||
Base64.getDecoder().decode(signatures.get(0)), publickey)) {
|
||||
Bukkit.getPluginManager()
|
||||
.callEvent(new PluginUpdater.UpdatedEvent(gson.fromJson(payload, JsonObject.class)));
|
||||
return new Response(200, "All right", exchange);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return new Response(400,
|
||||
"Invalid data, error: " + e + " If you're messing with this, stop messing with this.", exchange); // Blame the user
|
||||
}
|
||||
return new Response(400, "Verification failed", exchange);
|
||||
}
|
||||
|
||||
// Method for signature verification that initializes with the Public Key,
|
||||
// updates the data to be verified and then verifies them using the signature
|
||||
private boolean verifySignature(byte[] data, byte[] signature, String keystr) throws Exception {
|
||||
Signature sig = Signature.getInstance("SHA1withRSA");
|
||||
sig.initVerify(getPublic(keystr));
|
||||
sig.update(data);
|
||||
|
||||
return sig.verify(signature);
|
||||
}
|
||||
|
||||
// Method to retrieve the Public Key from a file
|
||||
public PublicKey getPublic(String keystr) throws Exception {
|
||||
byte[] keyBytes = Base64.getDecoder().decode(keystr);
|
||||
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
return kf.generatePublic(spec);
|
||||
}
|
||||
|
||||
public static JsonElement fromString(String json, String path) throws JsonSyntaxException {
|
||||
JsonObject obj = gson.fromJson(json, JsonObject.class);
|
||||
String[] seg = path.split("\\.");
|
||||
for (String element : seg) {
|
||||
if (obj != null) {
|
||||
JsonElement ele = obj.get(element);
|
||||
if (!ele.isJsonObject())
|
||||
return ele;
|
||||
else
|
||||
obj = ele.getAsJsonObject();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ public abstract class Page implements HttpHandler {
|
|||
if (exchange.getRequestURI().getPath().equals("/" + GetName()))
|
||||
IOHelper.SendResponse(handlePage(exchange));
|
||||
else {
|
||||
IOHelper.SendResponse(404, "404 Not found", exchange);
|
||||
IOHelper.SendResponse(404, "404 Not found: " + exchange.getRequestURI().getPath(), exchange);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Internal Server Error in ButtonWebsiteModule!", e);
|
||||
|
|
Loading…
Reference in a new issue