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