Browse code

nginx auth handler

David Phan authored on 05/12/2014 09:51:35
Showing 9 changed files
... ...
@@ -1,5 +1,5 @@
1 1
 mail {
2
-     auth_http 127.0.0.1:8085/nginx;
2
+     auth_http 127.0.0.1:8090/nginx;
3 3
      proxy on;
4 4
      starttls on;
5 5
 
6 6
new file mode 100644
... ...
@@ -0,0 +1,19 @@
0
+Manifest-Version: 1.0
1
+Bundle-ManifestVersion: 2
2
+Bundle-Name: net.bluemind.authentication.handler
3
+Bundle-SymbolicName: net.bluemind.authentication.handler;singleton:=true
4
+Bundle-Version: 1.0.0.qualifier
5
+Bundle-Vendor: www.blue-mind.net
6
+Fragment-Host: net.bluemind.core.rest.http
7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
8
+Require-Bundle: net.bluemind.lib.vertx;bundle-version="1.0.0",
9
+ net.bluemind.slf4j;bundle-version="1.6.4",
10
+ net.bluemind.lib.netty4,
11
+ net.bluemind.locator.client,
12
+ net.bluemind.authentication.api,
13
+ net.bluemind.core.rest,
14
+ net.bluemind.core.context,
15
+ net.bluemind.server.api,
16
+ net.bluemind.config,
17
+ net.bluemind.core.container.persistance,
18
+ net.bluemind.core.rest.http.vertx;bundle-version="1.0.0"
0 19
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+source.. = src/
1
+bin.includes = META-INF/,\
2
+               .,\
3
+               fragment.xml
0 4
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<?eclipse version="3.4"?>
2
+<fragment>
3
+   <extension
4
+         point="net.bluemind.core.rest.http.vertx.httpRoute">
5
+      <route
6
+            handler="net.bluemind.authentication.handler.Nginx"
7
+            path="/nginx">
8
+      </route>
9
+   </extension>
10
+
11
+</fragment>
0 12
new file mode 100644
... ...
@@ -0,0 +1,10 @@
0
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1
+  <modelVersion>4.0.0</modelVersion>
2
+  <parent>
3
+    <groupId>net.bluemind</groupId>
4
+    <version>1.0.0-SNAPSHOT</version>
5
+    <artifactId>net.bluemind.authentication.plugins</artifactId>
6
+  </parent>
7
+  <artifactId>net.bluemind.authentication.handler</artifactId>
8
+  <packaging>eclipse-plugin</packaging>
9
+</project>
0 10
new file mode 100644
... ...
@@ -0,0 +1,155 @@
0
+/* BEGIN LICENSE
1
+ * Copyright © Blue Mind SAS, 2012-2014
2
+ *
3
+ * This file is part of Blue Mind. Blue Mind 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
+ * or the CeCILL as published by CeCILL.info (version 2 of the License).
10
+ *
11
+ * There are special exceptions to the terms and conditions of the
12
+ * licenses as they are applied to this program. See LICENSE.txt in
13
+ * the directory of this program distribution.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
+ *
19
+ * See LICENSE.txt
20
+ * END LICENSE
21
+ */
22
+package net.bluemind.authentication.handler;
23
+
24
+import io.netty.buffer.ByteBuf;
25
+import io.netty.buffer.Unpooled;
26
+import io.netty.handler.codec.base64.Base64;
27
+import io.netty.handler.codec.base64.Base64Dialect;
28
+
29
+import java.util.List;
30
+
31
+import net.bluemind.authentication.api.IAuthentication;
32
+import net.bluemind.authentication.api.LoginResponse;
33
+import net.bluemind.authentication.api.LoginResponse.Status;
34
+import net.bluemind.config.InstallationId;
35
+import net.bluemind.core.container.model.ItemValue;
36
+import net.bluemind.core.context.SecurityContext;
37
+import net.bluemind.core.rest.ServerSideServiceProvider;
38
+import net.bluemind.locator.client.LocatorClient;
39
+import net.bluemind.server.api.Assignment;
40
+import net.bluemind.server.api.IServer;
41
+import net.bluemind.server.api.Server;
42
+
43
+import org.slf4j.Logger;
44
+import org.slf4j.LoggerFactory;
45
+import org.vertx.java.core.Handler;
46
+import org.vertx.java.core.MultiMap;
47
+import org.vertx.java.core.http.HttpServerRequest;
48
+import org.vertx.java.core.http.HttpServerResponse;
49
+
50
+public class Nginx implements Handler<HttpServerRequest> {
51
+
52
+	private static final Logger logger = LoggerFactory.getLogger(Nginx.class);
53
+	private final LocatorClient locator;
54
+
55
+	public Nginx() {
56
+		locator = new LocatorClient();
57
+	}
58
+
59
+	@Override
60
+	public void handle(final HttpServerRequest req) {
61
+		MultiMap headers = req.headers();
62
+		final String latd = decode(headers.get("Auth-User"));
63
+		String codedPass = headers.get("Auth-Pass");
64
+		final String pass = decode(codedPass);
65
+
66
+		logger.debug("** Login: '{}', Password: '{}', b64: '{}'", latd, pass,
67
+				codedPass);
68
+
69
+		final String dstPort = headers.get("X-Auth-Port");
70
+		req.endHandler(new Handler<Void>() {
71
+
72
+			@Override
73
+			public void handle(Void v) {
74
+				try {
75
+					long time = System.currentTimeMillis();
76
+					IAuthentication authService = ServerSideServiceProvider
77
+							.getProvider(SecurityContext.ANONYMOUS).instance(
78
+									IAuthentication.class);
79
+
80
+					LoginResponse resp = authService.login(latd, pass,
81
+							"nginx-auth-http");
82
+					if (resp.status == Status.Bad) {
83
+						fail(latd, req.response());
84
+					} else {
85
+						String srv = locator.locateHost("mail/imap", latd);
86
+
87
+						if (srv == null) {
88
+							IServer serverService = ServerSideServiceProvider
89
+									.getProvider(SecurityContext.SYSTEM)
90
+									.instance(IServer.class,
91
+											InstallationId.getIdentifier());
92
+
93
+							List<Assignment> assignments = serverService
94
+									.getAssignments(latd.split("@")[1]);
95
+
96
+							if (assignments == null || assignments.isEmpty()) {
97
+								fail(latd, req.response());
98
+								return;
99
+							}
100
+
101
+							for (Assignment assignment : assignments) {
102
+								if ("mail/imap".equals(assignment.tag)) {
103
+									ItemValue<Server> server = serverService
104
+											.getComplete(assignment.serverUid);
105
+									srv = server.value.ip;
106
+									break;
107
+								}
108
+							}
109
+
110
+						}
111
+
112
+						MultiMap respHeaders = req.response().headers();
113
+						respHeaders.add("Auth-Status", "OK");
114
+						respHeaders.add("Auth-Server", srv);
115
+						respHeaders.add("Auth-Port", dstPort);
116
+						req.response().end();
117
+						time = System.currentTimeMillis() - time;
118
+						logger.info(
119
+								"[{}] will use cyrus backend {}, done in {}ms.",
120
+								latd, srv, time);
121
+					}
122
+
123
+				} catch (Throwable e) {
124
+					fail(latd, req.response());
125
+				}
126
+			}
127
+		});
128
+	}
129
+
130
+	/**
131
+	 * @param b64
132
+	 * @return
133
+	 */
134
+	private String decode(String b64) {
135
+		ByteBuf srcBuf = Unpooled.wrappedBuffer(b64.getBytes());
136
+		ByteBuf decoded = Base64.decode(srcBuf, Base64Dialect.STANDARD);
137
+		byte[] dec = new byte[decoded.capacity()];
138
+		decoded.getBytes(0, dec);
139
+		srcBuf.release();
140
+		decoded.release();
141
+		String decStr = new String(dec);
142
+		return decStr;
143
+	}
144
+
145
+	/**
146
+	 * @param latd
147
+	 * @param resp
148
+	 */
149
+	private void fail(String latd, HttpServerResponse resp) {
150
+		logger.error("[{}] Denied.", latd);
151
+		resp.headers().add("Auth-Status", "Invalid login or password");
152
+		resp.end();
153
+	}
154
+}
... ...
@@ -10,6 +10,7 @@
10 10
 	<packaging>pom</packaging>
11 11
 	<modules>
12 12
 		<module>net.bluemind.authentication.api</module>
13
+		<module>net.bluemind.authentication.handler</module>
13 14
 		<module>net.bluemind.authentication.service</module>
14 15
 		<module>net.bluemind.authentication.provider</module>
15 16
 		<module>net.bluemind.authentication.service.tests</module>
... ...
@@ -41,6 +41,7 @@
41 41
       <plugin id="net.bluemind.archive.store"/>
42 42
       <plugin id="net.bluemind.archive.store.snappy"/>
43 43
       <plugin id="net.bluemind.authentication.api"/>
44
+      <plugin id="net.bluemind.authentication.handler" fragment="true"/>
44 45
       <plugin id="net.bluemind.authentication.provider"/>
45 46
       <plugin id="net.bluemind.authentication.service"/>
46 47
       <plugin id="net.bluemind.calendar.api"/>
... ...
@@ -178,8 +178,7 @@ public abstract class EasTestCase extends TestCase {
178 178
 		System.err.println(" **** IMAP HOST " + imapHost + ", LOGIN: " + latd
179 179
 				+ ", PASSWORD: " + testPass);
180 180
 
181
-		// FIXME use 114 instead of 1143
182
-		imap = new StoreClient(imapHost, 1143, latd, testPass);
181
+		imap = new StoreClient(imapHost, 143, latd, testPass);
183 182
 		boolean loggedInImap = imap.login(false);
184 183
 		assertTrue(loggedInImap);
185 184