Cleaned sources
This commit is contained in:
@ -1,21 +1,24 @@
|
||||
package org.skinner;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.skinner.json.*;
|
||||
import org.skinner.json.JSON;
|
||||
import org.skinner.json.JSONArray;
|
||||
import org.skinner.json.JSONObject;
|
||||
|
||||
import com.sun.net.httpserver.*;
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
|
||||
public class RestAPI extends SafeHttpHandler {
|
||||
|
||||
|
||||
RestAPI(String root) {
|
||||
super(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handle(HttpExchange exchange, URI uri) throws Exception {
|
||||
String path = uri.getPath();
|
||||
switch (exchange.getRequestMethod().toUpperCase())
|
||||
@ -26,11 +29,11 @@ public class RestAPI extends SafeHttpHandler {
|
||||
case "/skins":
|
||||
getSkins(exchange);
|
||||
return;
|
||||
|
||||
|
||||
case "/profiles":
|
||||
profiles(exchange);
|
||||
return;
|
||||
|
||||
|
||||
// Template-ish routes
|
||||
default:
|
||||
if (path.startsWith("/skin/")) {
|
||||
@ -40,14 +43,14 @@ public class RestAPI extends SafeHttpHandler {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "POST":
|
||||
switch (path)
|
||||
{
|
||||
case "/skin":
|
||||
addSkin(exchange);
|
||||
return;
|
||||
|
||||
|
||||
case "/profile":
|
||||
register(exchange);
|
||||
return;
|
||||
@ -57,14 +60,14 @@ public class RestAPI extends SafeHttpHandler {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "PATCH":
|
||||
switch (path)
|
||||
{
|
||||
case "/profile":
|
||||
updateProfile(exchange, uri);
|
||||
return;
|
||||
|
||||
|
||||
default:
|
||||
if (path.startsWith("/skin/")) {
|
||||
renameSkin(exchange, uri);
|
||||
@ -72,7 +75,7 @@ public class RestAPI extends SafeHttpHandler {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case "DELETE":
|
||||
switch (path)
|
||||
{
|
||||
@ -86,26 +89,26 @@ public class RestAPI extends SafeHttpHandler {
|
||||
}
|
||||
Headers headers = exchange.getResponseHeaders();
|
||||
headers.add("Content-Type", "text/plain");
|
||||
|
||||
|
||||
byte[] response = "Missing API endpoint".getBytes();
|
||||
exchange.sendResponseHeaders(404, response.length);
|
||||
exchange.getResponseBody().write(response);
|
||||
exchange.close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
protected void getSkin(HttpExchange exchange, URI uri) throws Exception {
|
||||
String[] pathParts = uri.getPath().split("/");
|
||||
String hash = pathParts[pathParts.length-1].split("\\.")[0];
|
||||
|
||||
|
||||
Skin skin = Database.getSkin(hash);
|
||||
if (skin == null) {
|
||||
notfound(exchange, "Skin not found");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Query query = new Query(uri.getQuery());
|
||||
|
||||
|
||||
byte[] response = query.getOrDefault("legacy", "false").toLowerCase().equals("true") ?
|
||||
skin.getPngOld() :
|
||||
skin.getPng();
|
||||
@ -114,10 +117,10 @@ public class RestAPI extends SafeHttpHandler {
|
||||
exchange.getResponseBody().write(response);
|
||||
exchange.close();
|
||||
}
|
||||
|
||||
|
||||
protected void getSkins(HttpExchange exchange) throws Exception {
|
||||
HashLabelPair[] pairs = Database.getSkinHashesAndLabels();
|
||||
|
||||
|
||||
JSONArray array = new JSONArray();
|
||||
for (HashLabelPair pair : pairs) {
|
||||
JSONObject object = new JSONObject();
|
||||
@ -127,66 +130,6 @@ public class RestAPI extends SafeHttpHandler {
|
||||
object.put("png_old", JSON.from(getRoot() + "skin/"+pair.getHash()+".png?legacy=true"));
|
||||
array.add(object);
|
||||
}
|
||||
|
||||
byte[] response = array.toString().getBytes();
|
||||
exchange.getResponseHeaders().add("Content-Type", "application/json");
|
||||
exchange.sendResponseHeaders(200, response.length);
|
||||
exchange.getResponseBody().write(response);
|
||||
exchange.close();
|
||||
}
|
||||
|
||||
protected void getSkinsFull(HttpExchange exchange) throws Exception {
|
||||
Skin[] skins = Database.getSkins();
|
||||
|
||||
JSONArray array = new JSONArray();
|
||||
for (Skin skin : skins)
|
||||
array.add(skinToResponseJSON(skin));
|
||||
|
||||
byte[] response = array.toString().getBytes();
|
||||
exchange.getResponseHeaders().add("Content-Type", "application/json");
|
||||
exchange.sendResponseHeaders(200, response.length);
|
||||
exchange.getResponseBody().write(response);
|
||||
exchange.close();
|
||||
}
|
||||
|
||||
protected void addSkin(HttpExchange exchange) throws Exception {
|
||||
MultipartForm form = new MultipartForm(exchange);
|
||||
|
||||
if (!form.contains("skin")) {
|
||||
text(exchange, 400, "Expected \"skin\" field not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream is = new ByteArrayInputStream(form.get("skin"));
|
||||
Skin skin = Skin.loadFromImage(is, form.getString("label"));
|
||||
Database.addSkin(skin);
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
protected void renameSkin(HttpExchange exchange, URI uri) throws Exception {
|
||||
String[] pathParts = uri.getPath().split("/");
|
||||
String hash = pathParts[pathParts.length-1];
|
||||
|
||||
String label = new String(exchange.getRequestBody().readAllBytes());
|
||||
|
||||
Database.updateSkinLabel(hash, label);
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
protected void deleteSkin(HttpExchange exchange, URI uri) throws Exception {
|
||||
String[] pathParts = uri.getPath().split("/");
|
||||
String hash = pathParts[pathParts.length-1];
|
||||
|
||||
Database.deleteSkin(hash);
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
protected void profiles(HttpExchange exchange) throws Exception {
|
||||
Profile[] profiles = Database.getProfiles();
|
||||
|
||||
JSONArray array = new JSONArray();
|
||||
for (Profile profile : profiles)
|
||||
array.add(profileToResponseJSON(profile));
|
||||
|
||||
byte[] response = array.toString().getBytes();
|
||||
exchange.getResponseHeaders().add("Content-Type", "application/json");
|
||||
@ -194,10 +137,72 @@ public class RestAPI extends SafeHttpHandler {
|
||||
exchange.getResponseBody().write(response);
|
||||
exchange.close();
|
||||
}
|
||||
|
||||
|
||||
protected void getSkinsFull(HttpExchange exchange) throws Exception {
|
||||
Skin[] skins = Database.getSkins();
|
||||
|
||||
JSONArray array = new JSONArray();
|
||||
for (Skin skin : skins) {
|
||||
array.add(skinToResponseJSON(skin));
|
||||
}
|
||||
|
||||
byte[] response = array.toString().getBytes();
|
||||
exchange.getResponseHeaders().add("Content-Type", "application/json");
|
||||
exchange.sendResponseHeaders(200, response.length);
|
||||
exchange.getResponseBody().write(response);
|
||||
exchange.close();
|
||||
}
|
||||
|
||||
protected void addSkin(HttpExchange exchange) throws Exception {
|
||||
MultipartForm form = new MultipartForm(exchange);
|
||||
|
||||
if (!form.contains("skin")) {
|
||||
text(exchange, 400, "Expected \"skin\" field not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream is = new ByteArrayInputStream(form.get("skin"));
|
||||
Skin skin = Skin.loadFromImage(is, form.getString("label"));
|
||||
Database.addSkin(skin);
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
protected void renameSkin(HttpExchange exchange, URI uri) throws Exception {
|
||||
String[] pathParts = uri.getPath().split("/");
|
||||
String hash = pathParts[pathParts.length-1];
|
||||
|
||||
String label = new String(exchange.getRequestBody().readAllBytes());
|
||||
|
||||
Database.updateSkinLabel(hash, label);
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
protected void deleteSkin(HttpExchange exchange, URI uri) throws Exception {
|
||||
String[] pathParts = uri.getPath().split("/");
|
||||
String hash = pathParts[pathParts.length-1];
|
||||
|
||||
Database.deleteSkin(hash);
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
protected void profiles(HttpExchange exchange) throws Exception {
|
||||
Profile[] profiles = Database.getProfiles();
|
||||
|
||||
JSONArray array = new JSONArray();
|
||||
for (Profile profile : profiles) {
|
||||
array.add(profileToResponseJSON(profile));
|
||||
}
|
||||
|
||||
byte[] response = array.toString().getBytes();
|
||||
exchange.getResponseHeaders().add("Content-Type", "application/json");
|
||||
exchange.sendResponseHeaders(200, response.length);
|
||||
exchange.getResponseBody().write(response);
|
||||
exchange.close();
|
||||
}
|
||||
|
||||
protected void register(HttpExchange exchange) throws Exception {
|
||||
MultipartForm form = new MultipartForm(exchange);
|
||||
|
||||
|
||||
if (!form.contains("username")) {
|
||||
text(exchange, 400, "Expected \"username\" field not provided");
|
||||
return;
|
||||
@ -206,14 +211,14 @@ public class RestAPI extends SafeHttpHandler {
|
||||
text(exchange, 400, "Expected \"password\" field not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String username = form.getString("username");
|
||||
String password = form.getString("password");
|
||||
|
||||
|
||||
String salt = Profile.generateSalt();
|
||||
String hash = Profile.generateHash(password, salt);
|
||||
String uuid = Profile.generateUUID();
|
||||
|
||||
|
||||
Database.addProfile(new Profile(
|
||||
-1,
|
||||
username,
|
||||
@ -224,7 +229,7 @@ public class RestAPI extends SafeHttpHandler {
|
||||
));
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
|
||||
protected void updateProfile(HttpExchange exchange, URI uri) throws Exception {
|
||||
Headers headers = exchange.getRequestHeaders();
|
||||
if (!headers.containsKey("Authorization")) {
|
||||
@ -237,33 +242,34 @@ public class RestAPI extends SafeHttpHandler {
|
||||
}
|
||||
String auth = headers.getFirst("Authorization");
|
||||
String[] authParts = auth.trim().split(" ");
|
||||
|
||||
|
||||
if (!authParts[0].equals("Basic")) {
|
||||
text(exchange, 401, "Invalid authorization method");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String[] cerd = new String(Base64.getDecoder().decode(authParts[1])).split(":");
|
||||
if (cerd.length != 2) {
|
||||
text(exchange, 401, "Invalid cerdentials format");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Profile profile = Database.getProfileByName(cerd[0]);
|
||||
|
||||
|
||||
if (profile == null || !Profile.generateHash(cerd[1], profile.getSalt()).equals(profile.getPassword())) {
|
||||
text(exchange, 401, "Failed to authorize");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Query query = new Query(uri.getQuery());
|
||||
|
||||
if (query.containsKey("skin"))
|
||||
|
||||
if (query.containsKey("skin")) {
|
||||
Database.setProfileSkin(profile, Database.getSkin(query.get("skin")));
|
||||
|
||||
}
|
||||
|
||||
ok(exchange);
|
||||
}
|
||||
|
||||
|
||||
private JSONObject skinToResponseJSON(Skin skin) {
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("hash", JSON.from(skin.getHash()));
|
||||
@ -271,7 +277,7 @@ public class RestAPI extends SafeHttpHandler {
|
||||
object.put("png_old", JSON.from(getRoot() + "skin/"+skin.getHash()+".png?legacy=true"));
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
private JSONObject profileToResponseJSON(Profile profile) {
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("username", JSON.from(profile.getUsername()));
|
||||
@ -279,5 +285,5 @@ public class RestAPI extends SafeHttpHandler {
|
||||
object.put("skin", skinToResponseJSON(profile.getSkin()));
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user