2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.webseal.simulator;
23 import static java.nio.charset.StandardCharsets.UTF_8;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.net.MalformedURLException;
30 import java.net.URLEncoder;
31 import java.security.KeyStoreException;
32 import java.security.NoSuchAlgorithmException;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Enumeration;
36 import java.util.List;
38 import java.util.Map.Entry;
40 import java.util.stream.Collectors;
41 import java.util.zip.GZIPInputStream;
42 import javax.net.ssl.SSLContext;
43 import javax.servlet.RequestDispatcher;
44 import javax.servlet.ServletConfig;
45 import javax.servlet.ServletException;
46 import javax.servlet.ServletInputStream;
47 import javax.servlet.http.Cookie;
48 import javax.servlet.http.HttpServlet;
49 import javax.servlet.http.HttpServletRequest;
50 import javax.servlet.http.HttpServletResponse;
51 import lombok.AllArgsConstructor;
53 import org.apache.http.Header;
54 import org.apache.http.client.methods.CloseableHttpResponse;
55 import org.apache.http.client.methods.HttpDelete;
56 import org.apache.http.client.methods.HttpGet;
57 import org.apache.http.client.methods.HttpPost;
58 import org.apache.http.client.methods.HttpPut;
59 import org.apache.http.client.methods.HttpRequestBase;
60 import org.apache.http.client.methods.HttpUriRequest;
61 import org.apache.http.config.Registry;
62 import org.apache.http.config.RegistryBuilder;
63 import org.apache.http.conn.socket.ConnectionSocketFactory;
64 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
65 import org.apache.http.conn.ssl.NoopHostnameVerifier;
66 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
67 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
68 import org.apache.http.entity.ContentType;
69 import org.apache.http.entity.InputStreamEntity;
70 import org.apache.http.impl.client.CloseableHttpClient;
71 import org.apache.http.impl.client.HttpClients;
72 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
73 import org.apache.http.ssl.SSLContextBuilder;
74 import org.openecomp.sdc.webseal.simulator.conf.Conf;
76 public class SdcProxy extends HttpServlet {
78 private static final long serialVersionUID = 1L;
79 private static final Set<String> RESERVED_HEADERS =
80 Arrays.stream(ReservedHeaders.values()).map(ReservedHeaders::getValue).collect(Collectors.toSet());
81 private static final String USER_ID = "USER_ID";
82 private static final String HTTP_IV_USER = "HTTP_IV_USER";
83 private static final String SDC1 = "/sdc1";
84 private static final String ONBOARDING = "/onboarding/";
85 private static final String SCRIPTS = "/scripts";
86 private static final String STYLES = "/styles";
87 private static final String LANGUAGES = "/languages";
88 private static final String CONFIGURATIONS = "/configurations";
90 private CloseableHttpClient httpClient;
94 public void init(ServletConfig config) throws ServletException {
96 conf = Conf.getInstance();
98 url = new URL(conf.getFeHost());
99 } catch (MalformedURLException me) {
100 throw new ServletException("Proxy URL is invalid", me);
104 httpClient = buildRestClient();
105 } catch (Exception e) {
106 throw new ServletException("Build rest client failed", e);
111 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
112 proxy(request, response, MethodEnum.GET);
116 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
118 String userId = request.getParameter("userId");
119 String password = request.getParameter("password");
122 if (userId == null) {
123 userId = request.getHeader(USER_ID);
126 System.out.println("SdcProxy -> doPost userId=" + userId);
127 request.setAttribute("message", "OK");
128 if (password != null && getUser(userId, password) == null) {
129 MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
130 RequestDispatcher view = request.getRequestDispatcher("login");
131 request.setAttribute("message", "ERROR: userid or password incorect");
132 view.forward(mutableRequest, response);
134 System.out.println("SdcProxy -> doPost going to doGet");
135 request.setAttribute(HTTP_IV_USER, userId);
136 proxy(request, response, MethodEnum.POST);
141 public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
142 proxy(request, response, MethodEnum.PUT);
146 public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
147 proxy(request, response, MethodEnum.DELETE);
150 private void proxy(HttpServletRequest request, HttpServletResponse response, MethodEnum methodEnum) throws IOException {
152 Map<String, String[]> requestParameters = request.getParameterMap();
153 String userIdHeader = getUseridFromRequest(request);
154 // new request - forward to login page
155 if (userIdHeader == null) {
156 System.out.print("Going to login");
157 response.sendRedirect("/login");
161 final User user = getUser(userIdHeader);
163 String uri = getUri(request, requestParameters);
164 HttpRequestBase httpMethod = createHttpMethod(request, methodEnum, uri);
165 addHeadersToMethod(httpMethod, user, request);
167 try (CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpMethod)) {
168 response.setStatus(closeableHttpResponse.getStatusLine().getStatusCode());
169 if (request.getRequestURI().indexOf(".svg") > -1) {
170 response.setContentType("image/svg+xml");
173 if (closeableHttpResponse.getEntity() != null) {
174 InputStream responseBodyStream = closeableHttpResponse.getEntity().getContent();
175 Header contentEncodingHeader = closeableHttpResponse.getLastHeader("Content-Encoding");
176 if (contentEncodingHeader != null && contentEncodingHeader.getValue().equalsIgnoreCase("gzip")) {
177 responseBodyStream = new GZIPInputStream(responseBodyStream);
179 write(responseBodyStream, response.getOutputStream());
184 private User getUser(String userId, String password) {
185 User user = getUser(userId);
186 if (user.getPassword().equals(password)) {
192 private User getUser(String userId) {
193 return conf.getUsers().get(userId);
197 private List<String> getContextPaths() {
198 List<String> contextPaths = new ArrayList<>();
199 contextPaths.add(SDC1);
200 contextPaths.add(ONBOARDING);
201 contextPaths.add(STYLES);
202 contextPaths.add(SCRIPTS);
203 contextPaths.add(LANGUAGES);
204 contextPaths.add(CONFIGURATIONS);
208 private String getUri(HttpServletRequest request, Map<String, String[]> requestParameters) {
209 String suffix = request.getRequestURI();
210 if (getContextPaths().stream().anyMatch(request.getRequestURI()::contains)) {
211 suffix = alignUrlProxy(suffix);
213 StringBuilder query = alignUrlParameters(requestParameters);
214 return String.format("%s%s", url.toString() + suffix, query.toString());
217 private HttpRequestBase createHttpMethod(HttpServletRequest request, MethodEnum methodEnum, String uri) throws IOException {
218 HttpRequestBase proxyMethod = null;
219 ServletInputStream inputStream = null;
220 InputStreamEntity entity = null;
222 switch (methodEnum) {
224 proxyMethod = new HttpGet(uri);
227 proxyMethod = new HttpPost(uri);
228 inputStream = request.getInputStream();
229 entity = new InputStreamEntity(inputStream, getContentType(request));
230 ((HttpPost) proxyMethod).setEntity(entity);
233 proxyMethod = new HttpPut(uri);
234 inputStream = request.getInputStream();
235 entity = new InputStreamEntity(inputStream, getContentType(request));
236 ((HttpPut) proxyMethod).setEntity(entity);
239 proxyMethod = new HttpDelete(uri);
245 private ContentType getContentType(HttpServletRequest request) {
246 String contentTypeStr = request.getContentType();
247 if (contentTypeStr == null) {
248 contentTypeStr = request.getHeader("contentType");
250 ContentType contentType = ContentType.parse(contentTypeStr);
251 return ContentType.create(contentType.getMimeType());
254 private String getUseridFromRequest(HttpServletRequest request) {
256 String userIdHeader = request.getHeader(USER_ID);
257 if (userIdHeader != null) {
260 Object o = request.getAttribute(HTTP_IV_USER);
264 Cookie[] cookies = request.getCookies();
266 if (cookies != null) {
267 for (int i = 0; i < cookies.length; ++i) {
268 if (cookies[i].getName().equals(USER_ID)) {
269 userIdHeader = cookies[i].getValue();
276 private void addHeadersToMethod(HttpUriRequest proxyMethod, User user, HttpServletRequest request) {
278 proxyMethod.setHeader(ReservedHeaders.HTTP_IV_USER.name(), user.getUserId());
279 proxyMethod.setHeader(ReservedHeaders.USER_ID.name(), user.getUserId());
280 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_FIRSTNAME.name(), user.getFirstName());
281 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_EMAIL.name(), user.getEmail());
282 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_LASTNAME.name(), user.getLastName());
283 proxyMethod.setHeader(ReservedHeaders.HTTP_IV_REMOTE_ADDRESS.name(), "0.0.0.0");
284 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_WSTYPE.name(), "Intranet");
285 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_EMAIL.name(), "me@mail.com");
287 Enumeration<String> headerNames = request.getHeaderNames();
288 while (headerNames.hasMoreElements()) {
289 String headerName = headerNames.nextElement();
290 if (!RESERVED_HEADERS.contains(headerName)) {
291 Enumeration<String> headers = request.getHeaders(headerName);
292 while (headers.hasMoreElements()) {
293 String headerValue = headers.nextElement();
294 proxyMethod.setHeader(headerName, headerValue);
300 private String alignUrlProxy(String requestURI) {
302 int i = requestURI.indexOf(ONBOARDING);
304 return requestURI.substring(i);
307 i = requestURI.indexOf(SDC1 + SDC1);
309 return requestURI.substring(SDC1.length());
312 i = requestURI.indexOf(SDC1);
317 return SDC1 + requestURI;
320 private StringBuilder alignUrlParameters(Map<String, String[]> requestParameters) {
321 final var query = new StringBuilder();
322 for (final Entry<String, String[]> entry : requestParameters.entrySet()) {
323 for (final String value : entry.getValue()) {
324 if (query.length() == 0) {
329 query.append(String.format("&%s=%s", URLEncoder.encode(entry.getKey(), UTF_8), URLEncoder.encode(value, UTF_8)));
335 private void write(InputStream inputStream, OutputStream outputStream) throws IOException {
337 while (inputStream != null && (b = inputStream.read()) != -1) {
338 outputStream.write(b);
340 outputStream.flush();
344 public String getServletInfo() {
345 return "Http Proxy Servlet";
348 private CloseableHttpClient buildRestClient() throws NoSuchAlgorithmException, KeyStoreException {
349 final var builder = new SSLContextBuilder();
350 builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
351 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault(),
352 NoopHostnameVerifier.INSTANCE);
353 Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
354 .register("http", new PlainConnectionSocketFactory())
355 .register("https", sslsf)
357 PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
358 return HttpClients.custom()
359 .setSSLSocketFactory(sslsf)
360 .setConnectionManager(cm)
366 enum ReservedHeaders {
367 HTTP_IV_USER(SdcProxy.HTTP_IV_USER), USER_ID(SdcProxy.USER_ID), HTTP_CSP_FIRSTNAME("HTTP_CSP_FIRSTNAME"), HTTP_CSP_EMAIL(
368 "HTTP_CSP_EMAIL"), HTTP_CSP_LASTNAME("HTTP_CSP_LASTNAME"), HTTP_IV_REMOTE_ADDRESS("HTTP_IV_REMOTE_ADDRESS"), HTTP_CSP_WSTYPE(
369 "HTTP_CSP_WSTYPE"), HOST("Host"), CONTENTLENGTH("Content-Length");
371 private final String value;