001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.main; 029 030import org.opencms.ade.configuration.CmsADEManager; 031import org.opencms.ade.containerpage.CmsContainerpageService; 032import org.opencms.cache.CmsVfsMemoryObjectCache; 033import org.opencms.configuration.CmsConfigurationException; 034import org.opencms.configuration.CmsConfigurationManager; 035import org.opencms.configuration.CmsImportExportConfiguration; 036import org.opencms.configuration.CmsModuleConfiguration; 037import org.opencms.configuration.CmsParameterConfiguration; 038import org.opencms.configuration.CmsSchedulerConfiguration; 039import org.opencms.configuration.CmsSearchConfiguration; 040import org.opencms.configuration.CmsSitesConfiguration; 041import org.opencms.configuration.CmsSystemConfiguration; 042import org.opencms.configuration.CmsVariablesConfiguration; 043import org.opencms.configuration.CmsVfsConfiguration; 044import org.opencms.configuration.CmsWorkplaceConfiguration; 045import org.opencms.configuration.I_CmsNeedsAdminCmsObject; 046import org.opencms.crypto.I_CmsTextEncryption; 047import org.opencms.db.CmsAliasManager; 048import org.opencms.db.CmsDbEntryNotFoundException; 049import org.opencms.db.CmsDefaultUsers; 050import org.opencms.db.CmsExportPoint; 051import org.opencms.db.CmsLoginManager; 052import org.opencms.db.CmsSecurityManager; 053import org.opencms.db.CmsSqlManager; 054import org.opencms.db.CmsSubscriptionManager; 055import org.opencms.db.timing.CmsDefaultProfilingHandler; 056import org.opencms.db.timing.CmsThreadStatsTreeProfilingHandler; 057import org.opencms.file.CmsObject; 058import org.opencms.file.CmsProject; 059import org.opencms.file.CmsProperty; 060import org.opencms.file.CmsPropertyDefinition; 061import org.opencms.file.CmsRequestContext; 062import org.opencms.file.CmsResource; 063import org.opencms.file.CmsResourceFilter; 064import org.opencms.file.CmsUser; 065import org.opencms.file.CmsVfsResourceNotFoundException; 066import org.opencms.flex.CmsFlexCache; 067import org.opencms.flex.CmsFlexCacheConfiguration; 068import org.opencms.flex.CmsFlexController; 069import org.opencms.gwt.CmsGwtService; 070import org.opencms.gwt.CmsGwtServiceContext; 071import org.opencms.gwt.shared.CmsGwtConstants; 072import org.opencms.i18n.CmsEncoder; 073import org.opencms.i18n.CmsI18nInfo; 074import org.opencms.i18n.CmsLocaleManager; 075import org.opencms.i18n.CmsMessageContainer; 076import org.opencms.i18n.CmsSingleTreeLocaleHandler; 077import org.opencms.i18n.CmsVfsBundleManager; 078import org.opencms.importexport.CmsImportExportManager; 079import org.opencms.json.JSONObject; 080import org.opencms.jsp.jsonpart.CmsJsonPartFilter; 081import org.opencms.jsp.userdata.CmsUserDataRequestManager; 082import org.opencms.jsp.util.CmsJspStandardContextBean; 083import org.opencms.letsencrypt.CmsLetsEncryptConfiguration; 084import org.opencms.loader.CmsJspLoader; 085import org.opencms.loader.CmsResourceManager; 086import org.opencms.loader.CmsTemplateContextManager; 087import org.opencms.loader.I_CmsFlexCacheEnabledLoader; 088import org.opencms.loader.I_CmsResourceLoader; 089import org.opencms.lock.CmsLockManager; 090import org.opencms.module.CmsModuleManager; 091import org.opencms.monitor.CmsMemoryMonitor; 092import org.opencms.monitor.CmsMemoryMonitorConfiguration; 093import org.opencms.mx.CmsDiagnosticsMXBean; 094import org.opencms.publish.CmsPublishEngine; 095import org.opencms.publish.CmsPublishManager; 096import org.opencms.repository.CmsRepositoryManager; 097import org.opencms.rmi.CmsRemoteShellServer; 098import org.opencms.scheduler.CmsScheduleManager; 099import org.opencms.search.CmsSearchManager; 100import org.opencms.security.CmsOrgUnitManager; 101import org.opencms.security.CmsPersistentLoginTokenHandler; 102import org.opencms.security.CmsRole; 103import org.opencms.security.CmsRoleManager; 104import org.opencms.security.CmsRoleViolationException; 105import org.opencms.security.CmsSecurityException; 106import org.opencms.security.I_CmsAuthorizationHandler; 107import org.opencms.security.I_CmsCredentialsResolver; 108import org.opencms.security.I_CmsPasswordHandler; 109import org.opencms.security.I_CmsValidationHandler; 110import org.opencms.security.twofactor.CmsTwoFactorAuthenticationHandler; 111import org.opencms.site.CmsSite; 112import org.opencms.site.CmsSiteManagerImpl; 113import org.opencms.site.CmsSiteMatcher; 114import org.opencms.staticexport.CmsDefaultLinkSubstitutionHandler; 115import org.opencms.staticexport.CmsLinkManager; 116import org.opencms.staticexport.CmsStaticExportManager; 117import org.opencms.ugc.CmsUgcSessionFactory; 118import org.opencms.ui.apps.CmsWorkplaceAppManager; 119import org.opencms.ui.dialogs.CmsPublishScheduledDialog; 120import org.opencms.ui.error.CmsErrorUI; 121import org.opencms.ui.login.CmsLoginHelper; 122import org.opencms.ui.login.CmsLoginUI; 123import org.opencms.util.CmsRequestUtil; 124import org.opencms.util.CmsStringUtil; 125import org.opencms.util.CmsTaskWatcher; 126import org.opencms.util.CmsUUID; 127import org.opencms.workflow.CmsDefaultWorkflowManager; 128import org.opencms.workflow.I_CmsWorkflowManager; 129import org.opencms.workplace.CmsWorkplace; 130import org.opencms.workplace.CmsWorkplaceLoginHandler; 131import org.opencms.workplace.CmsWorkplaceManager; 132import org.opencms.workplace.CmsWorkplaceSettings; 133import org.opencms.xml.CmsXmlContentTypeManager; 134import org.opencms.xml.CmsXmlUtils; 135import org.opencms.xml.containerpage.CmsFormatterConfiguration; 136import org.opencms.xml.xml2json.I_CmsApiAuthorizationHandler; 137 138import java.io.FileOutputStream; 139import java.io.IOException; 140import java.lang.reflect.Field; 141import java.security.Security; 142import java.util.ArrayList; 143import java.util.Collections; 144import java.util.Date; 145import java.util.HashMap; 146import java.util.HashSet; 147import java.util.Hashtable; 148import java.util.Iterator; 149import java.util.LinkedHashMap; 150import java.util.List; 151import java.util.Locale; 152import java.util.Map; 153import java.util.ServiceLoader; 154import java.util.Set; 155import java.util.concurrent.ScheduledThreadPoolExecutor; 156import java.util.concurrent.TimeUnit; 157import java.util.concurrent.atomic.AtomicBoolean; 158 159import javax.servlet.ServletConfig; 160import javax.servlet.ServletContext; 161import javax.servlet.ServletException; 162import javax.servlet.http.HttpServletRequest; 163import javax.servlet.http.HttpServletResponse; 164import javax.servlet.http.HttpSession; 165 166import org.apache.commons.logging.Log; 167import org.apache.logging.log4j.CloseableThreadContext; 168 169import org.antlr.stringtemplate.StringTemplate; 170 171import com.google.common.base.Optional; 172import com.google.common.util.concurrent.ThreadFactoryBuilder; 173import com.google.gwt.user.client.rpc.core.java.util.LinkedHashMap_CustomFieldSerializer; 174 175/** 176 * The internal implementation of the core OpenCms "operating system" functions.<p> 177 * 178 * All access to this class must be done through the public static methods 179 * of the <code>{@link org.opencms.main.OpenCms}</code> object. 180 * Under no circumstances should you ever try to access this class directly.<p> 181 * 182 * This class is so OpenCms internal you should not even be reading this documentation ;-)<p> 183 * 184 * Any request to the <code>{@link org.opencms.main.OpenCmsServlet}</code> will be forwarded to this core class. 185 * The core will then try to map the request to a VFS (Virtual File System) URI, 186 * that is a <code>{@link org.opencms.file.CmsResource}</code> in the OpenCms database. 187 * If a resource is found, it will be read and forwarded to 188 * to the corresponding <code>{@link org.opencms.loader.I_CmsResourceLoader}</code>, 189 * which will then generate the output for the requested resource and return it to the requesting client.<p> 190 * 191 * There will be only one singleton instance of this object created for 192 * this core class. This means that in the default configuration, where 193 * OpenCms is accessed through a servlet context, there will be only one instance of 194 * the core in that servlet context.<p> 195 * 196 * @since 6.0.0 197 */ 198public final class OpenCmsCore { 199 200 /** Parameter to control whether generated links should always include the host. */ 201 public static final String PARAM_FORCE_ABSOLUTE_LINKS = "__forceAbsoluteLinks"; 202 203 /** The static log object for this class. */ 204 static final Log LOG = CmsLog.getLog(OpenCmsCore.class); 205 206 /** Lock object for synchronization. */ 207 private static final Object LOCK = new Object(); 208 209 /** Indicates if the configuration was successfully finished or not. */ 210 private static CmsMessageContainer m_errorCondition; 211 212 /** One instance to rule them all, one instance to find them... */ 213 private static OpenCmsCore m_instance; 214 215 static { 216 final String keyEntityExpansionLimit = "jdk.xml.entityExpansionLimit"; 217 if (System.getProperty(keyEntityExpansionLimit) == null) { 218 System.setProperty(keyEntityExpansionLimit, "64000"); 219 } 220 } 221 222 /** The ADE manager instance. */ 223 private CmsADEManager m_adeManager; 224 225 /** The manager for page aliases. */ 226 private CmsAliasManager m_aliasManager; 227 228 /** Map of API authorization handlers, with their names as keys. */ 229 private Map<String, I_CmsApiAuthorizationHandler> m_apiAuthorizations; 230 231 /** The configured authorization handler. */ 232 private I_CmsAuthorizationHandler m_authorizationHandler; 233 234 /** Admin CMS object. */ 235 private CmsObject m_configAdminCms; 236 237 /** The configuration manager that contains the information from the XML configuration. */ 238 private CmsConfigurationManager m_configurationManager; 239 240 /** The object used for resolving database user credentials. */ 241 private I_CmsCredentialsResolver m_credentialsResolver; 242 243 /** List of configured directory default file names. */ 244 private List<String> m_defaultFiles; 245 246 /** The default user and group names. */ 247 private CmsDefaultUsers m_defaultUsers; 248 249 /** The event manager for the event handling. */ 250 private CmsEventManager m_eventManager; 251 252 /** The thread pool executor. */ 253 private ScheduledThreadPoolExecutor m_executor; 254 255 /** The set of configured export points. */ 256 private Set<CmsExportPoint> m_exportPoints; 257 258 /** The flex cache instance. */ 259 private CmsFlexCache m_flexCache; 260 261 /** The context objects for GWT services. */ 262 private Map<String, CmsGwtServiceContext> m_gwtServiceContexts; 263 264 /** The site manager contains information about the Cms import/export. */ 265 private CmsImportExportManager m_importExportManager; 266 267 /** The LetsEncrypt configuration. */ 268 private CmsLetsEncryptConfiguration m_letsEncryptConfig; 269 270 /** The link manager to resolve links in <cms:link> tags. */ 271 private CmsLinkManager m_linkManager; 272 273 /** The locale manager used for obtaining the current locale. */ 274 private CmsLocaleManager m_localeManager; 275 276 /** The login manager. */ 277 private CmsLoginManager m_loginManager; 278 279 /** The memory monitor for the collection of memory and runtime statistics. */ 280 private CmsMemoryMonitor m_memoryMonitor; 281 282 /** The module manager. */ 283 private CmsModuleManager m_moduleManager; 284 285 /** The organizational unit manager. */ 286 private CmsOrgUnitManager m_orgUnitManager; 287 288 /** The password handler used to digest and validate passwords. */ 289 private I_CmsPasswordHandler m_passwordHandler; 290 291 /** The publish engine. */ 292 private CmsPublishEngine m_publishEngine; 293 294 /** The publish manager instance. */ 295 private CmsPublishManager m_publishManager; 296 297 /** The remote shell server. */ 298 private CmsRemoteShellServer m_remoteShellServer; 299 300 /** The repository manager. */ 301 private CmsRepositoryManager m_repositoryManager; 302 303 /** The configured request handlers that handle "special" requests, for example in the static export on demand. */ 304 private Map<String, I_CmsRequestHandler> m_requestHandlers; 305 306 /** Stores the resource init handlers that allow modification of the requested resource. */ 307 private List<I_CmsResourceInit> m_resourceInitHandlers; 308 309 /** The resource manager. */ 310 private CmsResourceManager m_resourceManager; 311 312 /** The role manager. */ 313 private CmsRoleManager m_roleManager; 314 315 /** The runlevel of this OpenCmsCore object instance. */ 316 private int m_runLevel; 317 318 /** The runtime properties allow storage of system wide accessible runtime information. */ 319 private Map<Object, Object> m_runtimeProperties; 320 321 /** The configured scheduler manager. */ 322 private CmsScheduleManager m_scheduleManager; 323 324 /** The search manager provides indexing and searching. */ 325 private CmsSearchManager m_searchManager; 326 327 /** The security manager to access the database and validate user permissions. */ 328 private CmsSecurityManager m_securityManager; 329 330 /** The session manager. */ 331 private CmsSessionManager m_sessionManager; 332 333 /** The site manager contains information about all configured sites. */ 334 private CmsSiteManagerImpl m_siteManager; 335 336 /** List of start/stop handlers. */ 337 private List<I_CmsStartStopHandler> m_startStopHandlers = new ArrayList<>(); 338 339 /** The static export manager. */ 340 private CmsStaticExportManager m_staticExportManager; 341 342 /** The subscription manager. */ 343 private CmsSubscriptionManager m_subscriptionManager; 344 345 /** The system information container for "read only" system settings. */ 346 private CmsSystemInfo m_systemInfo; 347 348 /** The template context manager. */ 349 private CmsTemplateContextManager m_templateContextManager; 350 351 /** The text encryptions. */ 352 private LinkedHashMap<String, I_CmsTextEncryption> m_textEncryptions; 353 354 /** The thread store. */ 355 private CmsThreadStore m_threadStore; 356 357 /** The 2FA handler. */ 358 private CmsTwoFactorAuthenticationHandler m_twoFactorAuthenticationHandler; 359 360 /** The user data request manager. */ 361 private CmsUserDataRequestManager m_userDataRequestManager; 362 363 /** The runtime validation handler. */ 364 private I_CmsValidationHandler m_validationHandler; 365 366 /** The VFS bundle manager. */ 367 private CmsVfsBundleManager m_vfsBundleManager; 368 369 /** The default memory object cache instance. */ 370 private CmsVfsMemoryObjectCache m_vfsMemoryObjectCache; 371 372 /** The workflow manager instance. */ 373 private I_CmsWorkflowManager m_workflowManager; 374 375 /** The workplace app manager. */ 376 private CmsWorkplaceAppManager m_workplaceAppManager; 377 378 /** The workplace manager contains information about the global workplace settings. */ 379 private CmsWorkplaceManager m_workplaceManager; 380 381 /** The XML content type manager that contains the initialized XML content types. */ 382 private CmsXmlContentTypeManager m_xmlContentTypeManager; 383 384 /** 385 * Protected constructor that will initialize the singleton OpenCms instance 386 * with runlevel {@link OpenCms#RUNLEVEL_1_CORE_OBJECT}.<p> 387 * 388 * @throws CmsInitException in case of errors during the initialization 389 */ 390 private OpenCmsCore() 391 throws CmsInitException { 392 393 if ((m_instance != null) && (m_instance.getRunLevel() > OpenCms.RUNLEVEL_0_OFFLINE)) { 394 throw new CmsInitException(Messages.get().container(Messages.ERR_ALREADY_INITIALIZED_0)); 395 } 396 initMembers(); 397 m_instance = this; 398 setRunLevel(OpenCms.RUNLEVEL_1_CORE_OBJECT); 399 } 400 401 /** 402 * Returns the path for the request.<p> 403 * 404 * First checks the {@link HttpServletRequest#getPathInfo()}, then 405 * the configured request error page attribute (if set), and then 406 * if still undefined the <code>/</code> is returned as path info.<p> 407 * 408 * This is only needed when the {@link HttpServletRequest#getPathInfo()} 409 * is not really working as expected like in BEA WLS 9.x, where we have 410 * to use the 'weblogic.servlet.errorPage' request attribute.<p> 411 * 412 * @param req the http request context 413 * 414 * @return the path for the request 415 */ 416 public static String getPathInfo(HttpServletRequest req) { 417 418 String path = req.getPathInfo(); 419 if (path == null) { 420 // if the HttpServletRequest#getPathInfo() method does not work properly 421 String requestErrorPageAttribute = OpenCms.getSystemInfo().getServletContainerSettings().getRequestErrorPageAttribute(); 422 if (requestErrorPageAttribute != null) { 423 // use the proper page attribute 424 path = (String)req.getAttribute(requestErrorPageAttribute); 425 if (path != null) { 426 int pos = path.indexOf("/", 1); 427 if (pos > 0) { 428 // cut off the servlet name 429 path = path.substring(pos); 430 } 431 } 432 } 433 } 434 if (path == null) { 435 path = "/"; 436 } 437 return path; 438 } 439 440 /** 441 * Returns the initialized OpenCms singleton instance.<p> 442 * 443 * @return the initialized OpenCms singleton instance 444 */ 445 protected static OpenCmsCore getInstance() { 446 447 if (m_errorCondition != null) { 448 // OpenCms is not properly initialized 449 throw new CmsInitException(m_errorCondition, false); 450 } 451 452 if (m_instance != null) { 453 return m_instance; 454 } 455 synchronized (LOCK) { 456 if (m_instance == null) { 457 try { 458 // create a new core object with runlevel 1 459 m_instance = new OpenCmsCore(); 460 } catch (CmsInitException e) { 461 // already initialized, this is all we need 462 LOG.debug(e.getMessage(), e); 463 } 464 } 465 } 466 return m_instance; 467 } 468 469 /** 470 * Sets the error condition.<p> 471 * 472 * @param errorCondition the error condition to set 473 */ 474 protected static void setErrorCondition(CmsMessageContainer errorCondition) { 475 476 // init exceptions should only be thrown during setup process 477 if ((m_instance != null) && (m_instance.getRunLevel() < OpenCms.RUNLEVEL_3_SHELL_ACCESS)) { 478 if (!Messages.ERR_CRITICAL_INIT_WIZARD_0.equals(errorCondition.getKey())) { 479 // if wizard is still enabled allow retry of initialization (for setup wizard) 480 m_errorCondition = errorCondition; 481 // output an error message to the console 482 System.err.println( 483 Messages.get().getBundle().key(Messages.LOG_INIT_FAILURE_MESSAGE_1, errorCondition.key())); 484 } 485 LOG.error(errorCondition.key(), new CmsException(errorCondition)); 486 m_instance = null; 487 } else if (m_instance != null) { 488 // OpenCms already was successful initialized 489 LOG.warn( 490 Messages.get().getBundle().key( 491 Messages.LOG_INIT_INVALID_ERROR_2, 492 Integer.valueOf(m_instance.getRunLevel()), 493 errorCondition.key())); 494 } 495 } 496 497 /** 498 * Gets the default CmsVfsMemoryCache instance. 499 * 500 * @return the default cache instance 501 */ 502 public CmsVfsMemoryObjectCache getVfsMemoryObjectCache() { 503 504 if (m_vfsMemoryObjectCache == null) { 505 m_vfsMemoryObjectCache = new CmsVfsMemoryObjectCache(); 506 } 507 return m_vfsMemoryObjectCache; 508 509 } 510 511 /** 512 * Adds the specified request handler to the Map of OpenCms request handlers. <p> 513 * 514 * @param handler the handler to add 515 */ 516 protected void addRequestHandler(I_CmsRequestHandler handler) { 517 518 if (handler == null) { 519 return; 520 } 521 String[] names = handler.getHandlerNames(); 522 for (int i = 0; i < names.length; i++) { 523 String name = names[i]; 524 if (m_requestHandlers.get(name) != null) { 525 CmsLog.INIT.error(Messages.get().getBundle().key(Messages.LOG_DUPLICATE_REQUEST_HANDLER_1, name)); 526 continue; 527 } 528 m_requestHandlers.put(name, handler); 529 if (CmsLog.INIT.isInfoEnabled()) { 530 CmsLog.INIT.info( 531 Messages.get().getBundle().key( 532 Messages.INIT_ADDED_REQUEST_HANDLER_2, 533 name, 534 handler.getClass().getName())); 535 } 536 } 537 } 538 539 /** 540 * Gets the ADE manager, and makes sure it is initialized.<p> 541 * 542 * @return the initialized ADE manager 543 */ 544 protected CmsADEManager getADEManager() { 545 546 if (!m_adeManager.isInitialized()) { 547 m_adeManager.initialize(); 548 } 549 return m_adeManager; 550 } 551 552 /** 553 * Returns the alias manager.<p> 554 * 555 * @return the alias manager 556 */ 557 protected CmsAliasManager getAliasManager() { 558 559 return m_aliasManager; 560 } 561 562 /** 563 * Gets the API authorization handler with the given name, or null if it doesn't exist. 564 * 565 * @param name the name of the API authorization handler 566 * @return the API authorization handler, or null if it wasn't found 567 */ 568 protected I_CmsApiAuthorizationHandler getApiAuthorization(String name) { 569 570 return m_apiAuthorizations.get(name); 571 572 } 573 574 /** 575 * Returns the configured authorization handler.<p> 576 * 577 * @return the configured authorization handler 578 */ 579 protected I_CmsAuthorizationHandler getAuthorizationHandler() { 580 581 return m_authorizationHandler; 582 } 583 584 /** 585 * Returns the initialized OpenCms configuration manager.<p> 586 * 587 * @return the initialized OpenCms configuration manager 588 */ 589 protected CmsConfigurationManager getConfigurationManager() { 590 591 return m_configurationManager; 592 } 593 594 /** 595 * Gets the configured credentials resolver instance.<p> 596 * 597 * @return the credentials resolver 598 */ 599 protected I_CmsCredentialsResolver getCredentialsResolver() { 600 601 if (m_credentialsResolver == null) { 602 CmsSystemConfiguration systemConfig = (CmsSystemConfiguration)m_configurationManager.getConfiguration( 603 CmsSystemConfiguration.class); 604 return systemConfig.getCredentialsResolver(); 605 } 606 607 return m_credentialsResolver; 608 } 609 610 /** 611 * Gets the database pool names.<p> 612 * 613 * @return the configured database pool names 614 */ 615 protected List<String> getDbPoolNames() { 616 617 return new ArrayList<>(m_configurationManager.getConfiguration().getList("db.pools")); 618 619 } 620 621 /** 622 * Returns the configured list of default directory file names.<p> 623 * 624 * @return the configured list of default directory file names 625 */ 626 protected List<String> getDefaultFiles() { 627 628 return m_defaultFiles; 629 } 630 631 /** 632 * Returns the default user and group name configuration.<p> 633 * 634 * @return the default user and group name configuration 635 */ 636 protected CmsDefaultUsers getDefaultUsers() { 637 638 return m_defaultUsers; 639 } 640 641 /** 642 * Returns the OpenCms event manager.<p> 643 * 644 * @return the OpenCms event manager 645 */ 646 protected CmsEventManager getEventManager() { 647 648 return m_eventManager; 649 } 650 651 /** 652 * Gets the thread pool executor.<p> 653 * 654 * @return the thread pool executor 655 */ 656 protected ScheduledThreadPoolExecutor getExecutor() { 657 658 return m_executor; 659 } 660 661 /** 662 * Returns the configured export points, 663 * the returned set being an unmodifiable set.<p> 664 * 665 * @return an unmodifiable set of the configured export points 666 */ 667 protected Set<CmsExportPoint> getExportPoints() { 668 669 return m_exportPoints; 670 } 671 672 /** 673 * Gets the flex cache. 674 * @return CmsFlexCache 675 */ 676 677 protected CmsFlexCache getFlexCache() { 678 679 return m_flexCache; 680 } 681 682 /** 683 * Gets a string containing all keys and variations currently in the flex cache, for debug purposes.<p> 684 * 685 * @return a debug information string with the flex cache data 686 */ 687 protected String getFlexCacheKeyDump() { 688 689 if (m_flexCache != null) { 690 StringBuffer buffer = new StringBuffer(); 691 m_flexCache.dumpKeys(buffer); 692 return buffer.toString(); 693 } else { 694 return null; 695 } 696 } 697 698 /** 699 * Returns the initialized import/export manager, 700 * which contains information about the Cms import/export.<p> 701 * 702 * @return the initialized import/export manager 703 */ 704 protected CmsImportExportManager getImportExportManager() { 705 706 return m_importExportManager; 707 } 708 709 /** 710 * Gets the LetsEncrypt configuration.<p> 711 * 712 * @return the LetsEncrypt configuration 713 */ 714 protected CmsLetsEncryptConfiguration getLetsEncryptConfig() { 715 716 return m_letsEncryptConfig; 717 } 718 719 /** 720 * Returns the link manager to resolve links in <link> tags.<p> 721 * 722 * @return the link manager to resolve links in <link> tags 723 */ 724 protected CmsLinkManager getLinkManager() { 725 726 return m_linkManager; 727 } 728 729 /** 730 * Returns the locale manager used for obtaining the current locale.<p> 731 * 732 * @return the locale manager 733 */ 734 protected CmsLocaleManager getLocaleManager() { 735 736 return m_localeManager; 737 } 738 739 /** 740 * Returns the lock manager used for the locking mechanism.<p> 741 * 742 * @return the lock manager used for the locking mechanism 743 */ 744 protected CmsLockManager getLockManager() { 745 746 return m_securityManager.getLockManager(); 747 } 748 749 /** 750 * Returns the login manager used to check the validity of a login.<p> 751 * 752 * @return the login manager 753 */ 754 protected CmsLoginManager getLoginManager() { 755 756 return m_loginManager; 757 } 758 759 /** 760 * Returns the memory monitor.<p> 761 * 762 * @return the memory monitor 763 */ 764 protected CmsMemoryMonitor getMemoryMonitor() { 765 766 return m_memoryMonitor; 767 } 768 769 /** 770 * Returns the module manager.<p> 771 * 772 * @return the module manager 773 */ 774 protected CmsModuleManager getModuleManager() { 775 776 return m_moduleManager; 777 } 778 779 /** 780 * Returns the organizational unit manager.<p> 781 * 782 * @return the organizational unit manager 783 */ 784 protected CmsOrgUnitManager getOrgUnitManager() { 785 786 return m_orgUnitManager; 787 } 788 789 /** 790 * Return the password handler.<p> 791 * 792 * @return the password handler 793 */ 794 protected I_CmsPasswordHandler getPasswordHandler() { 795 796 return m_passwordHandler; 797 } 798 799 /** 800 * Returns the publish manager instance.<p> 801 * 802 * @return the publish manager instance 803 */ 804 protected CmsPublishManager getPublishManager() { 805 806 return m_publishManager; 807 } 808 809 /** 810 * Returns the repository manager.<p> 811 * 812 * @return the repository manager 813 */ 814 protected CmsRepositoryManager getRepositoryManager() { 815 816 return m_repositoryManager; 817 } 818 819 /** 820 * Returns the handler instance for the specified name, 821 * or null if the name does not match any handler name.<p> 822 * 823 * @param name the name of the handler instance to return 824 * @return the handler instance for the specified name 825 */ 826 protected I_CmsRequestHandler getRequestHandler(String name) { 827 828 return m_requestHandlers.get(name); 829 } 830 831 /** 832 * Returns the resource manager.<p> 833 * 834 * @return the resource manager 835 */ 836 protected CmsResourceManager getResourceManager() { 837 838 return m_resourceManager; 839 } 840 841 /** 842 * Returns the role manager.<p> 843 * 844 * @return the role manager 845 */ 846 protected CmsRoleManager getRoleManager() { 847 848 return m_roleManager; 849 } 850 851 /** 852 * Returns the runlevel of this OpenCmsCore object instance.<p> 853 * 854 * For a detailed description about the possible run levels, 855 * please see {@link OpenCms#getRunLevel()}.<p> 856 * 857 * @return the runlevel of this OpenCmsCore object instance 858 * 859 * @see OpenCms#getRunLevel() 860 */ 861 protected int getRunLevel() { 862 863 return m_runLevel; 864 } 865 866 /** 867 * Looks up a value in the runtime property Map.<p> 868 * 869 * @param key the key to look up in the runtime properties 870 * @return the value for the key, or null if the key was not found 871 */ 872 protected Object getRuntimeProperty(Object key) { 873 874 return m_runtimeProperties.get(key); 875 } 876 877 /** 878 * Returns the configured schedule manager.<p> 879 * 880 * @return the configured schedule manager 881 */ 882 protected CmsScheduleManager getScheduleManager() { 883 884 return m_scheduleManager; 885 } 886 887 /** 888 * Returns the initialized search manager, 889 * which provides indexing and searching operations.<p> 890 * 891 * @return the initialized search manager 892 */ 893 protected CmsSearchManager getSearchManager() { 894 895 return m_searchManager; 896 } 897 898 /** 899 * Returns the initialized OpenCms security manager.<p> 900 * 901 * @return the initialized OpenCms security manager 902 */ 903 protected CmsSecurityManager getSecurityManager() { 904 905 return m_securityManager; 906 } 907 908 /** 909 * Returns the session manager.<p> 910 * 911 * @return the session manager 912 */ 913 protected CmsSessionManager getSessionManager() { 914 915 return m_sessionManager; 916 } 917 918 /** 919 * Returns the initialized site manager, 920 * which contains information about all configured sites.<p> 921 * 922 * @return the initialized site manager 923 */ 924 protected CmsSiteManagerImpl getSiteManager() { 925 926 return m_siteManager; 927 } 928 929 /** 930 * Returns an instance of the common sql manager.<p> 931 * 932 * @return an instance of the common sql manager 933 */ 934 protected CmsSqlManager getSqlManager() { 935 936 return m_securityManager.getSqlManager(); 937 } 938 939 /** 940 * Returns the properties for the static export.<p> 941 * 942 * @return the properties for the static export 943 */ 944 protected CmsStaticExportManager getStaticExportManager() { 945 946 return m_staticExportManager; 947 } 948 949 /** 950 * Returns the subscription manager.<p> 951 * 952 * @return the subscription manager 953 */ 954 protected CmsSubscriptionManager getSubscriptionManager() { 955 956 return m_subscriptionManager; 957 } 958 959 /** 960 * Returns the system information storage.<p> 961 * 962 * @return the system information storage 963 */ 964 protected CmsSystemInfo getSystemInfo() { 965 966 return m_systemInfo; 967 } 968 969 /** 970 * Gets the template context manager instance.<p> 971 * 972 * @return the template context manager instance 973 */ 974 protected CmsTemplateContextManager getTemplateContextManager() { 975 976 return m_templateContextManager; 977 978 } 979 980 /** 981 * Gets the text encryptions. 982 * 983 * @return the text encryptions 984 */ 985 protected Map<String, I_CmsTextEncryption> getTextEncryptions() { 986 987 return m_textEncryptions; 988 } 989 990 /** 991 * Returns the OpenCms Thread store.<p> 992 * 993 * @return the OpenCms Thread store 994 */ 995 protected CmsThreadStore getThreadStore() { 996 997 return m_threadStore; 998 } 999 1000 /** 1001 * Gets the two-factor authentication handler. 1002 * 1003 * @return the two-factor authentication handler 1004 */ 1005 protected CmsTwoFactorAuthenticationHandler getTwoFactorAuthenticationHandler() { 1006 1007 return m_twoFactorAuthenticationHandler; 1008 } 1009 1010 /** 1011 * Gets the user data request manager. 1012 * 1013 * @return the user data request manager 1014 */ 1015 protected CmsUserDataRequestManager getUserDataRequestManager() { 1016 1017 return m_userDataRequestManager; 1018 } 1019 1020 /** 1021 * Returns the runtime validation handler.<p> 1022 * 1023 * @return the validation handler 1024 */ 1025 protected I_CmsValidationHandler getValidationHandler() { 1026 1027 return m_validationHandler; 1028 } 1029 1030 /** 1031 * Returns the workflow manager instance.<p> 1032 * 1033 * @return the workflow manager 1034 */ 1035 protected I_CmsWorkflowManager getWorkflowManager() { 1036 1037 return m_workflowManager; 1038 } 1039 1040 /** 1041 * Returns the workplace app manager.<p> 1042 * 1043 * @return the workplace app manager 1044 */ 1045 protected CmsWorkplaceAppManager getWorkplaceAppManager() { 1046 1047 return m_workplaceAppManager; 1048 } 1049 1050 /** 1051 * Returns the initialized workplace manager, 1052 * which contains information about the global workplace settings.<p> 1053 * 1054 * @return the initialized workplace manager 1055 */ 1056 protected CmsWorkplaceManager getWorkplaceManager() { 1057 1058 return m_workplaceManager; 1059 } 1060 1061 /** 1062 * Returns the XML content type manager.<p> 1063 * 1064 * @return the XML content type manager 1065 */ 1066 protected CmsXmlContentTypeManager getXmlContentTypeManager() { 1067 1068 if (m_xmlContentTypeManager != null) { 1069 return m_xmlContentTypeManager; 1070 } 1071 if (getRunLevel() == OpenCms.RUNLEVEL_1_CORE_OBJECT) { 1072 // this is only to enable test cases to run 1073 m_xmlContentTypeManager = CmsXmlContentTypeManager.createTypeManagerForTestCases(); 1074 } 1075 return m_xmlContentTypeManager; 1076 } 1077 1078 /** 1079 * Initializes the OpenCms context for Vaadin UI servlet.<p> 1080 * 1081 * @param req the request 1082 * @param res the response 1083 * @param servlet the UI servlet 1084 * 1085 * @throws IOException if user authentication fails 1086 * @throws CmsException if something goes wrong 1087 */ 1088 protected void initCmsContextForUI(HttpServletRequest req, HttpServletResponse res, CmsUIServlet servlet) 1089 throws IOException, CmsException { 1090 1091 // instantiate CMS context 1092 String originalEncoding = req.getCharacterEncoding(); 1093 String referrer = req.getHeader("referer"); 1094 boolean allowPrivilegedLogin = (referrer == null) || !referrer.contains(CmsWorkplaceLoginHandler.LOGIN_HANDLER); 1095 1096 CmsObject cms = initCmsObject(req, res, allowPrivilegedLogin); 1097 servlet.setCms(cms); 1098 if (originalEncoding != null) { 1099 // getI18NInfo sets wrong encoding 1100 req.setCharacterEncoding(originalEncoding); 1101 } 1102 } 1103 1104 /** 1105 * Returns an independent copy of the provided CmsObject.<p> 1106 * 1107 * This can be useful in case a permanent reference to a CmsObject is stored. 1108 * Changing the request context values (for example project, siteroot) in the new CmsObject 1109 * will have no side effects to the CmsObject it was copied form.<p> 1110 * 1111 * The request time (<code>{@link CmsRequestContext#getRequestTime()}</code>) 1112 * is set to the current time.<p> 1113 * 1114 * @param cms the CmsObject to create a copy of 1115 * 1116 * @return an independent copy of the provided CmsObject 1117 * 1118 * @throws CmsException in case the initialization failed 1119 * 1120 * @see OpenCms#initCmsObject(CmsObject) 1121 * @see OpenCms#initCmsObject(CmsObject, CmsContextInfo) 1122 * @see OpenCms#initCmsObject(String) 1123 */ 1124 protected CmsObject initCmsObject(CmsObject cms) { 1125 1126 CmsRequestContext requestContext = cms.getRequestContext(); 1127 CmsRequestContext context = new CmsRequestContext( 1128 requestContext.getCurrentUser().clone(), 1129 (CmsProject)(requestContext.getCurrentProject().clone()), 1130 requestContext.getUri(), 1131 requestContext.getRequestMatcher(), 1132 requestContext.getSiteRoot(), 1133 requestContext.isSecureRequest(), 1134 requestContext.getLocale(), 1135 requestContext.getEncoding(), 1136 requestContext.getRemoteAddress(), 1137 System.currentTimeMillis(), 1138 m_resourceManager.getFolderTranslator(), 1139 m_resourceManager.getFileTranslator(), 1140 requestContext.getOuFqn(), 1141 requestContext.isForceAbsoluteLinks()); 1142 context.setDetailResource(requestContext.getDetailResource()); 1143 CmsObject result = new CmsObject(m_securityManager, context); 1144 return result; 1145 } 1146 1147 /** 1148 * Returns an initialized CmsObject with the user and context initialized as provided.<p> 1149 * 1150 * Note: Only if the provided <code>adminCms</code> CmsObject has admin permissions, 1151 * this method allows the creation a CmsObject for any existing user. Otherwise 1152 * only the default users 'Guest' and 'Export' can initialized with 1153 * this method, all other user names will throw an Exception.<p> 1154 * 1155 * @param adminCms must either be initialized with "Admin" permissions, or null 1156 * @param contextInfo the context info to create a CmsObject for 1157 * 1158 * @return an initialized CmsObject with the given users permissions 1159 * 1160 * @throws CmsException if an invalid user name was provided 1161 * @throws CmsRoleViolationException if the current user does not have the role permissions to create a context for the requested user 1162 * 1163 * @see org.opencms.db.CmsDefaultUsers#getUserGuest() 1164 * @see org.opencms.db.CmsDefaultUsers#getUserExport() 1165 * @see OpenCms#initCmsObject(CmsObject) 1166 * @see OpenCms#initCmsObject(CmsObject, CmsContextInfo) 1167 * @see OpenCms#initCmsObject(String) 1168 */ 1169 protected CmsObject initCmsObject(CmsObject adminCms, CmsContextInfo contextInfo) 1170 throws CmsRoleViolationException, CmsException { 1171 1172 String userName = contextInfo.getUserName(); 1173 1174 if ((adminCms == null) || !m_roleManager.hasRole(adminCms, CmsRole.ROOT_ADMIN)) { 1175 if (!userName.endsWith(getDefaultUsers().getUserGuest()) 1176 && !userName.endsWith(getDefaultUsers().getUserExport())) { 1177 1178 // if no admin object is provided, only "Guest" or "Export" user can be generated 1179 CmsMessageContainer message = Messages.get().container( 1180 Messages.ERR_INVALID_INIT_USER_2, 1181 userName, 1182 ((adminCms != null) ? (adminCms.getRequestContext().getCurrentUser().getName()) : "")); 1183 if (LOG.isWarnEnabled()) { 1184 LOG.warn(message.key()); 1185 } 1186 throw new CmsRoleViolationException(message); 1187 } 1188 } 1189 1190 return initCmsObject(contextInfo); 1191 } 1192 1193 /** 1194 * Handles the user authentification for each request sent to OpenCms.<p> 1195 * 1196 * User authentification is done in three steps: 1197 * <ol> 1198 * <li>Session authentification: OpenCms stores information of all authentificated 1199 * users in an internal storage based on the users session.</li> 1200 * <li>Authorization handler authentification: If the session authentification fails, 1201 * the current configured authorization handler is called.</li> 1202 * <li>Default user: When both authentification methods fail, the user is set to 1203 * the default (Guest) user.</li> 1204 * </ol> 1205 * 1206 * @param req the current http request 1207 * @param res the current http response 1208 * @param allowPrivilegedLogin <code>true</code> to allow login through authorization handlers 1209 * 1210 * @return the initialized cms context 1211 * 1212 * @throws IOException if user authentication fails 1213 * @throws CmsException in case something goes wrong 1214 */ 1215 protected CmsObject initCmsObject(HttpServletRequest req, HttpServletResponse res, boolean allowPrivilegedLogin) 1216 throws IOException, CmsException { 1217 1218 // first try to restore a stored session 1219 CmsObject cms = initCmsObjectFromSession(req); 1220 if (cms != null) { 1221 return cms; 1222 } 1223 if (allowPrivilegedLogin) { 1224 // if does not work, try to authorize the request 1225 I_CmsAuthorizationHandler.I_PrivilegedLoginAction loginAction = new I_CmsAuthorizationHandler.I_PrivilegedLoginAction() { 1226 1227 private CmsObject m_adminCms; 1228 1229 /** 1230 * @see org.opencms.security.I_CmsAuthorizationHandler.I_PrivilegedLoginAction#doLogin(javax.servlet.http.HttpServletRequest, java.lang.String) 1231 */ 1232 public CmsObject doLogin(HttpServletRequest request, String principal) throws CmsException { 1233 1234 try { 1235 CmsUser user = m_adminCms.readUser(principal); 1236 if (!user.isEnabled()) { 1237 throw new CmsException( 1238 Messages.get().container(Messages.ERR_INVALID_INIT_USER_2, user.getName(), "-")); 1239 } 1240 1241 // initialize the new cms object 1242 CmsContextInfo contextInfo = new CmsContextInfo(m_adminCms.getRequestContext()); 1243 contextInfo.setUserName(principal); 1244 CmsObject newCms = initCmsObject(m_adminCms, contextInfo); 1245 1246 if ((contextInfo.getRequestedUri().startsWith("/system/workplace/") 1247 // also check for new workplace 1248 || request.getRequestURI().startsWith(OpenCms.getSystemInfo().getWorkplaceContext())) 1249 && getRoleManager().hasRole(newCms, CmsRole.ELEMENT_AUTHOR)) { 1250 LOG.debug("Handling workplace login for user " + principal); 1251 CmsWorkplaceSettings settings = CmsLoginHelper.initSiteAndProject(newCms); 1252 request.getSession(true).setAttribute( 1253 CmsWorkplaceManager.SESSION_WORKPLACE_SETTINGS, 1254 settings); 1255 OpenCms.getSessionManager().updateSessionInfo(newCms, request); 1256 } 1257 m_adminCms.updateLastLoginDate(user); 1258 1259 // fire the login user event 1260 OpenCms.fireCmsEvent( 1261 I_CmsEventListener.EVENT_LOGIN_USER, 1262 Collections.<String, Object> singletonMap("data", user)); 1263 return newCms; 1264 } finally { 1265 m_adminCms = null; 1266 } 1267 } 1268 1269 /** 1270 * @see org.opencms.security.I_CmsAuthorizationHandler.I_PrivilegedLoginAction#getCmsObject() 1271 */ 1272 public CmsObject getCmsObject() { 1273 1274 return m_adminCms; 1275 } 1276 1277 /** 1278 * @see org.opencms.security.I_CmsAuthorizationHandler.I_PrivilegedLoginAction#setCmsObject(org.opencms.file.CmsObject) 1279 */ 1280 public void setCmsObject(CmsObject adminCms) { 1281 1282 m_adminCms = adminCms; 1283 } 1284 }; 1285 loginAction.setCmsObject(initCmsObject(req, res, OpenCms.getDefaultUsers().getUserAdmin(), null, null)); 1286 cms = m_authorizationHandler.initCmsObject(req, loginAction); 1287 if (cms != null) { 1288 return cms; 1289 } 1290 1291 // authentification failed or not enough permissions, so display a login screen 1292 m_authorizationHandler.requestAuthorization(req, res, getLoginFormURL(req, res)); 1293 } 1294 cms = initCmsObject( 1295 req, 1296 m_securityManager.readUser(null, OpenCms.getDefaultUsers().getUserGuest()), 1297 getSiteManager().matchRequest(req).getSiteRoot(), 1298 CmsProject.ONLINE_PROJECT_ID, 1299 ""); 1300 // return the initialized cms user context object 1301 return cms; 1302 } 1303 1304 /** 1305 * Returns an initialized CmsObject with the user initialized as provided, 1306 * with the "Online" project selected and "/" set as the current site root.<p> 1307 * 1308 * Note: Only the default users 'Guest' and 'Export' can initialized with 1309 * this method, all other user names will throw an Exception.<p> 1310 * 1311 * @param user the user name to initialize, can only be 1312 * {@link org.opencms.db.CmsDefaultUsers#getUserGuest()} or 1313 * {@link org.opencms.db.CmsDefaultUsers#getUserExport()} 1314 * 1315 * @return an initialized CmsObject with the given users permissions 1316 * 1317 * @throws CmsException if an invalid user name was provided, or if something else goes wrong 1318 * 1319 * @see org.opencms.db.CmsDefaultUsers#getUserGuest() 1320 * @see org.opencms.db.CmsDefaultUsers#getUserExport() 1321 * @see OpenCms#initCmsObject(String) 1322 * @see #initCmsObject(CmsObject, CmsContextInfo) 1323 */ 1324 protected CmsObject initCmsObject(String user) throws CmsException { 1325 1326 return initCmsObject(null, new CmsContextInfo(user)); 1327 } 1328 1329 /** 1330 * Initializes a new cms object from the session data of the request.<p> 1331 * 1332 * If no session data is found, <code>null</code> is returned.<p> 1333 * 1334 * @param req the request 1335 * 1336 * @return the new initialized cms object 1337 * 1338 * @throws CmsException if something goes wrong 1339 */ 1340 protected CmsObject initCmsObjectFromSession(HttpServletRequest req) throws CmsException { 1341 1342 String url = req.getRequestURL().toString(); 1343 String p = "[ " + url + " ] "; 1344 if (LOG.isDebugEnabled()) { 1345 LOG.debug(p + "Trying to init cms object from session for request \"" + req.toString() + "\"."); 1346 } 1347 // try to get an OpenCms user session info object for this request 1348 CmsSessionInfo sessionInfo = m_sessionManager.getSessionInfo(req); 1349 1350 if (sessionInfo == null) { 1351 if (LOG.isDebugEnabled()) { 1352 LOG.debug(p + "No session info found."); 1353 } 1354 return null; 1355 } 1356 if (!getSessionManager().hasValidClientToken(req)) { 1357 if (LOG.isDebugEnabled()) { 1358 LOG.debug("Client token in session invalid."); 1359 } 1360 return null; 1361 } 1362 1363 // initialize the requested site root 1364 CmsSite site = getSiteManager().matchRequest(req); 1365 1366 // a user name is found in the session manager, reuse this user information 1367 CmsUUID project = sessionInfo.getProject(); 1368 1369 // initialize site root from request 1370 String siteroot = sessionInfo.getSiteRoot(); 1371 if (siteroot == null) { 1372 // not sure if this can actually happen? 1373 LOG.debug(p + "site root from session info was null, determining site root from current request's host"); 1374 siteroot = site.getSiteRoot(); 1375 } 1376 // initialize user from request 1377 CmsUser user = m_securityManager.readUser(null, sessionInfo.getUserId()); 1378 1379 if (LOG.isDebugEnabled()) { 1380 LOG.debug(p + "Initializing cms object with user \"" + user.getName() + "\"."); 1381 LOG.debug(p + "siteRoot = " + siteroot); 1382 } 1383 return initCmsObject(req, user, siteroot, project, sessionInfo.getOrganizationalUnitFqn()); 1384 } 1385 1386 /** 1387 * Constructor to create a new OpenCms object.<p> 1388 * 1389 * It reads the configurations from the <code>opencms.properties</code> 1390 * file in the <code>config/</code> subdirectory. With the information 1391 * from this file is inits a ResourceBroker (Database access module), 1392 * various caching systems and other options.<p> 1393 * 1394 * This will only be done once per accessing class. 1395 * 1396 * @param configuration the configurations from the <code>opencms.properties</code> file 1397 * @throws CmsInitException in case OpenCms can not be initialized 1398 */ 1399 protected synchronized void initConfiguration(CmsParameterConfiguration configuration) throws CmsInitException { 1400 1401 String serverInfo = configuration.getString("context.servlet.container", null); 1402 1403 // output startup message to log file 1404 if (CmsLog.INIT.isInfoEnabled()) { 1405 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 1406 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 1407 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 1408 CmsLog.INIT.info( 1409 ". " 1410 + Messages.get().getBundle().key( 1411 Messages.GUI_SHELL_VERSION_1, 1412 OpenCms.getSystemInfo().getVersionNumber())); 1413 for (int i = 0; i < Messages.COPYRIGHT_BY_ALKACON.length; i++) { 1414 CmsLog.INIT.info(". " + Messages.COPYRIGHT_BY_ALKACON[i]); 1415 } 1416 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 1417 CmsLog.INIT.info( 1418 Messages.get().getBundle().key(Messages.INIT_STARTUP_TIME_1, new Date(System.currentTimeMillis()))); 1419 CmsLog.INIT.info( 1420 Messages.get().getBundle().key( 1421 Messages.INIT_OPENCMS_VERSION_1, 1422 OpenCms.getSystemInfo().getVersionNumber() + " [" + OpenCms.getSystemInfo().getVersionId() + "]")); 1423 if (serverInfo != null) { 1424 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SERVLET_CONTAINER_1, serverInfo)); 1425 } 1426 CmsLog.INIT.info( 1427 Messages.get().getBundle().key(Messages.INIT_WEBAPP_NAME_1, getSystemInfo().getWebApplicationName())); 1428 CmsLog.INIT.info( 1429 Messages.get().getBundle().key(Messages.INIT_SERVLET_PATH_1, getSystemInfo().getServletPath())); 1430 CmsLog.INIT.info( 1431 Messages.get().getBundle().key(Messages.INIT_OPENCMS_CONTEXT_1, getSystemInfo().getOpenCmsContext())); 1432 CmsLog.INIT.info( 1433 Messages.get().getBundle().key(Messages.INIT_WEBINF_PATH_1, getSystemInfo().getWebInfRfsPath())); 1434 CmsLog.INIT.info( 1435 Messages.get().getBundle().key( 1436 Messages.INIT_PROPERTY_FILE_1, 1437 getSystemInfo().getConfigurationFileRfsPath())); 1438 1439 String logFileRfsPath = getSystemInfo().getLogFileRfsPath(); 1440 CmsLog.INIT.info( 1441 Messages.get().getBundle().key( 1442 Messages.INIT_LOG_FILE_1, 1443 logFileRfsPath != null ? logFileRfsPath : "Managed by log4j")); 1444 } 1445 1446 String systemEncoding = null; 1447 try { 1448 systemEncoding = System.getProperty("file.encoding"); 1449 } catch (SecurityException se) { 1450 // security manager is active, but we will try other options before giving up 1451 LOG.debug("Security manager preventing access to file.encoding system property.", se); 1452 } 1453 try { 1454 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 1455 } catch (Exception e) { 1456 CmsLog.INIT.error(e.getLocalizedMessage(), e); 1457 } 1458 if (CmsLog.INIT.isInfoEnabled()) { 1459 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_FILE_ENCODING_1, systemEncoding)); 1460 } 1461 1462 // read server ethernet address (MAC) and init UUID generator 1463 String ethernetAddress = configuration.getString("server.ethernet.address", CmsStringUtil.getEthernetAddress()); 1464 if (CmsLog.INIT.isInfoEnabled()) { 1465 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_ETHERNET_ADDRESS_1, ethernetAddress)); 1466 } 1467 CmsUUID.init(ethernetAddress); 1468 1469 // set the server name 1470 String serverName = configuration.getString("server.name", "OpenCmsServer"); 1471 getSystemInfo().setServerName(serverName); 1472 1473 // check the installed Java SDK 1474 try { 1475 if (CmsLog.INIT.isInfoEnabled()) { 1476 String jdkinfo = System.getProperty("java.vm.name") + " "; 1477 jdkinfo += System.getProperty("java.vm.version") + " "; 1478 jdkinfo += System.getProperty("java.vm.info") + " "; 1479 jdkinfo += System.getProperty("java.vm.vendor") + " "; 1480 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_JAVA_VM_1, jdkinfo)); 1481 String osinfo = System.getProperty("os.name") + " "; 1482 osinfo += System.getProperty("os.version") + " "; 1483 osinfo += System.getProperty("os.arch") + " "; 1484 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_OPERATING_SYSTEM_1, osinfo)); 1485 } 1486 } catch (Exception e) { 1487 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_PROP_0), e); 1488 } 1489 1490 // create the configuration manager instance 1491 m_configurationManager = new CmsConfigurationManager(getSystemInfo().getConfigFolder()); 1492 // store the configuration read from "opencms.properties" in the configuration manager 1493 m_configurationManager.setConfiguration(configuration); 1494 1495 // now load the XML configuration 1496 try { 1497 m_configurationManager.loadXmlConfiguration(); 1498 } catch (Exception e) { 1499 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_XML_0), e); 1500 } 1501 1502 // get the system configuration 1503 CmsSystemConfiguration systemConfiguration = (CmsSystemConfiguration)m_configurationManager.getConfiguration( 1504 CmsSystemConfiguration.class); 1505 1506 if (systemConfiguration.useSaxImplSystemProperties()) { 1507 CmsXmlUtils.initSystemProperties(); 1508 } 1509 1510 // initialize the memory monitor 1511 CmsMemoryMonitorConfiguration memoryMonitorConfiguration = systemConfiguration.getCmsMemoryMonitorConfiguration(); 1512 // initialize the memory monitor 1513 try { 1514 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(memoryMonitorConfiguration.getClassName())) { 1515 m_memoryMonitor = (CmsMemoryMonitor)Class.forName( 1516 memoryMonitorConfiguration.getClassName()).newInstance(); 1517 } else { 1518 m_memoryMonitor = new CmsMemoryMonitor(); 1519 } 1520 } catch (Exception e) { 1521 // we can not start without a valid memory monitor 1522 throw new CmsInitException( 1523 Messages.get().container( 1524 Messages.ERR_CRITICAL_INIT_MEMORY_MONITOR_1, 1525 memoryMonitorConfiguration.getClassName()), 1526 e); 1527 } 1528 m_memoryMonitor.initialize(systemConfiguration); 1529 1530 // get the event manager from the configuration and initialize it with the events already registered 1531 CmsEventManager configuredEventManager = systemConfiguration.getEventManager(); 1532 configuredEventManager.initialize(m_eventManager); 1533 m_eventManager = configuredEventManager; 1534 1535 // check if the encoding setting is valid 1536 String setEncoding = systemConfiguration.getDefaultContentEncoding(); 1537 String defaultEncoding = CmsEncoder.lookupEncoding(setEncoding, null); 1538 if (defaultEncoding == null) { 1539 // we can not start without a valid encoding setting 1540 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_ENCODING_1, setEncoding)); 1541 } 1542 if (CmsLog.INIT.isInfoEnabled()) { 1543 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_OPENCMS_ENCODING_1, defaultEncoding)); 1544 } 1545 getSystemInfo().setDefaultEncoding(defaultEncoding); 1546 1547 // set version history information 1548 getSystemInfo().setVersionHistorySettings( 1549 systemConfiguration.isHistoryEnabled(), 1550 systemConfiguration.getHistoryVersions(), 1551 systemConfiguration.getHistoryVersionsAfterDeletion()); 1552 // set mail configuration 1553 getSystemInfo().setMailSettings(systemConfiguration.getMailSettings()); 1554 // set HTTP authentication settings 1555 getSystemInfo().setHttpAuthenticationSettings(systemConfiguration.getHttpAuthenticationSettings()); 1556 getSystemInfo().setRestrictDetailContents(systemConfiguration.isRestrictDetailContents()); 1557 1558 // set content notification settings 1559 getSystemInfo().setNotificationTime(systemConfiguration.getNotificationTime()); 1560 getSystemInfo().setNotificationProject(systemConfiguration.getNotificationProject()); 1561 m_executor = new ScheduledThreadPoolExecutor( 1562 3, 1563 new ThreadFactoryBuilder().setNameFormat("OpenCmsCore-exec-%d").build()); 1564 // set resource init classes 1565 m_resourceInitHandlers = systemConfiguration.getResourceInitHandlers(); 1566 1567 // register request handler classes 1568 Iterator<I_CmsRequestHandler> it = systemConfiguration.getRequestHandlers().iterator(); 1569 while (it.hasNext()) { 1570 I_CmsRequestHandler handler = it.next(); 1571 addRequestHandler(handler); 1572 if (CmsLog.INIT.isInfoEnabled()) { 1573 CmsLog.INIT.info( 1574 Messages.get().getBundle().key( 1575 Messages.INIT_REQUEST_HANDLER_CLASS_1, 1576 handler.getClass().getName())); 1577 } 1578 } 1579 1580 // read the default user configuration 1581 m_defaultUsers = systemConfiguration.getCmsDefaultUsers(); 1582 1583 // get the site manager from the configuration 1584 CmsSitesConfiguration sitesConfiguration = (CmsSitesConfiguration)m_configurationManager.getConfiguration( 1585 CmsSitesConfiguration.class); 1586 m_siteManager = sitesConfiguration.getSiteManager(); 1587 1588 CmsSchedulerConfiguration schedulerConfiguration = (CmsSchedulerConfiguration)m_configurationManager.getConfiguration( 1589 CmsSchedulerConfiguration.class); 1590 // set the scheduler manager 1591 m_scheduleManager = schedulerConfiguration.getScheduleManager(); 1592 1593 CmsVariablesConfiguration variablesConfiguration = (CmsVariablesConfiguration)m_configurationManager.getConfiguration( 1594 CmsVariablesConfiguration.class); 1595 1596 // get the VFS / resource configuration 1597 CmsVfsConfiguration vfsConfiguation = (CmsVfsConfiguration)m_configurationManager.getConfiguration( 1598 CmsVfsConfiguration.class); 1599 m_resourceManager = vfsConfiguation.getResourceManager(); 1600 m_xmlContentTypeManager = vfsConfiguation.getXmlContentTypeManager(); 1601 m_defaultFiles = vfsConfiguation.getDefaultFiles(); 1602 1603 // initialize translation engines 1604 m_resourceManager.setTranslators( 1605 vfsConfiguation.getFolderTranslator(), 1606 vfsConfiguation.getFileTranslator(), 1607 vfsConfiguation.getXsdTranslator()); 1608 1609 // try to initialize the flex cache 1610 CmsFlexCache flexCache = null; 1611 try { 1612 if (CmsLog.INIT.isInfoEnabled()) { 1613 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_FLEX_CACHE_STARTING_0)); 1614 } 1615 // get the flex cache configuration from the SystemConfiguration 1616 CmsFlexCacheConfiguration flexCacheConfiguration = systemConfiguration.getCmsFlexCacheConfiguration(); 1617 getSystemInfo().setDeviceSelector(flexCacheConfiguration.getDeviceSelector()); 1618 // pass configuration to flex cache for initialization 1619 flexCache = new CmsFlexCache(flexCacheConfiguration); 1620 m_flexCache = flexCache; 1621 if (CmsLog.INIT.isInfoEnabled()) { 1622 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_FLEX_CACHE_FINISHED_0)); 1623 } 1624 } catch (Exception e) { 1625 if (CmsLog.INIT.isWarnEnabled()) { 1626 CmsLog.INIT.warn(Messages.get().getBundle().key(Messages.INIT_FLEX_CACHE_ERROR_1, e.getMessage())); 1627 } 1628 } 1629 1630 if (flexCache != null) { 1631 // check all resource loaders if they require the Flex cache 1632 Iterator<I_CmsResourceLoader> i = m_resourceManager.getLoaders().iterator(); 1633 while (i.hasNext()) { 1634 Object o = i.next(); 1635 if (o instanceof I_CmsFlexCacheEnabledLoader) { 1636 // this resource loader requires the Flex cache 1637 ((I_CmsFlexCacheEnabledLoader)o).setFlexCache(flexCache); 1638 } 1639 } 1640 } 1641 1642 // get the import/export configuration 1643 CmsImportExportConfiguration importExportConfiguration = (CmsImportExportConfiguration)m_configurationManager.getConfiguration( 1644 CmsImportExportConfiguration.class); 1645 m_importExportManager = importExportConfiguration.getImportExportManager(); 1646 m_staticExportManager = importExportConfiguration.getStaticExportManager(); 1647 m_repositoryManager = importExportConfiguration.getRepositoryManager(); 1648 1649 // get the search configuration 1650 CmsSearchConfiguration searchConfiguration = (CmsSearchConfiguration)m_configurationManager.getConfiguration( 1651 CmsSearchConfiguration.class); 1652 m_searchManager = searchConfiguration.getSearchManager(); 1653 1654 // get the workplace configuration 1655 CmsWorkplaceConfiguration workplaceConfiguration = (CmsWorkplaceConfiguration)m_configurationManager.getConfiguration( 1656 CmsWorkplaceConfiguration.class); 1657 m_workplaceManager = workplaceConfiguration.getWorkplaceManager(); 1658 // add the export points from the workplace 1659 addExportPoints(m_workplaceManager.getExportPoints()); 1660 addExportPoints(m_staticExportManager.getExportPoints()); 1661 1662 // get the module configuration 1663 CmsModuleConfiguration moduleConfiguration = (CmsModuleConfiguration)m_configurationManager.getConfiguration( 1664 CmsModuleConfiguration.class); 1665 m_moduleManager = moduleConfiguration.getModuleManager(); 1666 1667 // get the password handler 1668 m_passwordHandler = systemConfiguration.getPasswordHandler(); 1669 1670 // get the validation handler 1671 m_validationHandler = systemConfiguration.getValidationHandler(); 1672 1673 // get the authorization handler 1674 m_authorizationHandler = systemConfiguration.getAuthorizationHandler(); 1675 1676 // get the login manager 1677 m_loginManager = systemConfiguration.getLoginManager(); 1678 // set the login message 1679 try { 1680 m_loginManager.setLoginMessage(null, variablesConfiguration.getLoginMessage()); 1681 m_loginManager.setBeforeLoginMessage(null, variablesConfiguration.getBeforeLoginMessage()); 1682 } catch (CmsRoleViolationException e1) { 1683 CmsLog.INIT.error(e1.getLocalizedMessage(), e1); 1684 } 1685 1686 // initialize the publish engine 1687 m_publishEngine = new CmsPublishEngine(systemConfiguration.getRuntimeInfoFactory()); 1688 1689 // Credentials resolver - needs to be set before the driver manager is initialized 1690 m_credentialsResolver = systemConfiguration.getCredentialsResolver(); 1691 1692 // init the OpenCms security manager 1693 m_securityManager = CmsSecurityManager.newInstance( 1694 m_configurationManager, 1695 systemConfiguration.getRuntimeInfoFactory(), 1696 m_publishEngine); 1697 1698 // get the publish manager 1699 m_publishManager = systemConfiguration.getPublishManager(); 1700 1701 // get the subscription manager 1702 m_subscriptionManager = systemConfiguration.getSubscriptionManager(); 1703 1704 // initialize the role manager 1705 m_roleManager = new CmsRoleManager(m_securityManager); 1706 1707 // initialize the organizational unit manager 1708 m_orgUnitManager = new CmsOrgUnitManager(m_securityManager); 1709 1710 // initialize the Thread store 1711 m_threadStore = new CmsThreadStore(m_securityManager); 1712 1713 // initialize the link manager 1714 m_linkManager = new CmsLinkManager(m_staticExportManager.getLinkSubstitutionHandler()); 1715 1716 m_aliasManager = new CmsAliasManager(m_securityManager); 1717 1718 // store the runtime properties 1719 m_runtimeProperties.putAll(systemConfiguration.getRuntimeProperties()); 1720 1721 // initialize the session storage provider 1722 I_CmsSessionStorageProvider sessionStorageProvider = systemConfiguration.getSessionStorageProvider(); 1723 1724 // get an Admin cms context object with site root set to "/" 1725 CmsObject adminCms; 1726 try { 1727 adminCms = initCmsObject(null, null, getDefaultUsers().getUserAdmin(), (String)null, (String)null); 1728 } catch (CmsException e) { 1729 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_ADMINCMS_0), e); 1730 } 1731 m_configAdminCms = adminCms; 1732 1733 m_repositoryManager.initializeCms(adminCms); 1734 // now initialize the other managers 1735 try { 1736 if (flexCache != null) { 1737 flexCache.initializeCms(initCmsObject(adminCms)); 1738 } 1739 1740 m_configurationManager.setAdminCms(adminCms); 1741 1742 // initialize the scheduler 1743 m_scheduleManager.initialize(initCmsObject(adminCms)); 1744 1745 // initialize the locale manager 1746 m_localeManager = systemConfiguration.getLocaleManager(); 1747 m_localeManager.initialize(initCmsObject(adminCms)); 1748 1749 // initialize the site manager 1750 m_siteManager.initialize(initCmsObject(adminCms)); 1751 1752 // initialize the static export manager 1753 m_staticExportManager.initialize(initCmsObject(adminCms)); 1754 1755 // initialize the XML content type manager 1756 m_xmlContentTypeManager.initialize(initCmsObject(adminCms)); 1757 1758 m_orgUnitManager.initialize(initCmsObject(adminCms)); 1759 1760 // initialize the module manager 1761 m_moduleManager.initialize(initCmsObject(adminCms), m_configurationManager); 1762 1763 // initialize the resource manager 1764 m_resourceManager.initialize(initCmsObject(adminCms)); 1765 1766 // initialize the publish manager 1767 m_publishManager.setPublishEngine(m_publishEngine); 1768 m_publishManager.setSecurityManager(m_securityManager); 1769 m_publishManager.setPublishListRemoveMode(systemConfiguration.getPublishListRemoveMode()); 1770 m_publishManager.initialize(initCmsObject(adminCms)); 1771 1772 // initialize the search manager 1773 m_searchManager.initialize(initCmsObject(adminCms)); 1774 1775 // initialize the VFS bundle manager 1776 m_vfsBundleManager = new CmsVfsBundleManager(adminCms); 1777 1778 // initialize the workplace manager 1779 m_workplaceManager.initialize(initCmsObject(adminCms)); 1780 1781 // initialize the session manager 1782 m_sessionManager.initialize(sessionStorageProvider, initCmsObject(adminCms)); 1783 m_sessionManager.setUserSessionMode(systemConfiguration.getUserSessionMode(true)); 1784 1785 // initialize the subscription manager 1786 m_subscriptionManager.setSecurityManager(m_securityManager); 1787 m_subscriptionManager.initialize(adminCms); 1788 1789 CmsUgcSessionFactory.setAdminCms(adminCms); 1790 1791 // initialize the formatter configuration 1792 CmsFormatterConfiguration.initialize(adminCms); 1793 CmsPersistentLoginTokenHandler.setAdminCms(initCmsObject(adminCms)); 1794 CmsLoginUI.setAdminCmsObject(initCmsObject(adminCms)); 1795 1796 // initialize ade manager 1797 m_adeManager = new CmsADEManager(initCmsObject(adminCms), m_memoryMonitor, systemConfiguration); 1798 m_workplaceAppManager = new CmsWorkplaceAppManager(initCmsObject(adminCms)); 1799 m_workplaceAppManager.loadApps(); 1800 m_workplaceAppManager.initWorkplaceCssUris(m_moduleManager); 1801 1802 m_templateContextManager = new CmsTemplateContextManager(initCmsObject(adminCms)); 1803 m_workflowManager = systemConfiguration.getWorkflowManager(); 1804 m_letsEncryptConfig = systemConfiguration.getLetsEncryptConfig(); 1805 1806 m_userDataRequestManager = systemConfiguration.getUserDataRequestManager(); 1807 if (m_userDataRequestManager != null) { 1808 m_userDataRequestManager.initialize(initCmsObject(adminCms)); 1809 } 1810 1811 if (m_workflowManager == null) { 1812 m_workflowManager = new CmsDefaultWorkflowManager(); 1813 m_workflowManager.setParameters(new HashMap<String, String>()); 1814 } 1815 1816 m_remoteShellServer = CmsRemoteShellServer.initialize(systemConfiguration); 1817 1818 CmsPublishScheduledDialog.setAdminCms(initCmsObject(adminCms)); 1819 1820 m_workflowManager.initialize(initCmsObject(adminCms)); 1821 m_apiAuthorizations = systemConfiguration.getApiAuthorizations(); 1822 for (I_CmsApiAuthorizationHandler apiAuthorization : m_apiAuthorizations.values()) { 1823 apiAuthorization.initialize(initCmsObject(adminCms)); 1824 } 1825 1826 for (I_CmsResourceInit resourceInit : m_resourceInitHandlers) { 1827 if (resourceInit instanceof I_CmsNeedsAdminCmsObject) { 1828 ((I_CmsNeedsAdminCmsObject)resourceInit).setAdminCmsObject(adminCms); 1829 } 1830 } 1831 for (I_CmsRequestHandler requestHandler : m_requestHandlers.values()) { 1832 if (requestHandler instanceof I_CmsNeedsAdminCmsObject) { 1833 ((I_CmsNeedsAdminCmsObject)requestHandler).setAdminCmsObject(adminCms); 1834 } 1835 } 1836 1837 m_textEncryptions = new LinkedHashMap<>(); 1838 for (I_CmsTextEncryption encryption : systemConfiguration.getTextEncryptions().values()) { 1839 encryption.initialize(OpenCms.initCmsObject(adminCms)); 1840 m_textEncryptions.put(encryption.getName(), encryption); 1841 } 1842 1843 m_twoFactorAuthenticationHandler = new CmsTwoFactorAuthenticationHandler( 1844 OpenCms.initCmsObject(adminCms), 1845 systemConfiguration.getTwoFactorAuthenticationConfig()); 1846 1847 } catch (CmsException e) { 1848 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_MANAGERS_0), e); 1849 } 1850 1851 try { 1852 // mitigate potential stringtemplate 3 class loading deadlock by making sure the class is loaded on startup 1853 @SuppressWarnings("unused") 1854 StringTemplate stringTemplate = new org.antlr.stringtemplate.StringTemplate(); 1855 } catch (Exception e) { 1856 CmsLog.INIT.error("Problem with initializing stringtemplate class: " + e.getLocalizedMessage(), e); 1857 } 1858 1859 try { 1860 getEventManager().fireEvent(I_CmsEventListener.EVENT_CLEAR_CACHES); 1861 } catch (Exception e) { 1862 CmsLog.INIT.error("Problem with clearing caches after initialization: " + e.getLocalizedMessage(), e); 1863 } 1864 CmsTaskWatcher.initialize(); 1865 } 1866 1867 /** 1868 * Initialization of the OpenCms runtime environment.<p> 1869 * 1870 * The connection information for the database is read 1871 * from the <code>opencms.properties</code> configuration file and all 1872 * driver manager are initialized via the initializer, 1873 * which usually will be an instance of a <code>OpenCms</code> class. 1874 * 1875 * @param context configuration of OpenCms from <code>web.xml</code> 1876 * @throws CmsInitException in case OpenCms can not be initialized 1877 */ 1878 protected synchronized void initContext(ServletContext context) throws CmsInitException { 1879 1880 m_gwtServiceContexts = new HashMap<String, CmsGwtServiceContext>(); 1881 1882 // automatic servlet container recognition and specific behavior: 1883 CmsServletContainerSettings servletContainerSettings = new CmsServletContainerSettings(context); 1884 getSystemInfo().init(servletContainerSettings); 1885 1886 // Collect the configurations 1887 CmsParameterConfiguration configuration; 1888 try { 1889 configuration = new CmsParameterConfiguration(getSystemInfo().getConfigurationFileRfsPath()); 1890 } catch (Exception e) { 1891 throw new CmsInitException( 1892 Messages.get().container( 1893 Messages.ERR_CRITICAL_INIT_PROPFILE_1, 1894 getSystemInfo().getConfigurationFileRfsPath()), 1895 e); 1896 } 1897 1898 String throwException = configuration.getString("servlet.exception.enabled", "auto"); 1899 if (!throwException.equals("auto")) { 1900 // set the parameter is not automatic, the rest of the servlet container dependent parameters 1901 // will be set when reading the system configuration, if not set to auto 1902 boolean throwExc = Boolean.valueOf(throwException).booleanValue(); 1903 getSystemInfo().getServletContainerSettings().setServletThrowsException(throwExc); 1904 } 1905 1906 // check if the wizard is enabled, if so stop initialization 1907 if (configuration.getBoolean("wizard.enabled", true)) { 1908 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_WIZARD_0)); 1909 } 1910 1911 // add an indicator that the configuration was processed from the servlet context 1912 configuration.add("context.servlet.container", context.getServerInfo()); 1913 1914 // output startup message and copyright to STDERR 1915 System.err.println( 1916 Messages.get().getBundle().key( 1917 Messages.LOG_STARTUP_CONSOLE_NOTE_2, 1918 OpenCms.getSystemInfo().getVersionNumber(), 1919 getSystemInfo().getWebApplicationName())); 1920 for (int i = 0; i < Messages.COPYRIGHT_BY_ALKACON.length; i++) { 1921 System.err.println(Messages.COPYRIGHT_BY_ALKACON[i]); 1922 } 1923 System.err.println(); 1924 1925 // initialize the configuration 1926 initConfiguration(configuration); 1927 } 1928 1929 /** 1930 * Initialize member variables.<p> 1931 */ 1932 protected void initMembers() { 1933 1934 synchronized (LOCK) { 1935 m_resourceInitHandlers = new ArrayList<I_CmsResourceInit>(); 1936 m_requestHandlers = new HashMap<String, I_CmsRequestHandler>(); 1937 m_systemInfo = new CmsSystemInfo(); 1938 m_exportPoints = Collections.emptySet(); 1939 m_defaultUsers = new CmsDefaultUsers(); 1940 m_localeManager = new CmsLocaleManager(Locale.ENGLISH); 1941 m_sessionManager = new CmsSessionManager(); 1942 m_runtimeProperties = new Hashtable<Object, Object>(); 1943 // the default event manager must be available because the configuration already registers events 1944 m_eventManager = new CmsEventManager(); 1945 // default link manager is required for test cases 1946 m_linkManager = new CmsLinkManager(new CmsDefaultLinkSubstitutionHandler()); 1947 } 1948 } 1949 1950 /** 1951 * Reads the requested resource from the OpenCms VFS, 1952 * in case a directory name is requested, the default files of the 1953 * directory will be looked up and the first match is returned.<p> 1954 * 1955 * The resource that is returned is always a <code>{@link org.opencms.file.CmsFile}</code>, 1956 * even though the content will usually not be loaded in the result. Folders are never returned since 1957 * the point of this method is really to load the default file if just a folder name is requested. If 1958 * there is no default file in a folder, then the return value is null and no CmsException is thrown.<p> 1959 * 1960 * The URI stored in the given OpenCms user context will be changed to the URI of the resource 1961 * that was found and returned.<p> 1962 * 1963 * Implementing and configuring an <code>{@link I_CmsResourceInit}</code> handler 1964 * allows to customize the process of default resource selection.<p> 1965 * 1966 * @param cms the current users OpenCms context 1967 * @param resourceName the path of the requested resource in the OpenCms VFS 1968 * @param req the current http request 1969 * @param res the current http response 1970 * 1971 * @return the requested resource read from the VFS 1972 * 1973 * @throws CmsException in case the requested file does not exist or the user has insufficient access permissions 1974 * 1975 * @see OpenCms#initResource(CmsObject, String, HttpServletRequest, HttpServletResponse) 1976 */ 1977 protected CmsResource initResource( 1978 CmsObject cms, 1979 String resourceName, 1980 HttpServletRequest req, 1981 HttpServletResponse res) 1982 throws CmsException { 1983 1984 CmsException tmpException = null; 1985 CmsResource resource; 1986 boolean handledSecure = false; 1987 1988 try { 1989 // try to read the requested resource 1990 resource = cms.readDefaultFile(resourceName, CmsResourceFilter.ignoreExpirationOffline(cms)); 1991 } catch (CmsException e) { 1992 // file or folder with given name does not exist, store exception 1993 tmpException = e; 1994 resource = null; 1995 } 1996 1997 if (resource != null) { 1998 // set the request uri to the right file 1999 cms.getRequestContext().setUri(cms.getSitePath(resource)); 2000 // test if this file is only available for internal access operations 2001 if (resource.isInternalOrInInternalFolder()) { 2002 throw new CmsException( 2003 Messages.get().container(Messages.ERR_READ_INTERNAL_RESOURCE_1, cms.getRequestContext().getUri())); 2004 } 2005 2006 resource = handleSecureResource(cms, req, res, resource, resourceName); 2007 if (resource == null) { 2008 handledSecure = true; 2009 2010 } 2011 } 2012 2013 boolean clearErrors = false; 2014 // test if this file has to be checked or modified 2015 for (I_CmsResourceInit handler : m_resourceInitHandlers) { 2016 try { 2017 resource = handler.initResource(resource, cms, req, res); 2018 // the loop has to be interrupted when the exception is thrown! 2019 } catch (CmsResourceInitException e) { 2020 if (e.isClearErrors()) { 2021 tmpException = null; 2022 clearErrors = true; 2023 } 2024 break; 2025 } catch (CmsSecurityException e) { 2026 tmpException = e; 2027 break; 2028 } 2029 } 2030 2031 // file is still null and not found exception was thrown, so throw original exception 2032 if (resource == null) { 2033 if (tmpException != null) { 2034 throw tmpException; 2035 } else if (!clearErrors) { 2036 throw new CmsVfsResourceNotFoundException( 2037 org.opencms.main.Messages.get().container( 2038 org.opencms.main.Messages.ERR_PATH_NOT_FOUND_1, 2039 resourceName)); 2040 2041 } 2042 } else { 2043 if (!handledSecure) { 2044 if (cms.getRequestContext().getDetailContentId() != null) { 2045 // in theory we should do this for all kinds of resource init handlers, 2046 // but I'm not clear on how to handle this in general, so only do this for detail pages for now 2047 resource = handleSecureResource(cms, req, res, resource, resourceName); 2048 handledSecure = true; 2049 } 2050 } 2051 } 2052 2053 // return the resource read from the VFS 2054 return resource; 2055 } 2056 2057 /** 2058 * Initializes the system with the OpenCms servlet.<p> 2059 * 2060 * This is the final step that is called on the servlets "init()" method. 2061 * It registers the servlets request handler and also outputs the final 2062 * startup message. The servlet should auto-load since the <load-on-startup> 2063 * parameter is set in the 'web.xml' by default.<p> 2064 * 2065 * @param servlet the OpenCms servlet 2066 */ 2067 protected void initServlet(OpenCmsServlet servlet) { 2068 2069 synchronized (LOCK) { 2070 // add the servlets request handler 2071 addRequestHandler(servlet); 2072 2073 // output the final 'startup is finished' message 2074 if (CmsLog.INIT.isInfoEnabled()) { 2075 CmsLog.INIT.info( 2076 Messages.get().getBundle().key( 2077 Messages.INIT_SYSTEM_RUNNING_1, 2078 CmsStringUtil.formatRuntime(getSystemInfo().getRuntime()))); 2079 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 2080 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2081 } 2082 } 2083 } 2084 2085 /** 2086 * Handler for built-in AJAX services that don't belong anywhere else and don't deserve their own request handler. 2087 * 2088 * @param remainingPath the remainder of the path after /handleBuiltinService 2089 * @param req the current request 2090 * @param res the current response 2091 * 2092 * @throws ServletException if something goes wrong 2093 */ 2094 protected void invokeBuiltinService(String remainingPath, HttpServletRequest req, HttpServletResponse res) 2095 throws ServletException { 2096 2097 try { 2098 CmsObject cms = initCmsObject(req, res); 2099 if (CmsGwtConstants.HANDLER_UNLOCK_PAGE.equals(remainingPath)) { 2100 CmsContainerpageService.unlockPage(cms, req, res); 2101 } else if (CmsGwtConstants.HANDLER_UPDATE_SESSION.equals(remainingPath)) { 2102 // Count this as a heartbeat request, because it's not caused by user activity 2103 boolean isHeartbeatRequest = true; 2104 OpenCms.getSessionManager().updateSessionInfo(cms, req, isHeartbeatRequest); 2105 } else if (remainingPath.startsWith(CmsGwtConstants.UNLOCK_FILE_PREFIX)) { 2106 String idStr = remainingPath.substring(CmsGwtConstants.UNLOCK_FILE_PREFIX.length()); 2107 try { 2108 cms.unlockResource(cms.readResource(new CmsUUID(idStr), CmsResourceFilter.ALL)); 2109 } catch (Exception e) { 2110 LOG.debug(e.getLocalizedMessage(), e); 2111 } 2112 } 2113 } catch (Exception e) { 2114 LOG.error(e.getLocalizedMessage(), e); 2115 throw new ServletException(e); 2116 } 2117 } 2118 2119 /** 2120 * Invokes the GWT servlet from within OpenCms.<p> 2121 * 2122 * @param serviceName the GWT PRC service class name 2123 * @param req the current servlet request 2124 * @param res the current servlet response 2125 * @param servletConfig the servlet configuration 2126 */ 2127 protected void invokeGwtService( 2128 String serviceName, 2129 HttpServletRequest req, 2130 HttpServletResponse res, 2131 ServletConfig servletConfig) { 2132 2133 CmsObject cms = null; 2134 try { 2135 // instantiate CMS context 2136 cms = initCmsObject(req, res); 2137 // instantiate GWT RPC service 2138 CmsGwtService rpcService = getGwtService(serviceName, servletConfig); 2139 // check permissions 2140 rpcService.checkPermissions(cms); 2141 String rpcContextStr = req.getHeader("X-OcmsRpcContext"); 2142 if (rpcContextStr == null) { 2143 rpcContextStr = "{}"; 2144 } 2145 // This makes the container page uri available in all RPC calls originating from the container page editor 2146 JSONObject rpcContext = new JSONObject(rpcContextStr); 2147 String pageIdStr = rpcContext.optString(CmsGwtConstants.RpcContext.PAGE_ID); 2148 CmsResource page = null; 2149 if (CmsUUID.isValidUUID(pageIdStr)) { 2150 try { 2151 page = cms.readResource(new CmsUUID(pageIdStr), CmsResourceFilter.IGNORE_EXPIRATION); 2152 } catch (Exception e) { 2153 LOG.error("Page id " + pageIdStr + " is unreadable: " + e.getLocalizedMessage(), e); 2154 } 2155 } 2156 if (page != null) { 2157 cms.getRequestContext().setUri(cms.getSitePath(page)); 2158 cms.getRequestContext().setAttribute(CmsRequestContext.ATTRIBUTE_ADE_CONTEXT_PATH, page.getRootPath()); 2159 } 2160 2161 // set runtime variables 2162 rpcService.setCms(cms); 2163 Object lock = req.getSession(); 2164 if (lock == null) { 2165 lock = new Object(); 2166 } 2167 rpcService.service(req, res); 2168 m_sessionManager.updateSessionInfo(cms, req, rpcService.isBroadcastCall()); 2169 } catch (CmsRoleViolationException rv) { 2170 // don't log these into the error channel 2171 LOG.debug(rv.getLocalizedMessage(), rv); 2172 // error code not set - set "unauthorized error" (401) 2173 int status = HttpServletResponse.SC_UNAUTHORIZED; 2174 res.setStatus(status); 2175 try { 2176 res.sendError(status, rv.toString()); 2177 } catch (IOException e) { 2178 // can be ignored 2179 LOG.error(e.getLocalizedMessage(), e); 2180 } 2181 } catch (Throwable t) { 2182 // error code not set - set "internal server error" (500) 2183 LOG.error(t.getLocalizedMessage(), t); 2184 int status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; 2185 res.setStatus(status); 2186 try { 2187 res.sendError(status, t.toString()); 2188 } catch (IOException e) { 2189 // can be ignored 2190 LOG.error(e.getLocalizedMessage(), e); 2191 } 2192 } 2193 } 2194 2195 /** 2196 * This method adds an Object to the OpenCms runtime properties. 2197 * The runtime properties can be used to store Objects that are shared 2198 * in the whole system.<p> 2199 * 2200 * @param key the key to add the Object with 2201 * @param value the value of the Object to add 2202 */ 2203 protected void setRuntimeProperty(Object key, Object value) { 2204 2205 m_runtimeProperties.put(key, value); 2206 } 2207 2208 /** 2209 * Displays a resource from the OpenCms by writing the result to the provided 2210 * Servlet response output stream.<p> 2211 * 2212 * @param req the current servlet request 2213 * @param res the current servlet response 2214 */ 2215 protected void showResource(HttpServletRequest req, HttpServletResponse res) { 2216 2217 CmsObject cms = null; 2218 try { 2219 cms = initCmsObject(req, res); 2220 Map<String, String> logInfo = new HashMap<>(); 2221 logInfo.put("cms_siteroot", cms.getRequestContext().getSiteRoot()); 2222 logInfo.put("cms_project", cms.getRequestContext().getCurrentProject().getName()); 2223 try (CloseableThreadContext.Instance threadContext = CloseableThreadContext.putAll(logInfo)) { 2224 LOG.info("Updating log context: " + logInfo); 2225 String uri = cms.getRequestContext().getUri(); 2226 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 2227 2228 if (uri.startsWith(CmsWorkplace.VFS_PATH_SITES)) { 2229 // resources within the sites folder may only be called with their site relative path 2230 // this should prevent showing pages from other sites with their root path 2231 throw new CmsVfsResourceNotFoundException( 2232 org.opencms.main.Messages.get().container( 2233 org.opencms.main.Messages.ERR_PATH_NOT_FOUND_1, 2234 uri)); 2235 } 2236 if (OpenCms.getStaticExportManager().isExportLink(cms, uri)) { 2237 // if we used the request's query string for getRfsName, clients could cause an unlimited number 2238 // of files to be exported just by varying the request parameters! 2239 String url = m_linkManager.getOnlineLink(cms, uri); 2240 res.sendRedirect(url); 2241 return; 2242 } 2243 } 2244 List<CmsSiteMatcher> currentSiteAliases = m_siteManager.getCurrentSite(cms).getAliases(); 2245 CmsSiteMatcher currentSiteMatcher = cms.getRequestContext().getRequestMatcher(); 2246 if (currentSiteAliases.contains(currentSiteMatcher.forDifferentScheme("http")) 2247 || currentSiteAliases.contains(currentSiteMatcher.forDifferentScheme("https"))) { 2248 int pos = currentSiteAliases.indexOf(currentSiteMatcher.forDifferentScheme("http")); 2249 if (pos == -1) { 2250 pos = currentSiteAliases.indexOf(currentSiteMatcher.forDifferentScheme("https")); 2251 } 2252 switch (currentSiteAliases.get(pos).getRedirectMode()) { 2253 case none: 2254 break; 2255 case temporary: 2256 res.sendRedirect( 2257 m_siteManager.getCurrentSite(cms).getUrl() + req.getContextPath() + req.getPathInfo()); 2258 return; 2259 case permanent: 2260 res.setHeader( 2261 CmsRequestUtil.HEADER_LOCATION, 2262 m_siteManager.getCurrentSite(cms).getUrl() + req.getContextPath() + req.getPathInfo()); 2263 res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); 2264 return; 2265 default: 2266 break; 2267 } 2268 } 2269 2270 // user is initialized, now deliver the requested resource 2271 CmsResource resource = initResource(cms, cms.getRequestContext().getUri(), req, res); 2272 2273 // a resource init handler may use its own authentication, but return a resource to be loaded instead of handling the complete request processing by itself. 2274 // For this case, a request context attribute is used to pass the CmsObject that should be used for loading the resource. 2275 2276 Object alternativeCmsObject = cms.getRequestContext().removeAttribute( 2277 I_CmsResourceInit.ATTR_ALTERNATIVE_CMS_OBJECT); 2278 CmsObject cmsForLoad = cms; 2279 if (alternativeCmsObject instanceof CmsObject) { 2280 // we know it's not null at this point 2281 cmsForLoad = (CmsObject)alternativeCmsObject; 2282 } 2283 if (resource != null) { 2284 boolean forceAbsoluteLinks = checkForceAbsoluteLinks(req, cms, resource); 2285 cms.getRequestContext().setForceAbsoluteLinks(forceAbsoluteLinks); 2286 2287 // a file was read, go on process it 2288 m_resourceManager.loadResource(cmsForLoad, resource, req, res); 2289 if (cmsForLoad == cms) { 2290 // if we used a different CmsObject, we don't want to update the session with either 2291 // CmsObject - it's not necessary to do it for the original CmsObject, and using the alternative CmsObject 2292 // if there is already a session would switch the session user to the one of that CmsObject. We don't 2293 // want that, since the primary use case for the alternative CmsObject mechanism is 'stateless' authentication 2294 // for resource init handlers. 2295 m_sessionManager.updateSessionInfo(cms, req); 2296 } 2297 } 2298 } 2299 2300 } catch ( 2301 2302 Throwable t) { 2303 errorHandling(cms, req, res, t); 2304 } 2305 } 2306 2307 /** 2308 * Destroys this OpenCms instance, called if the servlet (or shell) is shut down.<p> 2309 */ 2310 protected void shutDown() { 2311 2312 synchronized (LOCK) { 2313 if (getRunLevel() > OpenCms.RUNLEVEL_0_OFFLINE) { 2314 System.err.println( 2315 Messages.get().getBundle().key( 2316 Messages.LOG_SHUTDOWN_CONSOLE_NOTE_2, 2317 getSystemInfo().getVersionNumber(), 2318 getSystemInfo().getWebApplicationName())); 2319 if (CmsLog.INIT.isInfoEnabled()) { 2320 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2321 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2322 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 2323 CmsLog.INIT.info( 2324 Messages.get().getBundle().key( 2325 Messages.INIT_SHUTDOWN_START_1, 2326 getSystemInfo().getVersionNumber() + " [" + getSystemInfo().getVersionId() + "]")); 2327 CmsLog.INIT.info( 2328 Messages.get().getBundle().key( 2329 Messages.INIT_CURRENT_RUNLEVEL_1, 2330 Integer.valueOf(getRunLevel()))); 2331 CmsLog.INIT.info( 2332 Messages.get().getBundle().key( 2333 Messages.INIT_SHUTDOWN_TIME_1, 2334 new Date(System.currentTimeMillis()))); 2335 } 2336 2337 // take the system offline 2338 setRunLevel(OpenCms.RUNLEVEL_0_OFFLINE); 2339 2340 if (LOG.isDebugEnabled()) { 2341 // log exception to see which method did call the shutdown 2342 LOG.debug(Messages.get().getBundle().key(Messages.LOG_SHUTDOWN_TRACE_0), new Exception()); 2343 } 2344 2345 for (I_CmsStartStopHandler handler : m_startStopHandlers) { 2346 try { 2347 handler.shutdown(); 2348 } catch (Throwable e) { 2349 CmsLog.INIT.error(e.getLocalizedMessage(), e); 2350 } 2351 } 2352 2353 try { 2354 // the first thing we have to do is to wait until the current publish process finishes 2355 if (null != m_publishEngine) { 2356 m_publishEngine.shutDown(); 2357 } 2358 } catch (Throwable e) { 2359 CmsLog.INIT.error( 2360 Messages.get().getBundle().key(Messages.LOG_ERROR_PUBLISH_SHUTDOWN_1, e.getMessage()), 2361 e); 2362 } 2363 try { 2364 // search manager must be shut down early since there may be background indexing still ongoing 2365 if (m_searchManager != null) { 2366 m_searchManager.shutDown(); 2367 } 2368 } catch (Throwable e) { 2369 CmsLog.INIT.error( 2370 Messages.get().getBundle().key(Messages.LOG_ERROR_SEARCH_MANAGER_SHUTDOWN_1, e.getMessage()), 2371 e); 2372 } 2373 try { 2374 // remote shell server must be shut down early since there is a background thread ongoing that reloads from the VFS 2375 if (m_remoteShellServer != null) { 2376 m_remoteShellServer.shutDown(); 2377 } 2378 } catch (Throwable e) { 2379 CmsLog.INIT.error( 2380 Messages.get().getBundle().key(Messages.LOG_ERROR_REMOTESHELL_SHUTDOWN_1, e.getMessage()), 2381 e); 2382 } 2383 try { 2384 // VFS bundle manager must be shut down early since there is a background thread ongoing that reloads from the VFS 2385 if (m_vfsBundleManager != null) { 2386 m_vfsBundleManager.shutDown(); 2387 } 2388 } catch (Throwable e) { 2389 CmsLog.INIT.error( 2390 Messages.get().getBundle().key(Messages.LOG_ERROR_VFSBUNDLE_MANAGER_SHUTDOWN_1, e.getMessage()), 2391 e); 2392 } 2393 try { 2394 if (m_staticExportManager != null) { 2395 m_staticExportManager.shutDown(); 2396 } 2397 } catch (Throwable e) { 2398 CmsLog.INIT.error( 2399 Messages.get().getBundle().key(Messages.LOG_ERROR_EXPORT_SHUTDOWN_1, e.getMessage()), 2400 e); 2401 } 2402 try { 2403 if (m_moduleManager != null) { 2404 m_moduleManager.shutDown(); 2405 } 2406 } catch (Throwable e) { 2407 CmsLog.INIT.error( 2408 Messages.get().getBundle().key(Messages.LOG_ERROR_MODULE_SHUTDOWN_1, e.getMessage()), 2409 e); 2410 } 2411 2412 try { 2413 if (m_executor != null) { 2414 m_executor.shutdownNow(); 2415 m_executor.awaitTermination(30, TimeUnit.SECONDS); 2416 } 2417 } catch (Throwable e) { 2418 CmsLog.INIT.error( 2419 Messages.get().getBundle().key(Messages.LOG_ERROR_MODULE_SHUTDOWN_1, e.getMessage()), 2420 e); 2421 } 2422 2423 try { 2424 if (m_scheduleManager != null) { 2425 m_scheduleManager.shutDown(); 2426 } 2427 } catch (Throwable e) { 2428 CmsLog.INIT.error( 2429 Messages.get().getBundle().key(Messages.LOG_ERROR_SCHEDULE_SHUTDOWN_1, e.getMessage()), 2430 e); 2431 } 2432 try { 2433 if (m_resourceManager != null) { 2434 m_resourceManager.shutDown(); 2435 } 2436 } catch (Throwable e) { 2437 CmsLog.INIT.error( 2438 Messages.get().getBundle().key(Messages.LOG_ERROR_RESOURCE_SHUTDOWN_1, e.getMessage()), 2439 e); 2440 } 2441 2442 try { 2443 if (m_repositoryManager != null) { 2444 m_repositoryManager.shutDown(); 2445 } 2446 } catch (Throwable e) { 2447 CmsLog.INIT.error(e.getLocalizedMessage(), e); 2448 } 2449 2450 try { 2451 // has to be stopped before the security manager, since this thread uses it 2452 if (m_threadStore != null) { 2453 m_threadStore.shutDown(); 2454 } 2455 } catch (Throwable e) { 2456 CmsLog.INIT.error( 2457 Messages.get().getBundle().key(Messages.LOG_ERROR_THREAD_SHUTDOWN_1, e.getMessage()), 2458 e); 2459 } 2460 try { 2461 if (m_securityManager != null) { 2462 m_securityManager.destroy(); 2463 } 2464 } catch (Throwable e) { 2465 CmsLog.INIT.error( 2466 Messages.get().getBundle().key(Messages.LOG_ERROR_SECURITY_SHUTDOWN_1, e.getMessage()), 2467 e); 2468 } 2469 try { 2470 if (m_sessionManager != null) { 2471 m_sessionManager.shutdown(); 2472 } 2473 } catch (Throwable e) { 2474 CmsLog.INIT.error( 2475 Messages.get().getBundle().key(Messages.LOG_ERROR_SESSION_MANAGER_SHUTDOWN_1, e.getMessage()), 2476 e); 2477 } 2478 try { 2479 if (m_memoryMonitor != null) { 2480 m_memoryMonitor.shutdown(); 2481 } 2482 } catch (Throwable e) { 2483 CmsLog.INIT.error( 2484 Messages.get().getBundle().key(Messages.LOG_ERROR_MEMORY_MONITOR_SHUTDOWN_1, e.getMessage()), 2485 e); 2486 } 2487 try { 2488 if (m_adeManager != null) { 2489 m_adeManager.shutdown(); 2490 } 2491 } catch (Throwable e) { 2492 CmsLog.INIT.error( 2493 Messages.get().getBundle().key(Messages.LOG_ERROR_ADE_MANAGER_SHUTDOWN_1, e.getMessage()), 2494 e); 2495 } 2496 2497 String runtime = CmsStringUtil.formatRuntime(getSystemInfo().getRuntime()); 2498 if (CmsLog.INIT.isInfoEnabled()) { 2499 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_OPENCMS_STOPPED_1, runtime)); 2500 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 2501 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2502 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2503 } 2504 System.err.println(Messages.get().getBundle().key(Messages.LOG_CONSOLE_TOTAL_RUNTIME_1, runtime)); 2505 2506 } 2507 m_instance = null; 2508 } 2509 } 2510 2511 /** 2512 * This method updates the request context information.<p> 2513 * 2514 * The update information is:<br> 2515 * <ul> 2516 * <li>Requested Url</li> 2517 * <li>Locale</li> 2518 * <li>Encoding</li> 2519 * <li>Remote Address</li> 2520 * <li>Request Time</li> 2521 * </ul> 2522 * 2523 * @param request the current request 2524 * @param cms the cms object to update the request context for 2525 * 2526 * @return a new updated cms context 2527 * 2528 * @throws CmsException if something goes wrong 2529 */ 2530 protected CmsObject updateContext(HttpServletRequest request, CmsObject cms) throws CmsException { 2531 2532 // get the right site for the request 2533 String siteRoot = null; 2534 boolean isWorkplace = cms.getRequestContext().getUri().startsWith("/system/workplace/") 2535 || request.getRequestURI().startsWith(OpenCms.getSystemInfo().getWorkplaceContext()); 2536 if (isWorkplace && getRoleManager().hasRole(cms, CmsRole.ELEMENT_AUTHOR)) { 2537 // keep the site root for workplace requests 2538 siteRoot = cms.getRequestContext().getSiteRoot(); 2539 } else { 2540 CmsSite site = OpenCms.getSiteManager().matchRequest(request); 2541 siteRoot = site.getSiteRoot(); 2542 } 2543 return initCmsObject( 2544 request, 2545 cms.getRequestContext().getCurrentUser(), 2546 siteRoot, 2547 cms.getRequestContext().getCurrentProject().getUuid(), 2548 cms.getRequestContext().getOuFqn()); 2549 } 2550 2551 /** 2552 * Upgrades to runlevel {@link OpenCms#RUNLEVEL_3_SHELL_ACCESS}, 2553 * this is shell access to the database but no Servlet context.<p> 2554 * 2555 * To upgrade the runlevel, the system must be in runlevel {@link OpenCms#RUNLEVEL_1_CORE_OBJECT}, 2556 * otherwise an exception is thrown.<p> 2557 * 2558 * @param configuration the configuration 2559 * @throws CmsInitException in case OpenCms can not be initialized 2560 * @return the initialized OpenCmsCore 2561 */ 2562 protected OpenCmsCore upgradeRunlevel(CmsParameterConfiguration configuration) throws CmsInitException { 2563 2564 synchronized (LOCK) { 2565 if ((m_instance != null) && (getRunLevel() >= OpenCms.RUNLEVEL_2_INITIALIZING)) { 2566 // instance already in runlevel 3 or 4 2567 return m_instance; 2568 } 2569 if (getRunLevel() != OpenCms.RUNLEVEL_1_CORE_OBJECT) { 2570 CmsLog.INIT.error( 2571 Messages.get().getBundle().key( 2572 Messages.LOG_WRONG_INIT_SEQUENCE_2, 2573 Integer.valueOf(3), 2574 Integer.valueOf(getRunLevel()))); 2575 return m_instance; 2576 } 2577 2578 // set the runlevel to "initializing OpenCms" 2579 setRunLevel(OpenCms.RUNLEVEL_2_INITIALIZING); 2580 // initialize the configuration 2581 m_instance.initConfiguration(configuration); 2582 // upgrade the runlevel - OpenCms shell is available 2583 setRunLevel(OpenCms.RUNLEVEL_3_SHELL_ACCESS); 2584 2585 afterUpgradeRunlevel(); 2586 2587 return m_instance; 2588 } 2589 } 2590 2591 /** 2592 * Upgrades to runlevel {@link OpenCms#RUNLEVEL_4_SERVLET_ACCESS}, 2593 * this is the final runlevel with an initialized database and Servlet context.<p> 2594 * 2595 * To upgrade the runlevel, the system must be in runlevel {@link OpenCms#RUNLEVEL_1_CORE_OBJECT}, 2596 * otherwise an exception is thrown.<p> 2597 * 2598 * @param context the current servlet context 2599 * @throws CmsInitException in case OpenCms can not be initialized 2600 * @return the initialized OpenCmsCore 2601 */ 2602 protected OpenCmsCore upgradeRunlevel(ServletContext context) throws CmsInitException { 2603 2604 synchronized (LOCK) { 2605 if ((m_instance != null) && (getRunLevel() >= OpenCms.RUNLEVEL_4_SERVLET_ACCESS)) { 2606 // instance already in runlevel 5 or 6 2607 return m_instance; 2608 } 2609 if (getRunLevel() != OpenCms.RUNLEVEL_1_CORE_OBJECT) { 2610 CmsLog.INIT.error( 2611 Messages.get().getBundle().key( 2612 Messages.LOG_WRONG_INIT_SEQUENCE_2, 2613 Integer.valueOf(4), 2614 Integer.valueOf(getRunLevel()))); 2615 return m_instance; 2616 } 2617 2618 // set the runlevel to "initializing OpenCms" 2619 setRunLevel(OpenCms.RUNLEVEL_2_INITIALIZING); 2620 // initialize the servlet context 2621 m_instance.initContext(context); 2622 // initialization successfully finished - OpenCms servlet is online 2623 // the runlevel will change from 2 directly to 4, this is on purpose 2624 setRunLevel(OpenCms.RUNLEVEL_4_SERVLET_ACCESS); 2625 2626 afterUpgradeRunlevel(); 2627 2628 return m_instance; 2629 } 2630 } 2631 2632 /** 2633 * Writes the XML configuration for the provided configuration class.<p> 2634 * 2635 * @param clazz the configuration class to write the XML for 2636 */ 2637 protected void writeConfiguration(Class<?> clazz) { 2638 2639 // exception handling is provided here to ensure identical log messages 2640 try { 2641 m_configurationManager.writeConfiguration(clazz); 2642 } catch (IOException e) { 2643 CmsLog.getLog(CmsConfigurationManager.class).error( 2644 Messages.get().getBundle().key(Messages.LOG_ERROR_WRITING_CONFIG_1, clazz.getName()), 2645 e); 2646 } catch (CmsConfigurationException e) { 2647 CmsLog.getLog(CmsConfigurationManager.class).error( 2648 Messages.get().getBundle().key(Messages.LOG_ERROR_WRITING_CONFIG_1, clazz.getName()), 2649 e); 2650 } 2651 } 2652 2653 /** 2654 * Adds the given set of export points to the list of all configured export points.<p> 2655 * 2656 * @param exportPoints the export points to add 2657 */ 2658 private void addExportPoints(Set<CmsExportPoint> exportPoints) { 2659 2660 // create a new immutable set of export points 2661 HashSet<CmsExportPoint> newSet = new HashSet<CmsExportPoint>(m_exportPoints.size() + exportPoints.size()); 2662 newSet.addAll(exportPoints); 2663 newSet.addAll(m_exportPoints); 2664 m_exportPoints = Collections.unmodifiableSet(newSet); 2665 } 2666 2667 /** 2668 * Finishes the startup sequence after last runlevel upgrade.<p> 2669 */ 2670 private void afterUpgradeRunlevel() { 2671 2672 try { 2673 // read the persistent locks 2674 m_instance.m_securityManager.readLocks(); 2675 } catch (CmsException e) { 2676 if (LOG.isErrorEnabled()) { 2677 LOG.error( 2678 org.opencms.lock.Messages.get().getBundle().key(org.opencms.lock.Messages.ERR_READ_LOCKS_0), 2679 e); 2680 } 2681 } 2682 2683 if (OpenCms.getRunLevel() == OpenCms.RUNLEVEL_4_SERVLET_ACCESS) { 2684 // only init ADE manager in case of servlet initialization, it won't be needed in case of shell access 2685 CmsThreadStatsTreeProfilingHandler stats = new CmsThreadStatsTreeProfilingHandler(); 2686 try { 2687 CmsDefaultProfilingHandler.INSTANCE.addHandler(stats); 2688 m_adeManager.initialize(); 2689 } finally { 2690 CmsDefaultProfilingHandler.INSTANCE.removeHandler(stats); 2691 if (stats.hasData()) { 2692 String adeInitData = stats.dump(); 2693 String prefix = String.format("%010X", Long.valueOf(System.currentTimeMillis() / 1000)); 2694 String path = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf( 2695 "logs/" + prefix + "_startup-ade-driver-report.xml"); 2696 try (FileOutputStream out = new FileOutputStream(path)) { 2697 out.write(adeInitData.getBytes("UTF-8")); 2698 } catch (Exception e) { 2699 LOG.error( 2700 "Could not write ADE init profiling data to file, writing to log instead: " 2701 + e.getLocalizedMessage(), 2702 e); 2703 LOG.error(adeInitData); 2704 } 2705 } 2706 } 2707 2708 try { 2709 // get an Admin cms context object with site root set to "/" 2710 CmsObject adminCms = initCmsObject( 2711 null, 2712 null, 2713 getDefaultUsers().getUserAdmin(), 2714 (String)null, 2715 (String)null); 2716 OpenCms.getSearchManager().initSpellcheckIndex(adminCms); 2717 } catch (CmsException e) { 2718 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_ADMINCMS_0), e); 2719 } 2720 2721 } 2722 // everything is initialized, now start publishing 2723 m_publishManager.startPublishing(); 2724 2725 for (I_CmsStartStopHandler handler : ServiceLoader.load(I_CmsStartStopHandler.class)) { 2726 m_startStopHandlers.add(handler); 2727 } 2728 2729 for (I_CmsStartStopHandler handler : m_startStopHandlers) { 2730 try { 2731 handler.startup(m_configAdminCms); 2732 } catch (Exception e) { 2733 LOG.error(e.getLocalizedMessage(), e); 2734 } 2735 } 2736 2737 try { 2738 CmsDiagnosticsMXBean.register(); 2739 } catch (Throwable e) { 2740 CmsLog.INIT.error(e.getLocalizedMessage(), e); 2741 } 2742 2743 try { 2744 // Workaround: The GWT serializer for LinkedHashMaps uses reflection on java.util.LinkedHashMap that is disallowed in newer Java versions that use modules. 2745 // This can be bypassed by setting a private 'reflectionHasFailed' field in the serializer class. *This* reflective access is OK, because it does not access a different module. 2746 // GWT should really handle that problem, but as of version 2.9.0 it does not. This workaround can be removed if a newer GWT version handles the problem correctly. 2747 // (See https://github.com/gwtproject/gwt/issues/9584) 2748 2749 Field field = LinkedHashMap_CustomFieldSerializer.class.getDeclaredField("reflectionHasFailed"); 2750 field.setAccessible(true); 2751 ((AtomicBoolean)field.get(null)).set(true); 2752 } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 2753 CmsLog.INIT.error(e.getLocalizedMessage(), e); 2754 } 2755 2756 } 2757 2758 /** 2759 * Checks whether 'force absolute links' mode should be enabled in request context. 2760 * 2761 * @param req the current request 2762 * @param cms the CMS context 2763 * @param resource the resource to load 2764 * 2765 * @return true if 'force absolute links' mode should be enabled 2766 */ 2767 private boolean checkForceAbsoluteLinks(HttpServletRequest req, CmsObject cms, CmsResource resource) { 2768 2769 try { 2770 boolean forceAbsoluteLinks = Boolean.parseBoolean(req.getParameter(PARAM_FORCE_ABSOLUTE_LINKS)); 2771 if (forceAbsoluteLinks) { 2772 // only need to read the property if the request parameter is actually set 2773 CmsProperty enableForceAbsoluteProp = cms.readPropertyObject( 2774 resource, 2775 CmsPropertyDefinition.PROPERTY_LINKS_FORCEABSOLUTE_ENABLED, 2776 true); 2777 return Boolean.parseBoolean(enableForceAbsoluteProp.getValue()); 2778 } else { 2779 return false; 2780 } 2781 } catch (Exception e) { 2782 LOG.warn(e.getLocalizedMessage(), e); 2783 return false; 2784 } 2785 } 2786 2787 /** 2788 * This method performs the error handling for OpenCms.<p> 2789 * 2790 * @param cms the current cms context, might be null ! 2791 * @param req the client request 2792 * @param res the client response 2793 * @param t the exception that occurred 2794 */ 2795 private void errorHandling(CmsObject cms, HttpServletRequest req, HttpServletResponse res, Throwable t) { 2796 2797 // remove the controller attribute from the request 2798 CmsFlexController.removeController(req); 2799 req.removeAttribute(CmsJspStandardContextBean.ATTRIBUTE_NAME); 2800 2801 boolean canWrite = (!res.isCommitted() && !res.containsHeader("Location")); 2802 int status = -1; 2803 boolean isGuest = true; 2804 2805 if (t instanceof ServletException) { 2806 ServletException s = (ServletException)t; 2807 if (s.getRootCause() != null) { 2808 t = s.getRootCause(); 2809 } 2810 if (CmsJspLoader.isJasperCompilerException(t)) { 2811 LOG.error(t.getLocalizedMessage()); 2812 } else { 2813 LOG.error(t.getLocalizedMessage(), t); 2814 } 2815 } else if (t instanceof CmsSecurityException) { 2816 LOG.warn(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2817 // access error - display login dialog 2818 if (canWrite) { 2819 try { 2820 m_authorizationHandler.requestAuthorization(req, res, getLoginFormURL(req, res)); 2821 } catch (IOException ioe) { 2822 LOG.debug("Error calling authorization handler.", ioe); 2823 } 2824 return; 2825 } 2826 } else if (t instanceof CmsDbEntryNotFoundException) { 2827 LOG.warn(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2828 // user or group does not exist 2829 status = HttpServletResponse.SC_SERVICE_UNAVAILABLE; 2830 isGuest = false; 2831 } else if (t instanceof CmsVfsResourceNotFoundException) { 2832 LOG.warn(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2833 // file not found - display 404 error. 2834 status = HttpServletResponse.SC_NOT_FOUND; 2835 } else if (t instanceof CmsException) { 2836 LOG.error(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2837 if (t.getCause() != null) { 2838 t = t.getCause(); 2839 } 2840 } else if (t.getClass().getName().equals("org.apache.catalina.connector.ClientAbortException")) { 2841 // only log to debug channel any exceptions caused by a client abort - this is tomcat specific 2842 LOG.debug(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2843 } else { 2844 LOG.error(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2845 } 2846 2847 if (status < 1) { 2848 // error code not set - set "internal server error" (500) 2849 status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; 2850 } 2851 res.setStatus(status); 2852 2853 try { 2854 if ((cms != null) && (cms.getRequestContext().getCurrentUser() != null)) { 2855 isGuest = isGuest 2856 && (cms.getRequestContext().getCurrentUser().isGuestUser() 2857 || cms.userInGroup( 2858 cms.getRequestContext().getCurrentUser().getName(), 2859 OpenCms.getDefaultUsers().getGroupGuests())); 2860 } 2861 } catch (CmsException e) { 2862 // result is false 2863 LOG.error(e.getLocalizedMessage(), e); 2864 } 2865 2866 if (canWrite) { 2867 res.setContentType("text/html"); 2868 CmsRequestUtil.setNoCacheHeaders(res); 2869 if ((status != 404) 2870 && !isGuest 2871 && (cms != null) 2872 && (!CmsJsonPartFilter.isJsonRequest(req)) 2873 && !cms.getRequestContext().getCurrentProject().isOnlineProject()) { 2874 try { 2875 res.setStatus(HttpServletResponse.SC_OK); 2876 res.getWriter().print(CmsErrorUI.getBootstrapPage(cms, t, req)); 2877 } catch (IOException e) { 2878 // can be ignored 2879 LOG.error(e.getLocalizedMessage(), e); 2880 } 2881 } else { 2882 try { 2883 res.sendError(status, t.toString()); 2884 } catch (IOException e) { 2885 // can be ignored 2886 LOG.error(e.getLocalizedMessage(), e); 2887 } 2888 } 2889 } 2890 } 2891 2892 /** 2893 * 2894 * 2895 * @param serviceName the GWT PRC service class name 2896 * @param servletConfig the servlet configuration 2897 * 2898 * @return the GWT service instance 2899 * 2900 * @throws Throwable if something goes wrong 2901 */ 2902 private synchronized CmsGwtService getGwtService(String serviceName, ServletConfig servletConfig) throws Throwable { 2903 2904 CmsGwtServiceContext context = m_gwtServiceContexts.get(serviceName); 2905 if (context == null) { 2906 context = new CmsGwtServiceContext(serviceName); 2907 m_gwtServiceContexts.put(serviceName, context); 2908 } 2909 CmsGwtService gwtService = (CmsGwtService)Class.forName(serviceName).newInstance(); 2910 gwtService.init(servletConfig); 2911 gwtService.setContext(context); 2912 return gwtService; 2913 } 2914 2915 /** 2916 * Reads the login form which should be used for authenticating the current request.<p> 2917 * 2918 * @param req current request 2919 * @param res current response 2920 * 2921 * @return the URL of the login form or <code>null</code> if not set 2922 * 2923 * @throws IOException in case of IO errors 2924 */ 2925 private String getLoginFormURL(HttpServletRequest req, HttpServletResponse res) throws IOException { 2926 2927 CmsHttpAuthenticationSettings httpAuthenticationSettings = OpenCms.getSystemInfo().getHttpAuthenticationSettings(); 2928 String loginFormURL = null; 2929 2930 // this will create an admin user with the "right" site root already set 2931 CmsObject adminCms; 2932 try { 2933 adminCms = initCmsObject(req, res, OpenCms.getDefaultUsers().getUserAdmin(), null, null); 2934 } catch (CmsException e) { 2935 // this should never happen, if it does we can't continue 2936 throw new IOException( 2937 Messages.get().getBundle().key( 2938 Messages.ERR_INVALID_INIT_USER_2, 2939 OpenCms.getDefaultUsers().getUserAdmin(), 2940 2941 null), 2942 e); 2943 } 2944 // get the requested resource 2945 String path = adminCms.getRequestContext().getUri(); 2946 CmsProperty propertyLoginForm = null; 2947 try { 2948 propertyLoginForm = adminCms.readPropertyObject(path, CmsPropertyDefinition.PROPERTY_LOGIN_FORM, true); 2949 } catch (Throwable t) { 2950 if (t instanceof CmsVfsResourceNotFoundException) { 2951 // if we can't read the property from the path, try to use the resource init handlers to find the 2952 // resource to read it from 2953 CmsResource alternativeResource = null; 2954 try { 2955 2956 try { 2957 // use null as the response to avoid side effects like redirects, etc. 2958 alternativeResource = initResource(adminCms, path, req, null); 2959 } catch (Exception e) { 2960 LOG.warn(e.getLocalizedMessage(), e); 2961 } 2962 if (alternativeResource != null) { 2963 propertyLoginForm = adminCms.readPropertyObject( 2964 adminCms.getSitePath(alternativeResource), 2965 CmsPropertyDefinition.PROPERTY_LOGIN_FORM, 2966 true); 2967 } 2968 } catch (Exception e) { 2969 LOG.error(e.getLocalizedMessage(), e); 2970 } 2971 } 2972 2973 if (propertyLoginForm == null) { 2974 if (LOG.isWarnEnabled()) { 2975 LOG.warn( 2976 Messages.get().getBundle().key( 2977 Messages.LOG_ERROR_READING_AUTH_PROP_2, 2978 CmsPropertyDefinition.PROPERTY_LOGIN_FORM, 2979 path), 2980 t); 2981 } 2982 2983 } 2984 } 2985 2986 String params = null; 2987 if ((propertyLoginForm != null) 2988 && (propertyLoginForm != CmsProperty.getNullProperty()) 2989 && CmsStringUtil.isNotEmpty(propertyLoginForm.getValue())) { 2990 // login form property value was found 2991 // build a redirect URL using the value of the property 2992 // "__loginform" is a dummy request parameter that could be used in a JSP template to trigger 2993 // if the template should display a login formular or not 2994 loginFormURL = propertyLoginForm.getValue(); 2995 params = "__loginform=true"; 2996 } else if (!httpAuthenticationSettings.useBrowserBasedHttpAuthentication() 2997 && CmsStringUtil.isNotEmpty(httpAuthenticationSettings.getFormBasedHttpAuthenticationUri())) { 2998 // login form property value not set, but form login set in configuration 2999 // build a redirect URL to the default login form URI configured in opencms.properties 3000 loginFormURL = httpAuthenticationSettings.getFormBasedHttpAuthenticationUri(); 3001 } 3002 3003 String callbackURL = CmsRequestUtil.encodeParamsWithUri(path, req); 3004 if (loginFormURL != null) { 3005 if (!loginFormURL.startsWith("http")) { 3006 loginFormURL = m_linkManager.substituteLink(adminCms, loginFormURL, null, true); 3007 } else { 3008 callbackURL = m_linkManager.getServerLink(adminCms, path); 3009 callbackURL = CmsRequestUtil.encodeParamsWithUri(callbackURL, req); 3010 } 3011 } 3012 3013 return m_authorizationHandler.getLoginFormURL(loginFormURL, params, callbackURL); 3014 } 3015 3016 /** 3017 * If we are in the Online project, check if the given resource is marked as secure, and handle it according to the secure server configuration.<p> 3018 * 3019 * @param cms the current CMS context 3020 * @param req the current request 3021 * @param res the current response 3022 * @param resource the resource to check 3023 * @param resourceName the resource path from the request 3024 * 3025 * @return the resource to replace the original resource 3026 * 3027 * @throws CmsException if something goes wrong 3028 * @throws CmsVfsResourceNotFoundException if the resource could not be found 3029 */ 3030 private CmsResource handleSecureResource( 3031 CmsObject cms, 3032 HttpServletRequest req, 3033 HttpServletResponse res, 3034 CmsResource resource, 3035 String resourceName) 3036 throws CmsException, CmsVfsResourceNotFoundException { 3037 3038 // check online project 3039 if (cms.getRequestContext().getCurrentProject().isOnlineProject() && (res != null)) { 3040 boolean secure = false; 3041 try { 3042 // check if resource is secure 3043 secure = Boolean.valueOf( 3044 cms.readPropertyObject( 3045 cms.getSitePath(resource), 3046 CmsPropertyDefinition.PROPERTY_SECURE, 3047 true).getValue()).booleanValue(); 3048 } catch (CmsVfsResourceNotFoundException e) { 3049 LOG.warn(e.getLocalizedMessage(), e); 3050 } catch (CmsException e) { 3051 LOG.error(e.getLocalizedMessage(), e); 3052 } 3053 if (secure) { 3054 CmsResource resource1 = resource; 3055 // resource is secure, check site config 3056 CmsSite site = OpenCms.getSiteManager().getCurrentSite(cms); 3057 // check the secure url 3058 String secureUrl = null; 3059 try { 3060 secureUrl = site.getSecureUrl(); 3061 } catch (Exception e) { 3062 LOG.error( 3063 Messages.get().getBundle().key(Messages.ERR_SECURE_SITE_NOT_CONFIGURED_1, resourceName), 3064 e); 3065 throw new CmsException( 3066 Messages.get().container(Messages.ERR_SECURE_SITE_NOT_CONFIGURED_1, resourceName), 3067 e); 3068 } 3069 boolean usingSec = true; 3070 if (req != null) { 3071 usingSec = req.getRequestURL().toString().toUpperCase().startsWith(secureUrl.toUpperCase()); 3072 } 3073 if (site.isExclusiveUrl() && !usingSec) { 3074 resource1 = null; 3075 // secure resource without secure protocol, check error config 3076 if (site.isExclusiveError()) { 3077 // trigger 404 error 3078 throw new CmsVfsResourceNotFoundException( 3079 Messages.get().container(Messages.ERR_REQUEST_SECURE_RESOURCE_0)); 3080 } else { 3081 // redirect 3082 String target = OpenCms.getLinkManager().getOnlineLink(cms, resourceName); 3083 if (!target.toLowerCase().startsWith(secureUrl.toLowerCase())) { 3084 Optional<String> targetWithReplacedHost = CmsStringUtil.replacePrefix( 3085 target, 3086 site.getSiteMatcher().getUrl(), 3087 secureUrl, 3088 true); 3089 if (targetWithReplacedHost.isPresent()) { 3090 target = targetWithReplacedHost.get(); 3091 } 3092 if (!target.toLowerCase().startsWith(secureUrl.toLowerCase())) { 3093 LOG.warn("Failed to generate secure URL for " + target + ", site = " + site); 3094 } 3095 } 3096 3097 try { 3098 if (site.usesPermanentRedirects()) { 3099 res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); 3100 res.setHeader("Location", target); 3101 } else { 3102 res.sendRedirect(target); 3103 } 3104 } catch (Exception e) { 3105 // ignore, but should never happen 3106 LOG.error("Error sending secure resource redirect.", e); 3107 } 3108 } 3109 } 3110 resource = resource1; 3111 } 3112 3113 } 3114 return resource; 3115 } 3116 3117 /** 3118 * Initializes a CmsObject with the given context information.<p> 3119 * 3120 * @param contextInfo the information for the CmsObject context to create 3121 * 3122 * @return the initialized CmsObject 3123 * 3124 * @throws CmsException if something goes wrong 3125 */ 3126 private CmsObject initCmsObject(CmsContextInfo contextInfo) throws CmsException { 3127 3128 CmsUser user = contextInfo.getUser(); 3129 if (user == null) { 3130 user = m_securityManager.readUser(null, contextInfo.getUserName()); 3131 } 3132 3133 CmsProject project = contextInfo.getProject(); 3134 if (project == null) { 3135 project = m_securityManager.readProject(contextInfo.getProjectName()); 3136 } 3137 3138 // first create the request context 3139 CmsRequestContext context = new CmsRequestContext( 3140 user, 3141 project, 3142 contextInfo.getRequestedUri(), 3143 contextInfo.getRequestMatcher(), 3144 contextInfo.getSiteRoot(), 3145 contextInfo.isSecureRequest(), 3146 contextInfo.getLocale(), 3147 contextInfo.getEncoding(), 3148 contextInfo.getRemoteAddr(), 3149 contextInfo.getRequestTime(), 3150 m_resourceManager.getFolderTranslator(), 3151 m_resourceManager.getFileTranslator(), 3152 contextInfo.getOuFqn(), 3153 contextInfo.isForceAbsoluteLinks()); 3154 context.setDetailResource(contextInfo.getDetailResource()); 3155 3156 // now initialize and return the CmsObject 3157 return new CmsObject(m_securityManager, context); 3158 } 3159 3160 /** 3161 * Initializes a {@link CmsObject} with the given users information.<p> 3162 * 3163 * @param request the current http request (or <code>null</code>) 3164 * @param user the initialized user 3165 * @param siteRoot the users current site 3166 * @param projectId the id of the users current project 3167 * @param ouFqn the organizational unit 3168 * 3169 * @return the initialized CmsObject 3170 * 3171 * @throws CmsException in case something goes wrong 3172 */ 3173 private CmsObject initCmsObject( 3174 HttpServletRequest request, 3175 CmsUser user, 3176 String siteRoot, 3177 CmsUUID projectId, 3178 String ouFqn) 3179 throws CmsException { 3180 3181 CmsProject project = null; 3182 try { 3183 project = m_securityManager.readProject(projectId); 3184 } catch (CmsDbEntryNotFoundException e) { 3185 // project not found, switch to online project 3186 project = m_securityManager.readProject(CmsProject.ONLINE_PROJECT_ID); 3187 LOG.debug("Project '" + projectId + "' was not found, switch to online project.", e); 3188 } 3189 3190 // get requested resource uri and remote IP address, as well as time for "time warp" browsing 3191 String requestedResource = null; 3192 Long requestTimeAttr = null; 3193 String remoteAddr; 3194 CmsSiteMatcher requestMatcher; 3195 3196 boolean isSecureRequest = false; 3197 if (request != null) { 3198 // get path info from request 3199 requestedResource = getPathInfo(request); 3200 3201 // check for special header for remote address 3202 remoteAddr = request.getHeader(CmsRequestUtil.HEADER_X_FORWARDED_FOR); 3203 if (remoteAddr == null) { 3204 // if header is not available, use default remote address 3205 remoteAddr = request.getRemoteAddr(); 3206 } 3207 3208 // check for special "time warp" browsing 3209 HttpSession session = request.getSession(false); 3210 if (session != null) { 3211 // no new session must be created here 3212 requestTimeAttr = (Long)session.getAttribute(CmsContextInfo.ATTRIBUTE_REQUEST_TIME); 3213 } 3214 isSecureRequest = OpenCms.getSiteManager().usesSecureSite(request); 3215 3216 // create the request matcher 3217 requestMatcher = new CmsSiteMatcher(request.getRequestURL().toString()); 3218 3219 } else { 3220 // if no request is available, the IP is always set to localhost 3221 remoteAddr = CmsContextInfo.LOCALHOST; 3222 // also the request matcher is always the workplace server 3223 requestMatcher = OpenCms.getSiteManager().getWorkplaceSiteMatcher(); 3224 } 3225 if (requestedResource == null) { 3226 // path info can still be null 3227 requestedResource = "/"; 3228 } 3229 3230 // calculate the request time 3231 long requestTime; 3232 if (requestTimeAttr == null) { 3233 requestTime = System.currentTimeMillis(); 3234 } else { 3235 requestTime = requestTimeAttr.longValue(); 3236 } 3237 3238 // get locale and encoding 3239 CmsI18nInfo i18nInfo; 3240 if (m_localeManager.isInitialized()) { 3241 // locale manager is initialized 3242 // resolve locale and encoding 3243 if ((request != null) 3244 && (requestedResource.endsWith(OpenCmsServlet.HANDLE_GWT) || isWorkplaceServletRequest(request))) { 3245 // GWT RPC or workplace servlet call, always keep the request encoding and use the default locale 3246 i18nInfo = new CmsI18nInfo(CmsLocaleManager.getDefaultLocale(), request.getCharacterEncoding()); 3247 } else { 3248 String resourceName; 3249 if (requestedResource.startsWith(CmsWorkplace.VFS_PATH_SYSTEM)) { 3250 // add site root only if resource name does not start with "/system" 3251 resourceName = requestedResource; 3252 } else if (OpenCms.getSiteManager().startsWithShared(requestedResource)) { 3253 resourceName = requestedResource; 3254 } else { 3255 resourceName = siteRoot.concat(requestedResource); 3256 } 3257 i18nInfo = m_localeManager.getI18nInfo(request, user, project, resourceName); 3258 } 3259 } else { 3260 // locale manager not initialized, this will be true _only_ during system startup 3261 // the values set does not matter, no locale information form VFS is used on system startup 3262 // this is just to protect against null pointer exceptions 3263 i18nInfo = new CmsI18nInfo(Locale.ENGLISH, getSystemInfo().getDefaultEncoding()); 3264 } 3265 3266 // decode the requested resource, always using UTF-8 3267 requestedResource = CmsEncoder.decode(requestedResource); 3268 3269 // in case the current site could be configured for single tree localization, if so, remove the locale prefix if present 3270 CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot); 3271 if ((site != null) && CmsSite.LocalizationMode.singleTree.equals(site.getLocalizationMode())) { 3272 Locale locale = CmsSingleTreeLocaleHandler.getLocaleFromPath(requestedResource); 3273 if (locale != null) { 3274 requestedResource = requestedResource.substring( 3275 requestedResource.indexOf(locale.toString()) + locale.toString().length()); 3276 } 3277 } 3278 3279 // initialize the context info 3280 CmsContextInfo contextInfo = new CmsContextInfo( 3281 user, 3282 project, 3283 requestedResource, 3284 requestMatcher, 3285 siteRoot, 3286 isSecureRequest, 3287 i18nInfo.getLocale(), 3288 i18nInfo.getEncoding(), 3289 remoteAddr, 3290 requestTime, 3291 ouFqn, 3292 false); 3293 3294 // now generate and return the CmsObject 3295 return initCmsObject(contextInfo); 3296 } 3297 3298 /** 3299 * Handles the user authentification for each request sent to OpenCms.<p> 3300 * 3301 * User authentification is done in three steps: 3302 * <ol> 3303 * <li>Session authentification: OpenCms stores information of all authentificated 3304 * users in an internal storage based on the users session.</li> 3305 * <li>Authorization handler authentification: If the session authentification fails, 3306 * the current configured authorization handler is called.</li> 3307 * <li>Default user: When both authentification methods fail, the user is set to 3308 * the default (Guest) user.</li> 3309 * </ol> 3310 * 3311 * @param req the current http request 3312 * @param res the current http response 3313 * 3314 * @return the initialized cms context 3315 * 3316 * @throws IOException if user authentication fails 3317 * @throws CmsException in case something goes wrong 3318 */ 3319 private CmsObject initCmsObject(HttpServletRequest req, HttpServletResponse res) throws IOException, CmsException { 3320 3321 return initCmsObject(req, res, true); 3322 } 3323 3324 /** 3325 * Returns an initialized CmsObject with the given users permissions.<p> 3326 * 3327 * In case the password is <code>null</code>, or the user is the <code>Guest</code> user, 3328 * no password check is done. Therefore you can initialize all users without knowing their passwords 3329 * by just supplying <code>null</code> as password. This is intended only for 3330 * internal operation in the core.<p> 3331 * 3332 * @param req the current request 3333 * @param res the current response 3334 * @param user the user to initialize the CmsObject with 3335 * @param password the password of the user 3336 * @param ouFqn the organizational unit, if <code>null</code> the users ou is used 3337 * 3338 * @return a cms context that has been initialized with "Guest" permissions 3339 * 3340 * @throws CmsException in case the CmsObject could not be initialized 3341 */ 3342 private CmsObject initCmsObject( 3343 HttpServletRequest req, 3344 HttpServletResponse res, 3345 String user, 3346 String password, 3347 String ouFqn) 3348 throws CmsException { 3349 3350 String siteroot = null; 3351 // gather information from request if provided 3352 if (req != null) { 3353 siteroot = OpenCms.getSiteManager().matchRequest(req).getSiteRoot(); 3354 } 3355 // initialize the user 3356 if (user == null) { 3357 user = getDefaultUsers().getUserGuest(); 3358 } 3359 if (siteroot == null) { 3360 siteroot = "/"; 3361 } 3362 CmsObject cms = initCmsObject( 3363 req, 3364 m_securityManager.readUser(null, user), 3365 siteroot, 3366 CmsProject.ONLINE_PROJECT_ID, 3367 ouFqn); 3368 // login the user if different from Guest and password was provided 3369 if ((password != null) && !getDefaultUsers().isUserGuest(user)) { 3370 cms.loginUser(user, password, CmsContextInfo.LOCALHOST); 3371 } 3372 return cms; 3373 } 3374 3375 /** 3376 * Checks whether the given request targets the workplace UI servlet.<p> 3377 * 3378 * @param req the request 3379 * 3380 * @return <code>true</code> in case the given request targets the workplace UI servlet 3381 */ 3382 private boolean isWorkplaceServletRequest(HttpServletRequest req) { 3383 3384 String servletPath = req.getServletPath(); 3385 return (servletPath != null) && servletPath.startsWith(CmsSystemInfo.WORKPLACE_PATH); 3386 } 3387 3388 /** 3389 * Sets the init level of this OpenCmsCore object instance.<p> 3390 * 3391 * For a detailed description about the possible run levels, 3392 * please see {@link OpenCms#getRunLevel()}.<p> 3393 * 3394 * @param level the level to set 3395 */ 3396 private void setRunLevel(int level) { 3397 3398 if (m_instance != null) { 3399 if (m_instance.m_runLevel >= OpenCms.RUNLEVEL_1_CORE_OBJECT) { 3400 // otherwise the log is not available 3401 if (CmsLog.INIT.isInfoEnabled()) { 3402 CmsLog.INIT.info( 3403 Messages.get().getBundle().key( 3404 Messages.INIT_RUNLEVEL_CHANGE_2, 3405 Integer.valueOf(m_instance.m_runLevel), 3406 Integer.valueOf(level))); 3407 } 3408 } 3409 m_instance.m_runLevel = level; 3410 } 3411 } 3412 3413}