fix security violation
[sdc.git] / utils / webseal-simulator / src / main / java / org / openecomp / sdc / webseal / simulator / SdcProxy.java
1 package org.openecomp.sdc.webseal.simulator;
2
3 import org.apache.http.Header;
4 import org.apache.http.client.methods.*;
5 import org.apache.http.config.Registry;
6 import org.apache.http.config.RegistryBuilder;
7 import org.apache.http.conn.socket.ConnectionSocketFactory;
8 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
9 import org.apache.http.conn.ssl.NoopHostnameVerifier;
10 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
11 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
12 import org.apache.http.entity.ContentType;
13 import org.apache.http.entity.InputStreamEntity;
14 import org.apache.http.impl.client.CloseableHttpClient;
15 import org.apache.http.impl.client.HttpClients;
16 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
17 import org.apache.http.ssl.SSLContextBuilder;
18 import org.apache.log4j.Logger;
19 import org.openecomp.sdc.webseal.simulator.conf.Conf;
20
21 import javax.net.ssl.SSLContext;
22 import javax.servlet.RequestDispatcher;
23 import javax.servlet.ServletConfig;
24 import javax.servlet.ServletException;
25 import javax.servlet.ServletInputStream;
26 import javax.servlet.http.Cookie;
27 import javax.servlet.http.HttpServlet;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.io.UnsupportedEncodingException;
34 import java.net.MalformedURLException;
35 import java.net.URL;
36 import java.net.URLEncoder;
37 import java.security.KeyStoreException;
38 import java.security.NoSuchAlgorithmException;
39 import java.util.*;
40 import java.util.stream.Collectors;
41 import java.util.zip.GZIPInputStream;
42
43 public class SdcProxy extends HttpServlet {
44
45     private static final long serialVersionUID = 1L;
46     private static URL url;
47     private CloseableHttpClient httpClient;
48     private Conf conf;
49     private final String SDC1 = "/sdc1";
50     private final String ONBOARDING = "/onboarding/";
51     private final String SCRIPTS = "/scripts";
52     private final String STYLES = "/styles";
53     private final String LANGUAGES = "/languages";
54     private final String CONFIGURATIONS = "/configurations";
55     private static final Set<String> RESERVED_HEADERS = Arrays.stream(ReservedHeaders.values()).map(h -> h.name()).collect(Collectors.toSet());
56
57
58     private final static Logger logger = Logger.getLogger(SdcProxy.class);
59
60     public void init(ServletConfig config) throws ServletException {
61         super.init(config);
62         conf = Conf.getInstance();
63         try {
64             String feHost = conf.getFeHost();
65             url = new URL(feHost);
66         } catch (MalformedURLException me) {
67             throw new ServletException("Proxy URL is invalid", me);
68         }
69
70         try {
71             httpClient = buildRestClient();
72         } catch (Exception e) {
73             throw new ServletException("Build rest client failed", e);
74         }
75     }
76
77     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
78         proxy(request, response, MethodEnum.GET);
79     }
80
81     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
82
83         String userId = request.getParameter("userId");
84         String password = request.getParameter("password");
85
86         // Already sign-in
87         if (userId == null) {
88             userId = request.getHeader("USER_ID");
89         }
90
91         System.out.println("SdcProxy -> doPost userId=" + userId);
92         request.setAttribute("message", "OK");
93         if (password != null && getUser(userId, password) == null) {
94             MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
95             RequestDispatcher view = request.getRequestDispatcher("login");
96             request.setAttribute("message", "ERROR: userid or password incorect");
97             view.forward(mutableRequest, response);
98         } else {
99             System.out.println("SdcProxy -> doPost going to doGet");
100             request.setAttribute("HTTP_IV_USER", userId);
101             proxy(request, response, MethodEnum.POST);
102         }
103     }
104
105     public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
106         proxy(request, response, MethodEnum.PUT);
107     }
108
109     public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
110         proxy(request, response, MethodEnum.DELETE);
111     }
112
113     private synchronized void proxy(HttpServletRequest request, HttpServletResponse response, MethodEnum methodEnum) throws IOException, UnsupportedEncodingException {
114
115         Map<String, String[]> requestParameters = request.getParameterMap();
116         String userIdHeader = getUseridFromRequest(request);
117         User user = getUser(userIdHeader);
118
119         // new request - forward to login page
120         if (userIdHeader == null) {
121             System.out.print("Going to login");
122             response.sendRedirect("/login");
123             return;
124         }
125
126         String uri = getUri(request, requestParameters);
127         HttpRequestBase httpMethod = createHttpMethod(request, methodEnum, uri);
128         addHeadersToMethod(httpMethod, user, request);
129
130         try (CloseableHttpResponse closeableHttpResponse =  httpClient.execute(httpMethod)){;
131             response.setStatus(closeableHttpResponse.getStatusLine().getStatusCode());
132             if (request.getRequestURI().indexOf(".svg") > -1) {
133                 response.setContentType("image/svg+xml");
134             }
135
136             InputStream responseBodyStream = closeableHttpResponse.getEntity().getContent();
137             Header contentEncodingHeader = closeableHttpResponse.getLastHeader("Content-Encoding");
138             if (contentEncodingHeader != null && contentEncodingHeader.getValue().equalsIgnoreCase("gzip")) {
139                 responseBodyStream = new GZIPInputStream(responseBodyStream);
140             }
141             write(responseBodyStream, response.getOutputStream());
142
143         }
144     }
145
146     private User getUser(String userId, String password) {
147         User user = getUser(userId);
148         if (user.getPassword().equals(password)) {
149             return user;
150         }
151         return null;
152     }
153
154     private User getUser(String userId) {
155         return conf.getUsers().get(userId);
156
157     }
158
159     private List<String> getContextPaths() {
160         List<String> contextPaths = new ArrayList<>();
161         contextPaths.add(SDC1);
162         contextPaths.add(ONBOARDING);
163         contextPaths.add(STYLES);
164         contextPaths.add(SCRIPTS);
165         contextPaths.add(LANGUAGES);
166         contextPaths.add(CONFIGURATIONS);
167         return contextPaths;
168     }
169
170     private String getUri(HttpServletRequest request, Map<String, String[]> requestParameters) throws UnsupportedEncodingException {
171         String suffix = request.getRequestURI();
172         if (getContextPaths().stream().anyMatch(request.getRequestURI()::contains)) {
173             suffix = alignUrlProxy(suffix);
174         }
175         StringBuilder query = alignUrlParameters(requestParameters);
176         String uri = String.format("%s%s", new Object[]{this.url.toString() + suffix, query.toString()});
177         return uri;
178     }
179
180     private HttpRequestBase createHttpMethod(HttpServletRequest request, MethodEnum methodEnum, String uri) throws IOException {
181         HttpRequestBase proxyMethod = null;
182         ServletInputStream inputStream = null;
183         InputStreamEntity entity = null;
184
185         String contentType = request.getContentType();
186         ContentType myContent = ContentType.create(contentType);
187         switch (methodEnum) {
188             case GET:
189                 proxyMethod = new HttpGet(uri);
190                 break;
191             case POST:
192                 proxyMethod = new HttpPost(uri);
193                 inputStream = request.getInputStream();
194                 entity = new InputStreamEntity(inputStream, myContent);
195                 ((HttpPost) proxyMethod).setEntity(entity);
196                 break;
197             case PUT:
198                 proxyMethod = new HttpPut(uri);
199                 inputStream = request.getInputStream();
200                 entity = new InputStreamEntity(inputStream, myContent);
201                 ((HttpPut) proxyMethod).setEntity(entity);
202                 break;
203             case DELETE:
204                 proxyMethod = new HttpDelete(uri);
205                 break;
206         }
207         return proxyMethod;
208     }
209
210     private String getUseridFromRequest(HttpServletRequest request) {
211
212         String userIdHeader = request.getHeader("USER_ID");
213         if (userIdHeader != null) {
214             return userIdHeader;
215         }
216         Object o = request.getAttribute("HTTP_IV_USER");
217         if (o != null) {
218             return o.toString();
219         }
220         Cookie[] cookies = request.getCookies();
221
222         if (cookies != null) {
223             for (int i = 0; i < cookies.length; ++i) {
224                 if (cookies[i].getName().equals("USER_ID")) {
225                     userIdHeader = cookies[i].getValue();
226                 }
227             }
228         }
229         return userIdHeader;
230     }
231
232     private static void addHeadersToMethod(HttpUriRequest proxyMethod, User user, HttpServletRequest request) {
233
234         proxyMethod.setHeader(ReservedHeaders.HTTP_IV_USER.name(), user.getUserId());
235         proxyMethod.setHeader(ReservedHeaders.USER_ID.name(), user.getUserId());
236         proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_FIRSTNAME.name(), user.getFirstName());
237         proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_EMAIL.name(), user.getEmail());
238         proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_LASTNAME.name(), user.getLastName());
239         proxyMethod.setHeader(ReservedHeaders.HTTP_IV_REMOTE_ADDRESS.name(), "0.0.0.0");
240         proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_WSTYPE.name(), "Intranet");
241                 proxyMethod.setHeader(ReservedHeaders.HTTP_CSP_EMAIL.name(), "me@mail.com");
242
243                 Enumeration<String> headerNames = request.getHeaderNames();
244                 while (headerNames.hasMoreElements()) {
245                         String headerName = headerNames.nextElement();
246                         if (!RESERVED_HEADERS.contains(headerName)) {
247                                 Enumeration<String> headers = request.getHeaders(headerName);
248                                 while (headers.hasMoreElements()) {
249                                         String headerValue = headers.nextElement();
250 //                                      proxyMethod.setHeader(headerName, headerValue);
251                                 }
252                         }
253                 }
254     }
255
256     private String alignUrlProxy(String requestURI) {
257
258         int i = requestURI.indexOf(ONBOARDING);
259         if (-1 != i) {
260             return requestURI.substring(i);
261         }
262
263         i = requestURI.indexOf(SDC1 + SDC1);
264         if (-1 != i) {
265             return requestURI.substring(SDC1.length());
266         }
267
268         i = requestURI.indexOf(SDC1);
269         if (-1 != i) {
270             return requestURI;
271         }
272
273         return SDC1 + requestURI;
274     }
275
276     private static StringBuilder alignUrlParameters(Map<String, String[]> requestParameters) throws UnsupportedEncodingException {
277         StringBuilder query = new StringBuilder();
278         for (String name : requestParameters.keySet()) {
279             for (String value : (String[]) requestParameters.get(name)) {
280                 if (query.length() == 0) {
281                     query.append("?");
282                 } else {
283                     query.append("&");
284                 }
285                 name = URLEncoder.encode(name, "UTF-8");
286                 value = URLEncoder.encode(value, "UTF-8");
287
288                 query.append(String.format("&%s=%s", new Object[]{name, value}));
289             }
290         }
291         return query;
292     }
293
294     private void write(InputStream inputStream, OutputStream outputStream) throws IOException {
295         int b;
296         while (inputStream != null && (b = inputStream.read()) != -1) {
297             outputStream.write(b);
298         }
299         outputStream.flush();
300     }
301
302     public String getServletInfo() {
303         return "Http Proxy Servlet";
304     }
305
306     private enum ReservedHeaders {
307         HTTP_IV_USER, USER_ID, HTTP_CSP_FIRSTNAME, HTTP_CSP_EMAIL, HTTP_CSP_LASTNAME, HTTP_IV_REMOTE_ADDRESS, HTTP_CSP_WSTYPE
308     }
309
310     private static CloseableHttpClient buildRestClient() throws NoSuchAlgorithmException, KeyStoreException {
311         SSLContextBuilder builder = new SSLContextBuilder();
312         builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
313         SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault(),
314                 NoopHostnameVerifier.INSTANCE);
315         Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
316                 .register("http", new PlainConnectionSocketFactory())
317                 .register("https", sslsf)
318                 .build();
319         PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
320         return HttpClients.custom()
321                 .setSSLSocketFactory(sslsf)
322                 .setConnectionManager(cm)
323                 .build();
324     }
325 }