]> WPIA git - gigi.git/commitdiff
Merge "chg: extract url to links.txt"
authorBenny Baumann <BenBE1987@gmx.net>
Thu, 8 Feb 2018 19:48:29 +0000 (20:48 +0100)
committerGerrit Code Review <gigi-system@dogcraft.de>
Thu, 8 Feb 2018 19:48:29 +0000 (20:48 +0100)
src/club/wpia/gigi/Gigi.java
src/club/wpia/gigi/dbObjects/EmailAddress.java
src/club/wpia/gigi/pages/account/MyDetails.java
src/club/wpia/gigi/pages/account/MyOrganisationsForm.templ [deleted file]
src/club/wpia/gigi/pages/account/certs/CertificateRequest.java
src/club/wpia/gigi/pages/orga/AffiliationForm.java
src/club/wpia/gigi/pages/orga/MyOrganisationsForm.java [moved from src/club/wpia/gigi/pages/account/MyOrganisationsForm.java with 94% similarity]
src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ [new file with mode: 0644]
src/club/wpia/gigi/pages/orga/SwitchOrganisation.java [new file with mode: 0644]
tests/club/wpia/gigi/pages/account/TestCertificateRequest.java
tests/club/wpia/gigi/pages/orga/TestOrgSwitch.java [new file with mode: 0644]

index 6d8996c97cac5633a1d14b9ef5e7eb953bdc47e5..035f1a6f5430997139c9c8060212cddd5ee8494b 100644 (file)
@@ -71,6 +71,7 @@ import club.wpia.gigi.pages.main.CertStatusRequestPage;
 import club.wpia.gigi.pages.main.KeyCompromisePage;
 import club.wpia.gigi.pages.main.RegisterPage;
 import club.wpia.gigi.pages.orga.CreateOrgPage;
+import club.wpia.gigi.pages.orga.SwitchOrganisation;
 import club.wpia.gigi.pages.orga.ViewOrgPage;
 import club.wpia.gigi.pages.statistics.StatisticsRoles;
 import club.wpia.gigi.pages.wot.Points;
@@ -164,6 +165,7 @@ public final class Gigi extends HttpServlet {
             putPage(TTPAdminPage.PATH + "/*", new TTPAdminPage(), admMenu);
             putPage(CreateOrgPage.DEFAULT_PATH, new CreateOrgPage(), orgAdm);
             putPage(ViewOrgPage.DEFAULT_PATH + "/*", new ViewOrgPage(), orgAdm);
+            putPage(SwitchOrganisation.PATH, new SwitchOrganisation(), orgAdm);
 
             Menu support = createMenu("Support Console");
             putPage(SupportEnterTicketPage.PATH, new SupportEnterTicketPage(), support);
index 319e415b93e86a97d89da13ddcf5b18e8df12ec8..7d4c984e8e8233892e537799ce8b3ec4b174e4d9 100644 (file)
@@ -13,6 +13,7 @@ import club.wpia.gigi.email.MailProbe;
 import club.wpia.gigi.localisation.Language;
 import club.wpia.gigi.output.template.SprintfCommand;
 import club.wpia.gigi.util.RandomToken;
+import club.wpia.gigi.util.TimeConditions;
 
 public class EmailAddress implements IdCachable, Verifyable {
 
@@ -122,9 +123,10 @@ public class EmailAddress implements IdCachable, Verifyable {
     }
 
     public boolean isVerified() {
-        try (GigiPreparedStatement statmt = new GigiPreparedStatement("SELECT 1 FROM `emailPinglog` WHERE `email`=? AND `uid`=? AND `type`='active' AND `status`='success'")) {
+        try (GigiPreparedStatement statmt = new GigiPreparedStatement("SELECT 1 FROM `emailPinglog` WHERE `email`=? AND `uid`=? AND `type`='active' AND `status`='success' AND `when` > (now() - interval '1 months' * ?::INTEGER)")) {
             statmt.setString(1, address);
             statmt.setInt(2, owner.getId());
+            statmt.setInt(3, TimeConditions.getInstance().getEmailPingMonths());
             GigiResultSet e = statmt.executeQuery();
             return e.next();
         }
index 12d127faf38f00bca879dbf6eda7446f7f4845b8..b4a52d4eb1609121127b2e4cb6731451f99f4214 100644 (file)
@@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletResponse;
 import club.wpia.gigi.output.template.Form;
 import club.wpia.gigi.pages.LoginPage;
 import club.wpia.gigi.pages.Page;
+import club.wpia.gigi.pages.orga.MyOrganisationsForm;
 
 public class MyDetails extends Page {
 
diff --git a/src/club/wpia/gigi/pages/account/MyOrganisationsForm.templ b/src/club/wpia/gigi/pages/account/MyOrganisationsForm.templ
deleted file mode 100644 (file)
index 96d7bbe..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<input type='hidden' name='orgaForm' value='orga'/>
-<h2><?=_My Organisations?></h2>
-<table class="table">
-<? foreach($orgas) { ?>
-<tr><td><?=$orgName?></td><td><?=$orgID?></td><td><input class="btn btn-info" type='submit' value='<?=_switch to this organisation?>' name='org:<?=$orgID?>'/></td></tr>
-<? } ?>
-</table>
-<? if($personal) { ?>
-<input class="btn btn-primary" type='submit' value='<?=_switch back to personal use?>' name='org-leave'/>
-<? } ?>
index 8a1bc5943ea8dad8c66ed7a5e360edd83278f13c..cdf4dd41eed765b5959cb979d571a9462d0bd89f 100644 (file)
@@ -35,6 +35,7 @@ import club.wpia.gigi.util.DomainAssessment;
 import club.wpia.gigi.util.PEM;
 import club.wpia.gigi.util.RateLimit;
 import club.wpia.gigi.util.ServerConstants;
+import club.wpia.gigi.util.TimeConditions;
 import sun.security.pkcs.PKCS9Attribute;
 import sun.security.pkcs10.PKCS10;
 import sun.security.pkcs10.PKCS10Attribute;
@@ -356,8 +357,8 @@ public class CertificateRequest {
                         valid = false;
                     }
                 }
-            } else if (san.getType() == SANType.EMAIL) {
-                if (emailTemp != null && owner.isValidEmail(san.getName())) {
+            } else if (san.getType() == SANType.EMAIL && emailTemp != null) {
+                if (owner.isValidEmail(san.getName())) {
                     if (pMail != null && !emailTemp.isMultiple()) {
                         // remove
                     } else {
@@ -367,6 +368,11 @@ public class CertificateRequest {
                         filteredSANs.add(san);
                         continue;
                     }
+                } else {
+                    // remove
+                    error.mergeInto(new GigiApiException(SprintfCommand.createSimple(//
+                            "The requested subject alternate name email address \"{0}\" needs an email ping within the past {1} months.", san.getType().toString().toLowerCase() + ":" + san.getName(), TimeConditions.getInstance().getEmailPingMonths())));
+                    break;
                 }
             }
             error.mergeInto(new GigiApiException(SprintfCommand.createSimple(//
index 278e38b7d56b2364d51e30b97191cfffcb46f23a..1fd1c010ff09eb102f23263aba1a610500e06638 100644 (file)
@@ -39,7 +39,7 @@ public class AffiliationForm extends Form {
         } else if (req.getParameter("do_affiliate") != null) {
             User byEmail = User.getByEmail(req.getParameter("email"));
             if (byEmail == null) {
-                throw new GigiApiException("To add an admin, the email address is required.");
+                throw new GigiApiException("To add an admin, the email address needs to be known to the system.");
             }
             if (byEmail.canVerify()) {
                 o.addAdmin(byEmail, LoginPage.getUser(req), req.getParameter("master") != null);
similarity index 94%
rename from src/club/wpia/gigi/pages/account/MyOrganisationsForm.java
rename to src/club/wpia/gigi/pages/orga/MyOrganisationsForm.java
index 835973a12b385b300808daa05d8c6ee31a41cb8f..8858c5c0af631946f59850aabd348a8ed2e7be3d 100644 (file)
@@ -1,4 +1,4 @@
-package club.wpia.gigi.pages.account;
+package club.wpia.gigi.pages.orga;
 
 import java.io.PrintWriter;
 import java.util.Enumeration;
@@ -33,7 +33,7 @@ public class MyOrganisationsForm extends Form {
     public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         if (req.getParameter("org-leave") != null) {
             req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(target.getActor(), target.getActor()));
-            return new RedirectResult(MyDetails.PATH);
+            return new RedirectResult(SwitchOrganisation.PATH);
         }
         Enumeration<String> i = req.getParameterNames();
         int orgId = -1;
@@ -52,7 +52,7 @@ public class MyOrganisationsForm extends Form {
             if (org.getId() == orgId) {
 
                 req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(org, target.getActor()));
-                return new RedirectResult(MyDetails.PATH);
+                return new RedirectResult(SwitchOrganisation.PATH);
             }
         }
         throw new PermamentFormException(new GigiApiException("Context switch failed."));
diff --git a/src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ b/src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ
new file mode 100644 (file)
index 0000000..5c63f04
--- /dev/null
@@ -0,0 +1,9 @@
+<h2><?=_My Organisations?></h2>
+<? if($personal) { ?>
+<button class="btn btn-primary" type='submit' value='personal' name='org-leave'/><?=_Switch back to personal context?></button>
+<? } ?>
+<table class="table">
+<? foreach($orgas) { ?>
+<tr><td><?=$orgName?></td><td><?=$orgID?></td><td><button class="btn btn-info" type='submit' value='y' name='org:<?=$orgID?>'/><?=_Switch to this organisation?></button></td></tr>
+<? } ?>
+</table>
diff --git a/src/club/wpia/gigi/pages/orga/SwitchOrganisation.java b/src/club/wpia/gigi/pages/orga/SwitchOrganisation.java
new file mode 100644 (file)
index 0000000..16dfe6e
--- /dev/null
@@ -0,0 +1,29 @@
+package club.wpia.gigi.pages.orga;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import club.wpia.gigi.pages.ManagedFormPage;
+import club.wpia.gigi.util.AuthorizationContext;
+
+public class SwitchOrganisation extends ManagedFormPage {
+
+    public static final String PATH = "/orga/switch-orga";
+
+    public SwitchOrganisation() {
+        super("Switch to Organisation", MyOrganisationsForm.class);
+    }
+
+    @Override
+    public boolean isPermitted(AuthorizationContext ac) {
+        return ac != null && ac.getActor().getOrganisations().size() != 0;
+    }
+
+    @Override
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        new MyOrganisationsForm(req).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+    }
+}
index 79edd9327ad207e4ea981d362a3e131248190e0a..da580ccf48cae58a5d4aac3db449dc5cb553266b 100644 (file)
@@ -6,14 +6,19 @@ import static org.junit.Assert.*;
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import java.security.KeyPair;
+import java.util.Locale;
 
 import org.junit.Test;
 
 import club.wpia.gigi.GigiApiException;
+import club.wpia.gigi.database.GigiPreparedStatement;
+import club.wpia.gigi.dbObjects.EmailAddress;
 import club.wpia.gigi.dbObjects.Group;
 import club.wpia.gigi.pages.account.certs.CertificateRequest;
 import club.wpia.gigi.testUtils.ClientTest;
+import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail;
 import club.wpia.gigi.util.AuthorizationContext;
+import club.wpia.gigi.util.TimeConditions;
 
 public class TestCertificateRequest extends ClientTest {
 
@@ -85,4 +90,50 @@ public class TestCertificateRequest extends ClientTest {
         }
 
     }
+
+    @Test
+    public void testPingPeriodOneAddress() throws IOException, GeneralSecurityException, GigiApiException {
+        // get new email address with last ping in past
+        String furtherEmail = createUniqueName() + "@example.org";
+        EmailAddress ea = new EmailAddress(u, furtherEmail, Locale.ENGLISH);
+        TestMail mail = getMailReceiver().receive(furtherEmail);
+        try (GigiPreparedStatement stmt = new GigiPreparedStatement("UPDATE `emailPinglog` SET `status`='success'::`pingState`, `when` = (now() - interval '1 months' * ?::INTEGER) WHERE `email`=? ")) {
+            stmt.setInt(1, TimeConditions.getInstance().getEmailPingMonths());
+            stmt.setString(2, furtherEmail);
+            stmt.executeUpdate();
+        }
+
+        try {
+            CertificateRequest cr = new CertificateRequest(ac, generatePEMCSR(kp, "CN=a ab"));
+            cr.update("name", "SHA512", "mail", null, null, "email:" + furtherEmail);
+            cr.draft();
+            fail();
+        } catch (GigiApiException e) {
+            assertThat(e.getMessage(), containsString("needs an email ping within the past"));
+        }
+
+    }
+
+    @Test
+    public void testPingPeriodTwoAddresses() throws IOException, GeneralSecurityException, GigiApiException {
+        // get new email address with last ping in past
+        String furtherEmail = createUniqueName() + "@example.org";
+        EmailAddress ea = new EmailAddress(u, furtherEmail, Locale.ENGLISH);
+        TestMail mail = getMailReceiver().receive(furtherEmail);
+        try (GigiPreparedStatement stmt = new GigiPreparedStatement("UPDATE `emailPinglog` SET `status`='success'::`pingState`, `when` = (now() - interval '1 months' * ?::INTEGER) WHERE `email`=? ")) {
+            stmt.setInt(1, TimeConditions.getInstance().getEmailPingMonths());
+            stmt.setString(2, furtherEmail);
+            stmt.executeUpdate();
+        }
+
+        try {
+            CertificateRequest cr = new CertificateRequest(ac, generatePEMCSR(kp, "CN=a ab"));
+            cr.update("name", "SHA512", "mail", null, null, "email:" + furtherEmail + ",email:" + email);
+            cr.draft();
+            fail();
+        } catch (GigiApiException e) {
+            assertThat(e.getMessage(), containsString("needs an email ping within the past"));
+        }
+
+    }
 }
diff --git a/tests/club/wpia/gigi/pages/orga/TestOrgSwitch.java b/tests/club/wpia/gigi/pages/orga/TestOrgSwitch.java
new file mode 100644 (file)
index 0000000..94586e3
--- /dev/null
@@ -0,0 +1,121 @@
+package club.wpia.gigi.pages.orga;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.sql.SQLException;
+
+import org.junit.After;
+import org.junit.Test;
+
+import club.wpia.gigi.GigiApiException;
+import club.wpia.gigi.dbObjects.Organisation;
+import club.wpia.gigi.dbObjects.User;
+import club.wpia.gigi.testUtils.IOUtils;
+import club.wpia.gigi.testUtils.OrgTest;
+
+public class TestOrgSwitch extends OrgTest {
+
+    private User u2;
+
+    private Organisation org1 = createUniqueOrg();
+
+    private Organisation org2 = createUniqueOrg();
+
+    public TestOrgSwitch() throws IOException, GigiApiException {
+
+        assertEquals(403, get(SwitchOrganisation.PATH).getResponseCode());
+
+        String email = createUniqueName() + "@testdom.com";
+        u2 = User.getById(createVerificationUser("testworker", "testname", email, TEST_PASSWORD));
+        assertNull(executeBasicWebInteraction(cookie, ViewOrgPage.DEFAULT_PATH + "/" + org1.getId(), "email=" + URLEncoder.encode(u2.getEmail(), "UTF-8") + "&do_affiliate=y&master=y", 1));
+        assertNull(executeBasicWebInteraction(cookie, ViewOrgPage.DEFAULT_PATH + "/" + org2.getId(), "email=" + URLEncoder.encode(u2.getEmail(), "UTF-8") + "&do_affiliate=y&master=y", 1));
+
+        // login with new user u2
+        cookie = login(email, TEST_PASSWORD);
+    }
+
+    @After
+    public void purgeDbAfterTest() throws SQLException, IOException {
+        purgeDatabase();
+    }
+
+    @Test
+    public void testSwitchToOrg() throws IOException, GigiApiException {
+
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org:" + org1.getId() + "=y", 0));
+
+        String res = IOUtils.readURL(get(SwitchOrganisation.PATH));
+        assertThat(res, containsString("Logged in as " + org1.getName() + " (on behalf of " + u2.getPreferredName()));
+
+    }
+
+    @Test
+    public void testSwitchToNonOrg() throws IOException, GigiApiException {
+
+        String res = IOUtils.readURL(post(SwitchOrganisation.PATH, "org:5000=y"));
+        assertThat(res, containsString("Context switch failed"));
+
+    }
+
+    @Test
+    public void testSwitchToPersonal() throws IOException, GigiApiException {
+
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org-leave=personal", 0));
+
+        String res = IOUtils.readURL(get(SwitchOrganisation.PATH));
+        assertThat(res, containsString("Logged in as " + u2.getPreferredName()));
+
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org-leave=personal", 0));
+
+        res = IOUtils.readURL(get(SwitchOrganisation.PATH));
+        assertThat(res, containsString("Logged in as " + u2.getPreferredName()));
+
+    }
+
+    @Test
+    public void testSwitchOrgToOrg() throws IOException, GigiApiException {
+
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org:" + org1.getId() + "=y", 0));
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org:" + org2.getId() + "=y", 0));
+
+        String res = IOUtils.readURL(get(SwitchOrganisation.PATH));
+        assertThat(res, containsString("Logged in as " + org2.getName() + " (on behalf of " + u2.getPreferredName()));
+
+    }
+
+    @Test
+    public void testSwitchOrgToSameOrg() throws IOException, GigiApiException {
+
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org:" + org1.getId() + "=y", 0));
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org:" + org1.getId() + "=y", 0));
+
+        String res = IOUtils.readURL(get(SwitchOrganisation.PATH));
+        assertThat(res, containsString("Logged in as " + org1.getName() + " (on behalf of " + u2.getPreferredName()));
+
+    }
+
+    @Test
+    public void testSwitchOrgToNonOrg() throws IOException, GigiApiException {
+
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org:" + org1.getId() + "=y", 0));
+        String res = IOUtils.readURL(post(SwitchOrganisation.PATH, "org:5000=y"));
+        assertThat(res, containsString("Context switch failed"));
+
+    }
+
+    @Test
+    public void testSwitchOrgToPersonal() throws IOException, GigiApiException {
+
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org:" + org1.getId() + "=y", 0));
+        assertNull(executeBasicWebInteraction(cookie, SwitchOrganisation.PATH, "org-leave=personal", 0));
+
+        String res = IOUtils.readURL(get(SwitchOrganisation.PATH));
+        assertThat(res, containsString("Logged in as " + u2.getPreferredName()));
+
+    }
+
+}