Add support for the new caminus permission API

This commit is contained in:
Trever Fischer 2012-03-18 23:25:51 -04:00
parent 16d74ab611
commit 42616a6f71
6 changed files with 173 additions and 83 deletions

View File

@ -18,54 +18,48 @@ package us.camin;
*/ */
import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.Scanner;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.permissions.PermissionAttachment;
import java.io.IOException;
import org.json.JSONArray; import us.camin.api.ValidationResponse;
import org.json.JSONObject;
import org.json.JSONException;
public class JoinListener implements Listener { public class JoinListener implements Listener {
Logger log = Logger.getLogger("Caminus.Join"); Logger log = Logger.getLogger("Caminus.Join");
private String m_url; private String m_url;
private Plugin m_plugin;
public JoinListener() { public JoinListener(Plugin p) {
m_plugin = p;
} }
public void setURL(String url) {
m_url = url;
}
@EventHandler @EventHandler
public void onPlayerLogin(PlayerLoginEvent event) { public void onPlayerLogin(PlayerLoginEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
if (p.hasPermission("caminus.whitelisted")) ValidationResponse resp = null;
return;
try { try {
if (!isUserAuthed(p.getName())) { resp = m_plugin.api().validatePlayer(p.getName());
if (!resp.valid) {
event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "An active camin.us account is required."); event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "An active camin.us account is required.");
return;
} }
} catch (MalformedURLException e) {
event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "Auth URL is invalid!");
} catch (IOException e) { } catch (IOException e) {
event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "Camin.us auth server seems down."); event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Camin.us auth server seems down.");
} catch (JSONException e) { return;
event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "Bad auth server response.");
} }
PermissionAttachment att = p.addAttachment(m_plugin);
for(String perm : resp.permissions) {
log.info("Granting "+perm);
att.setPermission(perm, true);
}
p.recalculatePermissions();
log.info(p.hasPermission("caminus.whitelisted")+" "+p.hasPermission("bukkit.command.op.give"));
log.info(p.hasPermission("permissions.build")+"");
} }
@EventHandler @EventHandler
@ -73,13 +67,9 @@ public class JoinListener implements Listener {
Player p = event.getPlayer(); Player p = event.getPlayer();
String[] motd = null; String[] motd = null;
try { try {
motd = fetchMOTD(p.getName()); motd = m_plugin.api().fetchMOTD(p.getName());
} catch (MalformedURLException e) {
p.sendMessage("Could not fetch MOTD: Bad URL");
} catch (IOException e) { } catch (IOException e) {
p.sendMessage("Could not fetch MOTD: Communication error"); p.sendMessage("Could not fetch MOTD: Communication error");
} catch (JSONException e) {
p.sendMessage("Could not fetch MOTD: Bad JSON");
} }
if (motd != null) { if (motd != null) {
for(String msg : motd) { for(String msg : motd) {
@ -87,45 +77,4 @@ public class JoinListener implements Listener {
} }
} }
} }
public String[] fetchMOTD(String user) throws IOException, MalformedURLException, JSONException {
URL motdService = new URL(m_url+"motd/"+user);
log.info("Fetching MOTD for "+user+" from "+motdService);
HttpURLConnection conn = (HttpURLConnection)motdService.openConnection();
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
String jsonStr;
// Stupid scanner trick. \A means "beginning of input boundary".
try {
jsonStr = new java.util.Scanner(in).useDelimiter("\\A").next();
} catch (java.util.NoSuchElementException e) {
jsonStr = "";
}
in.close();
JSONObject jsonObj = new JSONObject(jsonStr);
JSONArray motd = jsonObj.getJSONArray("motd");
String[] ret = new String[motd.length()];
for (int i = 0;i<motd.length();i++) {
ret[i] = motd.optString(i);
}
return ret;
}
public boolean isUserAuthed(String user) throws IOException, MalformedURLException, JSONException {
URL authServer = new URL(m_url+"validate/"+user);
log.info("Authing "+user+" against "+authServer);
HttpURLConnection conn = (HttpURLConnection)authServer.openConnection();
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
String jsonStr;
try {
jsonStr = new java.util.Scanner(in).useDelimiter("\\A").next();
} catch (java.util.NoSuchElementException e) {
jsonStr = "";
}
in.close();
JSONObject jsonObj = new JSONObject(jsonStr);
boolean valid = jsonObj.optBoolean("valid");
if (valid)
return true;
return false;
}
} }

View File

@ -25,24 +25,32 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.util.HashMap; import java.util.HashMap;
import java.util.logging.Logger; import java.util.logging.Logger;
import us.camin.api.Server;
public class Plugin extends JavaPlugin { public class Plugin extends JavaPlugin {
Logger log = Logger.getLogger("Caminus");//Define your logger Logger log = Logger.getLogger("Caminus");//Define your logger
private Server m_api;
private JoinListener m_listener; private JoinListener m_listener;
public Server api() {
return m_api;
}
public void onDisable() { public void onDisable() {
log.info("[Caminus] Plugin disabled"); log.info("[Caminus] Plugin disabled");
m_api = null;
} }
public void onEnable() { public void onEnable() {
log.info("[Caminus] Plugin enabled"); log.info("[Caminus] Plugin enabled");
PluginManager pm = this.getServer().getPluginManager(); PluginManager pm = this.getServer().getPluginManager();
m_listener = new JoinListener(); m_listener = new JoinListener(this);
Configuration conf = getConfig(); Configuration conf = getConfig();
conf.addDefault("url", "http://camin.us/api/"); conf.addDefault("url", "http://camin.us/api/");
String url = conf.getString("url"); String url = conf.getString("url");
m_listener.setURL(url); m_api = new Server(url);
pm.registerEvents(m_listener, this); pm.registerEvents(m_listener, this);
} }
} }

View File

@ -0,0 +1,102 @@
package us.camin.api;
/*
This file is part of Caminus
Caminus is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caminus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Caminus. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.logging.Logger;
import java.util.Scanner;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
public class Server {
Logger log = Logger.getLogger("Caminus.API");
private String m_url;
public ValidationResponse validatePlayer(String name) throws IOException {
ValidationResponse resp = new ValidationResponse();
URL authServer = new URL(m_url+"validate/"+name);
log.info("Authing "+name+" against "+authServer);
HttpURLConnection conn = (HttpURLConnection)authServer.openConnection();
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
String jsonStr;
try {
jsonStr = new java.util.Scanner(in).useDelimiter("\\A").next();
} catch (java.util.NoSuchElementException e) {
jsonStr = "";
}
in.close();
try {
JSONObject jsonObj = new JSONObject(jsonStr);
resp.valid = jsonObj.optBoolean("valid");
if (!resp.valid)
return resp;
JSONArray perms = jsonObj.getJSONArray("permissions");
resp.permissions = new String[perms.length()];
for (int i = 0;i<perms.length();i++) {
resp.permissions[i] = perms.optString(i);
}
} catch (JSONException e) {
throw new IOException("JSON parse error", e);
}
return resp;
}
public Server(String url) {
m_url = url;
}
public void setURL(String url) {
m_url = url;
}
public String[] fetchMOTD(String user) throws IOException {
URL motdService = new URL(m_url+"motd/"+user);
log.info("Fetching MOTD for "+user+" from "+motdService);
HttpURLConnection conn = (HttpURLConnection)motdService.openConnection();
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
String jsonStr;
// Stupid scanner trick. \A means "beginning of input boundary".
try {
jsonStr = new java.util.Scanner(in).useDelimiter("\\A").next();
} catch (java.util.NoSuchElementException e) {
jsonStr = "";
}
in.close();
String[] ret = new String[0];
try {
JSONObject jsonObj = new JSONObject(jsonStr);
JSONArray motd = jsonObj.getJSONArray("motd");
ret = new String[motd.length()];
for (int i = 0;i<motd.length();i++) {
ret[i] = motd.optString(i);
}
} catch (JSONException e) {
throw new IOException("JSON parse error", e);
}
return ret;
}
}

View File

@ -0,0 +1,25 @@
package us.camin.api;
/*
This file is part of Caminus
Caminus is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Caminus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Caminus. If not, see <http://www.gnu.org/licenses/>.
*/
public class ValidationResponse {
public boolean valid = false;
public String[] permissions = new String[0];
}

View File

@ -52,9 +52,9 @@ public class APIServer {
ServletOutputStream out = resp.getOutputStream(); ServletOutputStream out = resp.getOutputStream();
if (req.getPathInfo().equals("/TestUser")) if (req.getPathInfo().equals("/TestUser"))
out.println("{valid: true, error: ''}"); out.println("{valid: true, error: '', permissions: ['*']}");
else else
out.println("{valid: false, error: 'Test Failure'}"); out.println("{valid: false, error: 'Test Failure', permissions: []}");
} }
} }

View File

@ -25,16 +25,16 @@ import static org.junit.Assert.*;
import java.io.IOException; import java.io.IOException;
import us.camin.JoinListener; import us.camin.api.Server;
import us.camin.api.ValidationResponse;
public class JoinTest { public class JoinTest {
private JoinListener listener; private Server api;
private APIServer server; private APIServer server;
@Before public void setup() throws Exception { @Before public void setup() throws Exception {
server = new APIServer(); server = new APIServer();
server.start(); server.start();
listener = new JoinListener(); api = new Server("http://localhost:8001/api/");
listener.setURL("http://localhost:8001/api/");
} }
@After public void teardown() throws Exception { @After public void teardown() throws Exception {
@ -42,16 +42,22 @@ public class JoinTest {
} }
@Test public void validUser() throws IOException, JSONException { @Test public void validUser() throws IOException, JSONException {
assertTrue(listener.isUserAuthed("TestUser")); ValidationResponse resp = api.validatePlayer("TestUser");
assertTrue(resp.valid);
assertNotNull(resp.permissions);
assertTrue(resp.permissions.length>0);
} }
@Test public void invaliduser() throws IOException, JSONException { @Test public void invaliduser() throws IOException, JSONException {
assertFalse(listener.isUserAuthed("InvalidUser")); ValidationResponse resp = api.validatePlayer("InvalidUser");
assertFalse(resp.valid);
assertNotNull(resp.permissions);
assertEquals(resp.permissions.length, 0);
} }
@Test public void motd() throws IOException, JSONException { @Test public void motd() throws IOException, JSONException {
String[] goodMOTD = {"Test MOTD"}; String[] goodMOTD = {"Test MOTD"};
String[] motd = listener.fetchMOTD("TestUser"); String[] motd = api.fetchMOTD("TestUser");
assertArrayEquals(null, goodMOTD, motd); assertArrayEquals(null, goodMOTD, motd);
} }
} }