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