From: Felix Dörre Date: Mon, 17 Dec 2018 20:00:32 +0000 (+0100) Subject: Merge "chg: rephrase wording to make clear that OrgAdmin works on behalf of org" X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=77fa99471ddad0dfc5c039829498fb973fbf341f;hp=5b7941ba6f39cabd29b3eb20db0fee688c3fffde Merge "chg: rephrase wording to make clear that OrgAdmin works on behalf of org" --- diff --git a/src/club/wpia/gigi/dbObjects/Certificate.java b/src/club/wpia/gigi/dbObjects/Certificate.java index 0654a416..61fd7d34 100644 --- a/src/club/wpia/gigi/dbObjects/Certificate.java +++ b/src/club/wpia/gigi/dbObjects/Certificate.java @@ -500,6 +500,19 @@ public class Certificate implements IdCachable { return null; } + public java.util.Date getExpiryDate() { + if (getStatus() == CertificateStatus.ISSUED) { + try (GigiPreparedStatement prep = new GigiPreparedStatement("SELECT expire FROM certs WHERE id=?")) { + prep.setInt(1, getId()); + GigiResultSet res = prep.executeQuery(); + if (res.next()) { + return res.getTimestamp("expire"); + } + } + } + return null; + } + public void setLoginEnabled(boolean activate) { if (activate) { if ( !isLoginEnabled()) { diff --git a/src/club/wpia/gigi/output/NameInput.java b/src/club/wpia/gigi/output/NameInput.java index d9116b12..272c06e4 100644 --- a/src/club/wpia/gigi/output/NameInput.java +++ b/src/club/wpia/gigi/output/NameInput.java @@ -106,6 +106,9 @@ public class NameInput implements Outputable { if (toSplit == null || toSplit.trim().isEmpty()) { return new String[0]; } + toSplit = toSplit.replaceAll("(?>[\\p{Z}\\s]*)([\u002d\u058a\u05be\u1806\u2010\u2011\u2012\u2013\u2014\u2015\u2e3a\u2e3b\ufe58\ufe63\uff0d])(?>[\\p{Z}\\s]*)", "-"); + toSplit = toSplit.replaceAll("(?>[\\p{Z}\\s]+)", " ").trim(); + return toSplit.split(" "); } diff --git a/src/club/wpia/gigi/pages/main/CertStatusRequestForm.java b/src/club/wpia/gigi/pages/main/CertStatusRequestForm.java index 88e1264b..5d23f67f 100644 --- a/src/club/wpia/gigi/pages/main/CertStatusRequestForm.java +++ b/src/club/wpia/gigi/pages/main/CertStatusRequestForm.java @@ -1,6 +1,7 @@ package club.wpia.gigi.pages.main; import java.io.PrintWriter; +import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -46,9 +47,12 @@ public class CertStatusRequestForm extends Form { } if (c.getStatus() == CertificateStatus.REVOKED) { - java.util.Date revocationDate = c.getRevocationDate(); + Date revocationDate = c.getRevocationDate(); throw new PermamentFormException(new GigiApiException(SprintfCommand.createSimple("Certificate has been revoked on {0}.", revocationDate))); } + if (c.getExpiryDate().before(new Date())) { + return new SuccessMessageResult((SprintfCommand.createSimple("Certificate is valid but has expired on {0}.", c.getExpiryDate()))); + } return new SuccessMessageResult(new TranslateCommand("Certificate is valid.")); } diff --git a/src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ b/src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ index 5c63f04f..6978a60f 100644 --- a/src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ +++ b/src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ @@ -1,4 +1,5 @@

+ diff --git a/tests/club/wpia/gigi/pages/account/TestMyDetailsEdit.java b/tests/club/wpia/gigi/pages/account/TestMyDetailsEdit.java index d5b1cf33..eed6b771 100644 --- a/tests/club/wpia/gigi/pages/account/TestMyDetailsEdit.java +++ b/tests/club/wpia/gigi/pages/account/TestMyDetailsEdit.java @@ -147,4 +147,78 @@ public class TestMyDetailsEdit extends ManagedTest { // test add invalid group assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "action=addGroup&groupToModify=non-existing", 0)); } + + @Test + public void testHyphen() throws IOException { + + String fn = "Hans-Dieter"; + String fnc = fn; + String ln = "Müller-Schmitz"; + String lnc = ln; + testAddName(fn, ln, fnc, lnc); + + fn = "Hans- Dieter"; + ln = "Müller- Schmitz"; + testAddName(fn, ln, fnc, lnc); + + fn = "Hans -Dieter"; + ln = "Müller -Schmitz"; + testAddName(fn, ln, fnc, lnc); + + fn = "Hans - Dieter"; + ln = "Müller - Schmitz"; + testAddName(fn, ln, fnc, lnc); + + String[] hyphen = { + "\u002d", "\u058a", "\u05be", "\u1806", "\u2010", "\u2011", "\u2012", "\u2013", "\u2014", "\u2015", "\u2e3a", "\u2e3b", "\ufe58", "\ufe63", "\uff0d" + }; + + for (int i = 0; i < hyphen.length; i++) { + fn = "Hans " + hyphen[i] + " Dieter"; + ln = "Müller " + hyphen[i] + " Schmitz"; + testAddName(fn, ln, fnc, lnc); + } + } + + @Test + public void testBlanks() throws IOException { + + String fn = "Hans"; + String fnc = fn; + String ln = "Müller"; + String lnc = ln; + testAddName(fn, ln, fnc, lnc); + + fn = "Hans "; + ln = "Müller "; + testAddName(fn, ln, fnc, lnc); + + fn = " Hans"; + ln = " Müller"; + testAddName(fn, ln, fnc, lnc); + + fn = "Hans Dieter"; + ln = "Müller Schmitz"; + testAddName(fn, ln, fnc, lnc, 4); + + fn = "Hans Dieter "; + ln = " Müller Schmitz"; + testAddName(fn, ln, fnc, lnc, 4); + } + + public void testAddName(String fn, String ln, String fnc, String lnc) throws IOException { + testAddName(fn, ln, fnc, lnc, 2); + } + + public void testAddName(String fn, String ln, String fnc, String lnc, int partLength) throws IOException { + int startn = User.getById(id).getNames().length; + assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "action=addName&name-type=western&fname=" + fn + "&lname=" + ln, 0)); + User u = User.getById(id); + + NamePart[] parts = u.getNames()[startn].getParts(); + assertThat(Arrays.asList(parts), CoreMatchers.hasItem(new NamePart(NamePartType.FIRST_NAME, fnc))); + assertThat(Arrays.asList(parts), CoreMatchers.hasItem(new NamePart(NamePartType.LAST_NAME, lnc))); + assertEquals(partLength, parts.length); + assertEquals(startn + 1, User.getById(id).getNames().length); + } } diff --git a/tests/club/wpia/gigi/pages/main/CertStatusTest.java b/tests/club/wpia/gigi/pages/main/CertStatusTest.java index 373c55c2..f16ebb36 100644 --- a/tests/club/wpia/gigi/pages/main/CertStatusTest.java +++ b/tests/club/wpia/gigi/pages/main/CertStatusTest.java @@ -11,11 +11,14 @@ import java.net.URLConnection; import java.net.URLEncoder; import java.security.GeneralSecurityException; import java.security.KeyPair; +import java.time.LocalDate; +import java.time.ZoneId; import org.hamcrest.CoreMatchers; 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.Certificate.CertificateStatus; import club.wpia.gigi.dbObjects.Certificate.RevocationType; @@ -31,8 +34,12 @@ public class CertStatusTest extends ClientTest { private Certificate cert; + private Certificate certExpired; + private String serial; + private String serialExpired; + private String foreignPEM = "-----BEGIN CERTIFICATE-----\n" + "MIIGvjCCBKagAwIBAgIVEQAAAAfLkxaJ4wATnrSBUbEr3UsxMA0GCSqGSIb3DQEB\n" + "DQUAMHExFzAVBgNVBAMMDkFzc3VyZWQgMjAxNy0yMSowKAYDVQQKDCFUZXN0IEVu\n" + "dmlyb25tZW50IENBIEx0ZC4tMTctMDMtMDQxHTAbBgNVBAsMFFRlc3QgRW52aXJv\n" + "bm1lbnQgQ0FzMQswCQYDVQQGEwJBVTAeFw0xNzA4MTUxMDI5NTdaFw0xNzA4MTYw\n" + "MDAwMDBaMDkxETAPBgNVBAMMCE1hcmN1cyBNMSQwIgYJKoZIhvcNAQkBFhVtLm1h\n" + "ZW5nZWxAaW5vcGlhZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n" + "AQCv9hFCn69zHNapLimr4B9xK2PcYYRmINbBiihJ42WSIcf6VfxgQRPXZ9JCGDKn\n" + "haANqAyfOCuvtIuN1jJoYOo1VTQd3tkL9IvAwPVpsPiiHeYKqJRNxCkfU6kPGY2x\n" + "QV4+gDErXp/0AL792oAq6W3RoYIeiHXLKvLoYLBbSqtTCkfCYgEhv/3bflswU1JH\n" + "fr6QsvUJ1epH7QpiE5J8pp9hWKfcEufekYnMWASKITS4ronQcyfMocf9BlEf87ou\n" + "wri0NF8EBBhwq6C2+Ag9QlNHtylyUTj4+3XR//3K+6T/8neNK/9CNZ6sXqz5SnFX\n" + "BZTQONK2vavDvbSDhgQ0CuCbyN+rwjjSHYSgywqjkKb1tzB39N7Hd2fR5LcnBD3/\n" + "alQGIh808iukSm7TNwmdSCl2dRug2nTH5qdFLgk2wH+UcoOZH1lEn3UA2IYScmUH\n" + "sgeF6bIojS8Qj1UQZPwlblDiNvudYx2QQG9aNqWz+4O+6a5IpRugY9jnG5Z5sPum\n" + "IpXl1q+VNz8FLlZavpxccjGlIW0179kctA5FEoTHgogzE/rAt5tmHD+kdVEgpquR\n" + "yjpVVYG/R64oUQDjBeen1aKt2yzv+CP1frvml/bUKcb4qZ3z15K6gD0wrKQVWJoD\n" + "0j6gPAs10N2khPbjX9sYJqFr4Tket1DtCIusPQj7JxQm1wIDAQABo4IBgzCCAX8w\n" + "DAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU5N/6GJVVMyrAd/HgiN7PQQ7mTOUwHwYD\n" + "VR0jBBgwFoAUwygt1+5B0HactieygKVNyE3m9W0wDgYDVR0PAQH/BAQDAgOoMB0G\n" + "A1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDCBjgYIKwYBBQUHAQEEgYEwfzAz\n" + "BggrBgEFBQcwAYYnaHR0cDovL2cyLm9jc3AudGVzdDEuYmFja3VwLmRvZ2NyYWZ0\n" + "LmRlMEgGCCsGAQUFBzAChjxodHRwOi8vZzIuY3J0LnRlc3QxLmJhY2t1cC5kb2dj\n" + "cmFmdC5kZS9nMi8yMDE3L2Fzc3VyZWQtMi5jcnQwTQYDVR0fBEYwRDBCoECgPoY8\n" + "aHR0cDovL2cyLmNybC50ZXN0MS5iYWNrdXAuZG9nY3JhZnQuZGUvZzIvMjAxNy9h\n" + "c3N1cmVkLTIuY3JsMCAGA1UdEQQZMBeBFW0ubWFlbmdlbEBpbm9waWFlLmNvbTAN\n" + "BgkqhkiG9w0BAQ0FAAOCAgEATRC7wwfFNExFk6LGcAbYSJViVs8ZgFuaTEzlBrik\n" + "mf9f8QA7Aj2bH2hqCdjbem1ElXhbADcJopS46P7yfH57zUj3qvD9znK0DdqWpvsO\n" + "nCB7/kdA0KysxTZ+D5gFgk/MpDfNP8ALB1SHGEOv/l4gQs0Zn6ORxt+4zrLzqExO\n" + "dMYdxcVQCl0ft5tQRUSxg1k2y8crgplR02TvhJCrb+RNCS0SQMkEA11bZKEpLBYk\n" + "bJMJYMr+SMN/wtC/vjXm9hrPGqnfqpJC7IqHUfzcBt10dGPqzvO/6xnEZn4YSgjr\n" + "MyoVUnOmcgolFrToYbXr3CNoQFO5Dgz7hbXH59/6ph35g7Q3hllTV+DGV753Baaa\n" + "bMgAsUeJqdMcJSAorLKjibinF/odbJ/kghAg7LBLQUmCvfYWzKhnfETXQ/qXbOk7\n" + "fufEB0z1AnzOB032Cde+FZg1NofjyF8N0UuK4l8fS+hSX6bcJaIuvUSNm5Mj2laZ\n" + "cskPgOu2Gng1JteLbotEKnruKshfKgo64Fq/mPASHfrSdAeQ/shlL6JG3QQeiw9k\n" + "Yu7lu7neRduthxwEdZ8EYrQ0fnHWrmnGsDCpvNIv1coaPc0ghi2pfGjEBAXGQoQ3\n" + "7Bia1anze/wG/9viZyuH1Ms10Ya9E8bPfB1D7B26tB6IZUNLaMnoYbCd+EN7Zjx/\n" + "Yac=\n" + "-----END CERTIFICATE-----"; public CertStatusTest() throws GeneralSecurityException, IOException, GigiApiException, InterruptedException { @@ -46,31 +53,44 @@ public class CertStatusTest extends ClientTest { await(j); serial = cert.getSerial().toLowerCase(); + certExpired = cr.draft(); + j = certExpired.issue(null, "2y", u); + await(j); + serialExpired = certExpired.getSerial().toLowerCase(); + try (GigiPreparedStatement prep = new GigiPreparedStatement("UPDATE `certs` SET `expire`=? WHERE `id`=?")) { + prep.setDate(1, java.sql.Date.valueOf(LocalDate.now(ZoneId.of("UTC")))); + prep.setInt(2, certExpired.getId()); + prep.execute(); + } + } @Test public void testCertStatus() throws IOException, InterruptedException, GigiApiException, GeneralSecurityException { - testExecution("serial=" + URLEncoder.encode(serial, "UTF-8"), null, false);// serial - testExecution("serial=0000" + URLEncoder.encode(serial, "UTF-8"), null, false);// leading - // Zeros - testExecution("serial=0000" + URLEncoder.encode(serial.toUpperCase(), "UTF-8"), null, false);// upper - // case + testExecution("serial=" + URLEncoder.encode(serial, "UTF-8"), null, false, false);// serial + testExecution("serial=0000" + URLEncoder.encode(serial, "UTF-8"), null, false, false);// leading + // Zeros + testExecution("serial=0000" + URLEncoder.encode(serial.toUpperCase(), "UTF-8"), null, false, false);// upper + // case - testExecution("serial=0000", "Malformed serial", false); - testExecution("serial=0lkd", "Malformed serial", false); + testExecution("serial=0000", "Malformed serial", false, false); + testExecution("serial=0lkd", "Malformed serial", false, false); - testExecution("cert=" + URLEncoder.encode(PEM.encode("CERTIFICATE", cert.cert().getEncoded()), "UTF-8"), null, false); - testExecution("cert=" + URLEncoder.encode(foreignPEM, "UTF-8"), "Certificate to check not found.", false); - testExecution("cert=sometext", "Certificate could not be parsed", false); + testExecution("cert=" + URLEncoder.encode(PEM.encode("CERTIFICATE", cert.cert().getEncoded()), "UTF-8"), null, false, false); + testExecution("cert=" + URLEncoder.encode(foreignPEM, "UTF-8"), "Certificate to check not found.", false, false); + testExecution("cert=sometext", "Certificate could not be parsed", false, false); await(cert.revoke(RevocationType.USER)); - testExecution("serial=" + URLEncoder.encode(serial, "UTF-8"), "Certificate has been revoked on ", true);// serial - testExecution("cert=" + URLEncoder.encode(PEM.encode("CERTIFICATE", cert.cert().getEncoded()), "UTF-8"), "Certificate has been revoked on ", true); + testExecution("serial=" + URLEncoder.encode(serial, "UTF-8"), "Certificate has been revoked on ", true, false);// serial + testExecution("cert=" + URLEncoder.encode(PEM.encode("CERTIFICATE", cert.cert().getEncoded()), "UTF-8"), "Certificate has been revoked on ", true, false); + + testExecution("serial=" + URLEncoder.encode(serialExpired, "UTF-8"), null, false, true);// serial + testExecution("cert=" + URLEncoder.encode(PEM.encode("CERTIFICATE", certExpired.cert().getEncoded()), "UTF-8"), null, false, true); } - public void testExecution(String query, String error, boolean revoked) throws IOException, InterruptedException, GigiApiException, GeneralSecurityException { + public void testExecution(String query, String error, boolean revoked, boolean expired) throws IOException, InterruptedException, GigiApiException, GeneralSecurityException { URLConnection uc = new URL("https://" + getServerName() + CertStatusRequestPage.PATH).openConnection(); uc.addRequestProperty("Cookie", cookie); String content = IOUtils.readURL(uc); @@ -88,7 +108,11 @@ public class CertStatusTest extends ClientTest { if (error == null) { assertThat(result, hasNoError()); - assertThat(result, CoreMatchers.containsString("Certificate is valid.")); + if (expired) { + assertThat(result, CoreMatchers.containsString("Certificate is valid but has expired on")); + } else { + assertThat(result, CoreMatchers.containsString("Certificate is valid.")); + } } else { assertThat(fetchStartErrorMessage(result), CoreMatchers.containsString(error)); if (revoked == false) {