From 4f2d297e6ec20de29f6cf876c5f6ead55220f4f3 Mon Sep 17 00:00:00 2001 From: Young Gyu Park Date: Tue, 5 Jun 2018 17:43:49 +0900 Subject: User Entity to manage user information on datastore Test: go/vts-web-staging Bug: 109718593 Change-Id: I8a3f1e16790ff0d2e0d92e498088aa22fe3e3087 --- .../com/android/vts/config/ObjectifyListener.java | 45 ++- .../com/android/vts/config/ObjectifyWebFilter.java | 4 +- .../java/com/android/vts/entity/UserEntity.java | 101 ++++++ .../java/com/android/vts/servlet/BaseServlet.java | 363 +++++++++++---------- src/main/resources/config.properties | 4 + 5 files changed, 333 insertions(+), 184 deletions(-) create mode 100644 src/main/java/com/android/vts/entity/UserEntity.java (limited to 'src') diff --git a/src/main/java/com/android/vts/config/ObjectifyListener.java b/src/main/java/com/android/vts/config/ObjectifyListener.java index 22b6011..835cba9 100644 --- a/src/main/java/com/android/vts/config/ObjectifyListener.java +++ b/src/main/java/com/android/vts/config/ObjectifyListener.java @@ -18,17 +18,26 @@ package com.android.vts.config; import com.android.vts.entity.TestSuiteFileEntity; import com.android.vts.entity.TestSuiteResultEntity; -import com.googlecode.objectify.ObjectifyFactory; +import com.android.vts.entity.UserEntity; +import com.googlecode.objectify.Key; import com.googlecode.objectify.ObjectifyService; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; +import static com.googlecode.objectify.ObjectifyService.ofy; + /** The @WebListener annotation for registering a class as a listener of a web application. */ -// @WebListener +@WebListener /** * Initializing Objectify Service at the container start up before any web components like servlet * get initialized. @@ -44,11 +53,41 @@ public class ObjectifyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { ObjectifyService.init(); - // ObjectifyFactory objectifyFactory = ObjectifyService.factory(); ObjectifyService.register(TestSuiteFileEntity.class); ObjectifyService.register(TestSuiteResultEntity.class); + ObjectifyService.register(UserEntity.class); ObjectifyService.begin(); logger.log(Level.INFO, "Value Initialized from context."); + + Properties systemConfigProp = new Properties(); + + try { + InputStream defaultInputStream = + ObjectifyListener.class + .getClassLoader() + .getResourceAsStream("config.properties"); + + systemConfigProp.load(defaultInputStream); + + String adminEmail = systemConfigProp.getProperty("user.adminEmail"); + if (adminEmail.isEmpty()) { + logger.log(Level.WARNING, "Admin email is not properly set. Check config file"); + } else { + String adminName = systemConfigProp.getProperty("user.adminName"); + String adminCompany = systemConfigProp.getProperty("user.adminCompany"); + + if (UserEntity.getAdminUserList(adminEmail).size() == 0) { + UserEntity userEntity = new UserEntity(adminEmail, adminName, adminCompany); + userEntity.setIsAdmin(true); + userEntity.save(); + logger.log(Level.INFO, "The user is saved successfully."); + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } } /** Receives notification that the ServletContext is about to be shut down. */ diff --git a/src/main/java/com/android/vts/config/ObjectifyWebFilter.java b/src/main/java/com/android/vts/config/ObjectifyWebFilter.java index d008291..3813d0b 100644 --- a/src/main/java/com/android/vts/config/ObjectifyWebFilter.java +++ b/src/main/java/com/android/vts/config/ObjectifyWebFilter.java @@ -18,8 +18,10 @@ package com.android.vts.config; import com.googlecode.objectify.ObjectifyFilter; +import javax.servlet.annotation.WebFilter; + /** Annotation used to declare a servlet filter. */ -// @WebFilter(urlPatterns = {"/*"}) +@WebFilter(urlPatterns = {"/*"}) /** * Servlet filter for objectify library. Objectify requires a filter to clean up any thread-local * transaction contexts and pending asynchronous operations that remain at the end of a request. diff --git a/src/main/java/com/android/vts/entity/UserEntity.java b/src/main/java/com/android/vts/entity/UserEntity.java new file mode 100644 index 0000000..e5f9f8f --- /dev/null +++ b/src/main/java/com/android/vts/entity/UserEntity.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may + * obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.vts.entity; + +import com.googlecode.objectify.Key; +import com.googlecode.objectify.annotation.Cache; +import com.googlecode.objectify.annotation.Entity; +import com.googlecode.objectify.annotation.Id; +import com.googlecode.objectify.annotation.Index; +import java.util.List; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import java.util.Date; + +import static com.googlecode.objectify.ObjectifyService.ofy; + +/** Entity Class for User */ +@Cache +@Entity +@EqualsAndHashCode(of = "id") +@NoArgsConstructor +public class UserEntity { + + /** User email field */ + @Id @Getter @Setter String email; + + /** User name field */ + @Getter @Setter String name; + + /** User name field */ + @Getter @Setter String company; + + /** User enable or disable field */ + @Index @Getter @Setter Boolean enable; + + /** User admin flag field */ + @Index @Getter @Setter Boolean isAdmin; + + /** When this record was created or updated */ + @Index @Getter Date updated; + + /** Construction function for UserEntity Class */ + public UserEntity( + String email, + String name, + String company) { + this.email = email; + this.name = name; + this.enable = true; + this.isAdmin = false; + this.company = company; + } + + /** Saving function for the instance of this class */ + public void save() { + this.updated = new Date(); + ofy().save().entity(this).now(); + } + + public static List getAdminUserList(String adminEmail) { + Key key = Key.create(UserEntity.class, adminEmail); + return ofy().load() + .type(UserEntity.class) + .filterKey(key) + .filter("enable", true) + .filter("isAdmin", true) + .list(); + } + + public static List getAdminUserList() { + return ofy().load() + .type(UserEntity.class) + .filter("enable", true) + .filter("isAdmin", true) + .list(); + } + + public static List getUserList() { + return ofy().load() + .type(UserEntity.class) + .filter("enable", true) + .filter("isAdmin", false) + .list(); + } +} diff --git a/src/main/java/com/android/vts/servlet/BaseServlet.java b/src/main/java/com/android/vts/servlet/BaseServlet.java index 7b4c624..045c051 100644 --- a/src/main/java/com/android/vts/servlet/BaseServlet.java +++ b/src/main/java/com/android/vts/servlet/BaseServlet.java @@ -17,6 +17,7 @@ package com.android.vts.servlet; import com.android.vts.entity.TestSuiteResultEntity; +import com.android.vts.entity.UserEntity; import com.android.vts.util.EmailHelper; import com.android.vts.util.GcsHelper; import com.google.appengine.api.users.User; @@ -42,198 +43,200 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public abstract class BaseServlet extends HttpServlet { - protected final Logger logger = Logger.getLogger(getClass().getName()); - - protected String ERROR_MESSAGE_JSP = "WEB-INF/jsp/error_msg.jsp"; - - // Environment variables - protected static String GERRIT_URI; - protected static String GERRIT_SCOPE; - protected static String CLIENT_ID; - protected static String ANALYTICS_ID; - - protected static final String TREE_DEFAULT_PARAM = "treeDefault"; - - public enum PageType { - TOT("Test", "/"), - RELEASE("Release", "/show_release"), - COVERAGE_OVERVIEW("Coverage", "/show_coverage_overview"), - PROFILING_LIST("Profiling", "/show_profiling_list"), - TABLE("", "/show_table"), - TREE("", "/show_tree"), - GRAPH("Profiling", "/show_graph"), - COVERAGE("Coverage", "/show_coverage"), - PERFORMANCE_DIGEST("Performance Digest", "/show_performance_digest"), - PLAN_RELEASE("", "/show_plan_release"), - PLAN_RUN("Plan Run", "/show_plan_run"), - PROFILING_OVERVIEW("", "/show_profiling_overview"); - - public final String defaultName; - public final String defaultUrl; - - PageType(String defaultName, String defaultUrl) { - this.defaultName = defaultName; - this.defaultUrl = defaultUrl; - } - } - - public static class Page { - private final PageType type; - private final String name; - private final String url; - - public Page(PageType type) { - this.type = type; - this.name = type.defaultName; - this.url = type.defaultUrl; - } - - public Page(PageType type, String name, String url) { - this.type = type; - this.name = type.defaultName + name; - this.url = type.defaultUrl + url; - } - public Page(PageType type, String name, String url, Boolean withoutDefault) { - this.type = type; - this.name = name; - this.url = type.defaultUrl + url; - } + protected final Logger logger = Logger.getLogger(getClass().getName()); + + protected String ERROR_MESSAGE_JSP = "WEB-INF/jsp/error_msg.jsp"; + + // Environment variables + protected static String GERRIT_URI; + protected static String GERRIT_SCOPE; + protected static String CLIENT_ID; + protected static String ANALYTICS_ID; + + protected static final String TREE_DEFAULT_PARAM = "treeDefault"; + + public enum PageType { + TOT("Test", "/"), + RELEASE("Release", "/show_release"), + COVERAGE_OVERVIEW("Coverage", "/show_coverage_overview"), + PROFILING_LIST("Profiling", "/show_profiling_list"), + TABLE("", "/show_table"), + TREE("", "/show_tree"), + GRAPH("Profiling", "/show_graph"), + COVERAGE("Coverage", "/show_coverage"), + PERFORMANCE_DIGEST("Performance Digest", "/show_performance_digest"), + PLAN_RELEASE("", "/show_plan_release"), + PLAN_RUN("Plan Run", "/show_plan_run"), + PROFILING_OVERVIEW("", "/show_profiling_overview"); + + public final String defaultName; + public final String defaultUrl; + + PageType(String defaultName, String defaultUrl) { + this.defaultName = defaultName; + this.defaultUrl = defaultUrl; + } + } - public Page(PageType type, String url) { - this.type = type; - this.name = type.defaultName; - this.url = type.defaultUrl + url; - } + public static class Page { - public String getName() { - return name; - } + private final PageType type; + private final String name; + private final String url; - public String getUrl() { - return url; - } + public Page(PageType type) { + this.type = type; + this.name = type.defaultName; + this.url = type.defaultUrl; } - public static final List navbarLinks; - - static { - List links = new ArrayList<>(); - links.add(new Page(PageType.TOT)); - links.add(new Page(PageType.RELEASE)); - links.add(new Page(PageType.COVERAGE_OVERVIEW)); - links.add(new Page(PageType.PROFILING_LIST)); - navbarLinks = links; + public Page(PageType type, String name, String url) { + this.type = type; + this.name = type.defaultName + name; + this.url = type.defaultUrl + url; } - public abstract PageType getNavParentType(); - - /** - * Get a list of URL/Display name pairs for the breadcrumb hierarchy. - * - * @param request The HttpServletRequest object for the page request. - * @return a list of Page entries. - */ - public abstract List getBreadcrumbLinks(HttpServletRequest request); - - /** System Configuration Property class */ - protected static Properties systemConfigProp = new Properties(); + public Page(PageType type, String name, String url, Boolean withoutDefault) { + this.type = type; + this.name = name; + this.url = type.defaultUrl + url; + } - @Override - public void init(ServletConfig cfg) throws ServletException { - super.init(cfg); + public Page(PageType type, String url) { + this.type = type; + this.name = type.defaultName; + this.url = type.defaultUrl + url; + } - try { - InputStream defaultInputStream = - BaseServlet.class - .getClassLoader() - .getResourceAsStream("config.properties"); - systemConfigProp.load(defaultInputStream); - - GERRIT_URI = systemConfigProp.getProperty("gerrit.uri"); - GERRIT_SCOPE = systemConfigProp.getProperty("gerrit.scope"); - CLIENT_ID = systemConfigProp.getProperty("appengine.clientID"); - ANALYTICS_ID = systemConfigProp.getProperty("analytics.id"); - - TestSuiteResultEntity.setPropertyValues(systemConfigProp); - EmailHelper.setPropertyValues(systemConfigProp); - GcsHelper.setGcsProjectId(systemConfigProp.getProperty("gcs.projectID")); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + public String getName() { + return name; } - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - // If the user is logged out, allow them to log back in and return to the page. - // Set the logout URL to direct back to a login page that directs to the current request. - UserService userService = UserServiceFactory.getUserService(); - Optional currentUser = Optional.ofNullable(userService.getCurrentUser()); - String currentUserEmail = - currentUser.isPresent() - ? currentUser.map(user -> user.getEmail().trim()).orElse("") - : ""; - String requestUri = request.getRequestURI(); - String requestArgs = request.getQueryString(); - String loginURI = userService.createLoginURL(requestUri + '?' + requestArgs); - String logoutURI = userService.createLogoutURL(loginURI); - if (currentUserEmail != "") { - - int activeIndex; - switch (getNavParentType()) { - case PROFILING_LIST: - activeIndex = 3; - break; - case COVERAGE_OVERVIEW: - activeIndex = 2; - break; - case RELEASE: - activeIndex = 1; - break; - default: - activeIndex = 0; - break; - } - if (request.getParameter(TREE_DEFAULT_PARAM) != null) { - HttpSession session = request.getSession(true); - boolean treeDefault = request.getParameter(TREE_DEFAULT_PARAM).equals("true"); - session.setAttribute(TREE_DEFAULT_PARAM, treeDefault); - } - - request.setAttribute("serverName", request.getServerName()); - request.setAttribute("logoutURL", logoutURI); - request.setAttribute("email", currentUserEmail); - request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID)); - request.setAttribute("breadcrumbLinks", getBreadcrumbLinks(request)); - request.setAttribute("navbarLinks", navbarLinks); - request.setAttribute("activeIndex", activeIndex); - response.setContentType("text/html"); - - if (currentUserEmail.endsWith("@google.com")) { - doGetHandler(request, response); - } else { - RequestDispatcher dispatcher = - request.getRequestDispatcher("WEB-INF/jsp/auth_error.jsp"); - try { - dispatcher.forward(request, response); - } catch (ServletException e) { - logger.log(Level.SEVERE, "Servlet Exception caught : ", e); - } - } - } else { - response.sendRedirect(loginURI); + public String getUrl() { + return url; + } + } + + public static final List navbarLinks; + + static { + List links = new ArrayList<>(); + links.add(new Page(PageType.TOT)); + links.add(new Page(PageType.RELEASE)); + links.add(new Page(PageType.COVERAGE_OVERVIEW)); + links.add(new Page(PageType.PROFILING_LIST)); + navbarLinks = links; + } + + public abstract PageType getNavParentType(); + + /** + * Get a list of URL/Display name pairs for the breadcrumb hierarchy. + * + * @param request The HttpServletRequest object for the page request. + * @return a list of Page entries. + */ + public abstract List getBreadcrumbLinks(HttpServletRequest request); + + /** + * System Configuration Property class + */ + protected static Properties systemConfigProp = new Properties(); + + @Override + public void init(ServletConfig cfg) throws ServletException { + super.init(cfg); + + try { + InputStream defaultInputStream = + BaseServlet.class.getClassLoader().getResourceAsStream("config.properties"); + systemConfigProp.load(defaultInputStream); + + GERRIT_URI = systemConfigProp.getProperty("gerrit.uri"); + GERRIT_SCOPE = systemConfigProp.getProperty("gerrit.scope"); + CLIENT_ID = systemConfigProp.getProperty("appengine.clientID"); + ANALYTICS_ID = systemConfigProp.getProperty("analytics.id"); + + TestSuiteResultEntity.setPropertyValues(systemConfigProp); + EmailHelper.setPropertyValues(systemConfigProp); + GcsHelper.setGcsProjectId(systemConfigProp.getProperty("gcs.projectID")); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + // If the user is logged out, allow them to log back in and return to the page. + // Set the logout URL to direct back to a login page that directs to the current request. + UserService userService = UserServiceFactory.getUserService(); + Optional currentUser = Optional.ofNullable(userService.getCurrentUser()); + String currentUserEmail = + currentUser.isPresent() + ? currentUser.map(user -> user.getEmail().trim()).orElse("") + : ""; + String requestUri = request.getRequestURI(); + String requestArgs = request.getQueryString(); + String loginURI = userService.createLoginURL(requestUri + '?' + requestArgs); + String logoutURI = userService.createLogoutURL(loginURI); + if (currentUserEmail != "") { + + int activeIndex; + switch (getNavParentType()) { + case PROFILING_LIST: + activeIndex = 3; + break; + case COVERAGE_OVERVIEW: + activeIndex = 2; + break; + case RELEASE: + activeIndex = 1; + break; + default: + activeIndex = 0; + break; + } + if (request.getParameter(TREE_DEFAULT_PARAM) != null) { + HttpSession session = request.getSession(true); + boolean treeDefault = request.getParameter(TREE_DEFAULT_PARAM).equals("true"); + session.setAttribute(TREE_DEFAULT_PARAM, treeDefault); + } + + request.setAttribute("serverName", request.getServerName()); + request.setAttribute("logoutURL", logoutURI); + request.setAttribute("email", currentUserEmail); + request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID)); + request.setAttribute("breadcrumbLinks", getBreadcrumbLinks(request)); + request.setAttribute("navbarLinks", navbarLinks); + request.setAttribute("activeIndex", activeIndex); + response.setContentType("text/html"); + + if (currentUserEmail.endsWith("@google.com") || UserEntity.getUserList() + .contains(currentUserEmail)) { + doGetHandler(request, response); + } else { + RequestDispatcher dispatcher = + request.getRequestDispatcher("WEB-INF/jsp/auth_error.jsp"); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Exception caught : ", e); } + } + } else { + response.sendRedirect(loginURI); } - - /** - * Implementation of the doGet method to be executed by servlet subclasses. - * - * @param request The HttpServletRequest object. - * @param response The HttpServletResponse object. - * @throws IOException - */ - public abstract void doGetHandler(HttpServletRequest request, HttpServletResponse response) - throws IOException; + } + + /** + * Implementation of the doGet method to be executed by servlet subclasses. + * + * @param request The HttpServletRequest object. + * @param response The HttpServletResponse object. + */ + public abstract void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException; } diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties index 18e2d63..e1b9318 100644 --- a/src/main/resources/config.properties +++ b/src/main/resources/config.properties @@ -17,3 +17,7 @@ gcs.bucketName= gcs.suiteTestFolderName= bug.tracking.system= + +user.adminEmail= +user.adminName= +user.adminCompany= -- cgit v1.2.3