add: ensure that for Org Administrator actions certificate login is used
authorINOPIAE <m.maengel@inopiae.de>
Sun, 14 Jul 2019 09:44:40 +0000 (11:44 +0200)
committerINOPIAE <m.maengel@inopiae.de>
Sun, 8 Sep 2019 19:23:29 +0000 (21:23 +0200)
related to issue #150

Change-Id: I64beb829327d13f245792843e7bdf02e34b533dd

src/club/wpia/gigi/pages/MainPage.java
src/club/wpia/gigi/pages/MainPage.templ
src/club/wpia/gigi/pages/orga/MyOrganisationsForm.java
src/club/wpia/gigi/pages/orga/MyOrganisationsForm.templ
src/club/wpia/gigi/pages/orga/SwitchOrganisation.java
src/club/wpia/gigi/pages/orga/ViewOrgPage.java
tests/club/wpia/gigi/pages/TestMain.java
tests/club/wpia/gigi/pages/orga/TestOrgDomain.java
tests/club/wpia/gigi/pages/orga/TestOrgSwitch.java

index 53cad4a..7fb5228 100644 (file)
@@ -40,12 +40,7 @@ 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);
 
@@ -106,6 +101,14 @@ public class MainPage extends Page {
                 }
             });
             vars.put("hasorgs", !o.isEmpty());
+
+            if (u.isInGroup(Group.SUPPORTER) || u.isInGroup(Group.ORG_AGENT) || u.isInGroup(Group.TTP_AGENT) || u.canVerify() || !o.isEmpty()) {
+                vars.put("certlogin", LoginPage.getAuthorizationContext(req).isStronglyAuthenticated());
+                vars.put("certlogininfo", true);
+            } else {
+                vars.put("certlogininfo", false);
+            }
+
             getDefaultTemplate().output(resp.getWriter(), getLanguage(req), vars);
 
         } else {
index 88506f3..2b14f70 100644 (file)
@@ -86,7 +86,7 @@
   <li><?=$orgName?></li>
  <? } ?>
  </ul>
- <p><?=_!'<a href="/account/details">'change to organisation administrator context!'</a>'?></p>
+ <? if($certlogin) { ?><p><?=_!'<a href="/account/details">'change to organisation administrator context.'</a>'?><? } else { ?><p class="alert alert-warning"><?=_You need to be logged in via certificate to get access to the organisations.?><? } ?></p>
 </div>
 <? } ?>
 
index c4120fc..a083b7c 100644 (file)
@@ -62,6 +62,7 @@ public class MyOrganisationsForm extends Form {
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
         final List<Organisation> o = target.getActor().getOrganisations();
+        vars.put("certlogin", target.isStronglyAuthenticated());
         if (target.getTarget() != target.getActor()) {
             vars.put("personal", target.getTarget() != target.getActor());
         }
index 6978a60..1c28e52 100644 (file)
@@ -5,6 +5,6 @@
 <? } ?>
 <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>
+<tr><td><?=$orgName?></td><td><?=$orgID?></td><td><? if($certlogin) { ?><button class="btn btn-info" type='submit' value='y' name='org:<?=$orgID?>'/><?=_Switch to this organisation?></button><? } ?></td></tr>
 <? } ?>
 </table>
index 16dfe6e..1d680ca 100644 (file)
@@ -19,7 +19,7 @@ public class SwitchOrganisation extends ManagedFormPage {
 
     @Override
     public boolean isPermitted(AuthorizationContext ac) {
-        return ac != null && ac.getActor().getOrganisations().size() != 0;
+        return ac != null && ac.getActor().getOrganisations().size() != 0 && ac.isStronglyAuthenticated();
     }
 
     @Override
index a511906..0ee3d5d 100644 (file)
@@ -36,7 +36,7 @@ public class ViewOrgPage extends ManagedMultiFormPage {
 
     @Override
     public boolean isPermitted(AuthorizationContext ac) {
-        return ac != null && ((ac.isInGroup(CreateOrgPage.ORG_AGENT) && ac.isStronglyAuthenticated()) || ac.getActor().getOrganisations(true).size() != 0);
+        return ac != null && (ac.isInGroup(CreateOrgPage.ORG_AGENT) || ac.getActor().getOrganisations(true).size() != 0) && ac.isStronglyAuthenticated();
     }
 
     @Override
index 682daf8..194097f 100644 (file)
@@ -9,23 +9,24 @@ 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.dbObjects.Country;
+import club.wpia.gigi.dbObjects.Country.CountryCodeType;
+import club.wpia.gigi.dbObjects.Group;
+import club.wpia.gigi.dbObjects.Organisation;
+import club.wpia.gigi.dbObjects.User;
 import club.wpia.gigi.testUtils.ClientTest;
 import club.wpia.gigi.testUtils.IOUtils;
 
 public class TestMain extends ClientTest {
 
+    private User orgAdmin;
+
     @Test
-    public void testPasswordLogin() throws MalformedURLException, IOException {
+    public void testPasswordLogin() throws MalformedURLException, IOException, GigiApiException {
         URLConnection uc = new URL("https://" + getServerName()).openConnection();
         uc.addRequestProperty("Cookie", cookie);
         String content = IOUtils.readURL(uc);
@@ -42,16 +43,7 @@ public class TestMain extends ClientTest {
 
     @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;
+        cookie = cookieWithCertificateLogin(u);
 
         URLConnection uc = new URL("https://" + getSecureServerName()).openConnection();
         authenticate((HttpURLConnection) uc);
@@ -63,6 +55,42 @@ public class TestMain extends ClientTest {
         authenticate((HttpURLConnection) uc);
         content = IOUtils.readURL(uc);
         assertThat(content, containsString("You are authenticated via certificate, so you will be able to perform all actions."));
+    }
+
+    @Test
+    public void testPasswordLoginOrgAdmin() throws MalformedURLException, IOException, GigiApiException {
+        URLConnection uc = new URL("https://" + getServerName()).openConnection();
+        addOrgAdmin();
+        cookie = login(orgAdmin.getEmail(), TEST_PASSWORD);
+        loginCertificate = null;
+        uc.addRequestProperty("Cookie", cookie);
+        String content = IOUtils.readURL(uc);
+        assertThat(content, containsString("You need to be logged in via certificate to get access to the organisations."));
+        assertThat(content, containsString("For some actions, e.g. add verification, support, you need to be authenticated via certificate."));
+
+    }
+
+    @Test
+    public void testCertLoginOrgAdmin() throws GeneralSecurityException, IOException, GigiApiException, InterruptedException {
+        cookie = cookieWithCertificateLogin(u);
+        addOrgAdmin();
+        cookie = cookieWithCertificateLogin(orgAdmin);
+
+        URLConnection uc = new URL("https://" + getSecureServerName()).openConnection();
+        authenticate((HttpURLConnection) uc);
+        String content = IOUtils.readURL(uc);
+
+        assertThat(content, containsString("change to organisation administrator context"));
+        assertThat(content, containsString("You are authenticated via certificate, so you will be able to perform all actions."));
+    }
 
+    private void addOrgAdmin() throws GigiApiException, IOException {
+        makeAgent(u.getId());
+        u.grantGroup(getSupporter(), Group.ORG_AGENT);
+        clearCaches();
+        Organisation o = new Organisation(createUniqueName(), Country.getCountryByCode("DE", CountryCodeType.CODE_2_CHARS), "pr", "city", "test@example.com", "", "", u);
+        orgAdmin = User.getById(createVerificationUser("testworker", "testname", createUniqueName() + "@testdom.com", TEST_PASSWORD));
+        makeAgent(orgAdmin.getId());
+        o.addAdmin(orgAdmin, u, true);
     }
 }
index 7d4123c..f04f66a 100644 (file)
@@ -99,8 +99,7 @@ public class TestOrgDomain extends OrgTest {
         Domain d = new Domain(u, o, dom);
         assertEquals(1, o.getDomains().length);
         User admin = createOrgAdmin(o);
-        String adminCookie = login(admin.getEmail(), TEST_PASSWORD);
-        loginCertificate = null;
+        String adminCookie = cookieWithCertificateLogin(admin);
         assertNull(executeBasicWebInteraction(adminCookie, SwitchOrganisation.PATH, "org:" + o.getId() + "=y", 0));
 
         // test that delete button is not displayed
index 40aed5f..90362a9 100644 (file)
@@ -5,6 +5,8 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.*;
 
 import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URLConnection;
 import java.net.URLEncoder;
 import java.sql.SQLException;
 
@@ -118,4 +120,11 @@ public class TestOrgSwitch extends OrgTest {
 
     }
 
+    @Test
+    public void testSwitchOrgPasswordLogin() throws IOException, GigiApiException {
+        cookie = login(email, TEST_PASSWORD);
+        loginCertificate = null;
+        URLConnection uc = get(cookie, SwitchOrganisation.PATH);
+        assertEquals(403, ((HttpURLConnection) uc).getResponseCode());
+    }
 }