]> WPIA git - gigi.git/blob - tests/org/cacert/gigi/testUtils/TestEmailReceiver.java
Fix: consolidate TestEmailReveiver interface
[gigi.git] / tests / org / cacert / gigi / testUtils / TestEmailReceiver.java
1 package org.cacert.gigi.testUtils;
2
3 import java.io.DataInputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.net.Socket;
7 import java.net.SocketAddress;
8 import java.net.URL;
9 import java.net.URLConnection;
10 import java.util.concurrent.LinkedBlockingQueue;
11 import java.util.concurrent.TimeUnit;
12 import java.util.regex.Matcher;
13 import java.util.regex.Pattern;
14
15 import org.cacert.gigi.email.EmailProvider;
16
17 public final class TestEmailReceiver extends EmailProvider implements Runnable {
18
19     public class TestMail {
20
21         String to;
22
23         String subject;
24
25         String message;
26
27         String from;
28
29         String replyto;
30
31         public TestMail(String to, String subject, String message, String from, String replyto) {
32             this.to = to;
33             this.subject = subject;
34             this.message = message;
35             this.from = from;
36             this.replyto = replyto;
37         }
38
39         public String getTo() {
40             return to;
41         }
42
43         public String getSubject() {
44             return subject;
45         }
46
47         public String getMessage() {
48             return message;
49         }
50
51         public String getFrom() {
52             return from;
53         }
54
55         public String getReplyto() {
56             return replyto;
57         }
58
59         public String extractLink() {
60             Pattern link = Pattern.compile("https?://[^\\s]+(?=\\s)");
61             Matcher m = link.matcher(getMessage());
62             m.find();
63             return m.group(0);
64         }
65
66         public void verify() throws IOException {
67             String[] parts = extractLink().split("\\?");
68             URL u = new URL("https://" + ManagedTest.getServerName() + "/verify?" + parts[1]);
69
70             URLConnection csrfConn = u.openConnection();
71             String csrf = ManagedTest.getCSRF(csrfConn, 0);
72
73             u = new URL("https://" + ManagedTest.getServerName() + "/verify");
74             URLConnection uc = u.openConnection();
75             ManagedTest.cookie(uc, ManagedTest.stripCookie(csrfConn.getHeaderField("Set-Cookie")));
76             uc.setDoOutput(true);
77             uc.getOutputStream().write((parts[1] + "&csrf=" + csrf).getBytes("UTF-8"));
78             uc.connect();
79             uc.getInputStream().close();
80         }
81
82     }
83
84     private Socket s;
85
86     private DataInputStream dis;
87
88     private DataOutputStream dos;
89
90     public TestEmailReceiver(SocketAddress target) throws IOException {
91         s = new Socket();
92         s.connect(target);
93         s.setKeepAlive(true);
94         s.setSoTimeout(1000 * 60 * 60);
95         dis = new DataInputStream(s.getInputStream());
96         dos = new DataOutputStream(s.getOutputStream());
97         setInstance(this);
98     }
99
100     public void start() {
101         new Thread(this, "Mail reciever").start();
102     }
103
104     LinkedBlockingQueue<TestMail> mails = new LinkedBlockingQueue<TestEmailReceiver.TestMail>();
105
106     /**
107      * Retrieves an outgoing mail from the system. The method will return a
108      * {@link TestMail} or fail.
109      * 
110      * @return The intercepted {@link TestMail}
111      * @see #poll()
112      */
113     public TestMail receive() {
114         TestMail poll;
115
116         try {
117             poll = mails.poll(60, TimeUnit.SECONDS);
118
119         } catch (InterruptedException e) {
120             throw new AssertionError("Interrupted while recieving mails");
121         }
122         if (poll == null) {
123             throw new AssertionError("Mail recieving timed out");
124         }
125
126         return poll;
127     }
128
129     /**
130      * Retrieves an outgoing mail from the system or returns <code>null</code>
131      * if there was no mail sent in 30 seconds.
132      * 
133      * @return The intercepted {@link TestMail} or <code>null</code> if no mail
134      *         has been sent.
135      * @see #receive()
136      */
137     public TestMail poll() {
138         try {
139             return mails.poll(60, TimeUnit.SECONDS);
140
141         } catch (InterruptedException e) {
142             throw new AssertionError("Interrupted while recieving mails");
143         }
144     }
145
146     @Override
147     public void run() {
148         try {
149             while (true) {
150                 String type = dis.readUTF();
151                 if (type.equals("mail")) {
152                     String to = dis.readUTF();
153                     String subject = dis.readUTF();
154                     String message = dis.readUTF();
155                     String from = dis.readUTF();
156                     String replyto = dis.readUTF();
157                     mails.add(new TestMail(to, subject, message, from, replyto));
158                 } else if (type.equals("challengeAddrBox")) {
159                     String email = dis.readUTF();
160                     dos.writeUTF(quickEmailCheck(email));
161                     dos.flush();
162                 } else if (type.equals("ping")) {
163                 } else {
164                     System.err.println("Unknown type: " + type);
165                 }
166             }
167         } catch (IOException e) {
168             if ( !closed) {
169                 e.printStackTrace();
170             }
171         }
172
173     }
174
175     private String quickEmailCheck(String email) throws IOException {
176         if (approveRegex.matcher(email).matches()) {
177             return "OK";
178         } else {
179             return error;
180         }
181     }
182
183     String error = "FAIL";
184
185     public void setEmailCheckError(String error) {
186         this.error = error;
187     }
188
189     Pattern approveRegex = Pattern.compile(".*");
190
191     public void setApproveRegex(Pattern approveRegex) {
192         this.approveRegex = approveRegex;
193     }
194
195     public void clearMails() {
196         mails.clear();
197     }
198
199     public void reset() {
200         clearMails();
201         error = "FAIL";
202         approveRegex = Pattern.compile(".*");
203     }
204
205     boolean closed = false;
206
207     public void destroy() {
208         try {
209             closed = true;
210             s.close();
211         } catch (IOException e) {
212             e.printStackTrace();
213         }
214     }
215
216     @Override
217     public String checkEmailServer(int forUid, String address) throws IOException {
218         return quickEmailCheck(address);
219     }
220
221     @Override
222     public void sendmail(String to, String subject, String message, String from, String replyto, String toname, String fromname, String errorsto, boolean extra) throws IOException {
223         mails.add(new TestMail(to, subject, message, from, replyto));
224     }
225
226 }