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