Browse code

BM-12692 Fix: remove locator client dependency BM-12692 Fix: POP3 authentication BM-12692 Chore: clean code

Anthony Prades authored on 09/01/2018 14:02:43
Showing 2 changed files
... ...
@@ -7,7 +7,6 @@ Bundle-Vendor: www.blue-mind.net
7 7
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
8 8
 Require-Bundle: net.bluemind.lib.vertx;bundle-version="1.0.0",
9 9
  net.bluemind.slf4j;bundle-version="1.0.0",
10
- net.bluemind.locator.client,
11 10
  net.bluemind.authentication.api,
12 11
  net.bluemind.core.rest,
13 12
  net.bluemind.core.context,
... ...
@@ -18,6 +18,9 @@
18 18
  */
19 19
 package net.bluemind.authentication.handler;
20 20
 
21
+import java.security.InvalidParameterException;
22
+import java.util.List;
23
+
21 24
 import org.slf4j.Logger;
22 25
 import org.slf4j.LoggerFactory;
23 26
 import org.vertx.java.core.Handler;
... ...
@@ -36,17 +39,124 @@ import net.bluemind.core.context.SecurityContext;
36 36
 import net.bluemind.core.rest.ServerSideServiceProvider;
37 37
 import net.bluemind.domain.api.Domain;
38 38
 import net.bluemind.domain.api.IDomains;
39
-import net.bluemind.locator.client.LocatorClient;
39
+import net.bluemind.server.api.IServer;
40 40
 import net.bluemind.user.api.IUser;
41 41
 import net.bluemind.user.api.User;
42 42
 
43 43
 public final class Nginx implements Handler<HttpServerRequest> {
44 44
 
45 45
 	private static final Logger logger = LoggerFactory.getLogger(Nginx.class);
46
-	private final LocatorClient locator;
46
+	private final IDomains domainApi;
47
+
48
+	private static class QueryParameters {
49
+		public final String clientIp;
50
+		public final String backendPort;
51
+		public final String protocol;
52
+		public final String password;
53
+
54
+		public final String latd;
55
+		public final String backendLatd;
56
+
57
+		public final String backendSrv;
58
+
59
+		private QueryParameters(String clientIp, String protocol, String latd, String password, String backendSrv,
60
+				String backendPort, String backendLatd) {
61
+			this.clientIp = clientIp;
62
+			this.protocol = protocol;
63
+			this.latd = latd;
64
+			this.password = password;
65
+			this.backendSrv = backendSrv;
66
+			this.backendPort = backendPort;
67
+			this.backendLatd = backendLatd;
68
+		}
69
+
70
+		public static QueryParameters fromRequest(IDomains domainApi, HttpServerRequest req) {
71
+			String clientIp = req.headers().get("Client-IP");
72
+			String backendPort = req.headers().get("X-Auth-Port");
73
+			String protocol = req.headers().get("Auth-Protocol");
74
+
75
+			String latd = req.headers().get("Auth-User");
76
+			if (latd == null || "".equals(latd)) {
77
+				throw new InvalidParameterException("null or empty login");
78
+			}
79
+			latd = decode(latd);
80
+			String backendLatd = getBackendLatd(domainApi, protocol, latd);
81
+
82
+			String password = decode(req.headers().get("Auth-Pass"));
83
+
84
+			String backendSrv = getBackendSrv(domainApi, latd);
85
+
86
+			return new QueryParameters(clientIp, protocol, latd, password, backendSrv, backendPort, backendLatd);
87
+		}
88
+
89
+		public void setResponseHeaders(HttpServerResponse resp) {
90
+			MultiMap respHeaders = resp.headers();
91
+
92
+			respHeaders.add("Auth-Status", "OK");
93
+
94
+			respHeaders.add("Auth-Server", backendSrv);
95
+			respHeaders.add("Auth-Port", backendPort);
96
+
97
+			if (!latd.equals(backendLatd)) {
98
+				respHeaders.add("Auth-User", backendLatd);
99
+			}
100
+		}
101
+
102
+		private static String getBackendSrv(IDomains domainApi, String latd) {
103
+			if (latd.contains("@")) {
104
+				String userDomain = latd.split("@")[1];
105
+
106
+				ItemValue<Domain> domain = domainApi.findByNameOrAliases(userDomain);
107
+
108
+				if (domain != null) {
109
+					IServer serverApi = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
110
+							.instance(IServer.class, "default");
111
+					List<String> servers = serverApi.byAssignment(domain.uid, "mail/imap_frontend");
112
+					if (servers.size() != 0) {
113
+						return serverApi.getComplete(servers.get(0)).value.address();
114
+					}
115
+				}
116
+			}
117
+
118
+			throw new InvalidParameterException("No backend server found for " + latd);
119
+		}
120
+
121
+		private static String getBackendLatd(IDomains domainApi, String protocol, String latd) {
122
+			if ("pop3".equals(protocol) && latd.contains("@")) {
123
+				String[] latdParts = latd.split("@");
124
+
125
+				ItemValue<Domain> domain = domainApi.findByNameOrAliases(latdParts[1]);
126
+				if (domain != null) {
127
+					IUser userApi = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IUser.class,
128
+							domain.uid);
129
+					ItemValue<User> user = userApi.byEmail(latd);
130
+					if (user != null) {
131
+						return user.value.login + "@" + domain.value.name;
132
+					}
133
+				}
134
+			}
135
+
136
+			return latd;
137
+		}
138
+
139
+		/**
140
+		 * @param b64
141
+		 * @return
142
+		 */
143
+		private static String decode(String b64) {
144
+			ByteBuf srcBuf = Unpooled.wrappedBuffer(b64.getBytes());
145
+			ByteBuf decoded = Base64.decode(srcBuf, Base64Dialect.STANDARD);
146
+			byte[] dec = new byte[decoded.readableBytes()];
147
+			decoded.getBytes(0, dec);
148
+			srcBuf.release();
149
+			decoded.release();
150
+			String decStr = new String(dec);
151
+			return decStr;
152
+		}
153
+	}
47 154
 
48 155
 	public Nginx() {
49
-		locator = new LocatorClient();
156
+		domainApi = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM).instance(IDomains.class);
50 157
 	}
51 158
 
52 159
 	@Override
... ...
@@ -54,89 +164,40 @@ public final class Nginx implements Handler<HttpServerRequest> {
54 54
 		req.endHandler(new Handler<Void>() {
55 55
 			@Override
56 56
 			public void handle(Void v) {
57
-				String latd = null;
57
+				QueryParameters qp = null;
58 58
 				try {
59 59
 					long time = System.currentTimeMillis();
60
-					MultiMap headers = req.headers();
61
-					latd = decode(headers.get("Auth-User"));
62
-					String backendLatd = latd;
63 60
 
64
-					String clientIp = headers.get("Client-IP");
65
-					String dstPort = headers.get("X-Auth-Port");
66
-					String protocol = headers.get("Auth-Protocol");
67
-					String codedPass = headers.get("Auth-Pass");
68
-					final String pass = decode(codedPass);
61
+					qp = QueryParameters.fromRequest(domainApi, req);
69 62
 
70
-					String srv = locator.locateHost("mail/imap_frontend", latd);
71 63
 					IAuthentication authApi = ServerSideServiceProvider.getProvider(SecurityContext.ANONYMOUS)
72 64
 							.instance(IAuthentication.class);
73
-					ValidationKind kind = authApi.validate(latd, pass, "nginx-imap-password-check");
65
+					ValidationKind kind = authApi.validate(qp.latd, qp.password, "nginx-imap-password-check");
74 66
 					HttpServerResponse resp = req.response();
75 67
 					if (kind != ValidationKind.NONE) {
76
-						MultiMap respHeaders = resp.headers();
77
-						respHeaders.add("Auth-Status", "OK");
78
-						respHeaders.add("Auth-Server", srv);
79
-						respHeaders.add("Auth-Port", dstPort);
80
-
81
-						backendLatd = setBackendPop3Latd(respHeaders, backendLatd, latd, protocol);
68
+						qp.setResponseHeaders(resp);
69
+						resp.end();
82 70
 
83
-						req.response().end();
84 71
 						time = System.currentTimeMillis() - time;
85
-						logger.info("[{}][{}][{}] will use cyrus backend {} using login [{}], done in {}ms.", clientIp,
86
-								protocol, latd, srv, backendLatd, time);
72
+						logger.info("[{}][{}][{}] will use cyrus backend {} using login [{}], done in {}ms.",
73
+								qp.clientIp, qp.protocol, qp.latd, qp.backendSrv, qp.backendLatd, time);
87 74
 					} else {
88
-						fail(latd, clientIp, resp);
75
+						fail(qp, resp);
89 76
 					}
90
-
91 77
 				} catch (Exception e) {
92
-					fail(latd, "unknown", req.response());
78
+					logger.error(e.getMessage(), e);
79
+					fail(qp, req.response());
93 80
 				}
94 81
 			}
95
-
96
-			private String setBackendPop3Latd(MultiMap respHeaders, String backendLatd, String latd, String protocol) {
97
-				if ("pop3".equals(protocol) && latd.contains("@")) {
98
-					String userDomain = latd.split("@")[1];
99
-					IDomains domainApi = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
100
-							.instance(IDomains.class);
101
-					ItemValue<Domain> domain = domainApi.findByNameOrAliases(userDomain);
102
-
103
-					if (domain != null && !domain.value.name.equals(userDomain)) {
104
-						IUser userApi = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM)
105
-								.instance(IUser.class, domain.uid);
106
-						ItemValue<User> user = userApi.byEmail(latd);
107
-						if (user != null) {
108
-							backendLatd = user.value.login + "@" + domain.value.name;
109
-							respHeaders.add("Auth-User", backendLatd);
110
-						}
111
-					}
112
-				}
113
-
114
-				return backendLatd;
115
-			}
116 82
 		});
117 83
 	}
118 84
 
119 85
 	/**
120
-	 * @param b64
121
-	 * @return
122
-	 */
123
-	private String decode(String b64) {
124
-		ByteBuf srcBuf = Unpooled.wrappedBuffer(b64.getBytes());
125
-		ByteBuf decoded = Base64.decode(srcBuf, Base64Dialect.STANDARD);
126
-		byte[] dec = new byte[decoded.readableBytes()];
127
-		decoded.getBytes(0, dec);
128
-		srcBuf.release();
129
-		decoded.release();
130
-		String decStr = new String(dec);
131
-		return decStr;
132
-	}
133
-
134
-	/**
135 86
 	 * @param latd
136 87
 	 * @param resp
137 88
 	 */
138
-	private void fail(String latd, String clientIp, HttpServerResponse resp) {
139
-		logger.error("[{}] Denied auth from {}", latd, clientIp);
89
+	private void fail(QueryParameters qp, HttpServerResponse resp) {
90
+		logger.error("[{}] Denied auth from {}", qp == null ? null : qp.latd, qp == null ? null : qp.clientIp);
140 91
 		resp.headers().add("Auth-Status", "Invalid login or password");
141 92
 		resp.end();
142 93
 	}