1 /*****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 ****************************************************************/
19
20
21
22 package org.apache.james.remotemanager;
23
24 import org.apache.avalon.cornerstone.services.sockets.SocketManager;
25 import org.apache.avalon.cornerstone.services.threads.ThreadManager;
26 import org.apache.avalon.framework.container.ContainerUtil;
27 import org.apache.avalon.framework.service.ServiceException;
28 import org.apache.commons.net.telnet.TelnetClient;
29 import org.apache.james.services.JamesConnectionManager;
30 import org.apache.james.services.MailServer;
31 import org.apache.james.services.UsersRepository;
32 import org.apache.james.services.UsersStore;
33 import org.apache.james.test.mock.avalon.MockLogger;
34 import org.apache.james.test.mock.avalon.MockServiceManager;
35 import org.apache.james.test.mock.avalon.MockSocketManager;
36 import org.apache.james.test.mock.avalon.MockThreadManager;
37 import org.apache.james.test.mock.james.MockMailServer;
38 import org.apache.james.test.mock.james.MockUsersStore;
39 import org.apache.james.test.util.Util;
40 import org.apache.james.userrepository.MockUsersRepository;
41 import org.apache.james.util.InternetPrintWriter;
42 import org.apache.james.util.connection.SimpleConnectionManager;
43
44 import java.io.BufferedInputStream;
45 import java.io.BufferedOutputStream;
46 import java.io.BufferedReader;
47 import java.io.IOException;
48 import java.io.InputStreamReader;
49 import java.util.ArrayList;
50 import java.util.Iterator;
51 import java.util.List;
52
53 import junit.framework.TestCase;
54
55 /***
56 * Tests the org.apache.james.remotemanager.RemoteManager
57 * TODO: impl missing command tests for:
58 * USER
59 * SHUTDOWN (hard to test, because it does shutdown the whole (testing) JVM
60 */
61
62 public class RemoteManagerTest extends TestCase {
63
64 protected int m_remoteManagerListenerPort = Util.getNonPrivilegedPort();
65 protected RemoteManager m_remoteManager;
66 protected RemoteManagerTestConfiguration m_testConfiguration;
67 protected String m_host = "127.0.0.1";
68 protected BufferedReader m_reader;
69 protected InternetPrintWriter m_writer;
70 protected TelnetClient m_telnetClient;
71 private MockUsersRepository m_mockUsersRepository;
72 private MockMailServer mailServer;
73
74 protected void setUp() throws Exception {
75 m_remoteManager = new RemoteManager();
76 ContainerUtil.enableLogging(m_remoteManager, new MockLogger());
77 ContainerUtil.service(m_remoteManager, setUpServiceManager());
78 m_testConfiguration = new RemoteManagerTestConfiguration(m_remoteManagerListenerPort);
79 }
80
81 protected void tearDown() throws Exception {
82 ContainerUtil.dispose(mailServer);
83 super.tearDown();
84 }
85
86 protected void finishSetUp(RemoteManagerTestConfiguration testConfiguration) {
87 testConfiguration.init();
88 try {
89 ContainerUtil.configure(m_remoteManager, testConfiguration);
90 ContainerUtil.initialize(m_remoteManager);
91 } catch (Exception e) {
92 throw new RuntimeException(e);
93 }
94 }
95
96 protected void login() throws IOException {
97 login(m_testConfiguration.getLoginName(), m_testConfiguration.getLoginPassword());
98 }
99
100 protected void login(String name, String password) throws IOException {
101 sendCommand(name);
102 List answers = readAnswer();
103 String last = getLastLine(answers);
104 assertTrue("Last line does not start with Password: "+last,last.startsWith("Password:"));
105 sendCommand(password);
106 answers = readAnswer();
107 last = getLastLine(answers);
108 assertTrue("Last line does not start with Welcome: "+last,last.startsWith("Welcome"));
109 }
110
111 protected String getLastLine(List list) {
112 if (list == null || list.isEmpty()) return null;
113 return (String)list.get(list.size()-1);
114 }
115
116 protected List readAnswer() {
117 return readAnswer(1);
118 }
119
120 protected List readAnswer(int numLines) {
121 List allAnswerLines = new ArrayList();
122 try {
123 if (numLines > 0) {
124 for (int i = 0; i < numLines; i++) {
125 allAnswerLines.add(m_reader.readLine());
126 }
127 } else {
128 String line = m_reader.readLine();
129 allAnswerLines.add(line);
130
131 while (m_reader.ready()) {
132 allAnswerLines.add(m_reader.readLine());
133 }
134 }
135 return allAnswerLines;
136 } catch (IOException e) {
137 return null;
138 }
139 }
140
141 protected void sendCommand(String command) throws IOException {
142 m_writer.println(command);
143 m_writer.flush();
144 }
145
146 protected void connect() throws IOException {
147 m_telnetClient = new TelnetClient();
148 m_telnetClient.connect(m_host, m_remoteManagerListenerPort);
149
150 m_reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(m_telnetClient.getInputStream(), 1024), "ASCII"));
151 m_writer = new InternetPrintWriter(new BufferedOutputStream(m_telnetClient.getOutputStream(), 1024), true);
152
153 readAnswer(3);
154 }
155
156 private MockServiceManager setUpServiceManager() throws ServiceException {
157 MockServiceManager serviceManager = new MockServiceManager();
158 SimpleConnectionManager connectionManager = new SimpleConnectionManager();
159 ContainerUtil.enableLogging(connectionManager, new MockLogger());
160 serviceManager.put(JamesConnectionManager.ROLE, connectionManager);
161 mailServer = new MockMailServer();
162 serviceManager.put(MailServer.ROLE, mailServer);
163 m_mockUsersRepository = mailServer.getUsersRepository();
164 serviceManager.put(UsersRepository.ROLE, m_mockUsersRepository);
165 serviceManager.put(UsersStore.ROLE, new MockUsersStore(m_mockUsersRepository));
166 serviceManager.put(SocketManager.ROLE, new MockSocketManager(m_remoteManagerListenerPort));
167 serviceManager.put(ThreadManager.ROLE, new MockThreadManager());
168 return serviceManager;
169 }
170
171 public void testLogin() throws IOException {
172 finishSetUp(m_testConfiguration);
173 connect();
174
175 login();
176 }
177
178 public void testWrongLoginUser() throws IOException {
179 finishSetUp(m_testConfiguration);
180 connect();
181
182 sendCommand("sindbad");
183 List answers = readAnswer();
184 sendCommand(m_testConfiguration.getLoginPassword());
185
186
187 answers = readAnswer(2);
188 String last = getLastLine(answers);
189 assertTrue("Last line does not start with 'Login id:' but with '"+last+"'",last.startsWith("Login id:"));
190 }
191
192 public void testWrongLoginPassword() throws IOException {
193 finishSetUp(m_testConfiguration);
194 connect();
195
196 sendCommand(m_testConfiguration.getLoginName());
197 List answers = readAnswer();
198 sendCommand("getmethru");
199
200 answers = readAnswer(2);
201 String last = getLastLine(answers);
202 assertTrue("Line does not start with 'Login id:' but with '"+last+"'", last.startsWith("Login id:"));
203 }
204
205 public void testUserCount() throws IOException {
206 finishSetUp(m_testConfiguration);
207 connect();
208 login();
209
210 sendCommand("countusers");
211 assertTrue(getLastLine(readAnswer()).endsWith(" 0"));
212
213 sendCommand("adduser testCount1 testCount");
214 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
215
216 sendCommand("countusers");
217 assertTrue(getLastLine(readAnswer()).endsWith(" 1"));
218
219 sendCommand("adduser testCount2 testCount");
220 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
221
222 sendCommand("countusers");
223 assertTrue(getLastLine(readAnswer()).endsWith(" 2"));
224
225 m_mockUsersRepository.removeUser("testCount1");
226
227 sendCommand("countusers");
228 assertTrue(getLastLine(readAnswer()).endsWith(" 1"));
229 }
230
231 public void testAddUserAndVerify() throws IOException {
232 finishSetUp(m_testConfiguration);
233 connect();
234 login();
235
236 sendCommand("adduser testAdd test");
237 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
238
239 sendCommand("verify testNotAdded");
240 assertTrue(getLastLine(readAnswer()).endsWith(" does not exist"));
241
242 sendCommand("verify testAdd");
243 assertTrue(getLastLine(readAnswer()).endsWith(" exists"));
244
245 sendCommand("deluser testAdd");
246 readAnswer();
247
248 sendCommand("verify testAdd");
249 assertTrue(getLastLine(readAnswer()).endsWith(" does not exist"));
250 }
251
252 public void testDelUser() throws IOException {
253 finishSetUp(m_testConfiguration);
254 connect();
255 login();
256
257 sendCommand("adduser testDel test");
258 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
259
260 sendCommand("deluser testNotDeletable");
261 assertTrue(getLastLine(readAnswer()).endsWith(" doesn't exist"));
262
263 sendCommand("verify testDel");
264 assertTrue(getLastLine(readAnswer()).endsWith(" exists"));
265
266 sendCommand("deluser testDel");
267 assertTrue(getLastLine(readAnswer()).endsWith(" deleted"));
268
269 sendCommand("verify testDel");
270 assertTrue(getLastLine(readAnswer()).endsWith(" does not exist"));
271 }
272
273 public void testQuit() throws IOException {
274 int helpLines = 16;
275
276 finishSetUp(m_testConfiguration);
277 connect();
278 login();
279
280 sendCommand("help");
281 delay();
282 assertTrue("command line is effective", readAnswer().size() > 0);
283 readAnswer(helpLines);
284
285 sendCommand("quit");
286 delay();
287 assertTrue("",readAnswer(1).contains("Bye"));
288
289 sendCommand("help");
290 delay();
291 assertNull("connection is closed", m_reader.readLine());
292 }
293
294 public void testListUsers() throws IOException {
295 finishSetUp(m_testConfiguration);
296 connect();
297 login();
298
299 String[] users = new String[] {"ccc", "aaa", "dddd", "bbbbb"};
300
301 for (int i = 0; i < users.length; i++) {
302 String user = users[i];
303 sendCommand("adduser " + user + " test");
304 readAnswer(1);
305 }
306
307 delay();
308
309 sendCommand("listusers");
310 List list = readAnswer(5);
311
312 assertEquals("user count line", "Existing accounts " + users.length, list.get(0));
313
314 List readUserNames = new ArrayList();
315 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
316 String answerLine = (String) iterator.next();
317 if (!answerLine.startsWith("user: ")) continue;
318 readUserNames.add(answerLine.substring(6));
319 }
320 assertEquals("user count", users.length, readUserNames.size());
321
322 for (int i = 0; i < users.length; i++) {
323 String user = users[i];
324 assertTrue("name found", readUserNames.contains(user));
325 }
326 }
327
328 private void delay() {
329 try {
330 Thread.sleep(100);
331 } catch (InterruptedException e) {
332 ;
333 }
334 }
335
336 public void testCommandCaseInsensitive() throws IOException {
337 finishSetUp(m_testConfiguration);
338 connect();
339 login();
340
341 sendCommand("adduser testDel test");
342 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
343
344 sendCommand("verify testDel");
345 assertTrue(getLastLine(readAnswer()).endsWith(" exists"));
346
347 sendCommand("VERIFY testDel");
348 assertTrue(getLastLine(readAnswer()).endsWith(" exists"));
349
350 sendCommand("vErIfY testDel");
351 assertTrue(getLastLine(readAnswer()).endsWith(" exists"));
352 }
353
354 public void testParameterCaseSensitive() throws IOException {
355 finishSetUp(m_testConfiguration);
356 connect();
357 login();
358
359 sendCommand("adduser testDel test");
360 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
361
362 sendCommand("verify testDel");
363 assertTrue(getLastLine(readAnswer()).endsWith(" exists"));
364
365 sendCommand("verify TESTDEL");
366 assertTrue(getLastLine(readAnswer()).endsWith(" does not exist"));
367
368 sendCommand("verify testdel");
369 assertTrue(getLastLine(readAnswer()).endsWith(" does not exist"));
370 }
371
372 public void testAlias() throws IOException {
373 m_mockUsersRepository.setForceUseJamesUser();
374 finishSetUp(m_testConfiguration);
375 connect();
376 login();
377
378
379 sendCommand("setalias testNonExist1 testNonExist2");
380 assertTrue(getLastLine(readAnswer()).equals("No such user testNonExist1"));
381
382 sendCommand("adduser testAlias1 test");
383 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
384
385 sendCommand("showalias testAlias1");
386 assertTrue(getLastLine(readAnswer()).equals("User testAlias1 does not currently have an alias"));
387
388 sendCommand("setalias testAlias1 testNonExist2");
389 assertTrue(getLastLine(readAnswer()).equals("Alias unknown to server - create that user first."));
390
391 sendCommand("setalias testNonExist1 testAlias");
392 assertTrue(getLastLine(readAnswer()).equals("No such user testNonExist1"));
393
394 sendCommand("adduser testAlias2 test");
395 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
396
397
398 sendCommand("setalias testAlias1 testAlias2");
399 assertTrue(getLastLine(readAnswer()).equals("Alias for testAlias1 set to:testAlias2"));
400
401
402 sendCommand("setalias testAlias2 testAlias1");
403 assertTrue(getLastLine(readAnswer()).equals("Alias for testAlias2 set to:testAlias1"));
404
405
406 sendCommand("showalias testAlias1");
407 assertTrue(getLastLine(readAnswer()).equals("Current alias for testAlias1 is: testAlias2"));
408
409
410 sendCommand("setalias testAlias1 testAlias1");
411 assertTrue(getLastLine(readAnswer()).equals("Alias for testAlias1 set to:testAlias1"));
412
413 sendCommand("adduser testAlias3 test");
414 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
415
416
417 sendCommand("setalias testAlias1 testAlias3");
418 assertTrue(getLastLine(readAnswer()).equals("Alias for testAlias1 set to:testAlias3"));
419
420
421 sendCommand("showalias testAlias1");
422 assertTrue(getLastLine(readAnswer()).equals("Current alias for testAlias1 is: testAlias3"));
423
424
425 sendCommand("unsetalias testAlias1");
426 assertTrue(getLastLine(readAnswer()).equals("Alias for testAlias1 unset"));
427
428
429 sendCommand("showalias testAlias1");
430 assertTrue(getLastLine(readAnswer()).equals("User testAlias1 does not currently have an alias"));
431
432 }
433
434 public void testForward() throws IOException {
435 m_mockUsersRepository.setForceUseJamesUser();
436 finishSetUp(m_testConfiguration);
437 connect();
438 login();
439
440
441 sendCommand("setforwarding testNonExist1 testForward1@locahost");
442 assertTrue(getLastLine(readAnswer()).equals("No such user testNonExist1"));
443
444 sendCommand("adduser testForwardUser test");
445 assertTrue(getLastLine(readAnswer()).endsWith(" added"));
446
447 sendCommand("showforwarding testForwardUser");
448 assertTrue(getLastLine(readAnswer()).equals("User testForwardUser is not currently being forwarded"));
449
450 sendCommand("setforwarding testForwardUser testForward1@locahost");
451 assertTrue(getLastLine(readAnswer()).equals("Forwarding destination for testForwardUser set to:testForward1@locahost"));
452
453
454 sendCommand("showforwarding testForwardUser");
455 assertTrue(getLastLine(readAnswer()).equals("Current forwarding destination for testForwardUser is: testForward1@locahost"));
456
457
458 sendCommand("setforwarding testForwardUser testForward2@locahost");
459 assertTrue(getLastLine(readAnswer()).equals("Forwarding destination for testForwardUser set to:testForward2@locahost"));
460
461
462 sendCommand("showforwarding testForwardUser");
463 assertTrue(getLastLine(readAnswer()).equals("Current forwarding destination for testForwardUser is: testForward2@locahost"));
464
465
466 sendCommand("unsetforwarding testForwardUser");
467 assertTrue(getLastLine(readAnswer()).equals("Forward for testForwardUser unset"));
468
469
470 sendCommand("showforwarding testForwardUser");
471 assertTrue(getLastLine(readAnswer()).equals("User testForwardUser is not currently being forwarded"));
472
473 }
474
475 public void testSetPassword() throws IOException {
476 finishSetUp(m_testConfiguration);
477 connect();
478 login();
479
480 String lastLine;
481
482 sendCommand("adduser testPwdUser pwd1");
483 lastLine = getLastLine(readAnswer());
484 assertTrue(lastLine.endsWith(" added"));
485
486 assertTrue("initial password", m_mockUsersRepository.test("testPwdUser", "pwd1"));
487
488 sendCommand("setpassword testPwdUser ");
489 lastLine = getLastLine(readAnswer());
490 assertTrue("password changed to empty: "+lastLine, m_mockUsersRepository.test("testPwdUser", "pwd1"));
491
492
493 sendCommand("setpassword testPwdUser pwd2");
494 lastLine = getLastLine(readAnswer());
495 assertTrue("password not changed to pwd2: "+lastLine, m_mockUsersRepository.test("testPwdUser", "pwd2"));
496
497
498 sendCommand("setpassword testPwdUser pWD2");
499 lastLine = getLastLine(readAnswer());
500 assertFalse("password not changed to pWD2: "+lastLine, m_mockUsersRepository.test("testPwdUser", "pwd2"));
501 assertTrue("password not changed to pWD2: "+lastLine, m_mockUsersRepository.test("testPwdUser", "pWD2"));
502
503 }
504
505 }