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 org.apache.http.Header;
24 import org.apache.http.client.methods.*;
25 import org.apache.http.config.Registry;
26 import org.apache.http.config.RegistryBuilder;
27 import org.apache.http.conn.socket.ConnectionSocketFactory;
28 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
29 import org.apache.http.conn.ssl.NoopHostnameVerifier;
30 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
31 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
32 import org.apache.http.entity.ContentType;
33 import org.apache.http.entity.InputStreamEntity;
34 import org.apache.http.impl.client.CloseableHttpClient;
35 import org.apache.http.impl.client.HttpClients;
36 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
37 import org.apache.http.ssl.SSLContextBuilder;
38 import org.openecomp.sdc.logging.api.Logger;
39 import org.openecomp.sdc.logging.api.LoggerFactory;
40 import org.openecomp.sdc.webseal.simulator.conf.Conf;
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 java.io.IOException;
52 import java.io.InputStream;
53 import java.io.OutputStream;
54 import java.io.UnsupportedEncodingException;
55 import java.net.MalformedURLException;
57 import java.net.URLEncoder;
58 import java.security.KeyStoreException;
59 import java.security.NoSuchAlgorithmException;
61 import java.util.stream.Collectors;
62 import java.util.zip.GZIPInputStream;
64 public class SdcProxy extends HttpServlet {
66 private static final long serialVersionUID = 1L;
67 private static URL url;
68 private CloseableHttpClient httpClient;
70 private final String SDC1 = "/sdc1";
71 private final String ONBOARDING = "/onboarding/";
72 private final String SCRIPTS = "/scripts";
73 private final String STYLES = "/styles";
74 private final String LANGUAGES = "/languages";
75 private final String CONFIGURATIONS = "/configurations";
76 private static final Set<String> RESERVED_HEADERS = Arrays.stream(ReservedHeaders.values()).map(h -> h.getValue()).collect(Collectors.toSet());
78 private static final Logger logger = LoggerFactory.getLogger(SdcProxy.class);
80 public void init(ServletConfig config) throws ServletException {
82 conf = Conf.getInstance();
84 String feHost = conf.getFeHost();
85 url = new URL(feHost);
86 } catch (MalformedURLException me) {
87 throw new ServletException("Proxy URL is invalid", me);
91 httpClient = buildRestClient();
92 } catch (Exception e) {
93 throw new ServletException("Build rest client failed", e);
97 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
98 proxy(request, response, MethodEnum.GET);
101 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
103 String userId = request.getParameter("userId");
104 String password = request.getParameter("password");
107 if (userId == null) {
108 userId = request.getHeader("USER_ID");
111 System.out.println("SdcProxy -> doPost userId=" + userId);
112 request.setAttribute("message", "OK");
113 if (password != null && getUser(userId, password) == null) {
114 MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
115 RequestDispatcher view = request.getRequestDispatcher("login");
116 request.setAttribute("message", "ERROR: userid or password incorect");
117 view.forward(mutableRequest, response);
119 System.out.println("SdcProxy -> doPost going to doGet");
120 request.setAttribute("HTTP_IV_USER", userId);
121 proxy(request, response, MethodEnum.POST);
125 public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
126 proxy(request, response, MethodEnum.PUT);
129 public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
130 proxy(request, response, MethodEnum.DELETE);
133 private synchronized void proxy(HttpServletRequest request, HttpServletResponse response, MethodEnum methodEnum) throws IOException, UnsupportedEncodingException {
135 Map<String, String[]> requestParameters = request.getParameterMap();
136 String userIdHeader = getUseridFromRequest(request);
137 User user = getUser(userIdHeader);
139 // new request - forward to login page
140 if (userIdHeader == null) {
141 System.out.print("Going to login");
142 response.sendRedirect("/login");
146 String uri = getUri(request, requestParameters);
147 HttpRequestBase httpMethod = createHttpMethod(request, methodEnum, uri);
148 addHeadersToMethod(httpMethod, user, request);
150 try (CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpMethod)){;
151 response.setStatus(closeableHttpResponse.getStatusLine().getStatusCode());
152 if (request.getRequestURI().indexOf(".svg") > -1) {
153 response.setContentType("image/svg+xml");
156 if(closeableHttpResponse.getEntity() != null) {
157 InputStream responseBodyStream = closeableHttpResponse.getEntity().getContent();
158 Header contentEncodingHeader = closeableHttpResponse.getLastHeader("Content-Encoding");
159 if (contentEncodingHeader != null && contentEncodingHeader.getValue().equalsIgnoreCase("gzip")) {
160 responseBodyStream = new GZIPInputStream(responseBodyStream);
162 write(responseBodyStream, response.getOutputStream());
167 private User getUser(String userId, String password) {
168 User user = getUser(userId);
169 if (user.getPassword().equals(password)) {
175 private User getUser(String userId) {
176 return conf.getUsers().get(userId);
180 private List<String> getContextPaths() {
181 List<String> contextPaths = new ArrayList<>();
182 contextPaths.add(SDC1);
183 contextPaths.add(ONBOARDING);
184 contextPaths.add(STYLES);
185 contextPaths.add(SCRIPTS);
186 contextPaths.add(LANGUAGES);
187 contextPaths.add(CONFIGURATIONS);
191 private String getUri(HttpServletRequest request, Map<String, String[]> requestParameters) throws UnsupportedEncodingException {
192 String suffix = request.getRequestURI();
193 if (getContextPaths().stream().anyMatch(request.getRequestURI()::contains)) {
194 suffix = alignUrlProxy(suffix);
196 StringBuilder query = alignUrlParameters(requestParameters);
197 String uri = String.format("%s%s", new Object[]{this.url.toString() + suffix, query.toString()});
201 private HttpRequestBase createHttpMethod(HttpServletRequest request, MethodEnum methodEnum, String uri) throws IOException {
202 HttpRequestBase proxyMethod = null;
203 ServletInputStream inputStream = null;
204 InputStreamEntity entity = null;
206 switch (methodEnum) {
208 proxyMethod = new HttpGet(uri);
211 proxyMethod = new HttpPost(uri);
212 inputStream = request.getInputStream();
213 entity = new InputStreamEntity(inputStream, getContentType(request));
214 ((HttpPost) proxyMethod).setEntity(entity);
217 proxyMethod = new HttpPut(uri);
218 inputStream = request.getInputStream();
219 entity = new InputStreamEntity(inputStream, getContentType(request));
220 ((HttpPut) proxyMethod).setEntity(entity);
223 proxyMethod = new HttpDelete(uri);
229 private ContentType getContentType(HttpServletRequest request) {
230 String contentTypeStr = request.getContentType();
231 if (contentTypeStr == null ){
232 contentTypeStr = request.getHeader("contentType");
234 ContentType contentType = ContentType.parse(contentTypeStr);
235 return ContentType.create(contentType.getMimeType());
238 private String getUseridFromRequest(HttpServletRequest request) {
240 String userIdHeader = request.getHeader("USER_ID");
241 if (userIdHeader != null) {
244 Object o = request.getAttribute("HTTP_IV_USER");
248 Cookie[] cookies = request.getCookies();
250 if (cookies != null) {
251 for (int i = 0; i < cookies.length; ++i) {
252 if (cookies[i].getName().equals("USER_ID")) {
253 userIdHeader = cookies[i].getValue();
260 private static void addHeadersToMethod(HttpUriRequest proxyMethod, User user, HttpServletRequest request) {
262 proxyMethod.setHeader(ReservedHeaders.HTTP_IV_USER.name(), user.getUserId());
263 proxyMethod.setHeader(ReservedHeaders.USER_ID.name(), user.getUserId());
264 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_FIRSTNAME.name(), user.getFirstName());
265 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_EMAIL.name(), user.getEmail());
266 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_LASTNAME.name(), user.getLastName());
267 proxyMethod.setHeader(ReservedHeaders.HTTP_IV_REMOTE_ADDRESS.name(), "0.0.0.0");
268 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_WSTYPE.name(), "Intranet");
269 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_EMAIL.name(), "me@mail.com");
271 Enumeration<String> headerNames = request.getHeaderNames();
272 while (headerNames.hasMoreElements()) {
273 String headerName = headerNames.nextElement();
274 if (!RESERVED_HEADERS.contains(headerName)) {
275 Enumeration<String> headers = request.getHeaders(headerName);
276 while (headers.hasMoreElements()) {
277 String headerValue = headers.nextElement();
278 proxyMethod.setHeader(headerName, headerValue);
284 private String alignUrlProxy(String requestURI) {
286 int i = requestURI.indexOf(ONBOARDING);
288 return requestURI.substring(i);
291 i = requestURI.indexOf(SDC1 + SDC1);
293 return requestURI.substring(SDC1.length());
296 i = requestURI.indexOf(SDC1);
301 return SDC1 + requestURI;
304 private static StringBuilder alignUrlParameters(Map<String, String[]> requestParameters) throws UnsupportedEncodingException {
305 StringBuilder query = new StringBuilder();
306 for (String name : requestParameters.keySet()) {
307 for (String value : (String[]) requestParameters.get(name)) {
308 if (query.length() == 0) {
313 name = URLEncoder.encode(name, "UTF-8");
314 value = URLEncoder.encode(value, "UTF-8");
316 query.append(String.format("&%s=%s", new Object[]{name, value}));
322 private void write(InputStream inputStream, OutputStream outputStream) throws IOException {
324 while (inputStream != null && (b = inputStream.read()) != -1) {
325 outputStream.write(b);
327 outputStream.flush();
330 public String getServletInfo() {
331 return "Http Proxy Servlet";
334 enum ReservedHeaders {
335 HTTP_IV_USER("HTTP_IV_USER"), USER_ID("USER_ID"), HTTP_CSP_FIRSTNAME("HTTP_CSP_FIRSTNAME"), HTTP_CSP_EMAIL("HTTP_CSP_EMAIL"), HTTP_CSP_LASTNAME("HTTP_CSP_LASTNAME"), HTTP_IV_REMOTE_ADDRESS("HTTP_IV_REMOTE_ADDRESS"), HTTP_CSP_WSTYPE("HTTP_CSP_WSTYPE"), HOST("Host"), CONTENTLENGTH("Content-Length");
337 private String value;
339 ReservedHeaders(String value) {
343 public String getValue() {
349 private static CloseableHttpClient buildRestClient() throws NoSuchAlgorithmException, KeyStoreException {
350 SSLContextBuilder builder = new SSLContextBuilder();
351 builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
352 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault(),
353 NoopHostnameVerifier.INSTANCE);
354 Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
355 .register("http", new PlainConnectionSocketFactory())
356 .register("https", sslsf)
358 PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
359 return HttpClients.custom()
360 .setSSLSocketFactory(sslsf)
361 .setConnectionManager(cm)