1 /*
2  * Copyright (c) 2016 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you
5  * may not use this file except in compliance with the License. You may
6  * obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13  * implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 
17 package com.android.vts.servlet;
18 
19 import com.android.vts.entity.CoverageEntity;
20 import com.android.vts.entity.TestSuiteResultEntity;
21 import com.android.vts.entity.UserEntity;
22 import com.android.vts.util.EmailHelper;
23 import com.android.vts.util.GcsHelper;
24 import com.google.appengine.api.users.User;
25 import com.google.appengine.api.users.UserService;
26 import com.google.appengine.api.users.UserServiceFactory;
27 import com.google.gson.Gson;
28 
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Optional;
33 import java.util.Properties;
34 import java.util.logging.Level;
35 import java.util.logging.Logger;
36 import javax.servlet.RequestDispatcher;
37 import javax.servlet.ServletException;
38 import javax.servlet.ServletConfig;
39 import javax.servlet.http.HttpServlet;
40 import javax.servlet.http.HttpServletRequest;
41 import javax.servlet.http.HttpServletResponse;
42 import javax.servlet.http.HttpSession;
43 
44 public abstract class BaseServlet extends HttpServlet {
45 
46     protected final Logger logger = Logger.getLogger(getClass().getName());
47 
48     protected String ERROR_MESSAGE_JSP = "WEB-INF/jsp/error_msg.jsp";
49 
50     // Environment variables
51     protected static String GERRIT_URI;
52     protected static String GERRIT_SCOPE;
53     protected static String CLIENT_ID;
54     protected static String ANALYTICS_ID;
55 
56     protected static final String TREE_DEFAULT_PARAM = "treeDefault";
57 
58     public enum PageType {
59         TOT("Test", "/"),
60         RELEASE("Release", "/show_release"),
61         COVERAGE_OVERVIEW("Coverage", "/show_coverage_overview"),
62         PROFILING_LIST("Profiling", "/show_profiling_list"),
63         TABLE("", "/show_table"),
64         TREE("", "/show_tree"),
65         GRAPH("Profiling", "/show_graph"),
66         COVERAGE("Coverage", "/show_coverage"),
67         PERFORMANCE_DIGEST("Performance Digest", "/show_performance_digest"),
68         PLAN_RELEASE("", "/show_plan_release"),
69         PLAN_RUN("Plan Run", "/show_plan_run"),
70         PROFILING_OVERVIEW("", "/show_profiling_overview");
71 
72         public final String defaultName;
73         public final String defaultUrl;
74 
PageType(String defaultName, String defaultUrl)75         PageType(String defaultName, String defaultUrl) {
76             this.defaultName = defaultName;
77             this.defaultUrl = defaultUrl;
78         }
79     }
80 
81     public static class Page {
82 
83         private final PageType type;
84         private final String name;
85         private final String url;
86 
Page(PageType type)87         public Page(PageType type) {
88             this.type = type;
89             this.name = type.defaultName;
90             this.url = type.defaultUrl;
91         }
92 
Page(PageType type, String name, String url)93         public Page(PageType type, String name, String url) {
94             this.type = type;
95             this.name = type.defaultName + name;
96             this.url = type.defaultUrl + url;
97         }
98 
Page(PageType type, String name, String url, Boolean withoutDefault)99         public Page(PageType type, String name, String url, Boolean withoutDefault) {
100             this.type = type;
101             this.name = name;
102             this.url = type.defaultUrl + url;
103         }
104 
Page(PageType type, String url)105         public Page(PageType type, String url) {
106             this.type = type;
107             this.name = type.defaultName;
108             this.url = type.defaultUrl + url;
109         }
110 
getName()111         public String getName() {
112             return name;
113         }
114 
getUrl()115         public String getUrl() {
116             return url;
117         }
118     }
119 
120     public static final List<Page> navbarLinks;
121 
122     static {
123         List<Page> links = new ArrayList<>();
links.add(new Page(PageType.TOT))124         links.add(new Page(PageType.TOT));
links.add(new Page(PageType.RELEASE))125         links.add(new Page(PageType.RELEASE));
links.add(new Page(PageType.COVERAGE_OVERVIEW))126         links.add(new Page(PageType.COVERAGE_OVERVIEW));
links.add(new Page(PageType.PROFILING_LIST))127         links.add(new Page(PageType.PROFILING_LIST));
128         navbarLinks = links;
129     }
130 
getNavParentType()131     public abstract PageType getNavParentType();
132 
133     /**
134      * Get a list of URL/Display name pairs for the breadcrumb hierarchy.
135      *
136      * @param request The HttpServletRequest object for the page request.
137      * @return a list of Page entries.
138      */
getBreadcrumbLinks(HttpServletRequest request)139     public abstract List<Page> getBreadcrumbLinks(HttpServletRequest request);
140 
141     /** System Configuration Property class */
142     protected static Properties systemConfigProp = new Properties();
143 
144     @Override
init(ServletConfig cfg)145     public void init(ServletConfig cfg) throws ServletException {
146         super.init(cfg);
147 
148         systemConfigProp =
149                 Properties.class.cast(cfg.getServletContext().getAttribute("systemConfigProp"));
150 
151         GERRIT_URI = systemConfigProp.getProperty("gerrit.uri");
152         GERRIT_SCOPE = systemConfigProp.getProperty("gerrit.scope");
153         CLIENT_ID = systemConfigProp.getProperty("appengine.clientID");
154         ANALYTICS_ID = systemConfigProp.getProperty("analytics.id");
155 
156         CoverageEntity.setPropertyValues(systemConfigProp);
157         TestSuiteResultEntity.setPropertyValues(systemConfigProp);
158         EmailHelper.setPropertyValues(systemConfigProp);
159         GcsHelper.setGcsProjectId(systemConfigProp.getProperty("gcs.projectID"));
160     }
161 
162     @Override
doGet(HttpServletRequest request, HttpServletResponse response)163     public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
164         // If the user is logged out, allow them to log back in and return to the page.
165         // Set the logout URL to direct back to a login page that directs to the current request.
166         UserService userService = UserServiceFactory.getUserService();
167         Optional<User> currentUser = Optional.ofNullable(userService.getCurrentUser());
168         String currentUserEmail =
169                 currentUser.isPresent()
170                         ? currentUser.map(user -> user.getEmail().trim()).orElse("")
171                         : "";
172         String requestUri = request.getRequestURI();
173         String requestArgs = request.getQueryString();
174         String loginURI = userService.createLoginURL(requestUri + '?' + requestArgs);
175         String logoutURI = userService.createLogoutURL(loginURI);
176         if (currentUserEmail != "") {
177 
178             int activeIndex;
179             switch (getNavParentType()) {
180                 case PROFILING_LIST:
181                     activeIndex = 3;
182                     break;
183                 case COVERAGE_OVERVIEW:
184                     activeIndex = 2;
185                     break;
186                 case RELEASE:
187                     activeIndex = 1;
188                     break;
189                 default:
190                     activeIndex = 0;
191                     break;
192             }
193             if (request.getParameter(TREE_DEFAULT_PARAM) != null) {
194                 HttpSession session = request.getSession(true);
195                 boolean treeDefault = request.getParameter(TREE_DEFAULT_PARAM).equals("true");
196                 session.setAttribute(TREE_DEFAULT_PARAM, treeDefault);
197             }
198 
199             request.setAttribute("serverName", request.getServerName());
200             request.setAttribute("logoutURL", logoutURI);
201             request.setAttribute("email", currentUserEmail);
202             request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID));
203             request.setAttribute("breadcrumbLinks", getBreadcrumbLinks(request));
204             request.setAttribute("navbarLinks", navbarLinks);
205             request.setAttribute("activeIndex", activeIndex);
206             response.setContentType("text/html");
207 
208             if (currentUserEmail.endsWith("@google.com")
209                     || UserEntity.getUserList().contains(currentUserEmail)) {
210                 doGetHandler(request, response);
211             } else {
212                 RequestDispatcher dispatcher =
213                         request.getRequestDispatcher("WEB-INF/jsp/auth_error.jsp");
214                 try {
215                     dispatcher.forward(request, response);
216                 } catch (ServletException e) {
217                     logger.log(Level.SEVERE, "Servlet Exception caught : ", e);
218                 }
219             }
220         } else {
221             response.sendRedirect(loginURI);
222         }
223     }
224 
225     /**
226      * Implementation of the doGet method to be executed by servlet subclasses.
227      *
228      * @param request The HttpServletRequest object.
229      * @param response The HttpServletResponse object.
230      */
doGetHandler(HttpServletRequest request, HttpServletResponse response)231     public abstract void doGetHandler(HttpServletRequest request, HttpServletResponse response)
232             throws IOException;
233 }
234