From: INOPIAE Date: Mon, 8 Jul 2019 12:53:28 +0000 (+0200) Subject: add: ensure that for support actions certificate login is used X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=7c9a443cdc81dfc8129f898d510e13bccc558ee0 add: ensure that for support actions certificate login is used related to issue #150 Change-Id: I2bc368a8b93d1ccbb3522e74213d2057bd9b2d67 --- diff --git a/src/club/wpia/gigi/pages/MainPage.java b/src/club/wpia/gigi/pages/MainPage.java index 6d279109..53cad4a0 100644 --- a/src/club/wpia/gigi/pages/MainPage.java +++ b/src/club/wpia/gigi/pages/MainPage.java @@ -40,7 +40,12 @@ public class MainPage extends Page { vars.put("ra-agent", u.canVerify()); vars.put("vp", u.getVerificationPoints()); vars.put("xp", u.getExperiencePoints()); - + if (u.isInGroup(Group.SUPPORTER) || u.isInGroup(Group.ORG_AGENT) || u.isInGroup(Group.TTP_AGENT) || u.canVerify()) { + vars.put("certlogin", LoginPage.getAuthorizationContext(req).isStronglyAuthenticated()); + vars.put("certlogininfo", true); + } else { + vars.put("certlogininfo", false); + } Certificate[] c = u.getCertificates(false); vars.put("c-no", c.length); diff --git a/src/club/wpia/gigi/pages/MainPage.templ b/src/club/wpia/gigi/pages/MainPage.templ index a66ddd44..88506f30 100644 --- a/src/club/wpia/gigi/pages/MainPage.templ +++ b/src/club/wpia/gigi/pages/MainPage.templ @@ -1,5 +1,18 @@

+ + + +
+

+
+ + + + +

:

diff --git a/src/club/wpia/gigi/pages/admin/support/SupportEnterTicketPage.java b/src/club/wpia/gigi/pages/admin/support/SupportEnterTicketPage.java index 24f093a4..14b1faaf 100644 --- a/src/club/wpia/gigi/pages/admin/support/SupportEnterTicketPage.java +++ b/src/club/wpia/gigi/pages/admin/support/SupportEnterTicketPage.java @@ -47,7 +47,7 @@ public class SupportEnterTicketPage extends Page { @Override public boolean isPermitted(AuthorizationContext ac) { - return ac != null && ac.isInGroup(Group.SUPPORTER); + return ac != null && ac.isInGroup(Group.SUPPORTER) && ac.isStronglyAuthenticated(); } } diff --git a/src/club/wpia/gigi/util/AuthorizationContext.java b/src/club/wpia/gigi/util/AuthorizationContext.java index 719ac923..9888309a 100644 --- a/src/club/wpia/gigi/util/AuthorizationContext.java +++ b/src/club/wpia/gigi/util/AuthorizationContext.java @@ -79,7 +79,7 @@ public class AuthorizationContext implements Outputable, Serializable { } public boolean canSupport() { - return getSupporterTicketId() != null && isInGroup(Group.SUPPORTER); + return getSupporterTicketId() != null && isInGroup(Group.SUPPORTER) && isStronglyAuthenticated(); } private static final SprintfCommand sp = new SprintfCommand("Logged in as {0} via {1}.", Arrays.asList("${username", "${loginMethod")); diff --git a/tests/club/wpia/gigi/pages/TestMain.java b/tests/club/wpia/gigi/pages/TestMain.java new file mode 100644 index 00000000..682daf82 --- /dev/null +++ b/tests/club/wpia/gigi/pages/TestMain.java @@ -0,0 +1,68 @@ +package club.wpia.gigi.pages; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + +import org.junit.Test; + +import club.wpia.gigi.GigiApiException; +import club.wpia.gigi.dbObjects.Certificate; +import club.wpia.gigi.dbObjects.Certificate.CSRType; +import club.wpia.gigi.dbObjects.Digest; +import club.wpia.gigi.testUtils.ClientTest; +import club.wpia.gigi.testUtils.IOUtils; + +public class TestMain extends ClientTest { + + @Test + public void testPasswordLogin() throws MalformedURLException, IOException { + URLConnection uc = new URL("https://" + getServerName()).openConnection(); + uc.addRequestProperty("Cookie", cookie); + String content = IOUtils.readURL(uc); + + assertThat(content, not(containsString("via certificate"))); + + makeAgent(u.getId()); + uc = new URL("https://" + getServerName()).openConnection(); + uc.addRequestProperty("Cookie", cookie); + content = IOUtils.readURL(uc); + assertThat(content, containsString("For some actions, e.g. add verification, support, you need to be authenticated via certificate.")); + + } + + @Test + public void testCertLogin() throws GeneralSecurityException, IOException, GigiApiException, InterruptedException { + KeyPair kp = generateKeypair(); + String csr = generatePEMCSR(kp, "CN=" + u.getPreferredName().toString()); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", u.getPreferredName().toString()), Digest.SHA256, csr, CSRType.CSR, getClientProfile()); + final PrivateKey pk = kp.getPrivate(); + await(c.issue(null, "2y", u)); + final X509Certificate ce = c.cert(); + c.setLoginEnabled(true); + cookie = login(pk, ce); + loginCertificate = c; + loginPrivateKey = pk; + + URLConnection uc = new URL("https://" + getSecureServerName()).openConnection(); + authenticate((HttpURLConnection) uc); + String content = IOUtils.readURL(uc); + assertThat(content, not(containsString("via certificate"))); + + makeAgent(u.getId()); + uc = new URL("https://" + getSecureServerName()).openConnection(); + authenticate((HttpURLConnection) uc); + content = IOUtils.readURL(uc); + assertThat(content, containsString("You are authenticated via certificate, so you will be able to perform all actions.")); + + } +} diff --git a/tests/club/wpia/gigi/pages/admin/TestSEAdminNotificationMail.java b/tests/club/wpia/gigi/pages/admin/TestSEAdminNotificationMail.java index 97ac6a00..180455ce 100644 --- a/tests/club/wpia/gigi/pages/admin/TestSEAdminNotificationMail.java +++ b/tests/club/wpia/gigi/pages/admin/TestSEAdminNotificationMail.java @@ -158,7 +158,7 @@ public class TestSEAdminNotificationMail extends SEClientTest { // supporter removes supporter flag URLConnection uc = post(SupportUserDetailsPage.PATH + u.getId() + "/", "removeGroup&groupToModify=" + URLEncoder.encode(Group.SUPPORTER.getDBName(), "UTF-8")); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + MyDetails.PATH, uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + MyDetails.PATH, uc.getHeaderField("Location")); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); Group.SUPPORTER.getName().output(pw, Language.getInstance(Locale.ENGLISH), new HashMap()); diff --git a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageCertSearch.java b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageCertSearch.java index 74375f2f..cf9b403b 100644 --- a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageCertSearch.java +++ b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageCertSearch.java @@ -46,13 +46,13 @@ public class TestSEAdminPageCertSearch extends SEClientTest { @Test public void testSerialSearch() throws IOException { URLConnection uc = post(cookie, FindCertPage.PATH, "certType=serial&process=Next&cert=" + c.getSerial(), 0); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + Certificates.SUPPORT_PATH + "/" + c.getSerial(), uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + Certificates.SUPPORT_PATH + "/" + c.getSerial(), uc.getHeaderField("Location")); } @Test public void testEmailSearch() throws IOException { URLConnection uc = post(cookie, FindCertPage.PATH, "certType=email&process=Next&cert=" + URLEncoder.encode(certMail, "UTF-8"), 0); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + Certificates.SUPPORT_PATH + "/" + c.getSerial(), uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + Certificates.SUPPORT_PATH + "/" + c.getSerial(), uc.getHeaderField("Location")); } @Test @@ -67,7 +67,7 @@ public class TestSEAdminPageCertSearch extends SEClientTest { @Test public void testRevoke() throws IOException { URLConnection conn = post(Certificates.SUPPORT_PATH + "/" + c.getSerial(), "action=revoke"); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + Certificates.SUPPORT_PATH + "/" + c.getSerial(), conn.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + Certificates.SUPPORT_PATH + "/" + c.getSerial(), conn.getHeaderField("Location")); for (int i = 0; i < 2; i++) { TestMail tm = getMailReceiver().receive(i == 0 ? ServerConstants.getSupportMailAddress() : certMail); assertThat(tm.getMessage(), CoreMatchers.containsString(certMail)); diff --git a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageDetails.java b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageDetails.java index 9b92fcbc..9187c4f1 100644 --- a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageDetails.java +++ b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageDetails.java @@ -15,6 +15,7 @@ import org.junit.Test; import club.wpia.gigi.GigiApiException; import club.wpia.gigi.database.GigiPreparedStatement; +import club.wpia.gigi.dbObjects.Certificate; import club.wpia.gigi.dbObjects.EmailAddress; import club.wpia.gigi.dbObjects.ObjectCache; import club.wpia.gigi.dbObjects.User; @@ -27,7 +28,11 @@ import club.wpia.gigi.util.DayDate; public class TestSEAdminPageDetails extends SEClientTest { - public TestSEAdminPageDetails() throws IOException, GigiApiException {} + private Certificate cs; + + public TestSEAdminPageDetails() throws IOException, GigiApiException { + cs = loginCertificate; + } @Test public void testUserDetailsDisplay() throws MalformedURLException, IOException { @@ -118,12 +123,13 @@ public class TestSEAdminPageDetails extends SEClientTest { String clientCookie = login(email, TEST_PASSWORD); // try to open mypoints as user + loginCertificate = null; HttpURLConnection uc = get(clientCookie, SupportUserDetailsPage.PATH + id + "/points"); assertEquals(403, uc.getResponseCode()); // enter verification and open mypoints as supporter - + loginCertificate = cs; makeAgent(this.id); String location = createUniqueName(); try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `when`=? ")) { @@ -157,7 +163,10 @@ public class TestSEAdminPageDetails extends SEClientTest { } private int logCountUser(String cookie) throws IOException { - return getLogEntryCount(IOUtils.readURL(get(cookie, History.PATH))); + loginCertificate = null; + int count = getLogEntryCount(IOUtils.readURL(get(cookie, History.PATH))); + loginCertificate = cs; + return count; } private int getLogEntryCount(String readURL) { diff --git a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserDomainSearch.java b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserDomainSearch.java index d820a1d1..72bb2a6e 100644 --- a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserDomainSearch.java +++ b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserDomainSearch.java @@ -52,13 +52,13 @@ public class TestSEAdminPageUserDomainSearch extends SEClientTest { public void testDomainSearch() throws MalformedURLException, UnsupportedEncodingException, IOException, GigiApiException { URLConnection uc = post(FindUserByDomainPage.PATH, "process&domain=" + URLEncoder.encode(domainName, "UTF-8")); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + SupportUserDetailsPage.PATH + tid + "/", uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + SupportUserDetailsPage.PATH + tid + "/", uc.getHeaderField("Location")); } @Test public void testDomainSearchById() throws MalformedURLException, UnsupportedEncodingException, IOException, GigiApiException { URLConnection uc = post(FindUserByDomainPage.PATH, "process&domain=#" + d.getId()); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + SupportUserDetailsPage.PATH + tid + "/", uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + SupportUserDetailsPage.PATH + tid + "/", uc.getHeaderField("Location")); } @Test @@ -91,7 +91,7 @@ public class TestSEAdminPageUserDomainSearch extends SEClientTest { // test URLConnection uc = post(FindUserByDomainPage.PATH, "process&domain=" + URLEncoder.encode(dom, "UTF-8")); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + SupportOrgDomainPage.PATH + d.getId(), uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + SupportOrgDomainPage.PATH + d.getId(), uc.getHeaderField("Location")); String s = IOUtils.readURL(get(cookie, SupportOrgDomainPage.PATH + d.getId())); assertThat(s, containsString(dom)); diff --git a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserMailSearch.java b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserMailSearch.java index a21ca96a..50d96dd5 100644 --- a/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserMailSearch.java +++ b/tests/club/wpia/gigi/pages/admin/TestSEAdminPageUserMailSearch.java @@ -30,7 +30,7 @@ public class TestSEAdminPageUserMailSearch extends SEClientTest { int id = createVerifiedUser("Först", "Secönd", mail, TEST_PASSWORD); URLConnection uc = post(cookie, FindUserByEmailPage.PATH, "process&email=" + URLEncoder.encode(mail, "UTF-8"), 0); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); } @Test @@ -39,7 +39,7 @@ public class TestSEAdminPageUserMailSearch extends SEClientTest { int id = createVerifiedUser("Först", "Secönd", mail, TEST_PASSWORD); URLConnection uc = post(cookie, FindUserByEmailPage.PATH, "process&email=" + URLEncoder.encode("%@example.tld", "UTF-8"), 0); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); } @Test @@ -91,7 +91,7 @@ public class TestSEAdminPageUserMailSearch extends SEClientTest { createVerifiedEmail(testuser, mail2); URLConnection uc = post(cookie, FindUserByEmailPage.PATH, "process&email=" + URLEncoder.encode(mail2, "UTF-8"), 0); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); } @Test @@ -122,7 +122,7 @@ public class TestSEAdminPageUserMailSearch extends SEClientTest { createVerifiedEmail(testuser, mail3); URLConnection uc = post(cookie, FindUserByEmailPage.PATH, "process&email=" + URLEncoder.encode("%@example3.org", "UTF-8"), 0); - assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); + assertEquals("https://" + ServerConstants.getHostNamePortSecure(Host.SECURE) + SupportUserDetailsPage.PATH + id + "/", uc.getHeaderField("Location")); uc = post(cookie, FindUserByEmailPage.PATH, "process&email=" + URLEncoder.encode("%@test3.org", "UTF-8"), 0); diff --git a/tests/club/wpia/gigi/pages/admin/TestSEAdminTicketSetting.java b/tests/club/wpia/gigi/pages/admin/TestSEAdminTicketSetting.java index e20b4944..e85b03e9 100644 --- a/tests/club/wpia/gigi/pages/admin/TestSEAdminTicketSetting.java +++ b/tests/club/wpia/gigi/pages/admin/TestSEAdminTicketSetting.java @@ -7,12 +7,20 @@ import static org.junit.Assert.*; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; import java.util.Random; import org.junit.Test; import club.wpia.gigi.GigiApiException; +import club.wpia.gigi.dbObjects.Certificate; +import club.wpia.gigi.dbObjects.Certificate.CSRType; +import club.wpia.gigi.dbObjects.Digest; import club.wpia.gigi.dbObjects.Group; +import club.wpia.gigi.pages.admin.support.FindCertPage; import club.wpia.gigi.pages.admin.support.FindUserByDomainPage; import club.wpia.gigi.pages.admin.support.FindUserByEmailPage; import club.wpia.gigi.pages.admin.support.SupportEnterTicketForm; @@ -24,16 +32,31 @@ public class TestSEAdminTicketSetting extends ClientTest { public TestSEAdminTicketSetting() throws IOException, GigiApiException { grant(u, Group.SUPPORTER); - cookie = login(email, TEST_PASSWORD); + try { + KeyPair kp = generateKeypair(); + String csr = generatePEMCSR(kp, "CN=" + u.getPreferredName().toString()); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", u.getPreferredName().toString()), Digest.SHA256, csr, CSRType.CSR, getClientProfile()); + final PrivateKey pk = kp.getPrivate(); + await(c.issue(null, "2y", u)); + final X509Certificate ce = c.cert(); + c.setLoginEnabled(true); + cookie = login(pk, ce); + loginCertificate = c; + loginPrivateKey = pk; + } catch (InterruptedException e) { + throw new GigiApiException(e.toString()); + } catch (GeneralSecurityException e) { + throw new GigiApiException(e.toString()); + } } @Test public void testFulltextMailSearch() throws MalformedURLException, UnsupportedEncodingException, IOException { assertEquals(403, get(FindUserByEmailPage.PATH).getResponseCode()); - assertEquals(302, post(cookie, SupportEnterTicketPage.PATH, "ticketno=a20140808.8&setTicket=action", 0).getResponseCode()); + assertEquals(302, post(SupportEnterTicketPage.PATH, "ticketno=a20140808.8&setTicket=action", 0).getResponseCode()); assertEquals(200, get(FindUserByEmailPage.PATH).getResponseCode()); assertEquals(200, get(FindUserByDomainPage.PATH).getResponseCode()); - assertEquals(302, post(cookie, SupportEnterTicketPage.PATH, "ticketno=a20140808.8&deleteTicket=action", 0).getResponseCode()); + assertEquals(302, post(SupportEnterTicketPage.PATH, "ticketno=a20140808.8&deleteTicket=action", 0).getResponseCode()); assertEquals(403, get(FindUserByEmailPage.PATH).getResponseCode()); } @@ -45,9 +68,9 @@ public class TestSEAdminTicketSetting extends ClientTest { // test allowed character for (char ch : SupportEnterTicketForm.TICKET_PREFIX.toCharArray()) { ticket = ch + "20171212.1"; - assertEquals(302, post(cookie, SupportEnterTicketPage.PATH, "ticketno=" + ticket + "&setTicket=action", 0).getResponseCode()); + assertEquals(302, post(SupportEnterTicketPage.PATH, "ticketno=" + ticket + "&setTicket=action", 0).getResponseCode()); ticket = Character.toUpperCase(ch) + "20171212.1"; - assertEquals(302, post(cookie, SupportEnterTicketPage.PATH, "ticketno=" + ticket + "&setTicket=action", 0).getResponseCode()); + assertEquals(302, post(SupportEnterTicketPage.PATH, "ticketno=" + ticket + "&setTicket=action", 0).getResponseCode()); alphabet = alphabet.replaceAll(Character.toString(ch), ""); } @@ -99,4 +122,15 @@ public class TestSEAdminTicketSetting extends ClientTest { String res = IOUtils.readURL(post(SupportEnterTicketPage.PATH, "ticketno=" + ticket + "&setTicket=action")); assertThat(res, containsString("Ticket format malformed")); } + + @Test + public void testPWLogin() throws MalformedURLException, UnsupportedEncodingException, IOException { + String cookiePW = login(email, TEST_PASSWORD); + loginCertificate = null; + assertEquals(403, get(cookiePW, SupportEnterTicketPage.PATH).getResponseCode()); + assertEquals(403, get(cookiePW, FindUserByEmailPage.PATH).getResponseCode()); + assertEquals(403, get(cookiePW, FindUserByDomainPage.PATH).getResponseCode()); + assertEquals(403, get(cookiePW, FindCertPage.PATH).getResponseCode()); + } + } diff --git a/tests/club/wpia/gigi/testUtils/ClientTest.java b/tests/club/wpia/gigi/testUtils/ClientTest.java index 1cd12d26..17103f7c 100644 --- a/tests/club/wpia/gigi/testUtils/ClientTest.java +++ b/tests/club/wpia/gigi/testUtils/ClientTest.java @@ -1,8 +1,14 @@ package club.wpia.gigi.testUtils; import java.io.IOException; +import java.io.OutputStream; import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.security.GeneralSecurityException; +import club.wpia.gigi.GigiApiException; import club.wpia.gigi.dbObjects.User; /** @@ -44,11 +50,44 @@ public abstract class ClientTest extends ManagedTest { } public HttpURLConnection post(String path, String query, int formIndex) throws IOException { - return post(cookie, path, query, formIndex); + String server = getServerName(); + if (loginCertificate != null) { + server = getSecureServerName(); + } + URLConnection uc = new URL("https://" + server + path).openConnection(); + authenticate((HttpURLConnection) uc); + String csrf = getCSRF(uc, formIndex); + + uc = new URL("https://" + server + path).openConnection(); + authenticate((HttpURLConnection) uc); + uc.setDoOutput(true); + OutputStream os = uc.getOutputStream(); + os.write(("csrf=" + URLEncoder.encode(csrf, "UTF-8") + "&" // + + query// + ).getBytes("UTF-8")); + os.flush(); + return (HttpURLConnection) uc; } public HttpURLConnection get(String path) throws IOException { - return get(cookie, path); + String server = getServerName(); + if (loginCertificate != null) { + server = getSecureServerName(); + } + URLConnection uc = new URL("https://" + server + path).openConnection(); + authenticate((HttpURLConnection) uc); + return (HttpURLConnection) uc; + } + + protected void authenticate(HttpURLConnection uc) throws IOException { + uc.addRequestProperty("Cookie", cookie); + if (loginCertificate != null) { + try { + authenticateClientCert(loginPrivateKey, loginCertificate.cert(), uc); + } catch (GeneralSecurityException | GigiApiException e) { + throw new IOException(e); + } + } } } diff --git a/tests/club/wpia/gigi/testUtils/ManagedTest.java b/tests/club/wpia/gigi/testUtils/ManagedTest.java index aa18a304..25df2725 100644 --- a/tests/club/wpia/gigi/testUtils/ManagedTest.java +++ b/tests/club/wpia/gigi/testUtils/ManagedTest.java @@ -17,6 +17,7 @@ import java.net.URLConnection; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Paths; +import java.security.GeneralSecurityException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.Principal; @@ -42,6 +43,7 @@ import club.wpia.gigi.DevelLauncher; import club.wpia.gigi.GigiApiException; import club.wpia.gigi.database.GigiPreparedStatement; import club.wpia.gigi.database.GigiResultSet; +import club.wpia.gigi.dbObjects.Certificate; import club.wpia.gigi.dbObjects.EmailAddress; import club.wpia.gigi.dbObjects.Group; import club.wpia.gigi.dbObjects.Job; @@ -70,6 +72,10 @@ public class ManagedTest extends ConfiguredTest { private static String acceptLanguage = null; + protected static Certificate loginCertificate; + + protected static PrivateKey loginPrivateKey; + public static void setAcceptLanguage(String acceptLanguage) { ManagedTest.acceptLanguage = acceptLanguage; } @@ -469,12 +475,16 @@ public class ManagedTest extends ConfiguredTest { } public static HttpURLConnection post(String cookie, String path, String query, int formIndex) throws IOException, MalformedURLException, UnsupportedEncodingException { - URLConnection uc = new URL("https://" + getServerName() + path).openConnection(); - uc.addRequestProperty("Cookie", cookie); + String server = getServerName(); + if (loginCertificate != null) { + server = getSecureServerName(); + } + URLConnection uc = new URL("https://" + server + path).openConnection(); + authenticate((HttpURLConnection) uc, cookie); String csrf = getCSRF(uc, formIndex); - uc = new URL("https://" + getServerName() + path).openConnection(); - uc.addRequestProperty("Cookie", cookie); + uc = new URL("https://" + server + path).openConnection(); + authenticate((HttpURLConnection) uc, cookie); uc.setDoOutput(true); OutputStream os = uc.getOutputStream(); os.write(("csrf=" + URLEncoder.encode(csrf, "UTF-8") + "&" // @@ -485,8 +495,12 @@ public class ManagedTest extends ConfiguredTest { } public static HttpURLConnection get(String cookie, String path) throws IOException { - URLConnection uc = new URL("https://" + getServerName() + path).openConnection(); - uc.addRequestProperty("Cookie", cookie); + String server = getServerName(); + if (loginCertificate != null) { + server = getSecureServerName(); + } + URLConnection uc = new URL("https://" + server + path).openConnection(); + authenticate((HttpURLConnection) uc, cookie); return (HttpURLConnection) uc; } @@ -525,4 +539,15 @@ public class ManagedTest extends ConfiguredTest { supporter = User.getById(i); return supporter; } + + protected static void authenticate(HttpURLConnection uc, String cookie) throws IOException { + uc.addRequestProperty("Cookie", cookie); + if (loginCertificate != null) { + try { + authenticateClientCert(loginPrivateKey, loginCertificate.cert(), uc); + } catch (GeneralSecurityException | GigiApiException e) { + throw new IOException(e); + } + } + } } diff --git a/tests/club/wpia/gigi/testUtils/SEClientTest.java b/tests/club/wpia/gigi/testUtils/SEClientTest.java index 004f34f4..358a8c1e 100644 --- a/tests/club/wpia/gigi/testUtils/SEClientTest.java +++ b/tests/club/wpia/gigi/testUtils/SEClientTest.java @@ -3,8 +3,15 @@ package club.wpia.gigi.testUtils; import static org.junit.Assert.*; import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; import club.wpia.gigi.GigiApiException; +import club.wpia.gigi.dbObjects.Certificate; +import club.wpia.gigi.dbObjects.Certificate.CSRType; +import club.wpia.gigi.dbObjects.Digest; import club.wpia.gigi.dbObjects.Group; import club.wpia.gigi.pages.admin.support.SupportEnterTicketPage; @@ -16,7 +23,22 @@ public abstract class SEClientTest extends ClientTest { public SEClientTest() throws IOException, GigiApiException { grant(u, Group.SUPPORTER); - cookie = login(email, TEST_PASSWORD); + try { + KeyPair kp = generateKeypair(); + String csr = generatePEMCSR(kp, "CN=" + u.getPreferredName().toString()); + Certificate c = new Certificate(u, u, Certificate.buildDN("CN", u.getPreferredName().toString()), Digest.SHA256, csr, CSRType.CSR, getClientProfile()); + final PrivateKey pk = kp.getPrivate(); + await(c.issue(null, "2y", u)); + final X509Certificate ce = c.cert(); + c.setLoginEnabled(true); + loginCertificate = c; + loginPrivateKey = pk; + cookie = login(pk, ce); + } catch (InterruptedException e) { + throw new GigiApiException(e.toString()); + } catch (GeneralSecurityException e) { + throw new GigiApiException(e.toString()); + } assertEquals(302, post(cookie, SupportEnterTicketPage.PATH, "ticketno=a20140808.8&setTicket=action", 0).getResponseCode()); }