64b8cb1e69654c2eb16bb478b58c3bccc0c5c05a
[sdc.git] / catalog-fe / src / main / java / org / openecomp / sdc / fe / servlets / PortalServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.openecomp.sdc.fe.servlets;
21
22 import java.io.IOException;
23 import java.util.Enumeration;
24 import java.util.List;
25 import javax.servlet.RequestDispatcher;
26 import javax.servlet.ServletException;
27 import javax.servlet.http.Cookie;
28 import javax.servlet.http.HttpServlet;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.core.Context;
34 import org.onap.portalsdk.core.onboarding.exception.CipherUtilException;
35 import org.onap.portalsdk.core.onboarding.util.CipherUtil;
36 import org.onap.sdc.security.AuthenticationCookie;
37 import org.onap.sdc.security.RepresentationUtils;
38 import org.openecomp.sdc.common.impl.MutableHttpServletRequest;
39 import org.openecomp.sdc.common.log.wrappers.Logger;
40 import org.openecomp.sdc.fe.Constants;
41 import org.openecomp.sdc.fe.config.Configuration;
42 import org.openecomp.sdc.fe.config.ConfigurationManager;
43 import org.openecomp.sdc.fe.config.FeEcompErrorManager;
44
45 /**
46  * Root resource (exposed at "/" path)
47  */
48 @Path("/")
49 public class PortalServlet extends HttpServlet {
50
51     public static final String MISSING_HEADERS_MSG = "Missing Headers In Request";
52     private static final long serialVersionUID = 1L;
53     private static final String AUTHORIZATION_ERROR_MSG = "Autherization error";
54     private static final String NEW_LINE = System.getProperty("line.separator");
55     private static Logger log = Logger.getLogger(PortalServlet.class.getName());
56
57     private static String getUserIdFromCookie(HttpServletRequest request) throws CipherUtilException {
58         String userId = "";
59         Cookie[] cookies = request.getCookies();
60         Cookie userIdcookie = null;
61         if (cookies != null) {
62             for (Cookie cookie : cookies) {
63                 if (cookie.getName().equals(Constants.ECOMP_PORTAL_COOKIE)) {
64                     userIdcookie = cookie;
65                 }
66             }
67         }
68         if (userIdcookie != null) {
69             userId = CipherUtil.decrypt(userIdcookie.getValue());
70         }
71         return userId;
72     }
73
74     private static String getValueFromCookie(HttpServletRequest request, String cookieName) {
75         String value = "";
76         Cookie[] cookies = request.getCookies();
77         Cookie valueFromCookie = null;
78         if (cookies != null) {
79             for (Cookie cookie : cookies) {
80                 if (cookie.getName().endsWith(cookieName)) {
81                     valueFromCookie = cookie;
82                 }
83             }
84         }
85         if (valueFromCookie != null) {
86             value = valueFromCookie.getValue();
87         }
88         return value;
89     }
90
91     /**
92      * Entry point from ECOMP portal
93      */
94     @GET
95     @Path("/portal")
96     @Override
97     public void doGet(@Context final HttpServletRequest request, @Context final HttpServletResponse response) {
98         try {
99             addRequestHeadersUsingWebseal(request, response);
100         } catch (Exception e) {
101             FeEcompErrorManager.getInstance().logFePortalServletError("Portal Servlet");
102             log.error("Error during getting portal page", e);
103         }
104     }
105
106     /**
107      * Building new HTTP request and setting headers for the request The request will dispatch to index.html
108      *
109      * @param request
110      * @param response
111      * @throws ServletException
112      * @throws IOException
113      */
114     private void addRequestHeadersUsingWebseal(final HttpServletRequest request, final HttpServletResponse response)
115         throws ServletException, IOException {
116         response.setContentType("text/html");
117         // Create new request object to dispatch
118         MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
119         // Get configuration object (reads data from configuration.yaml)
120         Configuration configuration = getConfiguration(request);
121         // Check if we got header from webseal
122         String userId = request.getHeader(Constants.WEBSEAL_USER_ID_HEADER);
123         if (null == userId) {
124             // Authentication via ecomp portal
125             try {
126                 String userIdFromCookie = getUserIdFromCookie(request);
127                 if (("").equals(userIdFromCookie)) {
128                     // This is probably a webseal request, so missing header in request should be printed.
129                     response.sendError(HttpServletResponse.SC_USE_PROXY, MISSING_HEADERS_MSG);
130                 }
131                 userId = userIdFromCookie;
132             } catch (Exception e) {
133                 response.sendError(HttpServletResponse.SC_USE_PROXY, AUTHORIZATION_ERROR_MSG);
134                 log.error("Error during adding request header", e);
135             }
136         }
137         // Replace webseal header with open source header
138         mutableRequest.putHeader(Constants.USER_ID, userId);
139         // Getting identification headers from configuration.yaml
140
141         // (identificationHeaderFields) and setting them to new request
142
143         // mutableRequest
144         List<List<String>> identificationHeaderFields = configuration.getIdentificationHeaderFields();
145         for (List<String> possibleHeadersToRecieve : identificationHeaderFields) {
146             String allowedHeaderToPass = possibleHeadersToRecieve.get(0);
147             setNewHeader(possibleHeadersToRecieve, allowedHeaderToPass, request, mutableRequest);
148         }
149         // Getting optional headers from configuration.yaml
150
151         // (optionalHeaderFields) and setting them to new request mutableRequest
152         List<List<String>> optionalHeaderFields = configuration.getOptionalHeaderFields();
153         for (List<String> possibleHeadersToRecieve : optionalHeaderFields) {
154             String allowedHeaderToPass = possibleHeadersToRecieve.get(0);
155             setNewHeader(possibleHeadersToRecieve, allowedHeaderToPass, request, mutableRequest);
156         }
157         // Print headers from original request for debug purposes
158         printHeaders(request);
159         // In case using webseal, validate all mandatory headers (identificationHeaderFields) are included in the new request (mutableRequest).
160
161         // Via ecomp portal do not need to check the headers.
162         boolean allHeadersExist = true;
163         if (null != request.getHeader(Constants.WEBSEAL_USER_ID_HEADER)) {
164             allHeadersExist = checkHeaders(mutableRequest);
165         }
166         if (allHeadersExist) {
167             addCookies(response, mutableRequest, getMandatoryHeaders(request));
168             addCookies(response, mutableRequest, getOptionalHeaders(request));
169             getValueFromCookie(request, Constants.HTTP_CSP_FIRSTNAME);
170             getValueFromCookie(request, Constants.HTTP_CSP_LASTNAME);
171             //To be fixed
172
173             //addAuthCookie(response, userId, firstNameFromCookie, lastNameFromCookie);
174             RequestDispatcher rd = request.getRequestDispatcher("index.html");
175             rd.forward(mutableRequest, response);
176         } else {
177             response.sendError(HttpServletResponse.SC_USE_PROXY, MISSING_HEADERS_MSG);
178         }
179     }
180
181     boolean addAuthCookie(HttpServletResponse response, String userId, String firstName, String lastName) throws IOException {
182         boolean isBuildCookieCompleted = true;
183         Cookie authCookie = null;
184         Configuration.CookieConfig confCookie = ConfigurationManager.getConfigurationManager().getConfiguration().getAuthCookie();
185         //create authentication and send it to encryption
186         String encryptedCookie = "";
187         try {
188             AuthenticationCookie authenticationCookie = new AuthenticationCookie(userId, firstName, lastName);
189             String cookieAsJson = RepresentationUtils.toRepresentation(authenticationCookie);
190             encryptedCookie = org.onap.sdc.security.CipherUtil.encryptPKC(cookieAsJson, confCookie.getSecurityKey());
191         } catch (Exception e) {
192             isBuildCookieCompleted = false;
193             log.error(" Cookie Encryption failed ", e);
194         }
195         authCookie = new Cookie(confCookie.getCookieName(), encryptedCookie);
196         authCookie.setPath(confCookie.getPath());
197         authCookie.setDomain(confCookie.getDomain());
198         authCookie.setHttpOnly(true);
199         // add generated cookie to response
200         if (isBuildCookieCompleted) {
201             response.addCookie(authCookie);
202             return true;
203         }
204         response.sendError(HttpServletResponse.SC_UNAUTHORIZED, AUTHORIZATION_ERROR_MSG);
205         return false;
206     }
207
208     /**
209      * Print all request headers to the log
210      *
211      * @param request
212      */
213     private void printHeaders(HttpServletRequest request) {
214         if (log.isDebugEnabled()) {
215             StringBuilder builder = new StringBuilder();
216             String sessionId = "";
217             if (request.getSession() != null) {
218                 String id = request.getSession().getId();
219                 if (id != null) {
220                     sessionId = id;
221                 }
222             }
223             builder.append("Receiving request with headers:" + NEW_LINE);
224             log.debug("{}", request.getHeaderNames());
225             @SuppressWarnings("unchecked") Enumeration<String> headerNames = request.getHeaderNames();
226             if (headerNames != null) {
227                 while (headerNames.hasMoreElements()) {
228                     String headerName = headerNames.nextElement();
229                     String headerValue = request.getHeader(headerName);
230                     builder.append("session " + sessionId + " header: name = " + headerName + ", value = " + headerValue + NEW_LINE);
231                 }
232             }
233             log.debug(builder.toString());
234         }
235     }
236
237     /**
238      * Add cookies (that where set in the new request headers) in the response Using DefaultHTTPUtilities Object to prevent CRLF injection in HTTP
239      * headers.
240      *
241      * @param response
242      * @param request
243      * @param headers
244      */
245     private void addCookies(HttpServletResponse response, HttpServletRequest request, String[] headers) {
246         for (int i = 0; i < headers.length; i++) {
247             String currHeader = headers[i];
248             String headerValue = request.getHeader(currHeader);
249             if (headerValue != null) {
250                 final Cookie cookie = new Cookie(currHeader, headerValue);
251                 cookie.setSecure(true);
252                 response.addCookie(cookie);
253             }
254         }
255     }
256
257     /**
258      * Get mandatory headers (identificationHeaderFields) String array, and checks that each header exists in the new request
259      *
260      * @param request
261      * @return boolean
262      */
263     private boolean checkHeaders(HttpServletRequest request) {
264         String[] mandatoryHeaders = getMandatoryHeaders(request);
265         boolean allHeadersExist = true;
266         for (int i = 0; i < mandatoryHeaders.length; i++) {
267             String headerValue = request.getHeader(mandatoryHeaders[i]);
268             if (headerValue == null) {
269                 allHeadersExist = false;
270                 break;
271             }
272         }
273         return allHeadersExist;
274     }
275
276     /**
277      * Get mandatory headers (identificationHeaderFields) from configuration.yaml file and return String[]
278      *
279      * @param request
280      * @return String[]
281      */
282     private String[] getMandatoryHeaders(HttpServletRequest request) {
283         Configuration configuration = getConfiguration(request);
284         List<List<String>> identificationHeaderFields = configuration.getIdentificationHeaderFields();
285         String[] mandatoryHeaders = new String[identificationHeaderFields.size()];
286         for (int i = 0; i < identificationHeaderFields.size(); i++) {
287             mandatoryHeaders[i] = identificationHeaderFields.get(i).get(0);
288         }
289         return mandatoryHeaders;
290     }
291
292     /**
293      * Get optional headers (optionalHeaderFields) from configuration.yaml file and return String[]
294      *
295      * @param request
296      * @return String[]
297      */
298     private String[] getOptionalHeaders(HttpServletRequest request) {
299         Configuration configuration = getConfiguration(request);
300         List<List<String>> optionalHeaderFields = configuration.getOptionalHeaderFields();
301         String[] optionalHeaders = new String[optionalHeaderFields.size()];
302         for (int i = 0; i < optionalHeaderFields.size(); i++) {
303             optionalHeaders[i] = optionalHeaderFields.get(i).get(0);
304         }
305         return optionalHeaders;
306     }
307
308     /**
309      * Return Configuration object to read from configuration.yaml
310      *
311      * @param request
312      * @return Configuration
313      */
314     private Configuration getConfiguration(HttpServletRequest request) {
315         ConfigurationManager configManager = (ConfigurationManager) request.getSession().getServletContext()
316             .getAttribute(org.openecomp.sdc.common.api.Constants.CONFIGURATION_MANAGER_ATTR);
317         return configManager.getConfiguration();
318     }
319
320     private boolean setNewHeader(List<String> possibleOldHeaders, String newHeaderToSet, HttpServletRequest oldRequest,
321                                  MutableHttpServletRequest newRequest) {
322         boolean newHeaderIsSet = false;
323         for (int i = 0; i < possibleOldHeaders.size() && !newHeaderIsSet; i++) {
324             String headerValue = oldRequest.getHeader(possibleOldHeaders.get(i));
325             if (headerValue != null) {
326                 newRequest.putHeader(newHeaderToSet, headerValue);
327                 newHeaderIsSet = true;
328             }
329         }
330         return newHeaderIsSet;
331     }
332 }