Skip to content

Commit e978b44

Browse files
author
Anders Breid
authored
Fix multiple back ends login issue (#176)
* Fix multiple back ends login issue There was an issue where a user logged in to a back end but after switching back end became logged out from the previous back-end. It is now possible to be logged in to multiple back-ends and switch between them while still being logged in.
1 parent 36644d6 commit e978b44

File tree

1 file changed

+143
-45
lines changed

1 file changed

+143
-45
lines changed

src/main/java/com/ericsson/ei/frontend/EIRequestsController.java

Lines changed: 143 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package com.ericsson.ei.frontend;
1515

1616
import java.io.IOException;
17+
import java.net.URI;
1718
import java.util.ArrayList;
1819
import java.util.Arrays;
1920
import java.util.Enumeration;
@@ -48,6 +49,7 @@
4849
import org.springframework.web.bind.annotation.RestController;
4950

5051
import com.ericsson.ei.frontend.utils.EIRequestsControllerUtils;
52+
5153
@RestController
5254
public class EIRequestsController {
5355

@@ -59,33 +61,47 @@ public class EIRequestsController {
5961
private EIRequestsControllerUtils eiRequestsControllerUtils;
6062

6163
/**
62-
* Bridge all EI Http Requests with GET method. Used for fetching
63-
* Subscription by id or all subscriptions and EI Env Info.
64+
* Bridge all EI Http Requests with GET method. Used for fetching Subscription by id or all subscriptions and EI Env
65+
* Info.
66+
*
67+
* @param model
68+
* @param request
69+
* @return
6470
*/
6571
@CrossOrigin
66-
@RequestMapping(value = { "/subscriptions", "/subscriptions/*", "/information", "/download/*", "/auth",
67-
"/auth/*", "/queryAggregatedObject", "/queryMissedNotifications", "/query", "/rules/rule-check/testRulePageEnabled" }, method = RequestMethod.GET)
68-
public ResponseEntity<String> getRequests(Model model, HttpServletRequest request) {
69-
String eiRequestUrl = eiRequestsControllerUtils.getEIRequestURL(request);
72+
@RequestMapping(value = { "/subscriptions", "/subscriptions/*", "/information", "/download/*", "/auth", "/auth/*",
73+
"/queryAggregatedObject", "/queryMissedNotifications", "/query",
74+
"/rules/rule-check/testRulePageEnabled" }, method = RequestMethod.GET)
75+
public ResponseEntity<String> getRequests(Model model, HttpServletRequest incomingRequest) {
76+
String eiRequestUrl = eiRequestsControllerUtils.getEIRequestURL(incomingRequest);
7077
HttpGet outgoingRequest = new HttpGet(eiRequestUrl);
7178

72-
outgoingRequest = (HttpGet) addHeadersToRequest(outgoingRequest, request);
79+
outgoingRequest = (HttpGet) addHeadersToRequest(outgoingRequest, incomingRequest);
7380

74-
return getResponse(outgoingRequest, request);
81+
return executeHttpRequest(outgoingRequest, incomingRequest);
7582
}
7683

7784
/**
7885
* Bridge all EI Http Requests with POST method.
86+
*
87+
* @param model
88+
* @param incomingRequest
89+
* @return
7990
*/
8091
@CrossOrigin
81-
@RequestMapping(value = { "/subscriptions", "/rules/rule-check/aggregation", "/query" }, method = RequestMethod.POST)
92+
@RequestMapping(value = { "/subscriptions", "/rules/rule-check/aggregation",
93+
"/query" }, method = RequestMethod.POST)
8294
public ResponseEntity<String> postRequests(Model model, HttpServletRequest incomingRequest) {
8395
String eiRequestUrl = eiRequestsControllerUtils.getEIRequestURL(incomingRequest);
8496
String requestBody = "";
8597

8698
try {
87-
// Replaces \r with nothing in case system is run on windows \r may disturb tests. \r does not affect EI functionality.
88-
requestBody = incomingRequest.getReader().lines().collect(Collectors.joining(System.lineSeparator())).replaceAll("(\\r)", "");
99+
// Replaces \r with nothing in case system is run on windows \r may disturb
100+
// tests. \r does not affect EI functionality.
101+
requestBody = incomingRequest.getReader()
102+
.lines()
103+
.collect(Collectors.joining(System.lineSeparator()))
104+
.replaceAll("(\\r)", "");
89105
} catch (IOException e) {
90106
LOG.error("Forward Request Errors: " + e);
91107
}
@@ -100,12 +116,15 @@ public ResponseEntity<String> postRequests(Model model, HttpServletRequest incom
100116
outgoingRequest = (HttpPost) addHeadersToRequest(outgoingRequest, incomingRequest);
101117
outgoingRequest.setHeader("Content-type", "application/json");
102118

103-
return getResponse(outgoingRequest, incomingRequest);
119+
return executeHttpRequest(outgoingRequest, incomingRequest);
104120
}
105121

106122
/**
107-
* Bridge all EI Http Requests with PUT method. E.g. Making Update
108-
* Subscription Request.
123+
* Bridge all EI Http Requests with PUT method. E.g. Making Update Subscription Request.
124+
*
125+
* @param model
126+
* @param incomingRequest
127+
* @return
109128
*/
110129
@CrossOrigin
111130
@RequestMapping(value = "/subscriptions", method = RequestMethod.PUT)
@@ -114,7 +133,10 @@ public ResponseEntity<String> putRequests(Model model, HttpServletRequest incomi
114133
String requestBody = "";
115134

116135
try {
117-
requestBody = incomingRequest.getReader().lines().collect(Collectors.joining(System.lineSeparator())).replaceAll("(\\r)", "");
136+
requestBody = incomingRequest.getReader()
137+
.lines()
138+
.collect(Collectors.joining(System.lineSeparator()))
139+
.replaceAll("(\\r)", "");
118140
} catch (IOException e) {
119141
LOG.error("Forward Request Errors: " + e);
120142
}
@@ -129,12 +151,15 @@ public ResponseEntity<String> putRequests(Model model, HttpServletRequest incomi
129151
outgoingRequest = (HttpPut) addHeadersToRequest(outgoingRequest, incomingRequest);
130152
outgoingRequest.setHeader("Content-type", "application/json");
131153

132-
return getResponse(outgoingRequest, incomingRequest);
154+
return executeHttpRequest(outgoingRequest, incomingRequest);
133155
}
134156

135157
/**
136-
* Bridge all EI Http Requests with DELETE method. Used for DELETE
137-
* subscriptions.
158+
* Bridge all EI Http Requests with DELETE method. Used for DELETE subscriptions.
159+
*
160+
* @param model
161+
* @param incomingRequest
162+
* @return
138163
*/
139164
@CrossOrigin
140165
@RequestMapping(value = "/subscriptions/*", method = RequestMethod.DELETE)
@@ -145,30 +170,42 @@ public ResponseEntity<String> deleteRequests(Model model, HttpServletRequest inc
145170

146171
outgoingRequest = (HttpDelete) addHeadersToRequest(outgoingRequest, incomingRequest);
147172

148-
return getResponse(outgoingRequest, incomingRequest);
173+
return executeHttpRequest(outgoingRequest, incomingRequest);
149174
}
150175

151-
private ResponseEntity<String> getResponse(HttpRequestBase outgoingRequest, HttpServletRequest incomingRequest) {
176+
/**
177+
* This function executes the given outgoingRequest and returns a ResponseEntity
178+
*
179+
* @param outgoingRequest
180+
* @param incomingRequest
181+
* @return
182+
*/
183+
private ResponseEntity<String> executeHttpRequest(HttpRequestBase outgoingRequest,
184+
HttpServletRequest incomingRequest) {
152185
HttpHeaders headers = new HttpHeaders();
153186
String responseBody = "[]";
154187
int statusCode = HttpStatus.PROCESSING.value();
155188

156-
String url = outgoingRequest.getURI().toString();
189+
String url = outgoingRequest.getURI()
190+
.toString();
157191
LOG.debug("Forwarding request to: " + url);
158-
try (CloseableHttpResponse eiResponse = HttpClientBuilder.create().build().execute(outgoingRequest)) {
159-
if(eiResponse.getEntity() != null) {
192+
try (CloseableHttpResponse eiResponse = HttpClientBuilder.create()
193+
.build()
194+
.execute(outgoingRequest)) {
195+
if (eiResponse.getEntity() != null) {
160196
responseBody = StringUtils.defaultIfBlank(EntityUtils.toString(eiResponse.getEntity(), "utf-8"), "[]");
161197
}
162198

163-
headers = getHeadersFromResponse(headers, eiResponse, incomingRequest);
164-
statusCode = eiResponse.getStatusLine().getStatusCode();
199+
headers = getHeadersFromResponse(headers, eiResponse, incomingRequest, outgoingRequest);
200+
statusCode = eiResponse.getStatusLine()
201+
.getStatusCode();
165202

166-
LOG.debug("EI Http response status code: " + statusCode
167-
+ "\nEI Received response body:\n" + responseBody
203+
LOG.debug("EI Http response status code: " + statusCode + "\nEI Received response body:\n" + responseBody
168204
+ "\nForwarding response back to EI Frontend WebUI.");
169205
} catch (IOException e) {
170206
statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
171-
responseBody = "{\"statusCode\": " + statusCode + ", \"error\": \"Forward Request Error: " + String.valueOf(e) + "\"}";
207+
responseBody = "{\"statusCode\": " + statusCode + ", \"error\": \"Forward Request Error: "
208+
+ String.valueOf(e) + "\"}";
172209
LOG.error("Forward Request Errors: " + e);
173210
}
174211

@@ -177,17 +214,33 @@ private ResponseEntity<String> getResponse(HttpRequestBase outgoingRequest, Http
177214
return new ResponseEntity<>(responseBody, headers, HttpStatus.valueOf(statusCode));
178215
}
179216

180-
private HttpHeaders getHeadersFromResponse(HttpHeaders headers, CloseableHttpResponse eiResponse, HttpServletRequest incomingRequest) {
217+
/**
218+
* This function copies headers from the made request and puts it into the response. It also extracts any
219+
* x-path-tokens if found.
220+
*
221+
* @param headers
222+
* @param eiResponse
223+
* @param incomingRequest
224+
* @param outgoingRequest
225+
* @return
226+
*/
227+
private HttpHeaders getHeadersFromResponse(HttpHeaders headers, CloseableHttpResponse eiResponse,
228+
HttpServletRequest incomingRequest, HttpRequestBase outgoingRequest) {
181229
List<String> headerNameList = new ArrayList<String>();
182230
List<String> notCopiedHeaderNameList = new ArrayList<>();
183231

184232
for (Header header : eiResponse.getAllHeaders()) {
185-
if (header.getName().equalsIgnoreCase(X_AUTH_TOKEN)) {
233+
String headerName = header.getName();
234+
if (headerName.equalsIgnoreCase(X_AUTH_TOKEN)) {
186235
LOG.debug("Adding '" + X_AUTH_TOKEN + "' to current session.");
187-
incomingRequest.getSession().setAttribute(X_AUTH_TOKEN, header.getValue());
236+
237+
String xAuthTokenKey = getXpathTokenKey(outgoingRequest.getURI());
238+
incomingRequest.getSession()
239+
.setAttribute(xAuthTokenKey, header.getValue());
188240
}
189241

190-
boolean headerShouldBeCopied = HEADERS_TO_COPY.contains(header.getName().toLowerCase());
242+
boolean headerShouldBeCopied = HEADERS_TO_COPY.contains(header.getName()
243+
.toLowerCase());
191244
if (headerShouldBeCopied) {
192245
headerNameList.add(header.getName());
193246
headers.add(header.getName(), header.getValue());
@@ -196,18 +249,25 @@ private HttpHeaders getHeadersFromResponse(HttpHeaders headers, CloseableHttpRes
196249
}
197250
}
198251

199-
LOG.debug("Headers processed returning response: "+
200-
"\nHeaders copied to the response: " + headerNameList.toString() +
201-
"\nHeaders not copied to the response: " + notCopiedHeaderNameList.toString());
252+
LOG.debug("Headers processed returning response: " + "\nHeaders copied to the response: "
253+
+ headerNameList.toString() + "\nHeaders not copied to the response: "
254+
+ notCopiedHeaderNameList.toString());
202255
return headers;
203256
}
204257

258+
/**
259+
* This function copies headers from the incomming request into the outgoing request headers.
260+
*
261+
* @param outgoingRequest
262+
* @param incomingRequest
263+
* @return
264+
*/
205265
private HttpRequestBase addHeadersToRequest(HttpRequestBase outgoingRequest, HttpServletRequest incomingRequest) {
206266
Enumeration<String> headerNames = incomingRequest.getHeaderNames();
207267
List<String> headerNameList = new ArrayList<>();
208268
List<String> notCopiedHeaderNameList = new ArrayList<>();
209269

210-
while(headerNames.hasMoreElements()) {
270+
while (headerNames.hasMoreElements()) {
211271
String headerName = headerNames.nextElement();
212272
boolean headerShouldBeCopied = HEADERS_TO_COPY.contains(headerName.toLowerCase());
213273
if (headerShouldBeCopied) {
@@ -218,21 +278,59 @@ private HttpRequestBase addHeadersToRequest(HttpRequestBase outgoingRequest, Htt
218278
}
219279
}
220280

221-
if (incomingRequest.getSession().getAttribute(X_AUTH_TOKEN) != null) {
222-
LOG.debug("Adding '" + X_AUTH_TOKEN + "' to the request header.");
223-
outgoingRequest.addHeader(X_AUTH_TOKEN, incomingRequest.getSession().getAttribute(X_AUTH_TOKEN).toString());
281+
outgoingRequest = addXauthTokenToRequest(outgoingRequest, incomingRequest);
282+
283+
LOG.debug("Headers processed before making request: " + "\nHeaders copied to the request: "
284+
+ headerNameList.toString() + "\nHeaders not copied to the request: "
285+
+ notCopiedHeaderNameList.toString());
224286

225-
boolean userLoggingOut = incomingRequest.getRequestURL().toString().contains("logout");
287+
return outgoingRequest;
288+
}
289+
290+
/**
291+
* This function adds an x-path-token to an outgoing request if it exists for the back-end the request is made
292+
* towards.
293+
*
294+
* @param outgoingRequest
295+
* @param incomingRequest
296+
* @return
297+
*/
298+
private HttpRequestBase addXauthTokenToRequest(HttpRequestBase outgoingRequest,
299+
HttpServletRequest incomingRequest) {
300+
String xAuthTokenKey = getXpathTokenKey(outgoingRequest.getURI());
301+
boolean sessionContainsXAuthToken = incomingRequest.getSession()
302+
.getAttribute(xAuthTokenKey) != null;
303+
if (sessionContainsXAuthToken) {
304+
LOG.debug("Adding '" + X_AUTH_TOKEN + "' to the request header.");
305+
String xAuthToken = incomingRequest.getSession()
306+
.getAttribute(xAuthTokenKey)
307+
.toString();
308+
outgoingRequest.addHeader(X_AUTH_TOKEN, xAuthToken);
309+
310+
boolean userLoggingOut = incomingRequest.getRequestURL()
311+
.toString()
312+
.contains("logout");
226313
if (userLoggingOut) {
227314
LOG.debug("Removing '" + X_AUTH_TOKEN + "' from current session.");
228-
incomingRequest.getSession().setAttribute(X_AUTH_TOKEN, null);
315+
incomingRequest.getSession()
316+
.setAttribute(X_AUTH_TOKEN, null);
229317
}
230318
}
319+
return outgoingRequest;
320+
}
231321

232-
LOG.debug("Headers processed before making request: "+
233-
"\nHeaders copied to the request: " + headerNameList.toString() +
234-
"\nHeaders not copied to the request: " + notCopiedHeaderNameList.toString());
322+
/**
323+
* builds an xPathTokenKey, the token will be unique key for each http(s) host and port and stored for each session.
324+
*
325+
* @param uri
326+
* @return
327+
*/
328+
private String getXpathTokenKey(URI uri) {
329+
String host = uri.getHost();
330+
int port = uri.getPort();
331+
String scheme = uri.getScheme();
235332

236-
return outgoingRequest;
333+
String xAuthTokenKey = String.format("%s-%s%s%d", X_AUTH_TOKEN, scheme, host, port);
334+
return xAuthTokenKey;
237335
}
238336
}

0 commit comments

Comments
 (0)