]> WPIA git - gigi.git/blob - tests/club/wpia/gigi/ping/TestTiming.java
upd: correct url in email when ping fails
[gigi.git] / tests / club / wpia / gigi / ping / TestTiming.java
1 package club.wpia.gigi.ping;
2
3 import static org.junit.Assert.*;
4 import static org.junit.Assume.*;
5
6 import java.io.IOException;
7 import java.security.GeneralSecurityException;
8 import java.security.KeyPair;
9 import java.util.Date;
10 import java.util.List;
11
12 import org.hamcrest.CoreMatchers;
13 import org.junit.Test;
14
15 import club.wpia.gigi.GigiApiException;
16 import club.wpia.gigi.dbObjects.Certificate;
17 import club.wpia.gigi.dbObjects.Certificate.CSRType;
18 import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
19 import club.wpia.gigi.dbObjects.Certificate.SANType;
20 import club.wpia.gigi.dbObjects.CertificateProfile;
21 import club.wpia.gigi.dbObjects.Digest;
22 import club.wpia.gigi.dbObjects.Domain;
23 import club.wpia.gigi.dbObjects.DomainPingConfiguration;
24 import club.wpia.gigi.dbObjects.DomainPingExecution;
25 import club.wpia.gigi.dbObjects.DomainPingType;
26 import club.wpia.gigi.pages.account.domain.EditDomain;
27 import club.wpia.gigi.ping.DomainPinger.PingState;
28 import club.wpia.gigi.testUtils.PingTest;
29 import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail;
30 import club.wpia.gigi.util.RandomToken;
31 import club.wpia.gigi.util.ServerConstants;
32 import club.wpia.gigi.util.ServerConstants.Host;
33 import club.wpia.gigi.util.SimpleSigner;
34
35 public class TestTiming extends PingTest {
36
37     @Test
38     public void httpAndMailSuccessCert() throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
39         httpAndMailSuccess(true, false);
40     }
41
42     @Test
43     public void httpAndMailSuccessCertAndCorrect() throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
44         httpAndMailSuccess(true, true);
45     }
46
47     @Test
48     public void httpAndMailSuccessNoCert() throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
49         httpAndMailSuccess(false, false);
50     }
51
52     public void httpAndMailSuccess(boolean certs, boolean correct) throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
53         String test = getTestProps().getProperty("domain.http");
54         assumeNotNull(test);
55
56         // When we have a domain.
57         Domain d = new Domain(u, u, test);
58         String token = RandomToken.generateToken(16);
59         String value = RandomToken.generateToken(16);
60
61         // If we run the sub case that we have certificates on the domain,
62         // create a certificate now.
63         Certificate c = null;
64         if (certs) {
65             KeyPair kp = generateKeypair();
66             String key = generatePEMCSR(kp, "CN=testmail@example.com");
67             c = new Certificate(u, u, Certificate.buildDN("CN", "testmail@example.com"), Digest.SHA256, key, CSRType.CSR, CertificateProfile.getByName("server"), new Certificate.SubjectAlternateName(SANType.DNS, test));
68             await(c.issue(null, "2y", u));
69         }
70
71         // Register HTTP and Email pings.
72         updateService(token, value, "http");
73         d.addPing(DomainPingType.EMAIL, "postmaster");
74         d.addPing(DomainPingType.HTTP, token + ":" + value);
75
76         // Two successful pings
77         getMailReceiver().receive("postmaster@" + test).verify();
78         waitForPings(2);
79
80         assertEquals(0, countFailed(d.getPings(), 2));
81
82         // An own Pinger Daemon to control ping execution locally.
83         PingerDaemon pd = new PingerDaemon(null);
84         pd.initializeConnectionUsage();
85
86         // After 6 months the pings are executed again
87         pd.executeNeededPings(new Date(System.currentTimeMillis() + 6 * 31 * 24 * 60 * 60L * 1000));
88         getMailReceiver().receive("postmaster@" + test).verify();
89         waitForPings(4);
90         assertEquals(0, countFailed(d.getPings(), 4));
91
92         // After 6 months the pings are executed again, but when the HTTP file
93         // is wrong, that ping fails.
94         updateService(token, value + "broken", "http");
95         // Note that the time is still 6 months in the future, as the pings from
96         // before were still executed (and logged)
97         // as executed now.
98         pd.executeNeededPings(new Date(System.currentTimeMillis() + 6 * 31 * 24 * 60 * 60L * 1000));
99         getMailReceiver().receive("postmaster@" + test).verify();
100         waitForPings(6);
101         assertEquals(1, countFailed(d.getPings(), 6));
102         // Which renders the domain invalid
103         assertFalse(d.isVerified());
104
105         if (certs) {
106             // And the user gets a warning-mail if there was a cert
107             TestMail mail = getMailReceiver().receive(u.getEmail());
108             assertThat(mail.getMessage(), CoreMatchers.containsString(d.getSuffix()));
109             assertThat(mail.getMessage(), CoreMatchers.containsString(c.getSerial()));
110             if ( !correct) {
111                 // If the user ignores the warning, after two weeks
112                 pd.executeNeededPings(new Date(System.currentTimeMillis() + 15 * 24 * 60 * 60L * 1000));
113                 // The user receives another warning mail.
114                 mail = getMailReceiver().receive(u.getEmail());
115                 assertThat(mail.getMessage(), CoreMatchers.containsString("https://" + ServerConstants.getHostNamePortSecure(Host.WWW) + EditDomain.PATH + d.getId()));
116                 assertThat(mail.getMessage(), CoreMatchers.containsString(d.getSuffix()));
117                 assertThat(mail.getMessage(), CoreMatchers.containsString(c.getSerial()));
118                 // And when the revocation is carried out
119                 SimpleSigner.ping();
120                 // ... and the certificate gets revoked.
121                 assertEquals(CertificateStatus.REVOKED, c.getStatus());
122             } else {
123                 // But if the user corrects the ping, ...
124                 updateService(token, value, "http");
125                 // ... and the ping is re-executed,
126                 pd.handle(getPing(d.getConfiguredPings(), DomainPingType.HTTP));
127                 waitForPings(7);
128                 assertEquals(1, countFailed(d.getPings(), 7));
129
130                 // Even after two weeks
131                 pd.executeNeededPings(new Date(System.currentTimeMillis() + 15 * 24 * 60 * 60L * 1000));
132                 // and all resulting jobs are executed
133                 SimpleSigner.ping();
134                 // ... the certificate stays valid.
135                 assertEquals(CertificateStatus.ISSUED, c.getStatus());
136             }
137         } else {
138             // otherwise there is no mail
139         }
140
141     }
142
143     private DomainPingConfiguration getPing(List<DomainPingConfiguration> cp, DomainPingType tp) {
144         for (DomainPingConfiguration d : cp) {
145             if (d.getType() == tp) {
146                 return d;
147             }
148         }
149         throw new Error("Type not found.");
150     }
151
152     private int countFailed(DomainPingExecution[] pg, int count) {
153         assertEquals(count, pg.length);
154         int fld = 0;
155         for (DomainPingExecution e : pg) {
156             PingState state = e.getState();
157             if (e.getConfig().getType() == DomainPingType.HTTP) {
158                 if (state == PingState.FAILED) {
159                     fld++;
160                     continue;
161                 }
162             }
163             assertEquals(PingState.SUCCESS, state);
164         }
165         return fld;
166     }
167
168 }