Browse code

BM-12692 Test: add NGinx authentication handler JUnits

Anthony Prades authored on 09/01/2018 14:03:38
Showing 8 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<classpath>
2
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
3
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
4
+	<classpathentry kind="src" path="src"/>
5
+	<classpathentry kind="output" path="bin"/>
6
+</classpath>
0 7
new file mode 100644
... ...
@@ -0,0 +1,28 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<projectDescription>
2
+	<name>net.bluemind.authentication.handler.tests</name>
3
+	<comment></comment>
4
+	<projects>
5
+	</projects>
6
+	<buildSpec>
7
+		<buildCommand>
8
+			<name>org.eclipse.jdt.core.javabuilder</name>
9
+			<arguments>
10
+			</arguments>
11
+		</buildCommand>
12
+		<buildCommand>
13
+			<name>org.eclipse.pde.ManifestBuilder</name>
14
+			<arguments>
15
+			</arguments>
16
+		</buildCommand>
17
+		<buildCommand>
18
+			<name>org.eclipse.pde.SchemaBuilder</name>
19
+			<arguments>
20
+			</arguments>
21
+		</buildCommand>
22
+	</buildSpec>
23
+	<natures>
24
+		<nature>org.eclipse.pde.PluginNature</nature>
25
+		<nature>org.eclipse.jdt.core.javanature</nature>
26
+	</natures>
27
+</projectDescription>
0 28
new file mode 100644
... ...
@@ -0,0 +1,16 @@
0
+Manifest-Version: 1.0
1
+Bundle-ManifestVersion: 2
2
+Bundle-Name: net.bluemind.authentication.handler.tests
3
+Bundle-SymbolicName: net.bluemind.authentication.handler.tests
4
+Bundle-Version: 3.1.0.qualifier
5
+Bundle-Vendor: bluemind.net
6
+Fragment-Host: net.bluemind.authentication.handler
7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
8
+Require-Bundle: org.junit,
9
+ net.bluemind.core.jdbc.testshelper,
10
+ net.bluemind.core.elasticsearch.testshelper,
11
+ net.bluemind.tests.defaultdata,
12
+ com.ning.async-http-client,
13
+ net.bluemind.core.tests.testshelper,
14
+ net.bluemind.backend.cyrus,
15
+ net.bluemind.config
0 16
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+source.. = src/
1
+output.. = bin/
2
+bin.includes = META-INF/,\
3
+               .
0 4
new file mode 100644
... ...
@@ -0,0 +1,30 @@
0
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2
+	<modelVersion>4.0.0</modelVersion>
3
+	<parent>
4
+		<groupId>net.bluemind</groupId>
5
+		<artifactId>net.bluemind.authentication.plugins</artifactId>
6
+		<version>3.1.0-SNAPSHOT</version>
7
+	</parent>
8
+	<artifactId>net.bluemind.authentication.handler.tests</artifactId>
9
+	<packaging>eclipse-test-plugin</packaging>
10
+	<build>
11
+		<plugins>
12
+			<plugin>
13
+				<groupId>org.eclipse.tycho</groupId>
14
+				<artifactId>target-platform-configuration</artifactId>
15
+				<configuration>
16
+					<dependency-resolution>
17
+						<extraRequirements>
18
+							<requirement>
19
+								<type>eclipse-feature</type>
20
+								<id>net.bluemind.tests.feature</id>
21
+								<versionRange>0.0.0</versionRange>
22
+							</requirement>
23
+						</extraRequirements>
24
+					</dependency-resolution>
25
+				</configuration>
26
+			</plugin>
27
+		</plugins>
28
+	</build>
29
+</project>
0 30
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+[{ 
1
+ 	"name":"bluemind/postgres-tests" 
2
+ 	},{
3
+ 	"name":"bluemind/elasticsearch-tests"
4
+ 	 },{
5
+    "name":"bluemind/imap-role"
6
+}]
0 7
new file mode 100644
... ...
@@ -0,0 +1,286 @@
0
+/* BEGIN LICENSE
1
+  * Copyright © Blue Mind SAS, 2012-2018
2
+  *
3
+  * This file is part of BlueMind. BlueMind is a messaging and collaborative
4
+  * solution.
5
+  *
6
+  * This program is free software; you can redistribute it and/or modify
7
+  * it under the terms of either the GNU Affero General Public License as
8
+  * published by the Free Software Foundation (version 3 of the License).
9
+  *
10
+  * This program is distributed in the hope that it will be useful,
11
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+  *
14
+  * See LICENSE.txt
15
+  * END LICENSE
16
+  */
17
+package net.bluemind.authentication.handler;
18
+
19
+import static org.junit.Assert.assertEquals;
20
+import static org.junit.Assert.assertFalse;
21
+
22
+import java.util.ArrayList;
23
+import java.util.Arrays;
24
+import java.util.List;
25
+import java.util.concurrent.CountDownLatch;
26
+import java.util.concurrent.ExecutionException;
27
+
28
+import org.junit.Before;
29
+import org.junit.Test;
30
+import org.vertx.java.core.AsyncResult;
31
+import org.vertx.java.core.Handler;
32
+
33
+import com.google.common.collect.Lists;
34
+import com.ning.http.client.AsyncHttpClient;
35
+import com.ning.http.client.AsyncHttpClientConfig;
36
+import com.ning.http.client.ListenableFuture;
37
+import com.ning.http.client.RequestBuilder;
38
+import com.ning.http.client.Response;
39
+import com.ning.http.util.Base64;
40
+
41
+import net.bluemind.backend.cyrus.CyrusService;
42
+import net.bluemind.config.InstallationId;
43
+import net.bluemind.core.api.Email;
44
+import net.bluemind.core.container.model.ItemValue;
45
+import net.bluemind.core.container.persistance.ContainerStore;
46
+import net.bluemind.core.context.SecurityContext;
47
+import net.bluemind.core.elasticsearch.ElasticsearchTestHelper;
48
+import net.bluemind.core.jdbc.JdbcActivator;
49
+import net.bluemind.core.jdbc.JdbcTestHelper;
50
+import net.bluemind.core.rest.ServerSideServiceProvider;
51
+import net.bluemind.core.tests.BmTestContext;
52
+import net.bluemind.domain.api.Domain;
53
+import net.bluemind.lib.vertx.VertxPlatform;
54
+import net.bluemind.mailbox.api.Mailbox.Routing;
55
+import net.bluemind.pool.impl.BmConfIni;
56
+import net.bluemind.server.api.IServer;
57
+import net.bluemind.server.api.Server;
58
+import net.bluemind.tests.defaultdata.PopulateHelper;
59
+import net.bluemind.user.api.IUser;
60
+import net.bluemind.user.api.User;
61
+import net.bluemind.utils.Trust;
62
+
63
+public class NginxTests {
64
+	private ContainerStore containerHome;
65
+	private ItemValue<Server> dataLocation;
66
+	private User user;
67
+	private ItemValue<Domain> domain;
68
+	private String[] userAlias;
69
+	private String userLatd;
70
+
71
+	@Before
72
+	public void before() throws Exception {
73
+		String domainUid = "bm.lan";
74
+
75
+		JdbcTestHelper.getInstance().beforeTest();
76
+		JdbcTestHelper.getInstance().getDbSchemaService().initialize();
77
+		JdbcActivator.getInstance().setDataSource(JdbcTestHelper.getInstance().getDataSource());
78
+		ElasticsearchTestHelper.getInstance().beforeTest();
79
+
80
+		// register elasticsearch to locator
81
+		Server esServer = new Server();
82
+		esServer.ip = ElasticsearchTestHelper.getInstance().getHost();
83
+		esServer.tags = Lists.newArrayList("bm/es");
84
+
85
+		Server imapServer = new Server();
86
+		imapServer.ip = new BmConfIni().get("imap-role");
87
+		imapServer.tags = Lists.newArrayList("mail/imap", "mail/imap_frontend");
88
+
89
+		PopulateHelper.initGlobalVirt(esServer, imapServer);
90
+
91
+		IServer serverService = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IServer.class,
92
+				InstallationId.getIdentifier());
93
+
94
+		dataLocation = serverService.getComplete(imapServer.ip);
95
+
96
+		new CyrusService(imapServer.ip).createPartition(domainUid);
97
+		new CyrusService(imapServer.ip).refreshPartitions(Arrays.asList(domainUid));
98
+		new CyrusService(imapServer.ip).reload();
99
+
100
+		domain = initDomain(containerHome, domainUid, esServer, imapServer);
101
+
102
+		final CountDownLatch launched = new CountDownLatch(1);
103
+		VertxPlatform.spawnVerticles(new Handler<AsyncResult<Void>>() {
104
+			@Override
105
+			public void handle(AsyncResult<Void> event) {
106
+				launched.countDown();
107
+			}
108
+		});
109
+		launched.await();
110
+	}
111
+
112
+	@Test
113
+	public void imapAuthenticationInvalidPassword() throws InterruptedException, ExecutionException {
114
+		Response response = doNginxAuthenticationQuery("10.0.0.34", "imap", "144", userLatd, "invalidpassword");
115
+
116
+		assertEquals(200, response.getStatusCode());
117
+		assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
118
+
119
+		for (String alias : userAlias) {
120
+			response = doNginxAuthenticationQuery("10.0.0.34", "imap", "144", alias, "invalidpassword");
121
+
122
+			assertEquals(200, response.getStatusCode());
123
+			assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
124
+		}
125
+	}
126
+
127
+	@Test
128
+	public void imapAuthenticationInvalidLogin() throws InterruptedException, ExecutionException {
129
+		Response response = doNginxAuthenticationQuery("10.0.0.34", "imap", "144", "invalidlogin@" + domain.uid,
130
+				"password");
131
+
132
+		assertEquals(200, response.getStatusCode());
133
+		assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
134
+
135
+		response = doNginxAuthenticationQuery("10.0.0.34", "imap", "144", null, "password");
136
+
137
+		assertEquals(200, response.getStatusCode());
138
+		assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
139
+	}
140
+
141
+	@Test
142
+	public void imapLatdAuthenticationSuccess() throws InterruptedException, ExecutionException {
143
+		Response response = doNginxAuthenticationQuery("10.0.0.34", "imap", "144", userLatd, "password");
144
+
145
+		assertEquals(200, response.getStatusCode());
146
+		assertEquals("OK", response.getHeader("Auth-Status"));
147
+		assertEquals(dataLocation.value.address(), response.getHeader("Auth-Server"));
148
+		assertEquals("144", response.getHeader("Auth-Port"));
149
+		assertFalse(response.getHeaders().containsKey("Auth-User"));
150
+	}
151
+
152
+	@Test
153
+	public void imapAliasAuthenticationSuccess() throws InterruptedException, ExecutionException {
154
+		for (String alias : userAlias) {
155
+			Response response = doNginxAuthenticationQuery("10.0.0.34", "imap", "144", alias, "password");
156
+
157
+			assertEquals(200, response.getStatusCode());
158
+			assertEquals("OK", response.getHeader("Auth-Status"));
159
+			assertEquals(dataLocation.value.address(), response.getHeader("Auth-Server"));
160
+			assertEquals("144", response.getHeader("Auth-Port"));
161
+			assertFalse(response.getHeaders().containsKey("Auth-User"));
162
+		}
163
+	}
164
+
165
+	@Test
166
+	public void popLatdAuthenticationSuccess() throws InterruptedException, ExecutionException {
167
+		Response response = doNginxAuthenticationQuery("10.0.0.34", "pop3", "1110", userLatd, "password");
168
+
169
+		assertEquals(200, response.getStatusCode());
170
+		assertEquals("OK", response.getHeader("Auth-Status"));
171
+		assertEquals(dataLocation.value.address(), response.getHeader("Auth-Server"));
172
+		assertEquals("1110", response.getHeader("Auth-Port"));
173
+		assertFalse(response.getHeaders().containsKey("Auth-User"));
174
+	}
175
+
176
+	@Test
177
+	public void popAliasAuthenticationSuccess() throws InterruptedException, ExecutionException {
178
+		for (String alias : userAlias) {
179
+			Response response = doNginxAuthenticationQuery("10.0.0.34", "pop3", "1110", alias, "password");
180
+
181
+			assertEquals(200, response.getStatusCode());
182
+			assertEquals("OK", response.getHeader("Auth-Status"));
183
+			assertEquals(dataLocation.value.address(), response.getHeader("Auth-Server"));
184
+			assertEquals("1110", response.getHeader("Auth-Port"));
185
+			assertEquals(userLatd, response.getHeader("Auth-User"));
186
+		}
187
+	}
188
+
189
+	@Test
190
+	public void popAuthenticationInvalidPassword() throws InterruptedException, ExecutionException {
191
+		Response response = doNginxAuthenticationQuery("10.0.0.34", "pop3", "1110", userLatd, "invalidpassword");
192
+
193
+		assertEquals(200, response.getStatusCode());
194
+		assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
195
+
196
+		for (String alias : userAlias) {
197
+			response = doNginxAuthenticationQuery("10.0.0.34", "pop3", "1110", alias, "invalidpassword");
198
+
199
+			assertEquals(200, response.getStatusCode());
200
+			assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
201
+		}
202
+	}
203
+
204
+	@Test
205
+	public void popAuthenticationInvalidLogin() throws InterruptedException, ExecutionException {
206
+		Response response = doNginxAuthenticationQuery("10.0.0.34", "pop3", "1110", "invalidlogin@" + domain.uid,
207
+				"password");
208
+
209
+		assertEquals(200, response.getStatusCode());
210
+		assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
211
+
212
+		response = doNginxAuthenticationQuery("10.0.0.34", "pop3", "1110", null, "password");
213
+
214
+		assertEquals(200, response.getStatusCode());
215
+		assertEquals("Invalid login or password", response.getHeader("Auth-Status"));
216
+	}
217
+
218
+	private ItemValue<Domain> initDomain(ContainerStore containerHome, String domainUid, Server... servers)
219
+			throws Exception {
220
+		ItemValue<Domain> domain = PopulateHelper.createTestDomain(domainUid, servers);
221
+
222
+		user = PopulateHelper.getUser("u1." + System.nanoTime(), domainUid, Routing.internal);
223
+		user.password = "password";
224
+
225
+		userLatd = user.login + "@" + domain.uid;
226
+		userAlias = new String[] { user.login + ".alias@" + domainUid,
227
+				user.login + "@" + domain.value.aliases.iterator().next() };
228
+
229
+		List<Email> userEmails = new ArrayList<>();
230
+		userEmails.addAll(user.emails);
231
+
232
+		for (String alias : userAlias) {
233
+			Email em = new Email();
234
+			em.address = alias;
235
+			em.isDefault = false;
236
+			em.allAliases = false;
237
+			userEmails.add(em);
238
+		}
239
+		user.emails = userEmails;
240
+
241
+		new BmTestContext(SecurityContext.SYSTEM).provider().instance(IUser.class, domainUid).create(user.login, user);
242
+
243
+		return domain;
244
+	}
245
+
246
+	private AsyncHttpClient getHttpClient() {
247
+		AsyncHttpClientConfig config = new AsyncHttpClientConfig.Builder().setSSLContext(Trust.createSSLContext()) //
248
+				.setHostnameVerifier(Trust.acceptAllVerifier()) //
249
+				.setConnectTimeout(120 * 1000) //
250
+				.setReadTimeout(120 * 1000) //
251
+				.setRequestTimeout(120 * 1000) //
252
+				.setFollowRedirect(false) //
253
+				.setMaxRedirects(0) //
254
+				.setMaxRequestRetry(0) //
255
+				.setAllowPoolingConnections(true)//
256
+				.setSSLContext(Trust.createSSLContext()) //
257
+				.setAcceptAnyCertificate(true)//
258
+				.build();
259
+		return new AsyncHttpClient(config);
260
+	}
261
+
262
+	private Response doNginxAuthenticationQuery(String clientIp, String protocol, String port, String login,
263
+			String password) throws InterruptedException, ExecutionException {
264
+		RequestBuilder requestBuilder = new RequestBuilder();
265
+		requestBuilder.setMethod("GET");
266
+		requestBuilder.setBodyEncoding("utf-8");
267
+		requestBuilder.setUrl("http://localhost:8090/nginx");
268
+
269
+		requestBuilder.addHeader("Client-IP", clientIp);
270
+		requestBuilder.addHeader("Auth-Protocol", protocol);
271
+		requestBuilder.addHeader("X-Auth-Port", port);
272
+		requestBuilder.addHeader("Auth-User", login == null ? login : Base64.encode(login.getBytes()));
273
+		requestBuilder.addHeader("Auth-Pass", password == null ? password : Base64.encode(password.getBytes()));
274
+
275
+		AsyncHttpClient httpClient = getHttpClient();
276
+		ListenableFuture<Response> listenableFutureResponse = httpClient.executeRequest(requestBuilder.build());
277
+
278
+		while (!listenableFutureResponse.isDone()) {
279
+			Thread.sleep(100);
280
+		}
281
+
282
+		Response response = listenableFutureResponse.get();
283
+		return response;
284
+	}
285
+}
... ...
@@ -11,6 +11,7 @@
11 11
 	<modules>
12 12
 		<module>net.bluemind.authentication.api</module>
13 13
 		<module>net.bluemind.authentication.handler</module>
14
+		<module>net.bluemind.authentication.handler.tests</module>
14 15
 		<module>net.bluemind.authentication.persistence</module>
15 16
 		<module>net.bluemind.authentication.persistence.tests</module>
16 17
 		<module>net.bluemind.authentication.service</module>