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;
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);
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 {
}
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();
}
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 {
+++ /dev/null
-<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'/>
-<? } ?>
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;
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 {
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(//
} 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);
-package club.wpia.gigi.pages.account;
+package club.wpia.gigi.pages.orga;
import java.io.PrintWriter;
import java.util.Enumeration;
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;
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."));
--- /dev/null
+<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>
--- /dev/null
+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>());
+ }
+}
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 {
}
}
+
+ @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"));
+ }
+
+ }
}
--- /dev/null
+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()));
+
+ }
+
+}