001/* 002 * (C) Copyright 2011-2016 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * tdelprat, jcarsique 018 * 019 */ 020 021package org.nuxeo.wizard; 022 023import static org.nuxeo.common.Environment.NUXEO_DATA_DIR; 024import static org.nuxeo.launcher.config.ConfigurationGenerator.DB_EXCLUDE_CHECK_LIST; 025import static org.nuxeo.launcher.config.ConfigurationGenerator.DB_NOSQL_LIST; 026import static org.nuxeo.launcher.config.ConfigurationGenerator.INSTALL_AFTER_RESTART; 027import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_BIND_ADDRESS; 028import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_DB_HOST; 029import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_DB_NAME; 030import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_DB_PORT; 031import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_DB_PWD; 032import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_DB_USER; 033import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_MONGODB_NAME; 034import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_MONGODB_SERVER; 035import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_TEMPLATE_DBNAME; 036import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_TEMPLATE_DBNOSQL_NAME; 037import static org.nuxeo.launcher.config.ConfigurationGenerator.PARAM_WIZARD_DONE; 038 039import java.io.File; 040import java.io.IOException; 041import java.lang.reflect.Method; 042import java.net.InetAddress; 043import java.net.URLEncoder; 044import java.net.UnknownHostException; 045import java.sql.SQLException; 046import java.util.ArrayList; 047import java.util.Enumeration; 048import java.util.HashMap; 049import java.util.Hashtable; 050import java.util.List; 051import java.util.Map; 052 053import javax.naming.AuthenticationException; 054import javax.naming.NameNotFoundException; 055import javax.naming.NamingEnumeration; 056import javax.naming.NamingException; 057import javax.naming.directory.Attributes; 058import javax.naming.directory.DirContext; 059import javax.naming.directory.InitialDirContext; 060import javax.naming.directory.SearchControls; 061import javax.naming.directory.SearchResult; 062import javax.servlet.ServletException; 063import javax.servlet.http.HttpServlet; 064import javax.servlet.http.HttpServletRequest; 065import javax.servlet.http.HttpServletResponse; 066 067import org.apache.commons.codec.binary.Base64; 068import org.apache.commons.logging.Log; 069import org.apache.commons.logging.LogFactory; 070import org.nuxeo.launcher.commons.DatabaseDriverException; 071import org.nuxeo.launcher.config.ConfigurationException; 072import org.nuxeo.launcher.config.ConfigurationGenerator; 073import org.nuxeo.wizard.context.Context; 074import org.nuxeo.wizard.context.ParamCollector; 075import org.nuxeo.wizard.download.DownloadablePackageOptions; 076import org.nuxeo.wizard.download.PackageDownloader; 077import org.nuxeo.wizard.helpers.ConnectRegistrationHelper; 078import org.nuxeo.wizard.helpers.IPValidator; 079import org.nuxeo.wizard.helpers.NumberValidator; 080import org.nuxeo.wizard.helpers.PackageDownloaderHelper; 081import org.nuxeo.wizard.nav.Page; 082import org.nuxeo.wizard.nav.SimpleNavigationHandler; 083 084/** 085 * Main entry point : find the right handler and start jsp rendering 086 * 087 * @author Tiry (tdelprat@nuxeo.com) 088 * @since 5.4.2 089 */ 090public class RouterServlet extends HttpServlet { 091 092 private static final long serialVersionUID = 1L; 093 094 protected static Log log = LogFactory.getLog(RouterServlet.class); 095 096 protected SimpleNavigationHandler navHandler = SimpleNavigationHandler.instance(); 097 098 public static final String CONNECT_TOKEN_KEY = "ConnectRegistrationToken"; 099 100 protected String getAction(HttpServletRequest req) { 101 String uri = req.getRequestURI(); 102 103 int idx = uri.indexOf("?"); 104 if (idx > 0) { 105 uri = uri.substring(0, idx - 1); 106 } 107 String action = uri.replace(req.getContextPath() + "/router/", ""); 108 if (action.startsWith("/")) { 109 action = action.substring(1); 110 } 111 return action; 112 } 113 114 @Override 115 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 116 // process action 117 handleAction(getAction(req), req, resp); 118 } 119 120 @Override 121 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 122 // store posted data 123 req.setCharacterEncoding("UTF-8"); 124 Context.instance(req).getCollector().collectConfigurationParams(req); 125 doGet(req, resp); 126 } 127 128 protected Method findhandler(Page currentPage, String verb) { 129 String methodName = "handle" + currentPage.getAction() + verb; 130 Method method = null; 131 try { 132 method = this.getClass().getMethod(methodName, Page.class, HttpServletRequest.class, 133 HttpServletResponse.class); 134 } catch (Exception e) { 135 // fall back to default Handler lookup 136 methodName = "handleDefault" + verb; 137 try { 138 method = this.getClass().getMethod(methodName, Page.class, HttpServletRequest.class, 139 HttpServletResponse.class); 140 } catch (Exception e2) { 141 log.error("Unable to resolve default handler for " + verb, e); 142 } 143 } 144 return method; 145 } 146 147 protected void handleAction(String action, HttpServletRequest req, HttpServletResponse resp) 148 throws ServletException, IOException { 149 // locate page 150 Page currentPage = navHandler.getCurrentPage(action); 151 if (currentPage == null) { 152 resp.sendError(404, "Action " + action + " is not supported"); 153 return; 154 } 155 156 // find action handler 157 Method handler = findhandler(currentPage, req.getMethod()); 158 if (handler == null) { 159 resp.sendError(500, "No handler found for " + action); 160 return; 161 } 162 163 // execute handler => triggers rendering 164 try { 165 handler.invoke(this, currentPage, req, resp); 166 } catch (Exception e) { 167 log.error("Error during handler execution", e); 168 req.setAttribute("error", e); 169 req.getRequestDispatcher("/error.jsp").forward(req, resp); 170 } 171 } 172 173 // default handlers 174 175 public void handleDefaultGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 176 throws ServletException, IOException { 177 currentPage.dispatchToJSP(req, resp); 178 } 179 180 public void handleDefaultPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 181 throws ServletException, IOException { 182 // XXX validate data 183 currentPage.next().dispatchToJSP(req, resp, true); 184 } 185 186 // custom handlers 187 188 public void handleConnectGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 189 throws ServletException, IOException { 190 req.setAttribute("popupUrl", req.getContextPath() + "/ConnectCallback?action=display"); 191 handleDefaultGET(currentPage, req, resp); 192 } 193 194 public void handleConnectCallbackGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 195 throws ServletException, IOException { 196 Context ctx = Context.instance(req); 197 String token = req.getParameter(CONNECT_TOKEN_KEY); 198 String action = req.getParameter("action"); 199 String targetNav = null; 200 201 if (action == null || action.isEmpty()) { 202 action = "skip"; 203 } 204 if (action.equals("register") && (token == null || token.isEmpty())) { 205 action = "skip"; 206 } 207 208 if ("register".equals(action)) { 209 // store the registration info 210 Map<String, String> connectMap = new HashMap<>(); 211 Context context = Context.instance(req); 212 if (token != null) { 213 String tokenData = new String(Base64.decodeBase64(token)); 214 String[] tokenDataLines = tokenData.split("\n"); 215 for (String line : tokenDataLines) { 216 String[] parts = line.split(":"); 217 if (parts.length > 1) { 218 connectMap.put(parts[0], parts[1]); 219 } 220 } 221 context.storeConnectMap(connectMap); 222 } 223 224 // Save CLID 225 if (context.isConnectRegistrationDone()) { 226 // save Connect registration 227 ConnectRegistrationHelper.saveConnectRegistrationFile(context); 228 } 229 230 // deactivate the confirm form 231 SimpleNavigationHandler.instance().deactivatePage("ConnectFinish"); 232 // go to the next page 233 targetNav = currentPage.next().getAction(); 234 } else if ("skip".equals(action)) { 235 // activate the confirm form 236 SimpleNavigationHandler.instance().activatePage("ConnectFinish"); 237 // go to it 238 targetNav = currentPage.next().getAction(); 239 } else if ("prev".equals(action)) { 240 targetNav = currentPage.prev().prev().getAction(); 241 } else if ("display".equals(action)) { 242 // compute CB url 243 String cbUrl = req.getRequestURL().toString(); 244 cbUrl = cbUrl.replace("/router/" + currentPage.getAction(), "/ConnectCallback?cb=yes"); 245 // In order to avoid any issue with badly configured reverse proxies 246 // => get url from the client side 247 if (ctx.getBaseUrl() != null) { 248 cbUrl = ctx.getBaseUrl() + "ConnectCallback?cb=yes"; 249 } 250 cbUrl = URLEncoder.encode(cbUrl, "UTF-8"); 251 252 String redirect = ctx.getCollector().getConfigurationParam("org.nuxeo.connect.url", 253 "https://connect.nuxeo.com/nuxeo/site/") + "../../register/#/embedded?wizardCallbackUrl=" + cbUrl 254 + "&pkg=" + ctx.getDistributionKey(); 255 256 resp.sendRedirect(redirect); 257 return; 258 } 259 260 String targetUrl = req.getContextPath() + "/" + targetNav; 261 req.setAttribute("targetUrl", targetUrl); 262 handleDefaultGET(currentPage, req, resp); 263 } 264 265 public void handleConnectFinishGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 266 throws ServletException, IOException { 267 // get the connect Token and decode associated infos 268 String token = req.getParameter(CONNECT_TOKEN_KEY); 269 Map<String, String> connectMap = new HashMap<>(); 270 if (token != null) { 271 String tokenData = new String(Base64.decodeBase64(token)); 272 String[] tokenDataLines = tokenData.split("\n"); 273 for (String line : tokenDataLines) { 274 String[] parts = line.split(":"); 275 if (parts.length > 1) { 276 connectMap.put(parts[0], parts[1]); 277 } 278 } 279 Context.instance(req).storeConnectMap(connectMap); 280 } 281 handleDefaultGET(currentPage, req, resp); 282 } 283 284 public void handleDBPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 285 throws ServletException, IOException { 286 Context ctx = Context.instance(req); 287 ParamCollector collector = ctx.getCollector(); 288 289 String templateDbName = collector.getConfigurationParam(PARAM_TEMPLATE_DBNAME); 290 String templateDbNoSQLName = collector.getConfigurationParam(PARAM_TEMPLATE_DBNOSQL_NAME); 291 if ("true".equals(req.getParameter("refresh"))) { 292 collector.changeDBTemplate(templateDbName); 293 collector.changeDBTemplate(templateDbNoSQLName); 294 collector.removeDbKeys(); 295 currentPage.dispatchToJSP(req, resp); 296 return; 297 } 298 299 // Check relational database 300 if (!DB_EXCLUDE_CHECK_LIST.contains(templateDbName)) { 301 if (collector.getConfigurationParam(PARAM_DB_NAME).isEmpty()) { 302 ctx.trackError(PARAM_DB_NAME, "error.dbname.required"); 303 } 304 if (collector.getConfigurationParam(PARAM_DB_USER).isEmpty()) { 305 ctx.trackError(PARAM_DB_USER, "error.dbuser.required"); 306 } 307 if (collector.getConfigurationParam(PARAM_DB_PWD).isEmpty()) { 308 ctx.trackError(PARAM_DB_PWD, "error.dbpassword.required"); 309 } 310 if (collector.getConfigurationParam(PARAM_DB_HOST).isEmpty()) { 311 ctx.trackError(PARAM_DB_HOST, "error.dbhost.required"); 312 } 313 if (collector.getConfigurationParam(PARAM_DB_PORT).isEmpty()) { 314 ctx.trackError(PARAM_DB_PORT, "error.dbport.required"); 315 } else { 316 if (!NumberValidator.validate(collector.getConfigurationParam(PARAM_DB_PORT))) { 317 ctx.trackError(PARAM_DB_PORT, "error.invalid.port"); 318 } else { 319 int dbPort = Integer.parseInt(collector.getConfigurationParam(PARAM_DB_PORT)); 320 if (dbPort < 1024 || dbPort > 65536) { 321 ctx.trackError(PARAM_DB_PORT, "error.invalid.port"); 322 } 323 } 324 } 325 ConfigurationGenerator cg = collector.getConfigurationGenerator(); 326 try { 327 cg.checkDatabaseConnection(templateDbName, collector.getConfigurationParam(PARAM_DB_NAME), 328 collector.getConfigurationParam(PARAM_DB_USER), collector.getConfigurationParam(PARAM_DB_PWD), 329 collector.getConfigurationParam(PARAM_DB_HOST), collector.getConfigurationParam(PARAM_DB_PORT)); 330 } catch (DatabaseDriverException e) { 331 ctx.trackError(PARAM_DB_NAME, "error.db.driver.notfound"); 332 log.warn(e); 333 } catch (SQLException e) { 334 ctx.trackError(PARAM_DB_NAME, "error.db.connection"); 335 log.warn(e); 336 } 337 } 338 339 // Check NoSQL database 340 if (!DB_EXCLUDE_CHECK_LIST.contains(templateDbNoSQLName) && DB_NOSQL_LIST.contains(templateDbNoSQLName)) { 341 if (collector.getConfigurationParam(PARAM_MONGODB_NAME).isEmpty()) { 342 ctx.trackError(PARAM_MONGODB_NAME, "error.dbname.required"); 343 } 344 if (collector.getConfigurationParam(PARAM_MONGODB_SERVER).isEmpty()) { 345 ctx.trackError(PARAM_MONGODB_SERVER, "error.dburi.required"); 346 } 347 } 348 349 if (ctx.hasErrors()) { 350 currentPage.dispatchToJSP(req, resp); 351 } else { 352 currentPage.next().dispatchToJSP(req, resp, true); 353 } 354 } 355 356 public void handleUserPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 357 throws ServletException, IOException { 358 Context ctx = Context.instance(req); 359 ParamCollector collector = ctx.getCollector(); 360 361 String refreshParam = req.getParameter("refresh"); 362 String directoryType = collector.getConfigurationParam("nuxeo.directory.type"); 363 364 if ("true".equals(refreshParam)) { 365 currentPage.dispatchToJSP(req, resp); 366 return; 367 } 368 369 if ("checkNetwork".equals(refreshParam) || "checkAuth".equals(refreshParam) 370 || "checkUserLdapParam".equals(refreshParam) || "checkGroupLdapParam".equals(refreshParam)) { 371 try { 372 if ("checkNetwork".equals(refreshParam)) { 373 bindLdapConnection(collector, false); 374 ctx.trackInfo("nuxeo.ldap.url", "info.host.found"); 375 } else if ("checkAuth".equals(refreshParam)) { 376 bindLdapConnection(collector, true); 377 ctx.trackInfo("nuxeo.ldap.auth", "info.auth.success"); 378 } else { 379 DirContext dirContext = new InitialDirContext(getContextEnv(collector, true)); 380 String searchScope; 381 String searchBaseDn; 382 String searchClass; 383 String searchFilter; 384 if ("checkUserLdapParam".equals(refreshParam)) { 385 searchBaseDn = collector.getConfigurationParam("nuxeo.ldap.user.searchBaseDn"); 386 searchScope = collector.getConfigurationParam("nuxeo.ldap.user.searchScope"); 387 searchClass = collector.getConfigurationParam("nuxeo.ldap.user.searchClass"); 388 searchFilter = collector.getConfigurationParam("nuxeo.ldap.user.searchFilter"); 389 } else { 390 searchBaseDn = collector.getConfigurationParam("nuxeo.ldap.group.searchBaseDn"); 391 searchScope = collector.getConfigurationParam("nuxeo.ldap.group.searchScope"); 392 searchFilter = collector.getConfigurationParam("nuxeo.ldap.group.searchFilter"); 393 searchClass = ""; 394 } 395 396 SearchControls scts = new SearchControls(); 397 if ("onelevel".equals(searchScope)) { 398 scts.setSearchScope(SearchControls.ONELEVEL_SCOPE); 399 } else { 400 scts.setSearchScope(SearchControls.SUBTREE_SCOPE); 401 } 402 String filter = String.format("(&(%s)(objectClass=%s))", 403 searchFilter.isEmpty() ? "objectClass=*" : searchFilter, 404 searchClass.isEmpty() ? "*" : searchClass); 405 NamingEnumeration<SearchResult> results; 406 try { 407 results = dirContext.search(searchBaseDn, filter, scts); 408 if (!results.hasMore()) { 409 ctx.trackError("nuxeo.ldap.search", "error.ldap.noresult"); 410 } else { 411 SearchResult result = results.next(); 412 if (searchBaseDn.equalsIgnoreCase(result.getNameInNamespace()) && results.hasMore()) { 413 // try not to display the root of the search 414 // base DN 415 result = results.next(); 416 } 417 ctx.trackInfo("dn", result.getNameInNamespace()); 418 Attributes attributes = result.getAttributes(); 419 NamingEnumeration<String> ids = attributes.getIDs(); 420 String id; 421 StringBuilder sb; 422 while (ids.hasMore()) { 423 id = ids.next(); 424 NamingEnumeration<?> values = attributes.get(id).getAll(); 425 sb = new StringBuilder(); 426 while (values.hasMore()) { 427 sb.append(values.next()).append(" , "); 428 } 429 ctx.trackInfo(id, sb.substring(0, sb.length() - 3)); 430 } 431 } 432 } catch (NameNotFoundException e) { 433 ctx.trackError("nuxeo.ldap.search", "error.ldap.searchBaseDn"); 434 log.warn(e); 435 } 436 dirContext.close(); 437 } 438 } catch (AuthenticationException e) { 439 ctx.trackError("nuxeo.ldap.auth", "error.auth.failed"); 440 log.warn(e); 441 } catch (NamingException e) { 442 ctx.trackError("nuxeo.ldap.url", "error.host.not.found"); 443 log.warn(e); 444 } 445 } 446 447 // Form submit 448 if (!"default".equals(directoryType) && refreshParam.isEmpty()) { 449 // first check bind to LDAP server 450 try { 451 bindLdapConnection(collector, true); 452 } catch (NamingException e) { 453 ctx.trackError("nuxeo.ldap.auth", "error.ldap.bind.failed"); 454 log.warn(e); 455 } 456 457 // then check mandatory fields 458 if (collector.getConfigurationParam("nuxeo.ldap.user.searchBaseDn").isEmpty()) { 459 ctx.trackError("nuxeo.ldap.user.searchBaseDn", "error.user.searchBaseDn.required"); 460 } 461 if (collector.getConfigurationParam("nuxeo.ldap.user.mapping.rdn").isEmpty()) { 462 ctx.trackError("nuxeo.ldap.user.mapping.rdn", "error.user.rdn.required"); 463 } 464 if (collector.getConfigurationParam("nuxeo.ldap.user.mapping.username").isEmpty()) { 465 ctx.trackError("nuxeo.ldap.user.mapping.username", "error.user.username.required"); 466 } 467 if (collector.getConfigurationParam("nuxeo.ldap.user.mapping.password").isEmpty()) { 468 ctx.trackError("nuxeo.ldap.user.mapping.password", "error.user.password.required"); 469 } 470 if (collector.getConfigurationParam("nuxeo.ldap.user.mapping.firstname").isEmpty()) { 471 ctx.trackError("nuxeo.ldap.user.mapping.firstname", "error.user.firstname.required"); 472 } 473 if (collector.getConfigurationParam("nuxeo.ldap.user.mapping.lastname").isEmpty()) { 474 ctx.trackError("nuxeo.ldap.user.mapping.lastname", "error.user.lastname.required"); 475 } 476 String userGroupStorage = collector.getConfigurationParam("nuxeo.user.group.storage"); 477 if (!"userLdapOnly".equals(userGroupStorage) && !"multiUserSqlGroup".equals(userGroupStorage)) { 478 if (collector.getConfigurationParam("nuxeo.ldap.group.searchBaseDn").isEmpty()) { 479 ctx.trackError("nuxeo.ldap.group.searchBaseDn", "error.group.searchBaseDn.required"); 480 } 481 if (collector.getConfigurationParam("nuxeo.ldap.group.mapping.rdn").isEmpty()) { 482 ctx.trackError("nuxeo.ldap.group.mapping.rdn", "error.group.rdn.required"); 483 } 484 if (collector.getConfigurationParam("nuxeo.ldap.group.mapping.name").isEmpty()) { 485 ctx.trackError("nuxeo.ldap.group.mapping.name", "error.group.name.required"); 486 } 487 } 488 if ("true".equals(collector.getConfigurationParam("nuxeo.user.emergency.enable"))) { 489 if (collector.getConfigurationParam("nuxeo.user.emergency.username").isEmpty()) { 490 ctx.trackError("nuxeo.user.emergency.username", "error.emergency.username.required"); 491 } 492 if (collector.getConfigurationParam("nuxeo.user.emergency.password").isEmpty()) { 493 ctx.trackError("nuxeo.user.emergency.password", "error.emergency.password.required"); 494 } 495 } 496 } 497 498 if (ctx.hasErrors() || ctx.hasInfos()) { 499 currentPage.dispatchToJSP(req, resp); 500 } else { 501 currentPage.next().dispatchToJSP(req, resp, true); 502 } 503 } 504 505 private Hashtable<Object, Object> getContextEnv(ParamCollector collector, boolean checkAuth) { 506 String ldapUrl = collector.getConfigurationParam("nuxeo.ldap.url"); 507 String ldapBindDn = collector.getConfigurationParam("nuxeo.ldap.binddn"); 508 String ldapBindPassword = collector.getConfigurationParam("nuxeo.ldap.bindpassword"); 509 ConfigurationGenerator cg = collector.getConfigurationGenerator(); 510 return cg.getContextEnv(ldapUrl, ldapBindDn, ldapBindPassword, checkAuth); 511 } 512 513 private void bindLdapConnection(ParamCollector collector, boolean authenticate) throws NamingException { 514 ConfigurationGenerator cg = collector.getConfigurationGenerator(); 515 cg.checkLdapConnection(getContextEnv(collector, authenticate)); 516 } 517 518 public void handleSmtpPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 519 throws ServletException, IOException { 520 521 Context ctx = Context.instance(req); 522 ParamCollector collector = ctx.getCollector(); 523 524 if (collector.getConfigurationParam("mail.transport.auth").equals("true")) { 525 if (collector.getConfigurationParam("mail.transport.user").isEmpty()) { 526 ctx.trackError("mail.transport.user", "error.mail.transport.user.required"); 527 } 528 if (collector.getConfigurationParam("mail.transport.password").isEmpty()) { 529 ctx.trackError("mail.transport.password", "error.mail.transport.password.required"); 530 } 531 } 532 533 if (!collector.getConfigurationParam("mail.transport.port").isEmpty()) { 534 if (!NumberValidator.validate(collector.getConfigurationParam("mail.transport.port"))) { 535 ctx.trackError("mail.transport.port", "error.mail.transport.port.mustbeanumber"); 536 } 537 } 538 539 if (ctx.hasErrors()) { 540 currentPage.dispatchToJSP(req, resp); 541 } else { 542 currentPage.next().dispatchToJSP(req, resp, true); 543 } 544 } 545 546 public void handleRecapPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 547 throws ServletException, IOException { 548 Context ctx = Context.instance(req); 549 ParamCollector collector = ctx.getCollector(); 550 ConfigurationGenerator cg = collector.getConfigurationGenerator(); 551 552 // Mark package selection done 553 PackageDownloaderHelper.markPackageSelectionDone(ctx); 554 555 Map<String, String> changedParameters = collector.getConfigurationParams(); 556 changedParameters.put(PARAM_WIZARD_DONE, "true"); 557 try { 558 // save config 559 cg.saveFilteredConfiguration(changedParameters); 560 561 // // => page will trigger the restart 562 // new Page("", "reStarting.jsp").dispatchToJSP(req, resp); 563 currentPage.next().dispatchToJSP(req, resp, true); 564 } catch (ConfigurationException e) { 565 log.error("Could not save wizard parameters.", e); 566 currentPage.dispatchToJSP(req, resp); 567 } 568 } 569 570 public void handleGeneralPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 571 throws ServletException, IOException { 572 Context ctx = Context.instance(req); 573 ParamCollector collector = ctx.getCollector(); 574 String bindAddress = collector.getConfigurationParamValue(PARAM_BIND_ADDRESS); 575 if (bindAddress != null && !bindAddress.isEmpty()) { 576 if (!IPValidator.validate(bindAddress)) { 577 ctx.trackError(PARAM_BIND_ADDRESS, "error.invalid.ip"); 578 } 579 try { 580 InetAddress inetAddress = ConfigurationGenerator.getBindAddress(bindAddress); 581 ConfigurationGenerator.checkAddressReachable(inetAddress); 582 } catch (ConfigurationException e) { 583 ctx.trackError(PARAM_BIND_ADDRESS, "error.already.used.ip"); 584 } 585 } 586 587 if (ctx.hasErrors()) { 588 currentPage.dispatchToJSP(req, resp); 589 } else { 590 currentPage.next().dispatchToJSP(req, resp, true); 591 } 592 } 593 594 public void handleHomeGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 595 throws ServletException, IOException { 596 Context ctx = Context.instance(req); 597 if (PackageDownloaderHelper.isPackageSelectionDone(ctx)) { 598 navHandler.deactivatePage("PackagesSelection"); 599 navHandler.deactivatePage("PackagesDownload"); 600 navHandler.activatePage("PackagesSelectionDone"); 601 } 602 handleDefaultGET(currentPage, req, resp); 603 } 604 605 public void handleHomePOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 606 throws ServletException, IOException { 607 String baseUrl = req.getParameter("baseUrl"); 608 if (baseUrl != null && !baseUrl.isEmpty()) { 609 if (baseUrl.endsWith("Home")) { 610 baseUrl = baseUrl.substring(0, baseUrl.length() - 4); 611 Context.instance(req).setBaseUrl(baseUrl); 612 } 613 } 614 615 String browserInternetAccess = req.getParameter("browserInternetAccess"); 616 if ("true".equals(browserInternetAccess)) { 617 Context.instance(req).setBrowserInternetAccess(true); 618 SimpleNavigationHandler.instance().deactivatePage("NetworkBlocked"); 619 SimpleNavigationHandler.instance().activatePage("Connect"); 620 } else { 621 Context.instance(req).setBrowserInternetAccess(false); 622 SimpleNavigationHandler.instance().activatePage("NetworkBlocked"); 623 SimpleNavigationHandler.instance().deactivatePage("Connect"); 624 } 625 626 currentPage.next().dispatchToJSP(req, resp, true); 627 } 628 629 public void handleProxyPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 630 throws ServletException, IOException { 631 Context ctx = Context.instance(req); 632 ParamCollector collector = ctx.getCollector(); 633 String proxyType = collector.getConfigurationParamValue("nuxeo.http.proxy.type"); 634 if ("none".equals(proxyType)) { 635 collector.addConfigurationParam("nuxeo.http.proxy.type", null); 636 collector.addConfigurationParam("nuxeo.http.proxy.login", null); 637 collector.addConfigurationParam("nuxeo.http.proxy.password", null); 638 collector.addConfigurationParam("nuxeo.http.proxy.host", null); 639 collector.addConfigurationParam("nuxeo.http.proxy.port", null); 640 collector.addConfigurationParam("nuxeo.http.proxy.ntml.host", null); 641 collector.addConfigurationParam("nuxeo.http.proxy.ntml.domain", null); 642 if (!PackageDownloaderHelper.isPackageSelectionDone(ctx)) { 643 PackageDownloader.instance().setProxy(null, 0, null, null, null, null); 644 } 645 } else { 646 if (!NumberValidator.validate(collector.getConfigurationParam("nuxeo.http.proxy.port"))) { 647 ctx.trackError("nuxeo.http.proxy.port", "error.nuxeo.http.proxy.port"); 648 } 649 if (collector.getConfigurationParam("nuxeo.http.proxy.host").isEmpty()) { 650 ctx.trackError("nuxeo.http.proxy.host", "error.nuxeo.http.proxy.emptyHost"); 651 } 652 if ("anonymous".equals(proxyType)) { 653 collector.addConfigurationParam("nuxeo.http.proxy.login", null); 654 collector.addConfigurationParam("nuxeo.http.proxy.password", null); 655 collector.addConfigurationParam("nuxeo.http.proxy.ntml.host", null); 656 collector.addConfigurationParam("nuxeo.http.proxy.ntml.domain", null); 657 658 if (!ctx.hasErrors()) { 659 if (!PackageDownloaderHelper.isPackageSelectionDone(ctx)) { 660 PackageDownloader.instance().setProxy( 661 collector.getConfigurationParamValue("nuxeo.http.proxy.host"), 662 Integer.parseInt(collector.getConfigurationParamValue("nuxeo.http.proxy.port")), null, 663 null, null, null); 664 } 665 } 666 } else { 667 if (collector.getConfigurationParam("nuxeo.http.proxy.login").isEmpty()) { 668 ctx.trackError("nuxeo.http.proxy.login", "error.nuxeo.http.proxy.emptyLogin"); 669 } else { 670 if (!ctx.hasErrors()) { 671 if (!PackageDownloaderHelper.isPackageSelectionDone(ctx)) { 672 PackageDownloader.instance().setProxy( 673 collector.getConfigurationParamValue("nuxeo.http.proxy.host"), 674 Integer.parseInt(collector.getConfigurationParamValue("nuxeo.http.proxy.port")), 675 collector.getConfigurationParamValue("nuxeo.http.proxy.login"), 676 collector.getConfigurationParamValue("nuxeo.http.proxy.password"), 677 collector.getConfigurationParamValue("nuxeo.http.proxy.ntlm.host"), 678 collector.getConfigurationParamValue("nuxeo.http.proxy.ntml.domain")); 679 } 680 } 681 } 682 } 683 } 684 685 if (ctx.hasErrors()) { 686 currentPage.dispatchToJSP(req, resp); 687 } else { 688 currentPage.next().dispatchToJSP(req, resp, true); 689 } 690 } 691 692 public void handleResetGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) throws IOException { 693 // reset 694 Context.reset(); 695 SimpleNavigationHandler.reset(); 696 PackageDownloader.reset(); 697 698 // return to first page 699 String target = "/" + req.getContextPath() + "/" 700 + SimpleNavigationHandler.instance().getDefaultPage().getAction(); 701 if (target.startsWith("//")) { 702 target = target.substring(1); 703 } 704 resp.sendRedirect(target); 705 } 706 707 public void handlePackageOptionsResourceGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 708 throws IOException { 709 DownloadablePackageOptions options = PackageDownloader.instance().getPackageOptions(); 710 resp.setContentType("text/json"); 711 resp.getWriter().write(options.asJson()); 712 } 713 714 public void handlePackagesSelectionGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 715 throws ServletException, IOException { 716 handleDefaultGET(currentPage, req, resp); 717 } 718 719 public void handlePackagesSelectionPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 720 throws ServletException, IOException { 721 List<String> options = new ArrayList<>(); 722 Enumeration<String> params = req.getParameterNames(); 723 while (params.hasMoreElements()) { 724 String p = params.nextElement(); 725 if ("on".equals(req.getParameter(p))) { 726 options.add(p); 727 } 728 } 729 730 PackageDownloader.instance().selectOptions(options); 731 currentPage.next().dispatchToJSP(req, resp, true); 732 } 733 734 public void handlePackagesDownloadGET(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 735 throws ServletException, IOException { 736 if ("true".equals(req.getParameter("startDownload"))) { 737 PackageDownloader.instance().startDownload(); 738 } else if (req.getParameter("reStartDownload") != null) { 739 PackageDownloader.instance().reStartDownload(req.getParameter("reStartDownload")); 740 } 741 currentPage.dispatchToJSP(req, resp); 742 } 743 744 public void handlePackagesDownloadPOST(Page currentPage, HttpServletRequest req, HttpServletResponse resp) 745 throws ServletException, IOException { 746 ParamCollector collector = Context.instance(req).getCollector(); 747 748 String installationFilePath = new File(collector.getConfigurationParam(NUXEO_DATA_DIR), 749 INSTALL_AFTER_RESTART).getAbsolutePath(); 750 751 PackageDownloader.instance().scheduleDownloadedPackagesForInstallation(installationFilePath); 752 PackageDownloader.reset(); 753 currentPage.next().dispatchToJSP(req, resp, true); 754 } 755 756}