Mercurial > hg > release > thermostat-0.9
changeset 1080:dd39c8d202fb
Add more tests for WebStorageEndPoint.
Reviewed-by: neugens
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-April/006418.html
PR952
author | Severin Gehwolf <sgehwolf@redhat.com> |
---|---|
date | Tue, 23 Apr 2013 11:44:28 +0200 |
parents | dff087c3c875 |
children | 17aed647ccff |
files | web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java web/server/src/main/java/com/redhat/thermostat/web/server/auth/WebStoragePathHandler.java web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java |
diffstat | 3 files changed, 376 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Fri Apr 19 14:09:10 2013 +0200 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Tue Apr 23 11:44:28 2013 +0200 @@ -88,6 +88,7 @@ import com.redhat.thermostat.web.common.WebRemove; import com.redhat.thermostat.web.common.WebUpdate; import com.redhat.thermostat.web.server.auth.Roles; +import com.redhat.thermostat.web.server.auth.WebStoragePathHandler; @SuppressWarnings("serial") public class WebStorageEndPoint extends HttpServlet { @@ -215,6 +216,7 @@ } } + @WebStoragePathHandler( path = "ping" ) private void ping(HttpServletRequest req, HttpServletResponse resp) { if (! isAuthorized(req, resp, Roles.LOGIN)) { return; @@ -223,6 +225,7 @@ resp.setStatus(HttpServletResponse.SC_OK); } + @WebStoragePathHandler( path = "purge" ) private void purge(HttpServletRequest req, HttpServletResponse resp) { if (! isAuthorized(req, resp, Roles.PURGE)) { return; @@ -233,6 +236,7 @@ resp.setStatus(HttpServletResponse.SC_OK); } + @WebStoragePathHandler( path = "load-file" ) private void loadFile(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (! isAuthorized(req, resp, Roles.LOAD_FILE)) { return; @@ -252,6 +256,7 @@ } } + @WebStoragePathHandler( path = "save-file" ) private void saveFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (! isAuthorized(req, resp, Roles.SAVE_FILE)) { return; @@ -280,6 +285,7 @@ } + @WebStoragePathHandler( path = "get-count" ) private void getCount(HttpServletRequest req, HttpServletResponse resp) { if (! isAuthorized(req, resp, Roles.GET_COUNT)) { return; @@ -299,6 +305,7 @@ } } + @WebStoragePathHandler( path = "register-category" ) private synchronized void registerCategory(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (! isAuthorized(req, resp, Roles.REGISTER_CATEGORY)) { return; @@ -326,6 +333,7 @@ writer.flush(); } + @WebStoragePathHandler( path = "put-pojo" ) private void putPojo(HttpServletRequest req, HttpServletResponse resp) { String insertParam = req.getParameter("insert"); WebInsert insert = gson.fromJson(insertParam, WebInsert.class); @@ -351,6 +359,7 @@ resp.setStatus(HttpServletResponse.SC_OK); } + @WebStoragePathHandler( path = "remove-pojo" ) @SuppressWarnings({ "rawtypes", "unchecked" }) private void removePojo(HttpServletRequest req, HttpServletResponse resp) { if (! isAuthorized(req, resp, Roles.DELETE)) { @@ -370,6 +379,7 @@ resp.setStatus(HttpServletResponse.SC_OK); } + @WebStoragePathHandler( path = "update-pojo" ) @SuppressWarnings({ "rawtypes", "unchecked" }) private void updatePojo(HttpServletRequest req, HttpServletResponse resp) { if (! isAuthorized(req, resp, Roles.UPDATE)) { @@ -410,6 +420,7 @@ } } + @WebStoragePathHandler( path = "find-all" ) @SuppressWarnings({ "rawtypes", "unchecked" }) private void findAll(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (! isAuthorized(req, resp, Roles.READ)) { @@ -455,6 +466,7 @@ resp.flushBuffer(); } + @WebStoragePathHandler( path = "generate-token" ) private void generateToken(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (! isAuthorized(req, resp, Roles.CMD_CHANNEL_GENERATE) ) { return; @@ -468,6 +480,7 @@ resp.getOutputStream().write(token); } + @WebStoragePathHandler( path = "verify-token" ) private void verifyToken(HttpServletRequest req, HttpServletResponse resp) { if (! isAuthorized(req, resp, Roles.CMD_CHANNEL_VERIFY) ) { return; @@ -488,6 +501,7 @@ if (req.isUserInRole(role)) { return true; } else { + logger.log(Level.FINEST, "Not permitting access to " + req.getPathInfo() + ". User '" + req.getRemoteUser() + "' not in role " + role); resp.setStatus(HttpServletResponse.SC_FORBIDDEN); return false; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/auth/WebStoragePathHandler.java Tue Apr 23 11:44:28 2013 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.web.server.auth; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation for web storage handler methods. This is used in order + * to ensure proper authorization coverage. + * + */ +@Target( ElementType.METHOD ) +@Retention( RetentionPolicy.RUNTIME ) +public @interface WebStoragePathHandler { + + String path(); + +}
--- a/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Fri Apr 19 14:09:10 2013 +0200 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Tue Apr 23 11:44:28 2013 +0200 @@ -37,6 +37,7 @@ package com.redhat.thermostat.web.server; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; @@ -52,12 +53,17 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; +import java.lang.reflect.Method; import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; +import javax.servlet.http.HttpServletResponse; + import org.apache.commons.codec.binary.Base64; import org.eclipse.jetty.security.DefaultUserIdentity; import org.eclipse.jetty.security.LoginService; @@ -74,6 +80,7 @@ import org.mockito.ArgumentCaptor; import com.google.gson.Gson; +import com.redhat.thermostat.storage.core.Add; import com.redhat.thermostat.storage.core.Categories; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Cursor; @@ -96,6 +103,7 @@ import com.redhat.thermostat.web.common.WebRemove; import com.redhat.thermostat.web.common.WebUpdate; import com.redhat.thermostat.web.server.auth.Roles; +import com.redhat.thermostat.web.server.auth.WebStoragePathHandler; public class WebStorageEndpointTest { @@ -175,10 +183,69 @@ @After public void tearDown() throws Exception { - server.stop(); - server.join(); + // some tests don't use server + if (server != null) { + server.stop(); + server.join(); + } } + /** + * Makes sure that all paths we dispatch to, dispatch to + * {@link WebStoragePathHandler} annotated methods. + * + * @throws Exception + */ + @Test + public void ensureAuthorizationCovered() throws Exception { + // manually maintained list of path handlers which should include + // authorization checks + final String[] authPaths = new String[] { + "find-all", "put-pojo", "register-category", "remove-pojo", + "update-pojo", "get-count", "save-file", "load-file", + "purge", "ping", "generate-token", "verify-token" + }; + Map<String, Boolean> checkedAutPaths = new HashMap<>(); + for (String path: authPaths) { + checkedAutPaths.put(path, false); + } + int methodsReqAuthorization = 0; + for (Method method: WebStorageEndPoint.class.getDeclaredMethods()) { + if (method.isAnnotationPresent(WebStoragePathHandler.class)) { + methodsReqAuthorization++; + WebStoragePathHandler annot = method.getAnnotation(WebStoragePathHandler.class); + try { + // this may NPE if there is something funny going on in + // WebStorageEndPoint (e.g. one method annotated but this + // reference list has not been updated). + if (!checkedAutPaths.get(annot.path())) { + // mark path as covered + checkedAutPaths.put(annot.path(), true); + } else { + throw new AssertionError( + "method " + + method + + " annotated as web storage path handler (path '" + + annot.path() + + "'), but not in reference list we know about!"); + } + } catch (NullPointerException e) { + throw new AssertionError("Don't know about path '" + + annot.path() + "'"); + } + } + } + // at this point we should have all dispatched paths covered + for (String path: authPaths) { + assertTrue( + "Is " + path + + " marked with @WebStoragePathHandler and have proper authorization checks been included?", + checkedAutPaths.get(path)); + } + assertEquals(authPaths.length, methodsReqAuthorization); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void authorizedFindAllPojos() throws Exception { String[] roleNames = new String[] { @@ -203,7 +270,6 @@ TestClass expected2 = new TestClass(); expected2.setKey1("fluff2"); expected2.setKey2(43); - @SuppressWarnings("unchecked") Cursor<TestClass> cursor = mock(Cursor.class); when(cursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false); when(cursor.next()).thenReturn(expected1).thenReturn(expected2); @@ -216,7 +282,7 @@ URL url = new URL(endpoint + "/find-all"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setDoInput(true); conn.setDoOutput(true); @@ -248,6 +314,46 @@ verify(mockQuery).execute(); verifyNoMoreInteractions(mockQuery); } + + @Test + public void unauthorizedFindAllPojos() throws Exception { + String failMsg = "thermostat-read role missing, expected Forbidden!"; + doUnauthorizedTest("find-all", failMsg); + } + + private void doUnauthorizedTest(String pathForEndPoint, String failMessage) throws Exception { + String[] insufficientRoleNames = new String[] { + Roles.REGISTER_CATEGORY, + }; + doUnauthorizedTest(pathForEndPoint, failMessage, insufficientRoleNames, true); + } + + private void doUnauthorizedTest(String pathForEndPoint, String failMessage, + String[] insufficientRoles, boolean doRegisterCategory) throws Exception, + MalformedURLException, IOException, ProtocolException { + String testuser = "testuser"; + String password = "testpassword"; + final LoginService loginService = new TestLoginService(testuser, password, insufficientRoles); + port = FreePortFinder.findFreePort(new TryPort() { + + @Override + public void tryPort(int port) throws Exception { + startServer(port, loginService); + } + }); + if (doRegisterCategory) { + registerCategory(testuser, password); + } + + String endpoint = getEndpoint(); + URL url = new URL(endpoint + "/" + pathForEndPoint); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + sendAuthentication(conn, testuser, password); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + + assertEquals(failMessage, HttpServletResponse.SC_FORBIDDEN, conn.getResponseCode()); + } @Test public void authorizedReplacePutPojo() throws Exception { @@ -279,7 +385,7 @@ URL url = new URL(endpoint + "/put-pojo"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); @@ -297,14 +403,147 @@ verify(mockStorage).createReplace(category); verify(replace).setPojo(expected1); verify(replace).apply(); + } + + @Test + public void unauthorizedReplacePutPojo() throws Exception { + String[] insufficientRoleNames = new String[] { + Roles.REGISTER_CATEGORY, + }; + String testuser = "testuser"; + String password = "testpassword"; + final LoginService loginService = new TestLoginService(testuser, password, insufficientRoleNames); + port = FreePortFinder.findFreePort(new TryPort() { + + @Override + public void tryPort(int port) throws Exception { + startServer(port, loginService); + } + }); + registerCategory(testuser, password); + + String endpoint = getEndpoint(); + URL url = new URL(endpoint + "/put-pojo"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + sendAuthentication(conn, testuser, password); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setDoOutput(true); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + // replace + WebInsert insert = new WebInsert(categoryId, true); + Gson gson = new Gson(); + OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); + out.write("insert="); + gson.toJson(insert, out); + out.flush(); + out.write("&pojo="); + TestClass expected1 = new TestClass(); + gson.toJson(expected1, out); + out.write("\n"); + out.flush(); + + assertEquals("thermostat-replace role missing", HttpServletResponse.SC_FORBIDDEN, conn.getResponseCode()); } - private void sendAuthorization(HttpURLConnection conn, String username, String passwd) { + @Test + public void authorizedInsertPutPojo() throws Exception { + String[] roleNames = new String[] { + Roles.APPEND, + Roles.REGISTER_CATEGORY + }; + String testuser = "testuser"; + String password = "testpassword"; + final LoginService loginService = new TestLoginService(testuser, password, roleNames); + port = FreePortFinder.findFreePort(new TryPort() { + + @Override + public void tryPort(int port) throws Exception { + startServer(port, loginService); + } + }); + registerCategory(testuser, password); + + Add insert = mock(Add.class); + when(mockStorage.createAdd(any(Category.class))).thenReturn(insert); + + TestClass expected1 = new TestClass(); + expected1.setKey1("fluff1"); + expected1.setKey2(42); + + String endpoint = getEndpoint(); + + URL url = new URL(endpoint + "/put-pojo"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + sendAuthentication(conn, testuser, password); + + conn.setDoOutput(true); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + WebInsert ins = new WebInsert(categoryId, false); + Gson gson = new Gson(); + OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); + out.write("insert="); + gson.toJson(ins, out); + out.flush(); + out.write("&pojo="); + gson.toJson(expected1, out); + out.write("\n"); + out.flush(); + assertEquals(200, conn.getResponseCode()); + verify(mockStorage).createAdd(category); + verify(insert).setPojo(expected1); + verify(insert).apply(); + } + + @Test + public void unauthorizedInsertPutPojo() throws Exception { + String[] insufficientRoleNames = new String[] { + Roles.REGISTER_CATEGORY, + }; + String testuser = "testuser"; + String password = "testpassword"; + final LoginService loginService = new TestLoginService(testuser, password, insufficientRoleNames); + port = FreePortFinder.findFreePort(new TryPort() { + + @Override + public void tryPort(int port) throws Exception { + startServer(port, loginService); + } + }); + registerCategory(testuser, password); + + String endpoint = getEndpoint(); + URL url = new URL(endpoint + "/put-pojo"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + sendAuthentication(conn, testuser, password); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setDoOutput(true); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + // replace + WebInsert insert = new WebInsert(categoryId, false); + Gson gson = new Gson(); + OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); + out.write("insert="); + gson.toJson(insert, out); + out.flush(); + out.write("&pojo="); + TestClass expected1 = new TestClass(); + gson.toJson(expected1, out); + out.write("\n"); + out.flush(); + + assertEquals("thermostat-add role missing", HttpServletResponse.SC_FORBIDDEN, conn.getResponseCode()); + } + + private void sendAuthentication(HttpURLConnection conn, String username, String passwd) { String userpassword = username + ":" + passwd; String encodedAuthorization = Base64.encodeBase64String(userpassword.getBytes()); conn.setRequestProperty("Authorization", "Basic "+ encodedAuthorization); } + @SuppressWarnings("unchecked") @Test public void authorizedRemovePojo() throws Exception { String[] roleNames = new String[] { @@ -335,7 +574,7 @@ URL url = new URL(endpoint + "/remove-pojo"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); Map<Category<?>,Integer> categoryIds = new HashMap<>(); @@ -354,6 +593,12 @@ verify(mockRemove).where(key1, "test"); verify(mockStorage).removePojo(mockRemove); } + + @Test + public void unauthorizedRemovePojo() throws Exception { + String failMsg = "thermostat-remove role missing, expected Forbidden!"; + doUnauthorizedTest("remove-pojo", failMsg); + } @Test public void authorizedUpdatePojo() throws Exception { @@ -381,7 +626,7 @@ URL url = new URL(endpoint + "/update-pojo"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); @@ -408,6 +653,12 @@ verify(mockUpdate).apply(); verifyNoMoreInteractions(mockUpdate); } + + @Test + public void unauthorizedUpdatePojo() throws Exception { + String failMsg = "thermostat-update role missing, expected Forbidden!"; + doUnauthorizedTest("update-pojo", failMsg); + } @Test @@ -434,7 +685,7 @@ URL url = new URL(endpoint + "/get-count"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); @@ -451,6 +702,12 @@ verify(mockStorage).getCount(category); } + + @Test + public void unauthorizedGetCount() throws Exception { + String failMsg = "thermostat-get-count role missing, expected Forbidden!"; + doUnauthorizedTest("get-count", failMsg); + } @Test public void authorizedSaveFile() throws Exception { @@ -472,7 +729,7 @@ URL url = new URL(endpoint + "/save-file"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=fluff"); conn.setRequestProperty("Transfer-Encoding", "chunked"); @@ -485,7 +742,8 @@ out.write("Hello World\r\n"); out.write("--fluff--\r\n"); out.flush(); - int status = conn.getResponseCode(); + // needed in order to trigger inCaptor interaction with mock + conn.getResponseCode(); ArgumentCaptor<InputStream> inCaptor = ArgumentCaptor.forClass(InputStream.class); verify(mockStorage).saveFile(eq("fluff"), inCaptor.capture()); InputStream in = inCaptor.getValue(); @@ -500,6 +758,13 @@ } assertEquals("Hello World", new String(data)); } + + @Test + public void unauthorizedSaveFile() throws Exception { + String failMsg = "thermostat-save-file role missing, expected Forbidden!"; + String[] insufficientRoles = new String[0]; + doUnauthorizedTest("save-file", failMsg, insufficientRoles, false); + } @Test public void authorizedLoadFile() throws Exception { @@ -526,7 +791,7 @@ HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setDoInput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); @@ -545,6 +810,13 @@ assertEquals("Hello World", new String(data)); verify(mockStorage).loadFile("fluff"); } + + @Test + public void unauthorizedLoadFile() throws Exception { + String failMsg = "thermostat-load-file role missing, expected Forbidden!"; + String[] insufficientRoles = new String[0]; + doUnauthorizedTest("load-file", failMsg, insufficientRoles, false); + } @Test public void authorizedPurge() throws Exception { @@ -566,12 +838,19 @@ HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.getOutputStream().write("agentId=fluff".getBytes()); int status = conn.getResponseCode(); assertEquals(200, status); verify(mockStorage).purge("fluff"); } + + @Test + public void unauthorizedPurge() throws Exception { + String failMsg = "thermostat-purge role missing, expected Forbidden!"; + String[] insufficientRoles = new String[0]; + doUnauthorizedTest("purge", failMsg, insufficientRoles, false); + } private void registerCategory(String username, String password) { try { @@ -583,7 +862,7 @@ conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); - sendAuthorization(conn, username, password); + sendAuthentication(conn, username, password); OutputStream out = conn.getOutputStream(); Gson gson = new Gson(); OutputStreamWriter writer = new OutputStreamWriter(out); @@ -626,31 +905,9 @@ @Test public void unauthorizedGenerateToken() throws Exception { - String[] noRoles = new String[0]; - String testuser = "testuser"; - String password = "testpassword"; - final LoginService loginService = new TestLoginService(testuser, password, noRoles); - - port = FreePortFinder.findFreePort(new TryPort() { - - @Override - public void tryPort(int port) throws Exception { - startServer(port, loginService); - } - }); - - String endpoint = getEndpoint(); - URL url = new URL(endpoint + "/generate-token"); - - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("POST"); - sendAuthorization(conn, testuser, password); - conn.setDoOutput(true); - conn.setDoInput(true); - OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); - out.write("client-token=fluff"); - out.flush(); - assertEquals(403, conn.getResponseCode()); + String failMsg = "thermostat-cmdc-generate role missing, expected Forbidden!"; + String[] insufficientRoles = new String[0]; + doUnauthorizedTest("generate-token", failMsg, insufficientRoles, false); } @Test @@ -677,7 +934,7 @@ HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setDoInput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); @@ -712,7 +969,7 @@ HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setDoInput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); @@ -745,7 +1002,7 @@ HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); - sendAuthorization(conn, testuser, password); + sendAuthentication(conn, testuser, password); conn.setDoOutput(true); conn.setDoInput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); @@ -753,6 +1010,13 @@ out.flush(); assertEquals(403, conn.getResponseCode()); } + + @Test + public void unauthorizedVerifyToken() throws Exception { + String failMsg = "thermostat-cmdc-verify role missing, expected Forbidden!"; + String[] insufficientRoles = new String[0]; + doUnauthorizedTest("verify-token", failMsg, insufficientRoles, false); + } private byte[] verifyAuthorizedGenerateToken(String username, String password) throws IOException { String endpoint = getEndpoint(); @@ -760,7 +1024,7 @@ HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); - sendAuthorization(conn, username, password); + sendAuthentication(conn, username, password); conn.setDoOutput(true); conn.setDoInput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());