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