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.db; 029 030import org.opencms.ade.contenteditor.CmsAccessRestrictionInfo; 031import org.opencms.ade.publish.CmsTooManyPublishResourcesException; 032import org.opencms.configuration.CmsConfigurationManager; 033import org.opencms.configuration.CmsSystemConfiguration; 034import org.opencms.db.generic.CmsPublishHistoryCleanupFilter; 035import org.opencms.db.log.CmsLogEntry; 036import org.opencms.db.log.CmsLogFilter; 037import org.opencms.db.storage.I_CmsStorageDelivery; 038import org.opencms.db.urlname.CmsUrlNameMappingEntry; 039import org.opencms.db.urlname.CmsUrlNameMappingFilter; 040import org.opencms.file.CmsDataAccessException; 041import org.opencms.file.CmsFile; 042import org.opencms.file.CmsFolder; 043import org.opencms.file.CmsGroup; 044import org.opencms.file.CmsObject; 045import org.opencms.file.CmsProject; 046import org.opencms.file.CmsProperty; 047import org.opencms.file.CmsPropertyDefinition; 048import org.opencms.file.CmsRequestContext; 049import org.opencms.file.CmsResource; 050import org.opencms.file.CmsResourceFilter; 051import org.opencms.file.CmsStoredContentInfo; 052import org.opencms.file.CmsUser; 053import org.opencms.file.CmsUserSearchParameters; 054import org.opencms.file.CmsVfsException; 055import org.opencms.file.CmsVfsResourceAlreadyExistsException; 056import org.opencms.file.CmsVfsResourceNotFoundException; 057import org.opencms.file.I_CmsFileContentStreamHandler; 058import org.opencms.file.history.CmsHistoryPrincipal; 059import org.opencms.file.history.CmsHistoryProject; 060import org.opencms.file.history.I_CmsHistoryResource; 061import org.opencms.file.quota.CmsFolderSizeEntry; 062import org.opencms.file.quota.CmsFolderSizeOptions; 063import org.opencms.file.types.CmsResourceTypeJsp; 064import org.opencms.gwt.shared.alias.CmsAliasImportResult; 065import org.opencms.gwt.shared.alias.CmsAliasMode; 066import org.opencms.i18n.CmsMessageContainer; 067import org.opencms.lock.CmsLock; 068import org.opencms.lock.CmsLockException; 069import org.opencms.lock.CmsLockFilter; 070import org.opencms.lock.CmsLockManager; 071import org.opencms.lock.CmsLockType; 072import org.opencms.main.CmsEvent; 073import org.opencms.main.CmsException; 074import org.opencms.main.CmsIllegalArgumentException; 075import org.opencms.main.CmsInitException; 076import org.opencms.main.CmsLog; 077import org.opencms.main.CmsMultiException; 078import org.opencms.main.I_CmsEventListener; 079import org.opencms.main.OpenCms; 080import org.opencms.publish.CmsPublishEngine; 081import org.opencms.relations.CmsLink; 082import org.opencms.relations.CmsRelation; 083import org.opencms.relations.CmsRelationFilter; 084import org.opencms.relations.CmsRelationType; 085import org.opencms.report.I_CmsReport; 086import org.opencms.security.CmsAccessControlEntry; 087import org.opencms.security.CmsAccessControlList; 088import org.opencms.security.CmsDefaultPermissionHandler; 089import org.opencms.security.CmsOrganizationalUnit; 090import org.opencms.security.CmsPermissionSet; 091import org.opencms.security.CmsPermissionSetCustom; 092import org.opencms.security.CmsPermissionViolationException; 093import org.opencms.security.CmsPrincipal; 094import org.opencms.security.CmsRole; 095import org.opencms.security.CmsRoleViolationException; 096import org.opencms.security.CmsSecurityException; 097import org.opencms.security.I_CmsPermissionHandler; 098import org.opencms.security.I_CmsPermissionHandler.LockCheck; 099import org.opencms.security.I_CmsPrincipal; 100import org.opencms.security.twofactor.CmsSecondFactorInfo; 101import org.opencms.util.CmsFileUtil; 102import org.opencms.util.CmsStringUtil; 103import org.opencms.util.CmsUUID; 104 105import java.io.OutputStream; 106import java.sql.Connection; 107import java.sql.SQLException; 108import java.util.ArrayList; 109import java.util.Collection; 110import java.util.Collections; 111import java.util.Date; 112import java.util.HashMap; 113import java.util.HashSet; 114import java.util.Iterator; 115import java.util.List; 116import java.util.Locale; 117import java.util.Map; 118import java.util.Set; 119import java.util.function.Predicate; 120import java.util.stream.Collectors; 121 122import org.apache.commons.logging.Log; 123 124/** 125 * The OpenCms security manager.<p> 126 * 127 * The security manager checks the permissions required for a user action invoke by the Cms object. If permissions 128 * are granted, the security manager invokes a method on the OpenCms driver manager to access the database.<p> 129 * 130 * @since 6.0.0 131 */ 132public final class CmsSecurityManager { 133 134 /** 135 * Exception which indicates the user tried to call setRestricted while not being a member of the corresponding group. 136 */ 137 private static class RestrictionGroupMembershipException extends Exception { 138 139 /** Serial version id. */ 140 private static final long serialVersionUID = 1L; 141 142 /** 143 * Creates a new instance. 144 */ 145 public RestrictionGroupMembershipException() { 146 147 super(); 148 149 } 150 151 } 152 153 /** 154 * Exception which indicates the user tried to call setRestricted on a folder. 155 */ 156 private static class RestrictionNotSupportedForFoldersException extends Exception { 157 158 /** Serial version id. */ 159 private static final long serialVersionUID = 1L; 160 161 /** 162 * Creates a new instance. 163 */ 164 public RestrictionNotSupportedForFoldersException() { 165 166 super(); 167 168 } 169 170 } 171 172 /** The log object for this class. */ 173 private static final Log LOG = CmsLog.getLog(CmsSecurityManager.class); 174 175 /** The factory to create runtime info objects. */ 176 protected I_CmsDbContextFactory m_dbContextFactory; 177 178 /** The initialized OpenCms driver manager to access the database. */ 179 protected CmsDriverManager m_driverManager; 180 181 /** The lock manager. */ 182 private CmsLockManager m_lockManager; 183 184 /** Permission handler implementation. */ 185 private I_CmsPermissionHandler m_permissionHandler; 186 187 /** 188 * Default constructor.<p> 189 */ 190 private CmsSecurityManager() { 191 192 // intentionally left blank 193 } 194 195 /** 196 * Creates a new instance of the OpenCms security manager.<p> 197 * 198 * @param configurationManager the configuration manager 199 * @param runtimeInfoFactory the initialized OpenCms runtime info factory 200 * @param publishEngine the publish engine 201 * 202 * @return a new instance of the OpenCms security manager 203 * 204 * @throws CmsInitException if the security manager could not be initialized 205 */ 206 public static CmsSecurityManager newInstance( 207 CmsConfigurationManager configurationManager, 208 I_CmsDbContextFactory runtimeInfoFactory, 209 CmsPublishEngine publishEngine) 210 throws CmsInitException { 211 212 if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_2_INITIALIZING) { 213 // OpenCms is already initialized 214 throw new CmsInitException( 215 org.opencms.main.Messages.get().container(org.opencms.main.Messages.ERR_ALREADY_INITIALIZED_0)); 216 } 217 218 CmsSecurityManager securityManager = new CmsSecurityManager(); 219 securityManager.init(configurationManager, runtimeInfoFactory, publishEngine); 220 221 return securityManager; 222 } 223 224 /** 225 * Adds an alias.<p> 226 * 227 * @param context the current request context 228 * @param alias the alias to add 229 * @throws CmsException if something goes wrong 230 */ 231 public void addAlias(CmsRequestContext context, CmsAlias alias) throws CmsException { 232 233 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 234 try { 235 m_driverManager.addAlias(dbc, context.getCurrentProject(), alias); 236 } catch (Exception e) { 237 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 238 } finally { 239 dbc.clear(); 240 } 241 } 242 243 /** 244 * Adds a new relation to a given resource.<p> 245 * 246 * @param context the request context 247 * @param resource the resource to add the relation to 248 * @param target the target of the relation 249 * @param type the type of the relation 250 * @param importCase if importing relations 251 * 252 * @throws CmsException if something goes wrong 253 * 254 * @see #deleteRelationsForResource(CmsRequestContext, CmsResource, CmsRelationFilter) 255 * @see CmsObject#addRelationToResource(String, String, String) 256 */ 257 public void addRelationToResource( 258 CmsRequestContext context, 259 CmsResource resource, 260 CmsResource target, 261 CmsRelationType type, 262 boolean importCase) 263 throws CmsException { 264 265 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 266 267 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 268 try { 269 checkOfflineProject(dbc); 270 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 271 m_driverManager.addRelationToResource(dbc, resource, target, type, importCase); 272 modContext.add(resource); 273 } catch (Exception e) { 274 dbc.report( 275 null, 276 Messages.get().container( 277 Messages.ERR_ADD_RELATION_TO_RESOURCE_3, 278 context.getSitePath(resource), 279 context.getSitePath(target), 280 type), 281 e); 282 283 } finally { 284 dbc.clear(); 285 } 286 } 287 } 288 289 /** 290 * Adds a resource to the given organizational unit.<p> 291 * 292 * @param context the current request context 293 * @param orgUnit the organizational unit to add the resource to 294 * @param resource the resource that is to be added to the organizational unit 295 * 296 * @throws CmsException if something goes wrong 297 * 298 * @see org.opencms.security.CmsOrgUnitManager#addResourceToOrgUnit(CmsObject, String, String) 299 * @see org.opencms.security.CmsOrgUnitManager#removeResourceFromOrgUnit(CmsObject, String, String) 300 */ 301 public void addResourceToOrgUnit(CmsRequestContext context, CmsOrganizationalUnit orgUnit, CmsResource resource) 302 throws CmsException { 303 304 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 305 try { 306 checkOfflineProject(dbc); 307 checkRole(dbc, CmsRole.ADMINISTRATOR.forOrgUnit(orgUnit.getName())); 308 m_driverManager.addResourceToOrgUnit(dbc, orgUnit, resource); 309 } catch (Exception e) { 310 dbc.report( 311 null, 312 Messages.get().container( 313 Messages.ERR_ADD_RESOURCE_TO_ORGUNIT_2, 314 orgUnit.getName(), 315 dbc.removeSiteRoot(resource.getRootPath())), 316 e); 317 } finally { 318 dbc.clear(); 319 } 320 } 321 322 /** 323 * Adds a user to a group.<p> 324 * 325 * @param context the current request context 326 * @param username the name of the user that is to be added to the group 327 * @param groupname the name of the group 328 * @param readRoles if reading roles or groups 329 * 330 * @throws CmsException if operation was not successful 331 */ 332 public void addUserToGroup(CmsRequestContext context, String username, String groupname, boolean readRoles) 333 throws CmsException { 334 335 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 336 try { 337 CmsRole role = CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(username)); 338 checkRoleForUserModification(dbc, username, role); 339 m_driverManager.addUserToGroup( 340 dbc, 341 CmsOrganizationalUnit.removeLeadingSeparator(username), 342 CmsOrganizationalUnit.removeLeadingSeparator(groupname), 343 readRoles); 344 } catch (Exception e) { 345 dbc.report(null, Messages.get().container(Messages.ERR_ADD_USER_GROUP_FAILED_2, username, groupname), e); 346 } finally { 347 dbc.clear(); 348 } 349 } 350 351 /** 352 * Changes the lock of a resource to the current user, that is "steals" the lock from another user.<p> 353 * 354 * @param context the current request context 355 * @param resource the resource to change the lock for 356 * 357 * @throws CmsException if something goes wrong 358 * 359 * @see org.opencms.file.types.I_CmsResourceType#changeLock(CmsObject, CmsSecurityManager, CmsResource) 360 */ 361 public void changeLock(CmsRequestContext context, CmsResource resource) throws CmsException { 362 363 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 364 checkOfflineProject(dbc); 365 try { 366 m_driverManager.changeLock(dbc, resource, CmsLockType.EXCLUSIVE); 367 } catch (Exception e) { 368 dbc.report( 369 null, 370 Messages.get().container( 371 Messages.ERR_CHANGE_LOCK_OF_RESOURCE_2, 372 context.getSitePath(resource), 373 " - " + e.getMessage()), 374 e); 375 } finally { 376 dbc.clear(); 377 } 378 } 379 380 /** 381 * Returns a list with all sub resources of a given folder that have set the given property, 382 * matching the current property's value with the given old value and replacing it by a given new value.<p> 383 * 384 * @param context the current request context 385 * @param resource the resource on which property definition values are changed 386 * @param propertyDefinition the name of the property definition to change the value 387 * @param oldValue the old value of the property definition 388 * @param newValue the new value of the property definition 389 * @param recursive if true, change recursively all property values on sub-resources (only for folders) 390 * 391 * @return a list with the <code>{@link CmsResource}</code>'s where the property value has been changed 392 * 393 * @throws CmsVfsException for now only when the search for the old value fails 394 * @throws CmsException if operation was not successful 395 */ 396 public synchronized List<CmsResource> changeResourcesInFolderWithProperty( 397 CmsRequestContext context, 398 CmsResource resource, 399 String propertyDefinition, 400 String oldValue, 401 String newValue, 402 boolean recursive) 403 throws CmsException, CmsVfsException { 404 405 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 406 407 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 408 List<CmsResource> result = null; 409 try { 410 result = m_driverManager.changeResourcesInFolderWithProperty( 411 dbc, 412 resource, 413 propertyDefinition, 414 oldValue, 415 newValue, 416 recursive); 417 modContext.add(resource); 418 for (CmsResource changedResource : result) { 419 modContext.add(changedResource); 420 } 421 } catch (Exception e) { 422 dbc.report( 423 null, 424 Messages.get().container( 425 Messages.ERR_CHANGE_RESOURCES_IN_FOLDER_WITH_PROP_4, 426 new Object[] {propertyDefinition, oldValue, newValue, context.getSitePath(resource)}), 427 e); 428 } finally { 429 dbc.clear(); 430 } 431 return result; 432 } 433 } 434 435 /** 436 * Checks user name / password and other things which would prevent the user from logging in, but does not check the second factor for 2FA. 437 * 438 * <p>Throws an exception like the normal login method if these checks fail. If it succeeds, nothing actually happens. 439 * 440 * @param context the request context 441 * @param username the user name 442 * @param password the password 443 * @param remoteAddress the remote address 444 * @throws CmsException if the login check fails 445 */ 446 public void checkLogin(CmsRequestContext context, String username, String password, String remoteAddress) 447 throws CmsException { 448 449 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 450 CmsUser result = null; 451 try { 452 result = m_driverManager.loginUser( 453 dbc, 454 CmsOrganizationalUnit.removeLeadingSeparator(username), 455 password, 456 null, 457 remoteAddress, 458 CmsDriverManager.LoginUserMode.checkOnly); 459 } finally { 460 dbc.clear(); 461 } 462 } 463 464 /** 465 * Checks if the current user has management access to the given project.<p> 466 * 467 * @param dbc the current database context 468 * @param project the project to check 469 * 470 * @throws CmsRoleViolationException if the user does not have the required role permissions 471 */ 472 public void checkManagerOfProjectRole(CmsDbContext dbc, CmsProject project) throws CmsRoleViolationException { 473 474 boolean hasRole = false; 475 try { 476 if (hasRole(dbc, dbc.currentUser(), CmsRole.ROOT_ADMIN)) { 477 return; 478 } 479 hasRole = m_driverManager.getAllManageableProjects( 480 dbc, 481 m_driverManager.readOrganizationalUnit(dbc, project.getOuFqn()), 482 false).contains(project); 483 } catch (CmsException e) { 484 // should never happen 485 if (LOG.isErrorEnabled()) { 486 LOG.error(e.getLocalizedMessage(), e); 487 } 488 } 489 if (!hasRole) { 490 throw new CmsRoleViolationException( 491 org.opencms.security.Messages.get().container( 492 org.opencms.security.Messages.ERR_NOT_MANAGER_OF_PROJECT_2, 493 dbc.currentUser().getName(), 494 dbc.currentProject().getName())); 495 } 496 } 497 498 /** 499 * Checks if the project in the given database context is not the "Online" project, 500 * and throws an Exception if this is the case.<p> 501 * 502 * This is used to ensure a user is in an "Offline" project 503 * before write access to VFS resources is granted.<p> 504 * 505 * @param dbc the current OpenCms users database context 506 * 507 * @throws CmsVfsException if the project in the given database context is the "Online" project 508 */ 509 public void checkOfflineProject(CmsDbContext dbc) throws CmsVfsException { 510 511 if (dbc.currentProject().isOnlineProject()) { 512 throw new CmsVfsException( 513 org.opencms.file.Messages.get().container( 514 org.opencms.file.Messages.ERR_NOT_ALLOWED_IN_ONLINE_PROJECT_0)); 515 } 516 } 517 518 /** 519 * Performs a blocking permission check on a resource.<p> 520 * 521 * If the required permissions are not satisfied by the permissions the user has on the resource, 522 * an exception is thrown.<p> 523 * 524 * @param context the current request context 525 * @param resource the resource on which permissions are required 526 * @param requiredPermissions the set of permissions required to access the resource 527 * @param checkLock if true, the lock status of the resource is also checked 528 * @param filter the filter for the resource 529 * 530 * @throws CmsException in case of any i/o error 531 * @throws CmsSecurityException if the required permissions are not satisfied 532 * 533 * @see #checkPermissions(CmsRequestContext, CmsResource, CmsPermissionSet, I_CmsPermissionHandler.CmsPermissionCheckResult) 534 */ 535 public void checkPermissions( 536 CmsRequestContext context, 537 CmsResource resource, 538 CmsPermissionSet requiredPermissions, 539 boolean checkLock, 540 CmsResourceFilter filter) 541 throws CmsException, CmsSecurityException { 542 543 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 544 try { 545 // check the access permissions 546 checkPermissions(dbc, resource, requiredPermissions, checkLock, filter); 547 } finally { 548 dbc.clear(); 549 } 550 } 551 552 /** 553 * Checks if the current user has the permissions to publish the given publish list 554 * (which contains the information about the resources / project to publish).<p> 555 * 556 * @param dbc the current OpenCms users database context 557 * @param publishList the publish list to check (contains the information about the resources / project to publish) 558 * 559 * @throws CmsException if the user does not have the required permissions because of project lock state 560 * @throws CmsMultiException if issues occur like a direct publish is attempted on a resource 561 * whose parent folder is new or deleted in the offline project, 562 * or if the current user has no management access to the current project 563 */ 564 public void checkPublishPermissions(CmsDbContext dbc, CmsPublishList publishList) 565 throws CmsException, CmsMultiException { 566 567 // is the current project an "offline" project? 568 checkOfflineProject(dbc); 569 570 // check if this is a "direct publish" attempt 571 if (!publishList.isDirectPublish()) { 572 // check if the user is a manager of the current project, in this case he has publish permissions 573 checkManagerOfProjectRole(dbc, dbc.getRequestContext().getCurrentProject()); 574 } else { 575 // direct publish, create exception containers 576 CmsMultiException resourceIssues = new CmsMultiException(); 577 CmsMultiException permissionIssues = new CmsMultiException(); 578 // iterate all resources in the direct publish list 579 Iterator<CmsResource> it = publishList.getDirectPublishResources().iterator(); 580 List<String> parentFolders = new ArrayList<String>(); 581 while (it.hasNext()) { 582 CmsResource res = it.next(); 583 // the parent folder must not be new or deleted 584 String parentFolder = CmsResource.getParentFolder(res.getRootPath()); 585 if ((parentFolder != null) && !parentFolders.contains(parentFolder)) { 586 // check each parent folder only once 587 CmsResource parent = readResource(dbc, parentFolder, CmsResourceFilter.ALL); 588 if (parent.getState().isDeleted()) { 589 if (!(publishList.isUserPublishList() && publishList.getDeletedFolderList().contains(parent))) { 590 // parent folder is deleted - direct publish not allowed 591 resourceIssues.addException( 592 new CmsVfsException( 593 Messages.get().container( 594 Messages.ERR_DIRECT_PUBLISH_PARENT_DELETED_2, 595 dbc.getRequestContext().removeSiteRoot(res.getRootPath()), 596 parentFolder))); 597 } 598 } 599 if (parent.getState().isNew()) { 600 if (!(publishList.isUserPublishList() && publishList.getFolderList().contains(parent))) { 601 // parent folder is new - direct publish not allowed 602 resourceIssues.addException( 603 new CmsVfsException( 604 Messages.get().container( 605 Messages.ERR_DIRECT_PUBLISH_PARENT_NEW_2, 606 dbc.removeSiteRoot(res.getRootPath()), 607 parentFolder))); 608 } 609 } 610 // add checked parent folder to prevent duplicate checks 611 parentFolders.add(parentFolder); 612 } 613 // check if the user has the explicit permission to direct publish the selected resource 614 if (I_CmsPermissionHandler.PERM_ALLOWED != hasPermissions( 615 dbc.getRequestContext(), 616 res, 617 CmsPermissionSet.ACCESS_DIRECT_PUBLISH, 618 true, 619 CmsResourceFilter.ALL)) { 620 621 // the user has no "direct publish" permissions on the resource 622 permissionIssues.addException( 623 new CmsSecurityException( 624 Messages.get().container( 625 Messages.ERR_DIRECT_PUBLISH_NO_PERMISSIONS_1, 626 dbc.removeSiteRoot(res.getRootPath())))); 627 } 628 } 629 if (resourceIssues.hasExceptions() || permissionIssues.hasExceptions()) { 630 // there are issues, permission check has failed 631 resourceIssues.addExceptions(permissionIssues.getExceptions()); 632 throw resourceIssues; 633 } 634 } 635 // no issues have been found , permissions are granted 636 } 637 638 /** 639 * Checks if the user of the current database context has permissions to impersonate the given role 640 * in the given organizational unit.<p> 641 * 642 * If the organizational unit is <code>null</code>, this method will check if the 643 * given user has the given role for at least one organizational unit.<p> 644 * 645 * @param dbc the current OpenCms users database context 646 * @param role the role to check 647 * 648 * @throws CmsRoleViolationException if the user does not have the required role permissions 649 * 650 * @see org.opencms.security.CmsRoleManager#checkRole(CmsObject, CmsRole) 651 */ 652 public void checkRole(CmsDbContext dbc, CmsRole role) throws CmsRoleViolationException { 653 654 if (!hasRole(dbc, dbc.currentUser(), role)) { 655 if (role.getOuFqn() != null) { 656 throw role.createRoleViolationExceptionForOrgUnit(dbc.getRequestContext(), role.getOuFqn()); 657 } else { 658 throw role.createRoleViolationException(dbc.getRequestContext()); 659 } 660 } 661 } 662 663 /** 664 * Checks if the user of the current context has permissions to impersonate the given role.<p> 665 * 666 * If the organizational unit is <code>null</code>, this method will check if the 667 * given user has the given role for at least one organizational unit.<p> 668 * 669 * @param context the current request context 670 * @param role the role to check 671 * 672 * @throws CmsRoleViolationException if the user does not have the required role permissions 673 */ 674 public void checkRole(CmsRequestContext context, CmsRole role) throws CmsRoleViolationException { 675 676 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 677 try { 678 checkRole(dbc, role); 679 } finally { 680 dbc.clear(); 681 } 682 } 683 684 /** 685 * Checks if the user of the current database context has permissions to impersonate the given role 686 * for the given resource.<p> 687 * 688 * @param dbc the current OpenCms users database context 689 * @param role the role to check 690 * @param resource the resource to check the role for 691 * 692 * @throws CmsRoleViolationException if the user does not have the required role permissions 693 * 694 * @see org.opencms.security.CmsRoleManager#checkRole(CmsObject, CmsRole) 695 */ 696 public void checkRoleForResource(CmsDbContext dbc, CmsRole role, CmsResource resource) 697 throws CmsRoleViolationException { 698 699 if (!hasRoleForResource(dbc, dbc.currentUser(), role, resource)) { 700 throw role.createRoleViolationExceptionForResource(dbc.getRequestContext(), resource); 701 } 702 } 703 704 /** 705 * Checks if the user of the current context has permissions to impersonate the given role 706 * for the given resource.<p> 707 * 708 * @param context the current request context 709 * @param role the role to check 710 * @param resource the resource to check the role for 711 * 712 * @throws CmsRoleViolationException if the user does not have the required role permissions 713 */ 714 public void checkRoleForResource(CmsRequestContext context, CmsRole role, CmsResource resource) 715 throws CmsRoleViolationException { 716 717 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 718 try { 719 checkRoleForResource(dbc, role, resource); 720 } finally { 721 dbc.clear(); 722 } 723 } 724 725 /** 726 * Changes the resource flags of a resource.<p> 727 * 728 * The resource flags are used to indicate various "special" conditions 729 * for a resource. Most notably, the "internal only" setting which signals 730 * that a resource can not be directly requested with it's URL.<p> 731 * 732 * @param context the current request context 733 * @param resource the resource to change the flags for 734 * @param flags the new resource flags for this resource 735 * 736 * @throws CmsException if something goes wrong 737 * @throws CmsSecurityException if the user has insufficient permission for the given resource (({@link CmsPermissionSet#ACCESS_WRITE} required) 738 * 739 * @see org.opencms.file.types.I_CmsResourceType#chflags(CmsObject, CmsSecurityManager, CmsResource, int) 740 */ 741 742 public void chflags(CmsRequestContext context, CmsResource resource, int flags) 743 throws CmsException, CmsSecurityException { 744 745 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 746 747 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 748 try { 749 checkOfflineProject(dbc); 750 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 751 m_driverManager.chflags(dbc, resource, flags); 752 modContext.add(resource); 753 } catch (Exception e) { 754 dbc.report( 755 null, 756 Messages.get().container(Messages.ERR_CHANGE_RESOURCE_FLAGS_1, context.getSitePath(resource)), 757 e); 758 } finally { 759 dbc.clear(); 760 } 761 } 762 } 763 764 /** 765 * Changes the resource type of a resource.<p> 766 * 767 * OpenCms handles resources according to the resource type, 768 * not the file suffix. This is e.g. why a JSP in OpenCms can have the 769 * suffix ".html" instead of ".jsp" only. Changing the resource type 770 * makes sense e.g. if you want to make a plain text file a JSP resource, 771 * or a binary file an image, etc.<p> 772 * 773 * @param context the current request context 774 * @param resource the resource to change the type for 775 * @param type the new resource type for this resource 776 * 777 * @throws CmsException if something goes wrong 778 * @throws CmsSecurityException if the user has insufficient permission for the given resource (({@link CmsPermissionSet#ACCESS_WRITE} required)) 779 * 780 * @see org.opencms.file.types.I_CmsResourceType#chtype(CmsObject, CmsSecurityManager, CmsResource, int) 781 * @see CmsObject#chtype(String, int) 782 */ 783 @SuppressWarnings("javadoc") 784 public void chtype(CmsRequestContext context, CmsResource resource, int type) 785 throws CmsException, CmsSecurityException { 786 787 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 788 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 789 try { 790 checkOfflineProject(dbc); 791 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 792 if (CmsResourceTypeJsp.isJspTypeId(type)) { 793 // security check preventing the creation of a jsp file without permissions 794 checkRoleForResource(dbc, CmsRole.VFS_MANAGER, resource); 795 } 796 m_driverManager.chtype(dbc, resource, type); 797 modContext.add(resource); 798 } catch (Exception e) { 799 dbc.report( 800 null, 801 Messages.get().container(Messages.ERR_CHANGE_RESOURCE_TYPE_1, context.getSitePath(resource)), 802 e); 803 } finally { 804 dbc.clear(); 805 } 806 } 807 } 808 809 /** 810 * Cleans up publish history entries according to the given filter object. 811 * 812 * @param context the request context 813 * @param filter the filter describing what to clean up 814 * @return the number of cleaned up rows 815 * @throws CmsException if something goes wrong 816 */ 817 public int cleanupPublishHistory(CmsRequestContext context, CmsPublishHistoryCleanupFilter filter) 818 throws CmsException { 819 820 checkRole(context, CmsRole.VFS_MANAGER); 821 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 822 try { 823 return m_driverManager.cleanupPublishHistory(dbc, filter); 824 } catch (Exception e) { 825 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 826 return 0; 827 } finally { 828 dbc.clear(); 829 } 830 831 } 832 833 /** 834 * Copies the access control entries of a given resource to a destination resource.<p> 835 * 836 * Already existing access control entries of the destination resource are removed.<p> 837 * 838 * @param context the current request context 839 * @param source the resource to copy the access control entries from 840 * @param destination the resource to which the access control entries are copied 841 * 842 * @throws CmsException if something goes wrong 843 * @throws CmsSecurityException if the user has insufficient permission for the given resource ({@link CmsPermissionSet#ACCESS_CONTROL} required) 844 */ 845 public void copyAccessControlEntries(CmsRequestContext context, CmsResource source, CmsResource destination) 846 throws CmsException, CmsSecurityException { 847 848 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 849 850 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 851 try { 852 checkOfflineProject(dbc); 853 checkPermissions(dbc, source, CmsPermissionSet.ACCESS_READ, true, CmsResourceFilter.ALL); 854 checkPermissions(dbc, destination, CmsPermissionSet.ACCESS_CONTROL, true, CmsResourceFilter.ALL); 855 m_driverManager.copyAccessControlEntries(dbc, source, destination, true); 856 modContext.add(destination); 857 } catch (Exception e) { 858 CmsRequestContext rc = context; 859 dbc.report( 860 null, 861 Messages.get().container( 862 Messages.ERR_COPY_ACE_2, 863 rc.removeSiteRoot(source.getRootPath()), 864 rc.removeSiteRoot(destination.getRootPath())), 865 e); 866 } finally { 867 dbc.clear(); 868 } 869 } 870 } 871 872 /** 873 * Copies a resource.<p> 874 * 875 * You must ensure that the destination path is an absolute, valid and 876 * existing VFS path. Relative paths from the source are currently not supported.<p> 877 * 878 * The copied resource will always be locked to the current user 879 * after the copy operation.<p> 880 * 881 * In case the target resource already exists, it is overwritten with the 882 * source resource.<p> 883 * 884 * The <code>siblingMode</code> parameter controls how to handle siblings 885 * during the copy operation.<br> 886 * Possible values for this parameter are: <br> 887 * <ul> 888 * <li><code>{@link org.opencms.file.CmsResource#COPY_AS_NEW}</code></li> 889 * <li><code>{@link org.opencms.file.CmsResource#COPY_AS_SIBLING}</code></li> 890 * <li><code>{@link org.opencms.file.CmsResource#COPY_PRESERVE_SIBLING}</code></li> 891 * </ul><p> 892 * 893 * @param context the current request context 894 * @param source the resource to copy 895 * @param destination the name of the copy destination with complete path 896 * @param siblingMode indicates how to handle siblings during copy 897 * 898 * @throws CmsException if something goes wrong 899 * @throws CmsSecurityException if resource could not be copied 900 * 901 * @see CmsObject#copyResource(String, String, CmsResource.CmsResourceCopyMode) 902 * @see org.opencms.file.types.I_CmsResourceType#copyResource(CmsObject, CmsSecurityManager, CmsResource, String, CmsResource.CmsResourceCopyMode) 903 */ 904 public void copyResource( 905 CmsRequestContext context, 906 CmsResource source, 907 String destination, 908 CmsResource.CmsResourceCopyMode siblingMode) 909 throws CmsException, CmsSecurityException { 910 911 if ((CmsModificationContext.isInOnlineFolder(destination) != CmsModificationContext.isInOnlineFolder( 912 source.getRootPath())) && (siblingMode != CmsResource.COPY_AS_NEW)) { 913 siblingMode = CmsResource.COPY_AS_NEW; 914 LOG.warn( 915 "Copying resources into or out of online folders - switching to copy mode COPY_AS_NEW: " 916 + source.getRootPath() 917 + " -> " 918 + destination); 919 } 920 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 921 922 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 923 try { 924 checkOfflineProject(dbc); 925 checkPermissions(dbc, source, CmsPermissionSet.ACCESS_READ, true, CmsResourceFilter.ALL); 926 if (source.isFolder() && destination.startsWith(source.getRootPath())) { 927 throw new CmsVfsException( 928 Messages.get().container( 929 Messages.ERR_RECURSIVE_INCLUSION_2, 930 dbc.removeSiteRoot(source.getRootPath()), 931 dbc.removeSiteRoot(destination))); 932 } 933 // target permissions will be checked later 934 CmsResource newResource = m_driverManager.copyResource(dbc, source, destination, siblingMode); 935 modContext.add(newResource); 936 } catch (Exception e) { 937 dbc.report( 938 null, 939 Messages.get().container( 940 Messages.ERR_COPY_RESOURCE_2, 941 dbc.removeSiteRoot(source.getRootPath()), 942 dbc.removeSiteRoot(destination)), 943 e); 944 } finally { 945 dbc.clear(); 946 } 947 } 948 } 949 950 /** 951 * Copies a resource to the current project of the user.<p> 952 * 953 * @param context the current request context 954 * @param resource the resource to apply this operation to 955 * 956 * @throws CmsException if something goes wrong 957 * @throws CmsRoleViolationException if the current user does not have management access to the project 958 * 959 * @see org.opencms.file.types.I_CmsResourceType#copyResourceToProject(CmsObject, CmsSecurityManager, CmsResource) 960 */ 961 public void copyResourceToProject(CmsRequestContext context, CmsResource resource) 962 throws CmsException, CmsRoleViolationException { 963 964 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 965 try { 966 checkOfflineProject(dbc); 967 checkManagerOfProjectRole(dbc, context.getCurrentProject()); 968 969 m_driverManager.copyResourceToProject(dbc, resource); 970 } catch (Exception e) { 971 dbc.report( 972 null, 973 Messages.get().container( 974 Messages.ERR_COPY_RESOURCE_TO_PROJECT_2, 975 context.getSitePath(resource), 976 context.getCurrentProject().getName()), 977 e); 978 } finally { 979 dbc.clear(); 980 } 981 } 982 983 /** 984 * Counts the locked resources in this project.<p> 985 * 986 * @param context the current request context 987 * @param id the id of the project 988 * 989 * @return the amount of locked resources in this project 990 * 991 * @throws CmsException if something goes wrong 992 * @throws CmsRoleViolationException if the current user does not have management access to the project 993 */ 994 public int countLockedResources(CmsRequestContext context, CmsUUID id) 995 throws CmsException, CmsRoleViolationException { 996 997 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 998 CmsProject project = null; 999 int result = 0; 1000 try { 1001 project = m_driverManager.readProject(dbc, id); 1002 checkManagerOfProjectRole(dbc, project); 1003 result = m_driverManager.countLockedResources(project); 1004 } catch (Exception e) { 1005 dbc.report( 1006 null, 1007 Messages.get().container( 1008 Messages.ERR_COUNT_LOCKED_RESOURCES_PROJECT_2, 1009 (project == null) ? "<failed to read>" : project.getName(), 1010 id), 1011 e); 1012 } finally { 1013 dbc.clear(); 1014 } 1015 return result; 1016 } 1017 1018 /** 1019 * Counts the total number of users which match the given search criteria.<p> 1020 * 1021 * @param requestContext the request context 1022 * @param searchParams the search criteria object 1023 * 1024 * @return the number of users which match the search criteria 1025 * @throws CmsException if something goes wrong 1026 */ 1027 public long countUsers(CmsRequestContext requestContext, CmsUserSearchParameters searchParams) throws CmsException { 1028 1029 CmsDbContext dbc = m_dbContextFactory.getDbContext(requestContext); 1030 try { 1031 return m_driverManager.countUsers(dbc, searchParams); 1032 } catch (Exception e) { 1033 dbc.report(null, Messages.get().container(Messages.ERR_COUNT_USERS_0), e); 1034 return -1; 1035 } finally { 1036 dbc.clear(); 1037 } 1038 } 1039 1040 /** 1041 * Creates a new user group.<p> 1042 * 1043 * @param context the current request context 1044 * @param name the name of the new group 1045 * @param description the description for the new group 1046 * @param flags the flags for the new group 1047 * @param parent the name of the parent group (or <code>null</code>) 1048 * 1049 * @return a <code>{@link CmsGroup}</code> object representing the newly created group 1050 * 1051 * @throws CmsException if operation was not successful. 1052 * @throws CmsRoleViolationException if the role {@link CmsRole#ACCOUNT_MANAGER} is not owned by the current user 1053 */ 1054 public CmsGroup createGroup(CmsRequestContext context, String name, String description, int flags, String parent) 1055 throws CmsException, CmsRoleViolationException { 1056 1057 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1058 1059 CmsGroup result = null; 1060 try { 1061 checkRole(dbc, CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(name))); 1062 result = m_driverManager.createGroup(dbc, new CmsUUID(), name, description, flags, parent); 1063 } catch (Exception e) { 1064 dbc.report(null, Messages.get().container(Messages.ERR_CREATE_GROUP_1, name), e); 1065 } finally { 1066 dbc.clear(); 1067 } 1068 return result; 1069 } 1070 1071 /** 1072 * Creates a new organizational unit.<p> 1073 * 1074 * @param context the current request context 1075 * @param ouFqn the fully qualified name of the new organizational unit 1076 * @param description the description of the new organizational unit 1077 * @param flags the flags for the new organizational unit 1078 * @param resource the first associated resource 1079 * 1080 * @return a <code>{@link CmsOrganizationalUnit}</code> object representing 1081 * the newly created organizational unit 1082 * 1083 * @throws CmsException if operation was not successful 1084 * 1085 * @see org.opencms.security.CmsOrgUnitManager#createOrganizationalUnit(CmsObject, String, String, int, String) 1086 */ 1087 public CmsOrganizationalUnit createOrganizationalUnit( 1088 CmsRequestContext context, 1089 String ouFqn, 1090 String description, 1091 int flags, 1092 CmsResource resource) 1093 throws CmsException { 1094 1095 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1096 CmsOrganizationalUnit result = null; 1097 try { 1098 checkRole(dbc, CmsRole.ADMINISTRATOR.forOrgUnit(getParentOrganizationalUnit(ouFqn))); 1099 checkOfflineProject(dbc); 1100 result = m_driverManager.createOrganizationalUnit( 1101 dbc, 1102 CmsOrganizationalUnit.removeLeadingSeparator(ouFqn), 1103 description, 1104 flags, 1105 resource); 1106 } catch (Exception e) { 1107 dbc.report(null, Messages.get().container(Messages.ERR_CREATE_ORGUNIT_1, ouFqn), e); 1108 } finally { 1109 dbc.clear(); 1110 } 1111 return result; 1112 } 1113 1114 /** 1115 * Creates a project.<p> 1116 * 1117 * @param context the current request context 1118 * @param name the name of the project to create 1119 * @param description the description of the project 1120 * @param groupname the project user group to be set 1121 * @param managergroupname the project manager group to be set 1122 * @param projecttype the type of the project 1123 * 1124 * @return the created project 1125 * 1126 * @throws CmsException if something goes wrong 1127 * @throws CmsRoleViolationException if the current user does not own the role {@link CmsRole#PROJECT_MANAGER} 1128 */ 1129 public CmsProject createProject( 1130 CmsRequestContext context, 1131 String name, 1132 String description, 1133 String groupname, 1134 String managergroupname, 1135 CmsProject.CmsProjectType projecttype) 1136 throws CmsException, CmsRoleViolationException { 1137 1138 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1139 CmsProject result = null; 1140 try { 1141 checkRole(dbc, CmsRole.PROJECT_MANAGER.forOrgUnit(getParentOrganizationalUnit(name))); 1142 result = m_driverManager.createProject( 1143 dbc, 1144 CmsOrganizationalUnit.removeLeadingSeparator(name), 1145 description, 1146 CmsOrganizationalUnit.removeLeadingSeparator(groupname), 1147 CmsOrganizationalUnit.removeLeadingSeparator(managergroupname), 1148 projecttype); 1149 } catch (Exception e) { 1150 dbc.report(null, Messages.get().container(Messages.ERR_CREATE_PROJECT_1, name), e); 1151 } finally { 1152 dbc.clear(); 1153 } 1154 return result; 1155 } 1156 1157 /** 1158 * Creates a property definition.<p> 1159 * 1160 * Property definitions are valid for all resource types.<p> 1161 * 1162 * @param context the current request context 1163 * @param name the name of the property definition to create 1164 * 1165 * @return the created property definition 1166 * 1167 * @throws CmsException if something goes wrong 1168 * @throws CmsSecurityException if the current project is online. 1169 * @throws CmsRoleViolationException if the current user does not own the role {@link CmsRole#WORKPLACE_MANAGER} 1170 */ 1171 public CmsPropertyDefinition createPropertyDefinition(CmsRequestContext context, String name) 1172 throws CmsException, CmsSecurityException, CmsRoleViolationException { 1173 1174 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1175 CmsPropertyDefinition result = null; 1176 1177 try { 1178 checkOfflineProject(dbc); 1179 checkRole(dbc, CmsRole.WORKPLACE_MANAGER.forOrgUnit(null)); 1180 result = m_driverManager.createPropertyDefinition(dbc, name); 1181 } catch (Exception e) { 1182 dbc.report(null, Messages.get().container(Messages.ERR_CREATE_PROPDEF_1, name), e); 1183 } finally { 1184 dbc.clear(); 1185 } 1186 return result; 1187 } 1188 1189 /** 1190 * Creates a new resource with the provided content and properties.<p> 1191 * An exception is thrown if a resource with the given name already exists.<p> 1192 * 1193 * @param context the current request context 1194 * @param resourcePath the name of the resource to create (full path) 1195 * @param resource the new resource to create 1196 * @param content the content for the new resource 1197 * @param properties the properties for the new resource 1198 * 1199 * @return the created resource 1200 * 1201 * @throws CmsVfsResourceAlreadyExistsException if a resource with the given name already exists 1202 * @throws CmsVfsException if the project in the given database context is the "Online" project 1203 * @throws CmsException if something goes wrong 1204 */ 1205 public CmsResource createResource( 1206 CmsRequestContext context, 1207 String resourcePath, 1208 CmsResource resource, 1209 byte[] content, 1210 List<CmsProperty> properties) 1211 throws CmsVfsResourceAlreadyExistsException, CmsVfsException, CmsException { 1212 1213 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 1214 if (existsResource(context, resourcePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 1215 // check if the resource already exists by name 1216 throw new CmsVfsResourceAlreadyExistsException( 1217 org.opencms.db.generic.Messages.get().container( 1218 org.opencms.db.generic.Messages.ERR_RESOURCE_WITH_NAME_ALREADY_EXISTS_1, 1219 resource.getRootPath())); 1220 } 1221 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1222 CmsResource newResource = null; 1223 try { 1224 checkOfflineProject(dbc); 1225 newResource = m_driverManager.createResource(dbc, resourcePath, resource, content, properties, false); 1226 } catch (Exception e) { 1227 dbc.report( 1228 null, 1229 Messages.get().container( 1230 Messages.ERR_IMPORT_RESOURCE_2, 1231 context.getSitePath(resource), 1232 resourcePath), 1233 e); 1234 } finally { 1235 dbc.clear(); 1236 } 1237 modContext.add(newResource); 1238 return newResource; 1239 } 1240 } 1241 1242 /** 1243 * Creates a new resource of the given resource type with the provided content and properties.<p> 1244 * 1245 * If the provided content is null and the resource is not a folder, the content will be set to an empty byte array.<p> 1246 * 1247 * @param context the current request context 1248 * @param resourcename the name of the resource to create (full path) 1249 * @param type the type of the resource to create 1250 * @param content the content for the new resource 1251 * @param properties the properties for the new resource 1252 * 1253 * @return the created resource 1254 * 1255 * @throws CmsException if something goes wrong 1256 * 1257 * @see org.opencms.file.types.I_CmsResourceType#createResource(CmsObject, CmsSecurityManager, String, byte[], List) 1258 */ 1259 public synchronized CmsResource createResource( 1260 CmsRequestContext context, 1261 String resourcename, 1262 int type, 1263 byte[] content, 1264 List<CmsProperty> properties) 1265 throws CmsException { 1266 1267 String checkExistsPath = "/".equals(resourcename) ? "/" : CmsFileUtil.removeTrailingSeparator(resourcename); 1268 // We use checkExistsPath instead of resourcename because when creating a folder /foo/bar/, we want to fail 1269 // if a file /foo/bar already exists. 1270 1271 if (existsResource(context, checkExistsPath, CmsResourceFilter.ALL)) { 1272 // check if the resource already exists by name 1273 throw new CmsVfsResourceAlreadyExistsException( 1274 org.opencms.db.generic.Messages.get().container( 1275 org.opencms.db.generic.Messages.ERR_RESOURCE_WITH_NAME_ALREADY_EXISTS_1, 1276 resourcename)); 1277 } 1278 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 1279 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1280 CmsResource newResource = null; 1281 try { 1282 checkOfflineProject(dbc); 1283 newResource = m_driverManager.createResource(dbc, resourcename, type, content, properties); 1284 } catch (Exception e) { 1285 dbc.report(null, Messages.get().container(Messages.ERR_CREATE_RESOURCE_1, resourcename), e); 1286 } finally { 1287 dbc.clear(); 1288 } 1289 modContext.add(newResource); 1290 return newResource; 1291 } 1292 } 1293 1294 /** 1295 * Creates a new sibling of the source resource.<p> 1296 * 1297 * @param context the current request context 1298 * @param source the resource to create a sibling for 1299 * @param destination the name of the sibling to create with complete path 1300 * @param properties the individual properties for the new sibling 1301 * 1302 * @return the new created sibling 1303 * 1304 * @throws CmsException if something goes wrong 1305 * 1306 * @see org.opencms.file.types.I_CmsResourceType#createSibling(CmsObject, CmsSecurityManager, CmsResource, String, List) 1307 */ 1308 public CmsResource createSibling( 1309 CmsRequestContext context, 1310 CmsResource source, 1311 String destination, 1312 List<CmsProperty> properties) 1313 throws CmsException { 1314 1315 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1316 CmsResource sibling = null; 1317 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 1318 1319 try { 1320 checkOfflineProject(dbc); 1321 sibling = m_driverManager.createSibling(dbc, source, destination, properties); 1322 } catch (Exception e) { 1323 dbc.report( 1324 null, 1325 Messages.get().container( 1326 Messages.ERR_CREATE_SIBLING_1, 1327 context.removeSiteRoot(source.getRootPath())), 1328 e); 1329 } finally { 1330 dbc.clear(); 1331 } 1332 if (sibling != null) { 1333 modContext.add(sibling); 1334 } 1335 return sibling; 1336 } 1337 } 1338 1339 /** 1340 * Creates the project for the temporary workplace files.<p> 1341 * 1342 * @param context the current request context 1343 * 1344 * @return the created project for the temporary workplace files 1345 * 1346 * @throws CmsException if something goes wrong 1347 */ 1348 public CmsProject createTempfileProject(CmsRequestContext context) throws CmsException { 1349 1350 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1351 1352 CmsProject result = null; 1353 try { 1354 checkRole(dbc, CmsRole.PROJECT_MANAGER.forOrgUnit(null)); 1355 result = m_driverManager.createTempfileProject(dbc); 1356 } catch (Exception e) { 1357 dbc.report(null, Messages.get().container(Messages.ERR_CREATE_TEMPFILE_PROJECT_0), e); 1358 } finally { 1359 dbc.clear(); 1360 } 1361 return result; 1362 } 1363 1364 /** 1365 * Creates a new user.<p> 1366 * 1367 * @param context the current request context 1368 * @param name the name for the new user 1369 * @param password the password for the new user 1370 * @param description the description for the new user 1371 * @param additionalInfos the additional infos for the user 1372 * 1373 * @return the created user 1374 * 1375 * @see CmsObject#createUser(String, String, String, Map) 1376 * 1377 * @throws CmsException if something goes wrong 1378 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} 1379 */ 1380 public CmsUser createUser( 1381 CmsRequestContext context, 1382 String name, 1383 String password, 1384 String description, 1385 Map<String, Object> additionalInfos) 1386 throws CmsException, CmsRoleViolationException { 1387 1388 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1389 1390 CmsUser result = null; 1391 try { 1392 checkRole(dbc, CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(name))); 1393 result = m_driverManager.createUser( 1394 dbc, 1395 CmsOrganizationalUnit.removeLeadingSeparator(name), 1396 password, 1397 description, 1398 additionalInfos); 1399 } catch (Exception e) { 1400 dbc.report(null, Messages.get().container(Messages.ERR_CREATE_USER_1, name), e); 1401 } finally { 1402 dbc.clear(); 1403 } 1404 return result; 1405 } 1406 1407 /** 1408 * Deletes alias entries matching a filter.<p> 1409 * 1410 * @param context the request context 1411 * @param filter the alias filter 1412 * 1413 * @throws CmsException if something goes wrong 1414 */ 1415 public void deleteAliases(CmsRequestContext context, CmsAliasFilter filter) throws CmsException { 1416 1417 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1418 try { 1419 m_driverManager.deleteAliases(dbc, context.getCurrentProject(), filter); 1420 } catch (Exception e) { 1421 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 1422 } finally { 1423 dbc.clear(); 1424 } 1425 1426 } 1427 1428 /** 1429 * Deletes all entries in the published resource table.<p> 1430 * 1431 * @param context the current request context 1432 * @param linkType the type of resource deleted (0= non-parameter, 1=parameter) 1433 * 1434 * @throws CmsException if something goes wrong 1435 */ 1436 public void deleteAllStaticExportPublishedResources(CmsRequestContext context, int linkType) throws CmsException { 1437 1438 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1439 try { 1440 m_driverManager.deleteAllStaticExportPublishedResources(dbc, linkType); 1441 } catch (Exception e) { 1442 dbc.report(null, Messages.get().container(Messages.ERR_DELETE_STATEXP_PUBLISHED_RESOURCES_0), e); 1443 } finally { 1444 dbc.clear(); 1445 } 1446 } 1447 1448 /** 1449 * Deletes a group, where all permissions, users and children of the group 1450 * are transfered to a replacement group.<p> 1451 * 1452 * @param context the current request context 1453 * @param groupId the id of the group to be deleted 1454 * @param replacementId the id of the group to be transfered, can be <code>null</code> 1455 * 1456 * @throws CmsException if operation was not successful 1457 * @throws CmsSecurityException if the group is a default group. 1458 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} 1459 */ 1460 public void deleteGroup(CmsRequestContext context, CmsUUID groupId, CmsUUID replacementId) 1461 throws CmsException, CmsRoleViolationException, CmsSecurityException { 1462 1463 CmsGroup group = readGroup(context, groupId); 1464 if (group.isRole()) { 1465 throw new CmsSecurityException(Messages.get().container(Messages.ERR_DELETE_ROLE_GROUP_1, group.getName())); 1466 } 1467 CmsDbContext dbc = null; 1468 try { 1469 dbc = getDbContextForDeletePrincipal(context); 1470 // catch own exception as special cause for general "Error deleting group". 1471 checkRole(dbc, CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(group.getName()))); 1472 m_driverManager.deleteGroup(dbc, group, replacementId); 1473 } catch (Exception e) { 1474 CmsDbContext dbcForException = m_dbContextFactory.getDbContext(context); 1475 dbcForException.report(null, Messages.get().container(Messages.ERR_DELETE_GROUP_1, group.getName()), e); 1476 dbcForException.clear(); 1477 } finally { 1478 if (null != dbc) { 1479 dbc.clear(); 1480 } 1481 } 1482 } 1483 1484 /** 1485 * Delete a user group.<p> 1486 * 1487 * Only groups that contain no subgroups can be deleted.<p> 1488 * 1489 * @param context the current request context 1490 * @param name the name of the group that is to be deleted 1491 * 1492 * @throws CmsException if operation was not successful 1493 * @throws CmsSecurityException if the group is a default group. 1494 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} 1495 */ 1496 public void deleteGroup(CmsRequestContext context, String name) 1497 throws CmsException, CmsRoleViolationException, CmsSecurityException { 1498 1499 CmsGroup group = readGroup(context, name); 1500 if (group.isRole()) { 1501 throw new CmsSecurityException(Messages.get().container(Messages.ERR_DELETE_ROLE_GROUP_1, name)); 1502 } 1503 CmsDbContext dbc = null; 1504 try { 1505 dbc = getDbContextForDeletePrincipal(context); 1506 // catch own exception as special cause for general "Error deleting group". 1507 checkRole(dbc, CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(name))); 1508 m_driverManager.deleteGroup(dbc, group, null); 1509 } catch (Exception e) { 1510 CmsDbContext dbcForException = m_dbContextFactory.getDbContext(context); 1511 dbcForException.report(null, Messages.get().container(Messages.ERR_DELETE_GROUP_1, name), e); 1512 dbcForException.clear(); 1513 } finally { 1514 if (null != dbc) { 1515 dbc.clear(); 1516 } 1517 } 1518 1519 } 1520 1521 /** 1522 * Deletes the versions from the history tables, keeping the given number of versions per resource.<p> 1523 * 1524 * @param context the current request context 1525 * @param versionsToKeep number of versions to keep, is ignored if negative 1526 * @param versionsDeleted number of versions to keep for deleted resources, is ignored if negative 1527 * @param timeDeleted deleted resources older than this will also be deleted, is ignored if negative 1528 * @param clearDeletedFilter a filter to evaluate whether a the history entry for deleted resources should be cleared 1529 * @param report the report for output logging 1530 * 1531 * @throws CmsException if operation was not successful 1532 * @throws CmsRoleViolationException if the current user does not own the role {@link CmsRole#WORKPLACE_MANAGER} 1533 */ 1534 public void deleteHistoricalVersions( 1535 CmsRequestContext context, 1536 int versionsToKeep, 1537 int versionsDeleted, 1538 long timeDeleted, 1539 Predicate<I_CmsHistoryResource> clearDeletedFilter, 1540 I_CmsReport report) 1541 throws CmsException, CmsRoleViolationException { 1542 1543 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1544 try { 1545 CmsFolder root = readFolder(dbc, "/", CmsResourceFilter.ALL); 1546 checkRole(dbc, CmsRole.WORKPLACE_MANAGER.forOrgUnit(null)); 1547 checkPermissions(dbc, root, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.ALL); 1548 m_driverManager.deleteHistoricalVersions( 1549 dbc, 1550 versionsToKeep, 1551 versionsDeleted, 1552 timeDeleted, 1553 clearDeletedFilter, 1554 report); 1555 } catch (Exception e) { 1556 dbc.report( 1557 null, 1558 Messages.get().container( 1559 Messages.ERR_DELETE_HISTORY_4, 1560 new Object[] { 1561 "/", 1562 Integer.valueOf(versionsToKeep), 1563 Integer.valueOf(versionsDeleted), 1564 new Date(timeDeleted)}), 1565 e); 1566 } finally { 1567 dbc.clear(); 1568 } 1569 } 1570 1571 /** 1572 * Deletes all log entries matching the given filter.<p> 1573 * 1574 * @param context the current user context 1575 * @param filter the filter to use for deletion 1576 * 1577 * @throws CmsException if something goes wrong 1578 * 1579 * @see #getLogEntries(CmsRequestContext, CmsLogFilter) 1580 * @see CmsObject#deleteLogEntries(CmsLogFilter) 1581 */ 1582 public void deleteLogEntries(CmsRequestContext context, CmsLogFilter filter) throws CmsException { 1583 1584 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1585 try { 1586 checkRole(dbc, CmsRole.WORKPLACE_MANAGER); 1587 m_driverManager.deleteLogEntries(dbc, filter); 1588 } catch (Exception e) { 1589 dbc.report(null, Messages.get().container(Messages.ERR_DELETE_LOG_0), e); 1590 } finally { 1591 dbc.clear(); 1592 } 1593 } 1594 1595 /** 1596 * Deletes an organizational unit.<p> 1597 * 1598 * Only organizational units that contain no sub organizational unit can be deleted.<p> 1599 * 1600 * The organizational unit can not be delete if it is used in the request context, 1601 * or if the current user belongs to it.<p> 1602 * 1603 * All users and groups in the given organizational unit will be deleted.<p> 1604 * 1605 * @param context the current request context 1606 * @param organizationalUnit the organizational unit to delete 1607 * 1608 * @throws CmsException if operation was not successful 1609 * 1610 * @see org.opencms.security.CmsOrgUnitManager#deleteOrganizationalUnit(CmsObject, String) 1611 */ 1612 public void deleteOrganizationalUnit(CmsRequestContext context, CmsOrganizationalUnit organizationalUnit) 1613 throws CmsException { 1614 1615 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1616 try { 1617 // check for root ou 1618 if (organizationalUnit.getParentFqn() == null) { 1619 throw new CmsDataAccessException( 1620 org.opencms.security.Messages.get().container( 1621 org.opencms.security.Messages.ERR_ORGUNIT_ROOT_EDITION_0)); 1622 } 1623 1624 checkRole(dbc, CmsRole.ADMINISTRATOR.forOrgUnit(getParentOrganizationalUnit(organizationalUnit.getName()))); 1625 checkOfflineProject(dbc); 1626 m_driverManager.deleteOrganizationalUnit(dbc, organizationalUnit); 1627 } catch (Exception e) { 1628 dbc.report(null, Messages.get().container(Messages.ERR_DELETE_ORGUNIT_1, organizationalUnit.getName()), e); 1629 } finally { 1630 dbc.clear(); 1631 } 1632 } 1633 1634 /** 1635 * Deletes a project.<p> 1636 * 1637 * All modified resources currently inside this project will be reset to their online state.<p> 1638 * 1639 * @param context the current request context 1640 * @param projectId the ID of the project to be deleted 1641 * 1642 * @throws CmsException if something goes wrong 1643 * @throws CmsRoleViolationException if the current user does not own management access to the project 1644 */ 1645 public void deleteProject(CmsRequestContext context, CmsUUID projectId) 1646 throws CmsException, CmsRoleViolationException { 1647 1648 if (projectId.equals(CmsProject.ONLINE_PROJECT_ID)) { 1649 // online project must not be deleted 1650 throw new CmsVfsException( 1651 org.opencms.file.Messages.get().container( 1652 org.opencms.file.Messages.ERR_NOT_ALLOWED_IN_ONLINE_PROJECT_0)); 1653 } 1654 1655 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1656 CmsProject deleteProject = null; 1657 try { 1658 // read the project that should be deleted 1659 deleteProject = m_driverManager.readProject(dbc, projectId); 1660 checkManagerOfProjectRole(dbc, deleteProject); 1661 m_driverManager.deleteProject(dbc, deleteProject); 1662 } catch (Exception e) { 1663 String projectName = (deleteProject == null ? String.valueOf(projectId) : deleteProject.getName()); 1664 dbc.report(null, Messages.get().container(Messages.ERR_DELETE_PROJECT_1, projectName), e); 1665 } finally { 1666 dbc.clear(); 1667 } 1668 } 1669 1670 /** 1671 * Deletes a property definition.<p> 1672 * 1673 * @param context the current request context 1674 * @param name the name of the property definition to delete 1675 * 1676 * @throws CmsException if something goes wrong 1677 * @throws CmsSecurityException if the project to delete is the "Online" project 1678 * @throws CmsRoleViolationException if the current user does not own the role {@link CmsRole#WORKPLACE_MANAGER} 1679 */ 1680 public void deletePropertyDefinition(CmsRequestContext context, String name) 1681 throws CmsException, CmsSecurityException, CmsRoleViolationException { 1682 1683 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1684 try { 1685 checkOfflineProject(dbc); 1686 checkRole(dbc, CmsRole.WORKPLACE_MANAGER.forOrgUnit(null)); 1687 m_driverManager.deletePropertyDefinition(dbc, name); 1688 } catch (Exception e) { 1689 dbc.report(null, Messages.get().container(Messages.ERR_DELETE_PROPERTY_1, name), e); 1690 } finally { 1691 dbc.clear(); 1692 } 1693 } 1694 1695 /** 1696 * Deletes all relations for the given resource matching the given filter.<p> 1697 * 1698 * @param context the current user context 1699 * @param resource the resource to delete the relations for 1700 * @param filter the filter to use for deletion 1701 * 1702 * @throws CmsException if something goes wrong 1703 * 1704 * @see #addRelationToResource(CmsRequestContext, CmsResource, CmsResource, CmsRelationType, boolean) 1705 * @see CmsObject#deleteRelationsFromResource(String, CmsRelationFilter) 1706 */ 1707 public void deleteRelationsForResource(CmsRequestContext context, CmsResource resource, CmsRelationFilter filter) 1708 throws CmsException { 1709 1710 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 1711 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1712 1713 try { 1714 checkOfflineProject(dbc); 1715 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 1716 m_driverManager.deleteRelationsForResource(dbc, resource, filter); 1717 modContext.add(resource); 1718 } catch (Exception e) { 1719 dbc.report( 1720 null, 1721 Messages.get().container( 1722 Messages.ERR_DELETE_RELATIONS_1, 1723 dbc.removeSiteRoot(resource.getRootPath())), 1724 e); 1725 } finally { 1726 dbc.clear(); 1727 } 1728 } 1729 } 1730 1731 /** 1732 * Deletes a resource given its name.<p> 1733 * 1734 * The <code>siblingMode</code> parameter controls how to handle siblings 1735 * during the delete operation.<br> 1736 * Possible values for this parameter are: <br> 1737 * <ul> 1738 * <li><code>{@link CmsResource#DELETE_REMOVE_SIBLINGS}</code></li> 1739 * <li><code>{@link CmsResource#DELETE_PRESERVE_SIBLINGS}</code></li> 1740 * </ul><p> 1741 * 1742 * @param context the current request context 1743 * @param resource the name of the resource to delete (full path) 1744 * @param siblingMode indicates how to handle siblings of the deleted resource 1745 * 1746 * @throws CmsException if something goes wrong 1747 * @throws CmsSecurityException if the user does not have {@link CmsPermissionSet#ACCESS_WRITE} on the given resource 1748 * 1749 * @see org.opencms.file.types.I_CmsResourceType#deleteResource(CmsObject, CmsSecurityManager, CmsResource, CmsResource.CmsResourceDeleteMode) 1750 */ 1751 public void deleteResource( 1752 CmsRequestContext context, 1753 CmsResource resource, 1754 CmsResource.CmsResourceDeleteMode siblingMode) 1755 throws CmsException, CmsSecurityException { 1756 1757 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 1758 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1759 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(context); 1760 final CmsUUID forbiddenFolderId = OpenCms.getPublishManager().getPublishListVerifier().addForbiddenParentFolder( 1761 resource.getRootPath(), 1762 Messages.get().getBundle(locale).key(Messages.ERR_FORBIDDEN_PARENT_CURRENTLY_DELETING_0)); 1763 try { 1764 checkOfflineProject(dbc); 1765 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 1766 checkSystemLocks(dbc, resource); 1767 1768 // check write permissions for subresources in case of deleting a folder 1769 if (resource.isFolder()) { 1770 dbc.getRequestContext().setAttribute(I_CmsVfsDriver.REQ_ATTR_CHECK_PERMISSIONS, Boolean.TRUE); 1771 try { 1772 m_driverManager.getVfsDriver(dbc).removeFolder(dbc, dbc.currentProject(), resource); 1773 } catch (CmsDataAccessException e) { 1774 // unwrap the permission violation exception 1775 if (e.getCause() instanceof CmsPermissionViolationException) { 1776 throw (CmsPermissionViolationException)e.getCause(); 1777 } else { 1778 throw e; 1779 } 1780 } 1781 dbc.getRequestContext().removeAttribute(I_CmsVfsDriver.REQ_ATTR_CHECK_PERMISSIONS); 1782 } 1783 1784 deleteResource(dbc, resource, siblingMode); 1785 } catch (Exception e) { 1786 dbc.report( 1787 null, 1788 Messages.get().container(Messages.ERR_DELETE_RESOURCE_1, context.getSitePath(resource)), 1789 e); 1790 } finally { 1791 OpenCms.getPublishManager().getPublishListVerifier().removeForbiddenParentFolder(forbiddenFolderId); 1792 dbc.clear(); 1793 } 1794 } 1795 } 1796 1797 /** 1798 * Deletes an entry in the published resource table.<p> 1799 * 1800 * @param context the current request context 1801 * @param resourceName The name of the resource to be deleted in the static export 1802 * @param linkType the type of resource deleted (0= non-parameter, 1=parameter) 1803 * @param linkParameter the parameters of the resource 1804 * 1805 * @throws CmsException if something goes wrong 1806 */ 1807 public void deleteStaticExportPublishedResource( 1808 CmsRequestContext context, 1809 String resourceName, 1810 int linkType, 1811 String linkParameter) 1812 throws CmsException { 1813 1814 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1815 try { 1816 m_driverManager.deleteStaticExportPublishedResource(dbc, resourceName, linkType, linkParameter); 1817 } catch (Exception e) { 1818 dbc.report( 1819 null, 1820 Messages.get().container(Messages.ERR_DELETE_STATEXP_PUBLISHES_RESOURCE_1, resourceName), 1821 e); 1822 } finally { 1823 dbc.clear(); 1824 } 1825 } 1826 1827 /** 1828 * Deletes a user.<p> 1829 * 1830 * @param context the current request context 1831 * @param userId the Id of the user to be deleted 1832 * 1833 * @throws CmsException if something goes wrong 1834 */ 1835 public void deleteUser(CmsRequestContext context, CmsUUID userId) throws CmsException { 1836 1837 CmsUser user = readUser(context, userId); 1838 deleteUser(context, user, null); 1839 } 1840 1841 /** 1842 * Deletes a user, where all permissions and resources attributes of the user 1843 * were transfered to a replacement user.<p> 1844 * 1845 * @param context the current request context 1846 * @param userId the id of the user to be deleted 1847 * @param replacementId the id of the user to be transfered 1848 * 1849 * @throws CmsException if operation was not successful 1850 */ 1851 public void deleteUser(CmsRequestContext context, CmsUUID userId, CmsUUID replacementId) throws CmsException { 1852 1853 CmsUser user = readUser(context, userId); 1854 CmsUser replacementUser = null; 1855 if ((replacementId != null) && !replacementId.isNullUUID()) { 1856 replacementUser = readUser(context, replacementId); 1857 } 1858 deleteUser(context, user, replacementUser); 1859 } 1860 1861 /** 1862 * Deletes a user.<p> 1863 * 1864 * @param context the current request context 1865 * @param username the name of the user to be deleted 1866 * 1867 * @throws CmsException if something goes wrong 1868 */ 1869 public void deleteUser(CmsRequestContext context, String username) throws CmsException { 1870 1871 CmsUser user = readUser(context, username); 1872 deleteUser(context, user, null); 1873 } 1874 1875 /** 1876 * Destroys this security manager.<p> 1877 * 1878 * @throws Throwable if something goes wrong 1879 */ 1880 public synchronized void destroy() throws Throwable { 1881 1882 try { 1883 if (m_driverManager != null) { 1884 if (m_driverManager.getLockManager() != null) { 1885 try { 1886 writeLocks(); 1887 } catch (Throwable t) { 1888 if (LOG.isErrorEnabled()) { 1889 LOG.error( 1890 org.opencms.lock.Messages.get().getBundle().key( 1891 org.opencms.lock.Messages.ERR_WRITE_LOCKS_FINAL_0), 1892 t); 1893 } 1894 } 1895 } 1896 m_driverManager.destroy(); 1897 } 1898 } catch (Throwable t) { 1899 if (LOG.isErrorEnabled()) { 1900 LOG.error(Messages.get().getBundle().key(Messages.LOG_ERR_DRIVER_MANAGER_CLOSE_0), t); 1901 } 1902 } 1903 1904 m_driverManager = null; 1905 m_dbContextFactory = null; 1906 1907 if (CmsLog.INIT.isInfoEnabled()) { 1908 CmsLog.INIT.info( 1909 Messages.get().getBundle().key(Messages.INIT_SECURITY_MANAGER_SHUTDOWN_1, this.getClass().getName())); 1910 } 1911 } 1912 1913 /** 1914 * Checks the availability of a resource in the VFS, 1915 * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p> 1916 * 1917 * A resource may be of type <code>{@link CmsFile}</code> or 1918 * <code>{@link CmsFolder}</code>.<p> 1919 * 1920 * The specified filter controls what kind of resources should be "found" 1921 * during the read operation. This will depend on the application. For example, 1922 * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently 1923 * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code> 1924 * will ignore the date release / date expired information of the resource.<p> 1925 * 1926 * This method also takes into account the user permissions, so if 1927 * the given resource exists, but the current user has not the required 1928 * permissions, then this method will return <code>false</code>.<p> 1929 * 1930 * @param context the current request context 1931 * @param structureId the structure id of the resource to check 1932 * @param filter the resource filter to use while reading 1933 * 1934 * @return <code>true</code> if the resource is available 1935 * 1936 * @see CmsObject#existsResource(CmsUUID, CmsResourceFilter) 1937 * @see CmsObject#existsResource(CmsUUID) 1938 */ 1939 public boolean existsResource(CmsRequestContext context, CmsUUID structureId, CmsResourceFilter filter) { 1940 1941 boolean result = false; 1942 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1943 try { 1944 readResource(dbc, structureId, filter); 1945 result = true; 1946 } catch (Exception e) { 1947 result = false; 1948 } finally { 1949 dbc.clear(); 1950 } 1951 return result; 1952 } 1953 1954 /** 1955 * Checks the availability of a resource in the VFS, 1956 * using the <code>{@link CmsResourceFilter#DEFAULT}</code> filter.<p> 1957 * 1958 * A resource may be of type <code>{@link CmsFile}</code> or 1959 * <code>{@link CmsFolder}</code>.<p> 1960 * 1961 * The specified filter controls what kind of resources should be "found" 1962 * during the read operation. This will depend on the application. For example, 1963 * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently 1964 * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code> 1965 * will ignore the date release / date expired information of the resource.<p> 1966 * 1967 * This method also takes into account the user permissions, so if 1968 * the given resource exists, but the current user has not the required 1969 * permissions, then this method will return <code>false</code>.<p> 1970 * 1971 * @param context the current request context 1972 * @param resourcePath the name of the resource to read (full path) 1973 * @param filter the resource filter to use while reading 1974 * 1975 * @return <code>true</code> if the resource is available 1976 * 1977 * @see CmsObject#existsResource(String, CmsResourceFilter) 1978 * @see CmsObject#existsResource(String) 1979 */ 1980 public boolean existsResource(CmsRequestContext context, String resourcePath, CmsResourceFilter filter) { 1981 1982 boolean result = false; 1983 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 1984 try { 1985 readResource(dbc, resourcePath, filter); 1986 result = true; 1987 } catch (Exception e) { 1988 result = false; 1989 } finally { 1990 dbc.clear(); 1991 } 1992 return result; 1993 } 1994 1995 /** 1996 * Fills the given publish list with the the VFS resources that actually get published.<p> 1997 * 1998 * Please refer to the source code of this method for the rules on how to decide whether a 1999 * new/changed/deleted <code>{@link CmsResource}</code> object can be published or not.<p> 2000 * 2001 * @param context the current request context 2002 * @param publishList must be initialized with basic publish information (Project or direct publish operation) 2003 * 2004 * @return the given publish list filled with all new/changed/deleted files from the current (offline) project 2005 * that will be published actually 2006 * 2007 * @throws CmsException if something goes wrong 2008 * 2009 * @see org.opencms.db.CmsPublishList 2010 */ 2011 public CmsPublishList fillPublishList(CmsRequestContext context, CmsPublishList publishList) throws CmsException { 2012 2013 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2014 try { 2015 m_driverManager.fillPublishList(dbc, publishList); 2016 checkPublishPermissions(dbc, publishList); 2017 } catch (CmsTooManyPublishResourcesException e) { 2018 throw e; 2019 } catch (Exception e) { 2020 if (publishList.isDirectPublish()) { 2021 dbc.report( 2022 null, 2023 Messages.get().container( 2024 Messages.ERR_GET_PUBLISH_LIST_DIRECT_1, 2025 CmsFileUtil.formatResourceNames(context, publishList.getDirectPublishResources())), 2026 e); 2027 } else { 2028 dbc.report( 2029 null, 2030 Messages.get().container( 2031 Messages.ERR_GET_PUBLISH_LIST_PROJECT_1, 2032 context.getCurrentProject().getName()), 2033 e); 2034 } 2035 } finally { 2036 dbc.clear(); 2037 } 2038 return publishList; 2039 } 2040 2041 /** 2042 * Returns the list of access control entries of a resource given its name.<p> 2043 * 2044 * @param context the current request context 2045 * @param resource the resource to read the access control entries for 2046 * @param getInherited true if the result should include all access control entries inherited by parent folders 2047 * 2048 * @return a list of <code>{@link CmsAccessControlEntry}</code> objects defining all permissions for the given resource 2049 * 2050 * @throws CmsException if something goes wrong 2051 */ 2052 public List<CmsAccessControlEntry> getAccessControlEntries( 2053 CmsRequestContext context, 2054 CmsResource resource, 2055 boolean getInherited) 2056 throws CmsException { 2057 2058 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2059 List<CmsAccessControlEntry> result = null; 2060 try { 2061 result = m_driverManager.getAccessControlEntries(dbc, resource, getInherited); 2062 } catch (Exception e) { 2063 dbc.report( 2064 null, 2065 Messages.get().container(Messages.ERR_GET_ACL_ENTRIES_1, context.getSitePath(resource)), 2066 e); 2067 } finally { 2068 dbc.clear(); 2069 } 2070 return result; 2071 } 2072 2073 /** 2074 * Returns the access control list (summarized access control entries) of a given resource.<p> 2075 * 2076 * If <code>inheritedOnly</code> is set, only inherited access control entries are returned.<p> 2077 * 2078 * @param context the current request context 2079 * @param resource the resource 2080 * @param inheritedOnly skip non-inherited entries if set 2081 * 2082 * @return the access control list of the resource 2083 * 2084 * @throws CmsException if something goes wrong 2085 */ 2086 public CmsAccessControlList getAccessControlList( 2087 CmsRequestContext context, 2088 CmsResource resource, 2089 boolean inheritedOnly) 2090 throws CmsException { 2091 2092 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2093 CmsAccessControlList result = null; 2094 try { 2095 result = m_driverManager.getAccessControlList(dbc, resource, inheritedOnly); 2096 } catch (Exception e) { 2097 dbc.report( 2098 null, 2099 Messages.get().container(Messages.ERR_GET_ACL_ENTRIES_1, context.getSitePath(resource)), 2100 e); 2101 2102 } finally { 2103 dbc.clear(); 2104 } 2105 return result; 2106 } 2107 2108 /** 2109 * Gets the aliases for a given site.<p> 2110 * 2111 * @param requestContext the current request context 2112 * @param siteRoot the site root 2113 * 2114 * @return the list of aliases for the given site root 2115 * 2116 * @throws CmsException if something goes wrong 2117 */ 2118 public List<CmsAlias> getAliasesForSite(CmsRequestContext requestContext, String siteRoot) throws CmsException { 2119 2120 CmsDbContext dbc = m_dbContextFactory.getDbContext(requestContext); 2121 try { 2122 List<CmsAlias> aliases = m_driverManager.readAliasesBySite( 2123 dbc, 2124 requestContext.getCurrentProject(), 2125 siteRoot); 2126 return aliases; 2127 } catch (Exception e) { 2128 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 2129 return null; // will never be executed 2130 } finally { 2131 dbc.clear(); 2132 } 2133 } 2134 2135 /** 2136 * Gets all access control entries.<p> 2137 * 2138 * @param context the current request context 2139 * @return the list of all access control entries 2140 * 2141 * @throws CmsException if something goes wrong 2142 */ 2143 public List<CmsAccessControlEntry> getAllAccessControlEntries(CmsRequestContext context) throws CmsException { 2144 2145 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2146 List<CmsAccessControlEntry> result = null; 2147 try { 2148 result = m_driverManager.getAllAccessControlEntries(dbc); 2149 } catch (Exception e) { 2150 dbc.report(null, Messages.get().container(Messages.ERR_GET_ACL_ENTRIES_1, "<all resources>"), e); 2151 } finally { 2152 dbc.clear(); 2153 } 2154 return result; 2155 2156 } 2157 2158 /** 2159 * Returns all projects which are owned by the current user or which are 2160 * accessible for the group of the user.<p> 2161 * 2162 * @param context the current request context 2163 * @param orgUnit the organizational unit to search project in 2164 * @param includeSubOus if to include sub organizational units 2165 * 2166 * @return a list of objects of type <code>{@link CmsProject}</code> 2167 * 2168 * @throws CmsException if something goes wrong 2169 */ 2170 public List<CmsProject> getAllAccessibleProjects( 2171 CmsRequestContext context, 2172 CmsOrganizationalUnit orgUnit, 2173 boolean includeSubOus) 2174 throws CmsException { 2175 2176 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2177 List<CmsProject> result = null; 2178 try { 2179 result = m_driverManager.getAllAccessibleProjects(dbc, orgUnit, includeSubOus); 2180 } catch (Exception e) { 2181 dbc.report( 2182 null, 2183 Messages.get().container(Messages.ERR_GET_ALL_ACCESSIBLE_PROJECTS_1, dbc.currentUser().getName()), 2184 e); 2185 } finally { 2186 dbc.clear(); 2187 } 2188 return result; 2189 } 2190 2191 /** 2192 * Returns a list with all projects from history.<p> 2193 * 2194 * @param context the current request context 2195 * 2196 * @return list of <code>{@link CmsHistoryProject}</code> objects 2197 * with all projects from history. 2198 * 2199 * @throws CmsException if operation was not successful 2200 */ 2201 public List<CmsHistoryProject> getAllHistoricalProjects(CmsRequestContext context) throws CmsException { 2202 2203 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2204 List<CmsHistoryProject> result = null; 2205 try { 2206 result = m_driverManager.getAllHistoricalProjects(dbc); 2207 } catch (Exception e) { 2208 dbc.report( 2209 null, 2210 Messages.get().container(Messages.ERR_GET_ALL_ACCESSIBLE_PROJECTS_1, dbc.currentUser().getName()), 2211 e); 2212 } finally { 2213 dbc.clear(); 2214 } 2215 return result; 2216 } 2217 2218 /** 2219 * Returns all projects which are owned by the current user or which are manageable 2220 * for the group of the user.<p> 2221 * 2222 * @param context the current request context 2223 * @param orgUnit the organizational unit to search project in 2224 * @param includeSubOus if to include sub organizational units 2225 * 2226 * @return a list of objects of type <code>{@link CmsProject}</code> 2227 * 2228 * @throws CmsException if operation was not successful 2229 */ 2230 public List<CmsProject> getAllManageableProjects( 2231 CmsRequestContext context, 2232 CmsOrganizationalUnit orgUnit, 2233 boolean includeSubOus) 2234 throws CmsException { 2235 2236 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2237 List<CmsProject> result = null; 2238 try { 2239 result = m_driverManager.getAllManageableProjects(dbc, orgUnit, includeSubOus); 2240 } catch (Exception e) { 2241 dbc.report( 2242 null, 2243 Messages.get().container(Messages.ERR_GET_ALL_MANAGEABLE_PROJECTS_1, dbc.currentUser().getName()), 2244 e); 2245 } finally { 2246 dbc.clear(); 2247 } 2248 return result; 2249 } 2250 2251 /** 2252 * Returns all child groups of a group.<p> 2253 * 2254 * This method also returns all sub-child groups of the current group.<p> 2255 * 2256 * @param context the current request context 2257 * @param groupname the name of the group 2258 * @param includeSubChildren if set also returns all sub-child groups of the given group 2259 * 2260 * @return a list of all child <code>{@link CmsGroup}</code> objects or <code>null</code> 2261 * 2262 * @throws CmsException if operation was not successful 2263 */ 2264 public List<CmsGroup> getChildren(CmsRequestContext context, String groupname, boolean includeSubChildren) 2265 throws CmsException { 2266 2267 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2268 List<CmsGroup> result = null; 2269 try { 2270 result = m_driverManager.getChildren( 2271 dbc, 2272 m_driverManager.readGroup(dbc, CmsOrganizationalUnit.removeLeadingSeparator(groupname)), 2273 includeSubChildren); 2274 } catch (Exception e) { 2275 dbc.report(null, Messages.get().container(Messages.ERR_GET_CHILD_GROUPS_TRANSITIVE_1, groupname), e); 2276 } finally { 2277 dbc.clear(); 2278 } 2279 return result; 2280 } 2281 2282 /** 2283 * Gets a connection from a connection pool.<p> 2284 * @param poolUrl the connection pool url 2285 * @return a new connection from the pool 2286 * 2287 * @throws SQLException if getting the connection fails 2288 */ 2289 public Connection getConnection(String poolUrl) throws SQLException { 2290 2291 CmsDbPoolV11 pool = CmsDriverManager.m_pools.get(poolUrl); 2292 return pool.getConnection(); 2293 2294 } 2295 2296 /** 2297 * Returns the date when the resource was last visited by the user.<p> 2298 * 2299 * @param context the request context 2300 * @param poolName the name of the database pool to use 2301 * @param user the user to check the date 2302 * @param resource the resource to check the date 2303 * 2304 * @return the date when the resource was last visited by the user 2305 * 2306 * @throws CmsException if something goes wrong 2307 */ 2308 public long getDateLastVisitedBy(CmsRequestContext context, String poolName, CmsUser user, CmsResource resource) 2309 throws CmsException { 2310 2311 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2312 long result = 0; 2313 try { 2314 result = m_driverManager.getDateLastVisitedBy(dbc, poolName, user, resource); 2315 } catch (Exception e) { 2316 dbc.report( 2317 null, 2318 Messages.get().container( 2319 Messages.ERR_GET_DATE_LASTVISITED_2, 2320 user.getName(), 2321 context.getSitePath(resource)), 2322 e); 2323 } finally { 2324 dbc.clear(); 2325 } 2326 return result; 2327 } 2328 2329 /** 2330 * Returns all groups of the given organizational unit.<p> 2331 * 2332 * @param context the current request context 2333 * @param orgUnit the organizational unit to get the groups for 2334 * @param includeSubOus if all groups of sub-organizational units should be retrieved too 2335 * @param readRoles if to read roles or groups 2336 * 2337 * @return all <code>{@link CmsGroup}</code> objects in the organizational unit 2338 * 2339 * @throws CmsException if operation was not successful 2340 * 2341 * @see org.opencms.security.CmsOrgUnitManager#getResourcesForOrganizationalUnit(CmsObject, String) 2342 * @see org.opencms.security.CmsOrgUnitManager#getGroups(CmsObject, String, boolean) 2343 * @see org.opencms.security.CmsOrgUnitManager#getUsers(CmsObject, String, boolean) 2344 */ 2345 public List<CmsGroup> getGroups( 2346 CmsRequestContext context, 2347 CmsOrganizationalUnit orgUnit, 2348 boolean includeSubOus, 2349 boolean readRoles) 2350 throws CmsException { 2351 2352 List<CmsGroup> result = null; 2353 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2354 try { 2355 result = m_driverManager.getGroups(dbc, orgUnit, includeSubOus, readRoles); 2356 } catch (Exception e) { 2357 dbc.report(null, Messages.get().container(Messages.ERR_READ_ORGUNIT_GROUPS_1, orgUnit.getName()), e); 2358 } finally { 2359 dbc.clear(); 2360 } 2361 return result; 2362 } 2363 2364 /** 2365 * Returns the list of groups to which the user directly belongs to.<p> 2366 * 2367 * @param context the current request context 2368 * @param username The name of the user 2369 * @param ouFqn the fully qualified name of the organizational unit to restrict the result set for 2370 * @param includeChildOus include groups of child organizational units 2371 * @param readRoles if to read roles or groups 2372 * @param directGroupsOnly if set only the direct assigned groups will be returned, if not also indirect roles 2373 * @param remoteAddress the IP address to filter the groups in the result list 2374 * 2375 * @return a list of <code>{@link CmsGroup}</code> objects filtered by the given IP address 2376 * 2377 * @throws CmsException if operation was not successful 2378 */ 2379 public List<CmsGroup> getGroupsOfUser( 2380 CmsRequestContext context, 2381 String username, 2382 String ouFqn, 2383 boolean includeChildOus, 2384 boolean readRoles, 2385 boolean directGroupsOnly, 2386 String remoteAddress) 2387 throws CmsException { 2388 2389 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2390 List<CmsGroup> result = null; 2391 try { 2392 result = m_driverManager.getGroupsOfUser( 2393 dbc, 2394 CmsOrganizationalUnit.removeLeadingSeparator(username), 2395 CmsOrganizationalUnit.removeLeadingSeparator(ouFqn), 2396 includeChildOus, 2397 readRoles, 2398 directGroupsOnly, 2399 remoteAddress); 2400 } catch (Exception e) { 2401 dbc.report(null, Messages.get().container(Messages.ERR_GET_GROUPS_OF_USER_2, username, remoteAddress), e); 2402 } finally { 2403 dbc.clear(); 2404 } 2405 return result; 2406 } 2407 2408 /** 2409 * Returns the lock state of a resource.<p> 2410 * 2411 * @param context the current request context 2412 * @param resource the resource to return the lock state for 2413 * 2414 * @return the lock state of the resource 2415 * 2416 * @throws CmsException if something goes wrong 2417 */ 2418 public CmsLock getLock(CmsRequestContext context, CmsResource resource) throws CmsException { 2419 2420 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2421 CmsLock result = null; 2422 try { 2423 result = m_driverManager.getLock(dbc, resource); 2424 } catch (Exception e) { 2425 dbc.report(null, Messages.get().container(Messages.ERR_GET_LOCK_1, context.getSitePath(resource)), e); 2426 } finally { 2427 dbc.clear(); 2428 } 2429 return result; 2430 } 2431 2432 /** 2433 * Returns all locked resources in a given folder.<p> 2434 * 2435 * @param context the current request context 2436 * @param resource the folder to search in 2437 * @param filter the lock filter 2438 * 2439 * @return a list of locked resource paths (relative to current site) 2440 * 2441 * @throws CmsException if something goes wrong 2442 */ 2443 public List<String> getLockedResources(CmsRequestContext context, CmsResource resource, CmsLockFilter filter) 2444 throws CmsException { 2445 2446 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2447 List<String> result = null; 2448 try { 2449 checkOfflineProject(dbc); 2450 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_READ, false, CmsResourceFilter.ALL); 2451 result = m_driverManager.getLockedResources(dbc, resource, filter); 2452 } catch (Exception e) { 2453 dbc.report( 2454 null, 2455 Messages.get().container(Messages.ERR_COUNT_LOCKED_RESOURCES_FOLDER_1, context.getSitePath(resource)), 2456 e); 2457 } finally { 2458 dbc.clear(); 2459 } 2460 return result; 2461 } 2462 2463 /** 2464 * Returns all locked resources in a given folder.<p> 2465 * 2466 * @param context the current request context 2467 * @param resource the folder to search in 2468 * @param filter the lock filter 2469 * 2470 * @return a list of locked resource paths (relative to current site) 2471 * 2472 * @throws CmsException if something goes wrong 2473 */ 2474 public List<CmsResource> getLockedResourcesObjects( 2475 CmsRequestContext context, 2476 CmsResource resource, 2477 CmsLockFilter filter) 2478 throws CmsException { 2479 2480 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2481 List<CmsResource> result = null; 2482 try { 2483 checkOfflineProject(dbc); 2484 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_READ, false, CmsResourceFilter.ALL); 2485 result = m_driverManager.getLockedResourcesObjects(dbc, resource, filter); 2486 } catch (Exception e) { 2487 dbc.report( 2488 null, 2489 Messages.get().container(Messages.ERR_COUNT_LOCKED_RESOURCES_FOLDER_1, context.getSitePath(resource)), 2490 e); 2491 } finally { 2492 dbc.clear(); 2493 } 2494 return result; 2495 } 2496 2497 /** 2498 * Returns all locked resources in a given folder, but uses a cache for resource lookups.<p> 2499 * 2500 * @param context the current request context 2501 * @param resource the folder to search in 2502 * @param filter the lock filter 2503 * @param cache the cache to use 2504 * 2505 * @return a list of locked resource paths (relative to current site) 2506 * 2507 * @throws CmsException if something goes wrong 2508 */ 2509 public List<CmsResource> getLockedResourcesObjectsWithCache( 2510 CmsRequestContext context, 2511 CmsResource resource, 2512 CmsLockFilter filter, 2513 Map<String, CmsResource> cache) 2514 throws CmsException { 2515 2516 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2517 List<CmsResource> result = null; 2518 try { 2519 checkOfflineProject(dbc); 2520 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_READ, false, CmsResourceFilter.ALL); 2521 result = m_driverManager.getLockedResourcesObjectsWithCache(dbc, resource, filter, cache); 2522 } catch (Exception e) { 2523 dbc.report( 2524 null, 2525 Messages.get().container(Messages.ERR_COUNT_LOCKED_RESOURCES_FOLDER_1, context.getSitePath(resource)), 2526 e); 2527 } finally { 2528 dbc.clear(); 2529 } 2530 return result; 2531 } 2532 2533 /** 2534 * Returns the lock manger.<p> 2535 * 2536 * @return the lock manager 2537 */ 2538 public CmsLockManager getLockManager() { 2539 2540 return m_lockManager; 2541 } 2542 2543 /** 2544 * Returns all log entries matching the given filter.<p> 2545 * 2546 * @param context the current user context 2547 * @param filter the filter to match the log entries 2548 * 2549 * @return all log entries matching the given filter 2550 * 2551 * @throws CmsException if something goes wrong 2552 * 2553 * @see CmsObject#getLogEntries(CmsLogFilter) 2554 */ 2555 public List<CmsLogEntry> getLogEntries(CmsRequestContext context, CmsLogFilter filter) throws CmsException { 2556 2557 List<CmsLogEntry> result = null; 2558 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2559 try { 2560 result = m_driverManager.getLogEntries(dbc, filter); 2561 } catch (Exception e) { 2562 dbc.report(null, Messages.get().container(Messages.ERR_READ_LOG_ENTRIES_0), e); 2563 } finally { 2564 dbc.clear(); 2565 } 2566 return result; 2567 } 2568 2569 /** 2570 * Returns all resources of organizational units for which the current user has 2571 * the given role role.<p> 2572 * 2573 * @param context the current request context 2574 * @param role the role to check 2575 * 2576 * @return a list of {@link org.opencms.file.CmsResource} objects 2577 * 2578 * @throws CmsException if something goes wrong 2579 */ 2580 public List<CmsResource> getManageableResources(CmsRequestContext context, CmsRole role) throws CmsException { 2581 2582 List<CmsResource> resources; 2583 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2584 try { 2585 resources = getManageableResources(dbc, role); 2586 } finally { 2587 dbc.clear(); 2588 } 2589 return resources; 2590 } 2591 2592 /** 2593 * Returns all child organizational units of the given parent organizational unit including 2594 * hierarchical deeper organization units if needed.<p> 2595 * 2596 * @param context the current request context 2597 * @param parent the parent organizational unit 2598 * @param includeChildren if hierarchical deeper organization units should also be returned 2599 * 2600 * @return a list of <code>{@link CmsOrganizationalUnit}</code> objects 2601 * 2602 * @throws CmsException if operation was not successful 2603 * 2604 * @see org.opencms.security.CmsOrgUnitManager#getOrganizationalUnits(CmsObject, String, boolean) 2605 */ 2606 public List<CmsOrganizationalUnit> getOrganizationalUnits( 2607 CmsRequestContext context, 2608 CmsOrganizationalUnit parent, 2609 boolean includeChildren) 2610 throws CmsException { 2611 2612 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2613 List<CmsOrganizationalUnit> result = null; 2614 try { 2615 result = m_driverManager.getOrganizationalUnits(dbc, parent, includeChildren); 2616 } catch (Exception e) { 2617 dbc.report(null, Messages.get().container(Messages.ERR_GET_ORGUNITS_1, parent.getName()), e); 2618 } finally { 2619 dbc.clear(); 2620 } 2621 return result; 2622 } 2623 2624 /** 2625 * Returns all the organizational units for which the current user has the given role.<p> 2626 * 2627 * @param requestContext the current request context 2628 * @param role the role to check 2629 * @param includeSubOus if sub organizational units should be included in the search 2630 * 2631 * @return a list of {@link org.opencms.security.CmsOrganizationalUnit} objects 2632 * 2633 * @throws CmsException if something goes wrong 2634 */ 2635 public List<CmsOrganizationalUnit> getOrgUnitsForRole( 2636 CmsRequestContext requestContext, 2637 CmsRole role, 2638 boolean includeSubOus) 2639 throws CmsException { 2640 2641 CmsDbContext dbc = m_dbContextFactory.getDbContext(requestContext); 2642 List<CmsOrganizationalUnit> result = null; 2643 try { 2644 result = m_driverManager.getOrgUnitsForRole(dbc, role, includeSubOus); 2645 } catch (Exception e) { 2646 dbc.report( 2647 null, 2648 Messages.get().container(Messages.ERR_GET_ORGUNITS_ROLE_1, role.getName(requestContext.getLocale())), 2649 e); 2650 } finally { 2651 dbc.clear(); 2652 } 2653 return result; 2654 } 2655 2656 /** 2657 * Returns the parent group of a group.<p> 2658 * 2659 * @param context the current request context 2660 * @param groupname the name of the group 2661 * 2662 * @return group the parent group or <code>null</code> 2663 * 2664 * @throws CmsException if operation was not successful 2665 */ 2666 public CmsGroup getParent(CmsRequestContext context, String groupname) throws CmsException { 2667 2668 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2669 CmsGroup result = null; 2670 try { 2671 result = m_driverManager.getParent(dbc, CmsOrganizationalUnit.removeLeadingSeparator(groupname)); 2672 } catch (Exception e) { 2673 dbc.report(null, Messages.get().container(Messages.ERR_GET_PARENT_GROUP_1, groupname), e); 2674 } finally { 2675 dbc.clear(); 2676 } 2677 return result; 2678 } 2679 2680 /** 2681 * Returns the set of permissions of the current user for a given resource.<p> 2682 * 2683 * @param context the current request context 2684 * @param resource the resource 2685 * @param user the user 2686 * 2687 * @return bit set with allowed permissions 2688 * 2689 * @throws CmsException if something goes wrong 2690 */ 2691 public CmsPermissionSetCustom getPermissions(CmsRequestContext context, CmsResource resource, CmsUser user) 2692 throws CmsException { 2693 2694 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2695 CmsPermissionSetCustom result = null; 2696 try { 2697 result = m_driverManager.getPermissions(dbc, resource, user); 2698 } catch (Exception e) { 2699 dbc.report( 2700 null, 2701 Messages.get().container(Messages.ERR_GET_PERMISSIONS_2, user.getName(), context.getSitePath(resource)), 2702 e); 2703 } finally { 2704 dbc.clear(); 2705 } 2706 return result; 2707 } 2708 2709 /** 2710 * Returns the uuid id for the given id, 2711 * remove this method as soon as possible.<p> 2712 * 2713 * @param context the current cms context 2714 * @param id the old project id 2715 * 2716 * @return the new uuid for the given id 2717 * 2718 * @throws CmsException if something goes wrong 2719 */ 2720 public CmsUUID getProjectId(CmsRequestContext context, int id) throws CmsException { 2721 2722 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2723 CmsUUID result = null; 2724 try { 2725 result = m_driverManager.getProjectId(dbc, id); 2726 } catch (CmsException e) { 2727 dbc.report(null, e.getMessageContainer(), e); 2728 } finally { 2729 dbc.clear(); 2730 } 2731 return result; 2732 } 2733 2734 /** 2735 * Returns a new publish list that contains the unpublished resources related 2736 * to all resources in the given publish list, the related resources exclude 2737 * all resources in the given publish list and also locked (by other users) resources.<p> 2738 * 2739 * @param context the current cms context 2740 * @param publishList the publish list to exclude from result 2741 * @param filter the relation filter to use to get the related resources 2742 * 2743 * @return a new publish list that contains the related resources 2744 * 2745 * @throws CmsException if something goes wrong 2746 * 2747 * @see org.opencms.publish.CmsPublishManager#getRelatedResourcesToPublish(CmsObject, CmsPublishList) 2748 */ 2749 public CmsPublishList getRelatedResourcesToPublish( 2750 CmsRequestContext context, 2751 CmsPublishList publishList, 2752 CmsRelationFilter filter) 2753 throws CmsException { 2754 2755 if (!publishList.isDirectPublish()) { 2756 throw new CmsIllegalArgumentException( 2757 Messages.get().container(Messages.ERR_GET_RELATED_RESOURCES_PUBLISH_PROJECT_0)); 2758 } 2759 2760 CmsPublishList ret = null; 2761 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2762 try { 2763 ret = m_driverManager.getRelatedResourcesToPublish(dbc, publishList, filter); 2764 checkPublishPermissions(dbc, ret); 2765 } catch (Exception e) { 2766 dbc.report( 2767 null, 2768 Messages.get().container( 2769 Messages.ERR_GET_RELATED_RESOURCES_PUBLISH_DIRECT_1, 2770 CmsFileUtil.formatResourceNames(context, publishList.getDirectPublishResources())), 2771 e); 2772 } finally { 2773 dbc.clear(); 2774 } 2775 return ret; 2776 } 2777 2778 /** 2779 * Returns all relations for the given resource matching the given filter.<p> 2780 * 2781 * @param context the current user context 2782 * @param resource the resource to retrieve the relations for 2783 * @param filter the filter to match the relation 2784 * 2785 * @return all {@link org.opencms.relations.CmsRelation} objects for the given resource matching the given filter 2786 * 2787 * @throws CmsException if something goes wrong 2788 * 2789 * @see CmsObject#getRelationsForResource(String, CmsRelationFilter) 2790 */ 2791 public List<CmsRelation> getRelationsForResource( 2792 CmsRequestContext context, 2793 CmsResource resource, 2794 CmsRelationFilter filter) 2795 throws CmsException { 2796 2797 List<CmsRelation> result = null; 2798 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2799 try { 2800 // check the access permissions 2801 if (resource != null) { 2802 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_VIEW, false, CmsResourceFilter.ALL); 2803 } 2804 result = m_driverManager.getRelationsForResource(dbc, resource, filter); 2805 } catch (Exception e) { 2806 dbc.report( 2807 null, 2808 Messages.get().container( 2809 Messages.ERR_READ_RELATIONS_1, 2810 (resource != null) ? context.removeSiteRoot(resource.getRootPath()) : "null"), 2811 e); 2812 } finally { 2813 dbc.clear(); 2814 } 2815 return result; 2816 } 2817 2818 /** 2819 * Returns all resources of the given organizational unit.<p> 2820 * 2821 * @param context the current request context 2822 * @param orgUnit the organizational unit to get all resources for 2823 * 2824 * @return all <code>{@link CmsResource}</code> objects in the organizational unit 2825 * 2826 * @throws CmsException if operation was not successful 2827 * 2828 * @see org.opencms.security.CmsOrgUnitManager#getResourcesForOrganizationalUnit(CmsObject, String) 2829 * @see org.opencms.security.CmsOrgUnitManager#getGroups(CmsObject, String, boolean) 2830 * @see org.opencms.security.CmsOrgUnitManager#getUsers(CmsObject, String, boolean) 2831 */ 2832 public List<CmsResource> getResourcesForOrganizationalUnit(CmsRequestContext context, CmsOrganizationalUnit orgUnit) 2833 throws CmsException { 2834 2835 List<CmsResource> result = null; 2836 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2837 try { 2838 result = m_driverManager.getResourcesForOrganizationalUnit(dbc, orgUnit); 2839 } catch (Exception e) { 2840 dbc.report(null, Messages.get().container(Messages.ERR_READ_ORGUNIT_RESOURCES_1, orgUnit.getName()), e); 2841 } finally { 2842 dbc.clear(); 2843 } 2844 return result; 2845 } 2846 2847 /** 2848 * Returns all resources associated to a given principal via an ACE with the given permissions.<p> 2849 * 2850 * If the <code>includeAttr</code> flag is set it returns also all resources associated to 2851 * a given principal through some of following attributes.<p> 2852 * 2853 * <ul> 2854 * <li>User Created</li> 2855 * <li>User Last Modified</li> 2856 * </ul><p> 2857 * 2858 * @param context the current request context 2859 * @param principalId the id of the principal 2860 * @param permissions a set of permissions to match, can be <code>null</code> for all ACEs 2861 * @param includeAttr a flag to include resources associated by attributes 2862 * 2863 * @return a set of <code>{@link CmsResource}</code> objects 2864 * 2865 * @throws CmsException if something goes wrong 2866 */ 2867 public Set<CmsResource> getResourcesForPrincipal( 2868 CmsRequestContext context, 2869 CmsUUID principalId, 2870 CmsPermissionSet permissions, 2871 boolean includeAttr) 2872 throws CmsException { 2873 2874 Set<CmsResource> dependencies; 2875 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2876 try { 2877 dependencies = m_driverManager.getResourcesForPrincipal( 2878 dbc, 2879 dbc.currentProject(), 2880 principalId, 2881 permissions, 2882 includeAttr); 2883 } catch (Exception e) { 2884 dbc.report(null, Messages.get().container(Messages.ERR_READ_RESOURCES_FOR_PRINCIPAL_LOG_1, principalId), e); 2885 dependencies = new HashSet<CmsResource>(); 2886 } finally { 2887 dbc.clear(); 2888 } 2889 return dependencies; 2890 } 2891 2892 /** 2893 * Gets the rewrite aliases matching a given filter.<p> 2894 * 2895 * @param requestContext the current request context 2896 * @param filter the filter used for selecting the rewrite aliases 2897 * @return the rewrite aliases matching the given filter 2898 * 2899 * @throws CmsException if something goes wrong 2900 */ 2901 public List<CmsRewriteAlias> getRewriteAliases(CmsRequestContext requestContext, CmsRewriteAliasFilter filter) 2902 throws CmsException { 2903 2904 CmsDbContext dbc = m_dbContextFactory.getDbContext(requestContext); 2905 try { 2906 return m_driverManager.getRewriteAliases(dbc, filter); 2907 } catch (Exception e) { 2908 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 2909 return null; // will never be executed 2910 } finally { 2911 dbc.clear(); 2912 } 2913 2914 } 2915 2916 /** 2917 * Gets the groups which constitute a given role.<p> 2918 * 2919 * @param context the request context 2920 * @param role the role 2921 * @param directUsersOnly if true, only direct users of the role group will be returned 2922 * 2923 * @return the role's groups 2924 * 2925 * @throws CmsException if something goes wrong 2926 */ 2927 public Set<CmsGroup> getRoleGroups(CmsRequestContext context, CmsRole role, boolean directUsersOnly) 2928 throws CmsException { 2929 2930 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2931 try { 2932 return m_driverManager.getRoleGroups(dbc, role.getGroupName(), directUsersOnly); 2933 } catch (Exception e) { 2934 dbc.report(null, Messages.get().container(Messages.ERR_GET_ROLE_GROUPS_1, role.toString()), e); 2935 return null; // will never be executed 2936 } finally { 2937 dbc.clear(); 2938 } 2939 } 2940 2941 /** 2942 * Returns all roles the given user has for the given resource.<p> 2943 * 2944 * @param context the current request context 2945 * @param user the user to check 2946 * @param resource the resource to check the roles for 2947 * 2948 * @return a list of {@link CmsRole} objects 2949 * 2950 * @throws CmsException is something goes wrong 2951 */ 2952 public List<CmsRole> getRolesForResource(CmsRequestContext context, CmsUser user, CmsResource resource) 2953 throws CmsException { 2954 2955 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2956 List<CmsRole> result = null; 2957 try { 2958 result = m_driverManager.getRolesForResource(dbc, user, resource); 2959 } catch (Exception e) { 2960 dbc.report( 2961 null, 2962 Messages.get().container( 2963 Messages.ERR_GET_ROLES_FOR_RESOURCE_2, 2964 user.getName(), 2965 context.getSitePath(resource)), 2966 e); 2967 } finally { 2968 dbc.clear(); 2969 } 2970 return result; 2971 } 2972 2973 /** 2974 * Returns an instance of the common sql manager.<p> 2975 * 2976 * @return an instance of the common sql manager 2977 */ 2978 public CmsSqlManager getSqlManager() { 2979 2980 return m_driverManager.getSqlManager(); 2981 } 2982 2983 /** 2984 * Returns a delivery-capable storage backend by its stable storage identifier.<p> 2985 * 2986 * @param context the current request context 2987 * @param storage the stable storage identifier 2988 * 2989 * @return the delivery-capable storage backend, or <code>null</code> if not supported 2990 * 2991 * @throws CmsException if something goes wrong 2992 */ 2993 public I_CmsStorageDelivery getStoredContentDelivery(CmsRequestContext context, String storage) 2994 throws CmsException { 2995 2996 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 2997 try { 2998 return m_driverManager.getStoredContentDelivery(dbc, storage); 2999 } finally { 3000 dbc.clear(); 3001 } 3002 } 3003 3004 /** 3005 * Returns all users of the given organizational unit.<p> 3006 * 3007 * @param context the current request context 3008 * @param orgUnit the organizational unit to get the users for 3009 * @param recursive if all users of sub-organizational units should be retrieved too 3010 * 3011 * @return all <code>{@link CmsUser}</code> objects in the organizational unit 3012 * 3013 * @throws CmsException if operation was not successful 3014 * 3015 * @see org.opencms.security.CmsOrgUnitManager#getResourcesForOrganizationalUnit(CmsObject, String) 3016 * @see org.opencms.security.CmsOrgUnitManager#getGroups(CmsObject, String, boolean) 3017 * @see org.opencms.security.CmsOrgUnitManager#getUsers(CmsObject, String, boolean) 3018 */ 3019 public List<CmsUser> getUsers(CmsRequestContext context, CmsOrganizationalUnit orgUnit, boolean recursive) 3020 throws CmsException { 3021 3022 List<CmsUser> result = null; 3023 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3024 try { 3025 result = m_driverManager.getUsers(dbc, orgUnit, recursive); 3026 } catch (Exception e) { 3027 dbc.report(null, Messages.get().container(Messages.ERR_READ_ORGUNIT_USERS_1, orgUnit.getName()), e); 3028 } finally { 3029 dbc.clear(); 3030 } 3031 return result; 3032 } 3033 3034 /** 3035 * Returns a list of users in a group.<p> 3036 * 3037 * @param context the current request context 3038 * @param groupname the name of the group to list users from 3039 * @param includeOtherOuUsers include users of other organizational units 3040 * @param directUsersOnly if set only the direct assigned users will be returned, 3041 * if not also indirect users, ie. members of child groups 3042 * @param readRoles if to read roles or groups 3043 * 3044 * @return all <code>{@link CmsUser}</code> objects in the group 3045 * 3046 * @throws CmsException if operation was not successful 3047 */ 3048 public List<CmsUser> getUsersOfGroup( 3049 CmsRequestContext context, 3050 String groupname, 3051 boolean includeOtherOuUsers, 3052 boolean directUsersOnly, 3053 boolean readRoles) 3054 throws CmsException { 3055 3056 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3057 List<CmsUser> result = null; 3058 try { 3059 result = m_driverManager.getUsersOfGroup( 3060 dbc, 3061 CmsOrganizationalUnit.removeLeadingSeparator(groupname), 3062 includeOtherOuUsers, 3063 directUsersOnly, 3064 readRoles); 3065 } catch (Exception e) { 3066 dbc.report(null, Messages.get().container(Messages.ERR_GET_USERS_OF_GROUP_1, groupname), e); 3067 } finally { 3068 dbc.clear(); 3069 } 3070 return result; 3071 } 3072 3073 /** 3074 * Returns the current user's publish list.<p> 3075 * 3076 * @param context the request context 3077 * 3078 * @return the current user's publish list 3079 * 3080 * @throws CmsException if something goes wrong 3081 */ 3082 public List<CmsResource> getUsersPubList(CmsRequestContext context) throws CmsException { 3083 3084 List<CmsResource> result = null; 3085 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3086 try { 3087 result = m_driverManager.getUsersPubList(dbc, context.getCurrentUser().getId()); 3088 } catch (Exception e) { 3089 dbc.report( 3090 null, 3091 Messages.get().container(Messages.ERR_READ_USER_PUBLIST_1, context.getCurrentUser().getName()), 3092 e); 3093 3094 } finally { 3095 dbc.clear(); 3096 } 3097 return result; 3098 } 3099 3100 /** 3101 * Returns all users of the given organizational unit.<p> 3102 * 3103 * @param context the current request context 3104 * @param orgUnit the organizational unit to get the users for 3105 * @param recursive if all users of sub-organizational units should be retrieved too 3106 * 3107 * @return all <code>{@link CmsUser}</code> objects in the organizational unit 3108 * 3109 * @throws CmsException if operation was not successful 3110 * 3111 * @see org.opencms.security.CmsOrgUnitManager#getResourcesForOrganizationalUnit(CmsObject, String) 3112 * @see org.opencms.security.CmsOrgUnitManager#getGroups(CmsObject, String, boolean) 3113 * @see org.opencms.security.CmsOrgUnitManager#getUsers(CmsObject, String, boolean) 3114 */ 3115 public List<CmsUser> getUsersWithoutAdditionalInfo( 3116 CmsRequestContext context, 3117 CmsOrganizationalUnit orgUnit, 3118 boolean recursive) 3119 throws CmsException { 3120 3121 List<CmsUser> result = null; 3122 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3123 try { 3124 result = m_driverManager.getUsersWithoutAdditionalInfo(dbc, orgUnit, recursive); 3125 } catch (Exception e) { 3126 dbc.report(null, Messages.get().container(Messages.ERR_READ_ORGUNIT_USERS_1, orgUnit.getName()), e); 3127 } finally { 3128 dbc.clear(); 3129 } 3130 return result; 3131 } 3132 3133 /** 3134 * Performs a non-blocking permission check on a resource.<p> 3135 * 3136 * This test will not throw an exception in case the required permissions are not 3137 * available for the requested operation. Instead, it will return one of the 3138 * following values:<ul> 3139 * <li><code>{@link I_CmsPermissionHandler#PERM_ALLOWED}</code></li> 3140 * <li><code>{@link I_CmsPermissionHandler#PERM_FILTERED}</code></li> 3141 * <li><code>{@link I_CmsPermissionHandler#PERM_DENIED}</code></li></ul><p> 3142 * 3143 * @param context the current request context 3144 * @param resource the resource on which permissions are required 3145 * @param requiredPermissions the set of permissions required for the operation 3146 * @param checkLock if true, a lock for the current user is required for 3147 * all write operations, if false it's ok to write as long as the resource 3148 * is not locked by another user 3149 * @param filter the resource filter to use 3150 * 3151 * @return <code>{@link I_CmsPermissionHandler#PERM_ALLOWED}</code> if the user has sufficient permissions on the resource 3152 * for the requested operation 3153 * 3154 * @throws CmsException in case of i/o errors (NOT because of insufficient permissions) 3155 * 3156 * @see #hasPermissions(CmsDbContext, CmsResource, CmsPermissionSet, LockCheck, CmsResourceFilter) 3157 */ 3158 public I_CmsPermissionHandler.CmsPermissionCheckResult hasPermissions( 3159 CmsRequestContext context, 3160 CmsResource resource, 3161 CmsPermissionSet requiredPermissions, 3162 boolean checkLock, 3163 CmsResourceFilter filter) 3164 throws CmsException { 3165 3166 I_CmsPermissionHandler.CmsPermissionCheckResult result = null; 3167 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3168 try { 3169 result = hasPermissions( 3170 dbc, 3171 resource, 3172 requiredPermissions, 3173 checkLock ? LockCheck.yes : LockCheck.no, 3174 filter); 3175 } finally { 3176 dbc.clear(); 3177 } 3178 return result; 3179 } 3180 3181 /** 3182 * Performs a non-blocking permission check on a resource.<p> 3183 * 3184 * This test will not throw an exception in case the required permissions are not 3185 * available for the requested operation. Instead, it will return one of the 3186 * following values:<ul> 3187 * <li><code>{@link I_CmsPermissionHandler#PERM_ALLOWED}</code></li> 3188 * <li><code>{@link I_CmsPermissionHandler#PERM_FILTERED}</code></li> 3189 * <li><code>{@link I_CmsPermissionHandler#PERM_DENIED}</code></li></ul><p> 3190 * 3191 * @param context the current request context 3192 * @param resource the resource on which permissions are required 3193 * @param requiredPermissions the set of permissions required for the operation 3194 * @param checkLock if true, a lock for the current user is required for 3195 * all write operations, if false it's ok to write as long as the resource 3196 * is not locked by another user 3197 * @param filter the resource filter to use 3198 * 3199 * @return <code>{@link I_CmsPermissionHandler#PERM_ALLOWED}</code> if the user has sufficient permissions on the resource 3200 * for the requested operation 3201 * 3202 * @throws CmsException in case of i/o errors (NOT because of insufficient permissions) 3203 * 3204 * @see #hasPermissions(CmsDbContext, CmsResource, CmsPermissionSet, LockCheck, CmsResourceFilter) 3205 */ 3206 public I_CmsPermissionHandler.CmsPermissionCheckResult hasPermissions( 3207 CmsRequestContext context, 3208 CmsResource resource, 3209 CmsPermissionSet requiredPermissions, 3210 LockCheck checkLock, 3211 CmsResourceFilter filter) 3212 throws CmsException { 3213 3214 I_CmsPermissionHandler.CmsPermissionCheckResult result = null; 3215 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3216 try { 3217 result = hasPermissions(dbc, resource, requiredPermissions, checkLock, filter); 3218 } finally { 3219 dbc.clear(); 3220 } 3221 return result; 3222 } 3223 3224 /** 3225 * Checks if the given user has the given role in the given organizational unit.<p> 3226 * 3227 * If the organizational unit is <code>null</code>, this method will check if the 3228 * given user has the given role for at least one organizational unit.<p> 3229 * 3230 * @param dbc the current OpenCms users database context 3231 * @param user the user to check the role for 3232 * @param role the role to check 3233 * 3234 * @return <code>true</code> if the given user has the given role in the given organizational unit 3235 */ 3236 public boolean hasRole(CmsDbContext dbc, CmsUser user, CmsRole role) { 3237 3238 // try to read from cache 3239 String key = role.getGroupName() + "," + role.getOuFqn(); 3240 Boolean result = OpenCms.getMemoryMonitor().getGroupListCache().getHasRole(user.getId(), key); 3241 if (result != null) { 3242 return result.booleanValue(); 3243 } 3244 3245 // read all roles of the current user 3246 List<CmsGroup> roles; 3247 try { 3248 roles = m_driverManager.getGroupsOfUser( 3249 dbc, 3250 user.getName(), 3251 "", 3252 true, 3253 true, 3254 false, 3255 dbc.getRequestContext().getRemoteAddress()); 3256 } catch (CmsException e) { 3257 if (LOG.isErrorEnabled()) { 3258 LOG.error(e.getLocalizedMessage(), e); 3259 } 3260 // any exception: return false 3261 return false; 3262 } 3263 3264 boolean hasRole = hasRole(role, roles); 3265 3266 // hack: require individual user based confirmation for certain roles 3267 // this is for updated older systems where content managers have been WORKPLACE_USER only 3268 // to prevent access to certain ADE management functions 3269 if (hasRole && ((CmsRole.CATEGORY_EDITOR.equals(role)) || (CmsRole.GALLERY_EDITOR.equals(role)))) { 3270 String info = CmsRole.CONFIRM_ROLE_PREFIX + role.getRoleName(); 3271 Object prop = OpenCms.getRuntimeProperty(info); 3272 if ((prop != null) && Boolean.valueOf(prop.toString()).booleanValue()) { 3273 // individual user based confirmation for the role is required 3274 // if the user is a WORKPLACE_USER 3275 Object val = user.getAdditionalInfo(info); 3276 if ((val == null) || !Boolean.valueOf(val.toString()).booleanValue()) { 3277 // no individual user confirmation present 3278 if (hasRole(CmsRole.WORKPLACE_USER, roles) 3279 && !hasRole(CmsRole.DEVELOPER, roles) 3280 && !hasRole(CmsRole.PROJECT_MANAGER, roles) 3281 && !hasRole(CmsRole.ACCOUNT_MANAGER, roles)) { 3282 // user is a WORKPLACE_USER, confirmation is required but not present 3283 hasRole = false; 3284 } 3285 } 3286 } 3287 } 3288 3289 result = Boolean.valueOf(hasRole); 3290 OpenCms.getMemoryMonitor().getGroupListCache().setHasRole(user, key, result); 3291 return result.booleanValue(); 3292 } 3293 3294 /** 3295 * Checks if the given user has the given role in the given organizational unit.<p> 3296 * 3297 * If the organizational unit is <code>null</code>, this method will check if the 3298 * given user has the given role for at least one organizational unit.<p> 3299 * 3300 * @param context the current request context 3301 * @param user the user to check the role for 3302 * @param role the role to check 3303 * 3304 * @return <code>true</code> if the given user has the given role in the given organizational unit 3305 */ 3306 public boolean hasRole(CmsRequestContext context, CmsUser user, CmsRole role) { 3307 3308 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3309 boolean result; 3310 try { 3311 result = hasRole(dbc, user, role); 3312 } finally { 3313 dbc.clear(); 3314 } 3315 return result; 3316 } 3317 3318 /** 3319 * Checks if the given user has the given role for the given resource.<p> 3320 * 3321 * @param dbc the current OpenCms users database context 3322 * @param user the user to check the role for 3323 * @param role the role to check 3324 * @param resource the resource to check the role for 3325 * 3326 * @return <code>true</code> if the given user has the given role for the given resource 3327 */ 3328 public boolean hasRoleForResource(CmsDbContext dbc, CmsUser user, CmsRole role, CmsResource resource) { 3329 3330 // guest user has no role 3331 if (user.isGuestUser()) { 3332 return false; 3333 } 3334 3335 // try to read from cache 3336 3337 // *** 3338 // NOTE: We do intentionally *not* use the new group list cache here, as we have no good way to limit it at the moment, and this might generate a large amount of entries 3339 // *** 3340 String key = user.getId().toString() + role.getGroupName() + resource.getRootPath(); 3341 Boolean result = OpenCms.getMemoryMonitor().getCachedRole(key); 3342 if (result != null) { 3343 return result.booleanValue(); 3344 } 3345 3346 // read all roles of the current user 3347 List<CmsGroup> roles; 3348 try { 3349 roles = new ArrayList<CmsGroup>( 3350 m_driverManager.getGroupsOfUser( 3351 dbc, 3352 user.getName(), 3353 "", 3354 true, 3355 true, 3356 true, 3357 dbc.getRequestContext().getRemoteAddress())); 3358 } catch (CmsException e) { 3359 if (LOG.isErrorEnabled()) { 3360 LOG.error(e.getLocalizedMessage(), e); 3361 } 3362 // any exception: return false 3363 return false; 3364 } 3365 3366 // first check the user has the role at all 3367 if (!hasRole(role.forOrgUnit(null), roles)) { 3368 result = Boolean.FALSE; 3369 } 3370 3371 // then check if one applies to the given resource 3372 Iterator<CmsGroup> it = roles.iterator(); 3373 while ((result == null) && it.hasNext()) { 3374 CmsGroup group = it.next(); 3375 CmsRole givenRole = CmsRole.valueOf(group); 3376 if (hasRole(role.forOrgUnit(null), Collections.singletonList(group))) { 3377 // we have the same role, now check the resource if needed 3378 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(givenRole.getOuFqn())) { 3379 List<String> ouResourcePaths = OpenCms.getMemoryMonitor().getCachedOrgUnitResources( 3380 givenRole.getOuFqn()); 3381 if (ouResourcePaths == null) { 3382 try { 3383 CmsOrganizationalUnit orgUnit = m_driverManager.readOrganizationalUnit( 3384 dbc, 3385 givenRole.getOuFqn()); 3386 List<CmsResource> ouResources = m_driverManager.getResourcesForOrganizationalUnit( 3387 dbc, 3388 orgUnit); 3389 ouResourcePaths = ouResources.stream().map(res -> res.getRootPath()).collect( 3390 Collectors.toList()); 3391 OpenCms.getMemoryMonitor().cacheOrgUnitResources(givenRole.getOuFqn(), ouResourcePaths); 3392 } catch (Exception e) { 3393 LOG.error(e); 3394 } 3395 } 3396 if (ouResourcePaths != null) { 3397 for (String ouResource : ouResourcePaths) { 3398 if (resource.getRootPath().startsWith(ouResource)) { 3399 result = Boolean.TRUE; 3400 break; 3401 } 3402 } 3403 } 3404 3405 } else { 3406 result = Boolean.TRUE; 3407 } 3408 } 3409 } 3410 3411 if (result == null) { 3412 result = Boolean.FALSE; 3413 } 3414 OpenCms.getMemoryMonitor().cacheRole(key, result.booleanValue()); 3415 return result.booleanValue(); 3416 } 3417 3418 /** 3419 * Checks if the given user has the given role for the given resource.<p> 3420 * 3421 * @param context the current request context 3422 * @param user the user to check 3423 * @param role the role to check 3424 * @param resource the resource to check the role for 3425 * 3426 * @return <code>true</code> if the given user has the given role for the given resource 3427 */ 3428 public boolean hasRoleForResource(CmsRequestContext context, CmsUser user, CmsRole role, CmsResource resource) { 3429 3430 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3431 boolean result; 3432 try { 3433 result = hasRoleForResource(dbc, user, role, resource); 3434 } finally { 3435 dbc.clear(); 3436 } 3437 return result; 3438 } 3439 3440 /** 3441 * Writes a list of access control entries as new access control entries of a given resource.<p> 3442 * 3443 * Already existing access control entries of this resource are removed before.<p> 3444 * 3445 * Access is granted, if:<p> 3446 * <ul> 3447 * <li>the current user has control permission on the resource</li> 3448 * </ul><p> 3449 * 3450 * @param context the current request context 3451 * @param resource the resource 3452 * @param acEntries a list of <code>{@link CmsAccessControlEntry}</code> objects 3453 * 3454 * @throws CmsException if something goes wrong 3455 * @throws CmsSecurityException if the required permissions are not satisfied 3456 */ 3457 public void importAccessControlEntries( 3458 CmsRequestContext context, 3459 CmsResource resource, 3460 List<CmsAccessControlEntry> acEntries) 3461 throws CmsException, CmsSecurityException { 3462 3463 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 3464 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3465 try { 3466 checkOfflineProject(dbc); 3467 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_CONTROL, true, CmsResourceFilter.ALL); 3468 m_driverManager.importAccessControlEntries(dbc, resource, acEntries); 3469 modContext.add(resource); 3470 } catch (Exception e) { 3471 dbc.report( 3472 null, 3473 Messages.get().container(Messages.ERR_IMPORT_ACL_ENTRIES_1, context.getSitePath(resource)), 3474 e); 3475 } finally { 3476 dbc.clear(); 3477 } 3478 } 3479 } 3480 3481 /** 3482 * Creates a new resource with the provided content and properties.<p> 3483 * 3484 * The <code>content</code> parameter may be null if the resource id already exists. 3485 * If so, the created resource will be made a sibling of the existing resource, 3486 * the existing content will remain unchanged. 3487 * This is used during file import for import of siblings as the 3488 * <code>manifest.xml</code> only contains one binary copy per file. 3489 * If the resource id exists but the <code>content</code> is not null, 3490 * the created resource will be made a sibling of the existing resource, 3491 * and both will share the new content.<p> 3492 * 3493 * @param context the current request context 3494 * @param resourcePath the name of the resource to create (full path) 3495 * @param resource the new resource to create 3496 * @param content the content for the new resource 3497 * @param properties the properties for the new resource 3498 * @param importCase if <code>true</code>, signals that this operation is done while importing resource, 3499 * causing different lock behavior and potential "lost and found" usage 3500 * 3501 * @return the created resource 3502 * 3503 * @throws CmsException if something goes wrong 3504 */ 3505 public CmsResource importResource( 3506 CmsRequestContext context, 3507 String resourcePath, 3508 CmsResource resource, 3509 byte[] content, 3510 List<CmsProperty> properties, 3511 boolean importCase) 3512 throws CmsException { 3513 3514 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 3515 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3516 CmsResource newResource = null; 3517 try { 3518 checkOfflineProject(dbc); 3519 newResource = m_driverManager.createResource( 3520 dbc, 3521 resourcePath, 3522 resource, 3523 content, 3524 properties, 3525 importCase); 3526 modContext.add(newResource); 3527 } catch (Exception e) { 3528 dbc.report( 3529 null, 3530 Messages.get().container( 3531 Messages.ERR_IMPORT_RESOURCE_2, 3532 context.getSitePath(resource), 3533 resourcePath), 3534 e); 3535 } finally { 3536 dbc.clear(); 3537 } 3538 return newResource; 3539 } 3540 } 3541 3542 /** 3543 * Imports a rewrite alias.<p> 3544 * 3545 * @param requestContext the current request context 3546 * @param siteRoot the site root 3547 * @param source the rewrite alias source 3548 * @param target the rewrite alias target 3549 * @param mode the alias mode 3550 * @return the import result 3551 * 3552 * @throws CmsException if something goes wrong 3553 */ 3554 public CmsAliasImportResult importRewriteAlias( 3555 CmsRequestContext requestContext, 3556 String siteRoot, 3557 String source, 3558 String target, 3559 CmsAliasMode mode) 3560 throws CmsException { 3561 3562 CmsDbContext dbc = m_dbContextFactory.getDbContext(requestContext); 3563 try { 3564 return m_driverManager.importRewriteAlias(dbc, siteRoot, source, target, mode); 3565 } catch (Exception e) { 3566 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 3567 return null; 3568 } finally { 3569 dbc.clear(); 3570 } 3571 } 3572 3573 /** 3574 * Creates a new user by import.<p> 3575 * 3576 * @param context the current request context 3577 * @param id the id of the user 3578 * @param name the new name for the user 3579 * @param password the new password for the user 3580 * @param firstname the first name of the user 3581 * @param lastname the last name of the user 3582 * @param email the email of the user 3583 * @param flags the flags for a user (for example <code>{@link I_CmsPrincipal#FLAG_ENABLED}</code>) 3584 * @param dateCreated the creation date 3585 * @param additionalInfos the additional user infos 3586 * 3587 * @return the imported user 3588 * 3589 * @throws CmsException if something goes wrong 3590 * @throws CmsRoleViolationException if the role {@link CmsRole#ACCOUNT_MANAGER} is not owned by the current user. 3591 */ 3592 public CmsUser importUser( 3593 CmsRequestContext context, 3594 String id, 3595 String name, 3596 String password, 3597 String firstname, 3598 String lastname, 3599 String email, 3600 int flags, 3601 long dateCreated, 3602 Map<String, Object> additionalInfos) 3603 throws CmsException, CmsRoleViolationException { 3604 3605 CmsUser newUser = null; 3606 3607 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3608 3609 try { 3610 checkRole(dbc, CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(name))); 3611 newUser = m_driverManager.importUser( 3612 dbc, 3613 id, 3614 CmsOrganizationalUnit.removeLeadingSeparator(name), 3615 password, 3616 firstname, 3617 lastname, 3618 email, 3619 flags, 3620 dateCreated, 3621 additionalInfos); 3622 3623 } catch (Exception e) { 3624 dbc.report( 3625 null, 3626 Messages.get().container( 3627 Messages.ERR_IMPORT_USER_7, 3628 new Object[] { 3629 name, 3630 firstname, 3631 lastname, 3632 email, 3633 Integer.valueOf(flags), 3634 new Date(dateCreated), 3635 additionalInfos}), 3636 e); 3637 } finally { 3638 dbc.clear(); 3639 } 3640 3641 return newUser; 3642 } 3643 3644 /** 3645 * Increments a counter and returns its old value.<p> 3646 * 3647 * @param context the request context 3648 * @param name the name of the counter 3649 * 3650 * @return the value of the counter before incrementing 3651 * 3652 * @throws CmsException if something goes wrong 3653 */ 3654 public int incrementCounter(CmsRequestContext context, String name) throws CmsException { 3655 3656 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3657 try { 3658 return m_driverManager.incrementCounter(dbc, name); 3659 } catch (Exception e) { 3660 dbc.report(null, Messages.get().container(Messages.ERR_INCREMENT_COUNTER_1, name), e); 3661 return -1; // will never be reached 3662 } finally { 3663 dbc.clear(); 3664 } 3665 } 3666 3667 /** 3668 * Initializes this security manager with a given runtime info factory.<p> 3669 * 3670 * @param configurationManager the configurationManager 3671 * @param dbContextFactory the initialized OpenCms runtime info factory 3672 * @param publishEngine the publish engine 3673 * 3674 * @throws CmsInitException if the initialization fails 3675 */ 3676 public void init( 3677 CmsConfigurationManager configurationManager, 3678 I_CmsDbContextFactory dbContextFactory, 3679 CmsPublishEngine publishEngine) 3680 throws CmsInitException { 3681 3682 if (dbContextFactory == null) { 3683 throw new CmsInitException( 3684 org.opencms.main.Messages.get().container(org.opencms.main.Messages.ERR_CRITICAL_NO_DB_CONTEXT_0)); 3685 } 3686 3687 m_dbContextFactory = dbContextFactory; 3688 3689 CmsSystemConfiguration systemConfiguration = (CmsSystemConfiguration)configurationManager.getConfiguration( 3690 CmsSystemConfiguration.class); 3691 3692 // create the driver manager 3693 m_driverManager = CmsDriverManager.newInstance(configurationManager, this, dbContextFactory, publishEngine); 3694 3695 try { 3696 // invoke the init method of the driver manager 3697 m_driverManager.init(configurationManager, dbContextFactory); 3698 if (CmsLog.INIT.isInfoEnabled()) { 3699 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DRIVER_MANAGER_START_PHASE4_OK_0)); 3700 } 3701 } catch (Exception exc) { 3702 CmsMessageContainer message = Messages.get().container(Messages.LOG_ERR_DRIVER_MANAGER_START_0); 3703 if (LOG.isFatalEnabled()) { 3704 LOG.fatal(message.key(), exc); 3705 } 3706 throw new CmsInitException(message, exc); 3707 } 3708 3709 // create a new lock manager 3710 m_lockManager = m_driverManager.getLockManager(); 3711 3712 // initialize the permission handler 3713 String permHandlerClassName = systemConfiguration.getPermissionHandler(); 3714 if (permHandlerClassName == null) { 3715 // use default implementation 3716 m_permissionHandler = new CmsDefaultPermissionHandler(); 3717 } else { 3718 // use configured permission handler 3719 try { 3720 m_permissionHandler = (I_CmsPermissionHandler)Class.forName(permHandlerClassName).newInstance(); 3721 } catch (Exception e) { 3722 throw new CmsInitException( 3723 org.opencms.main.Messages.get().container( 3724 org.opencms.main.Messages.ERR_CRITICAL_CLASS_CREATION_1, 3725 permHandlerClassName), 3726 e); 3727 } 3728 } 3729 3730 m_permissionHandler.init(m_driverManager, systemConfiguration); 3731 3732 if (CmsLog.INIT.isInfoEnabled()) { 3733 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SECURITY_MANAGER_INIT_0)); 3734 } 3735 } 3736 3737 /** 3738 * Initializes the default groups for an organizational unit.<p> 3739 * 3740 * @param context the request context 3741 * @param ou the organizational unit 3742 */ 3743 public void initializeOrgUnit(CmsRequestContext context, CmsOrganizationalUnit ou) { 3744 3745 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3746 m_driverManager.initOrgUnit(dbc, ou); 3747 3748 } 3749 3750 /** 3751 * Checks if the specified resource is inside the current project.<p> 3752 * 3753 * The project "view" is determined by a set of path prefixes. 3754 * If the resource starts with any one of this prefixes, it is considered to 3755 * be "inside" the project.<p> 3756 * 3757 * @param context the current request context 3758 * @param resourcename the specified resource name (full path) 3759 * 3760 * @return <code>true</code>, if the specified resource is inside the current project 3761 */ 3762 public boolean isInsideCurrentProject(CmsRequestContext context, String resourcename) { 3763 3764 boolean result = false; 3765 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3766 try { 3767 result = m_driverManager.isInsideCurrentProject(dbc, resourcename); 3768 } finally { 3769 dbc.clear(); 3770 } 3771 return result; 3772 } 3773 3774 /** 3775 * Checks if the current user has management access to the current project.<p> 3776 * 3777 * @param context the current request context 3778 * 3779 * @return <code>true</code>, if the user has management access to the current project 3780 */ 3781 public boolean isManagerOfProject(CmsRequestContext context) { 3782 3783 try { 3784 return getAllManageableProjects( 3785 context, 3786 readOrganizationalUnit(context, context.getCurrentProject().getOuFqn()), 3787 false).contains(context.getCurrentProject()); 3788 } catch (CmsException e) { 3789 // should never happen 3790 if (LOG.isErrorEnabled()) { 3791 LOG.error(e.getLocalizedMessage(), e); 3792 } 3793 return false; 3794 } 3795 } 3796 3797 /** 3798 * Checks whether the subscription driver is available.<p> 3799 * 3800 * @return true if the subscription driver is available 3801 */ 3802 public boolean isSubscriptionDriverAvailable() { 3803 3804 return m_driverManager.isSubscriptionDriverAvailable(); 3805 } 3806 3807 /** 3808 * Locks a resource.<p> 3809 * 3810 * The <code>type</code> parameter controls what kind of lock is used.<br> 3811 * Possible values for this parameter are: <br> 3812 * <ul> 3813 * <li><code>{@link org.opencms.lock.CmsLockType#EXCLUSIVE}</code></li> 3814 * <li><code>{@link org.opencms.lock.CmsLockType#TEMPORARY}</code></li> 3815 * <li><code>{@link org.opencms.lock.CmsLockType#PUBLISH}</code></li> 3816 * </ul><p> 3817 * 3818 * @param context the current request context 3819 * @param resource the resource to lock 3820 * @param type type of the lock 3821 * 3822 * @throws CmsException if something goes wrong 3823 * 3824 * @see CmsObject#lockResource(String) 3825 * @see CmsObject#lockResourceTemporary(String) 3826 * @see org.opencms.file.types.I_CmsResourceType#lockResource(CmsObject, CmsSecurityManager, CmsResource, CmsLockType) 3827 */ 3828 public void lockResource(CmsRequestContext context, CmsResource resource, CmsLockType type) throws CmsException { 3829 3830 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3831 try { 3832 checkOfflineProject(dbc); 3833 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.ALL); 3834 m_driverManager.lockResource(dbc, resource, type); 3835 } catch (Exception e) { 3836 CmsMessageContainer messageContainer; 3837 if (e instanceof CmsLockException) { 3838 messageContainer = ((CmsLockException)e).getMessageContainer(); 3839 } else { 3840 messageContainer = Messages.get().container( 3841 Messages.ERR_LOCK_RESOURCE_2, 3842 context.getSitePath(resource), 3843 type.toString()); 3844 } 3845 dbc.report(null, messageContainer, e); 3846 } finally { 3847 dbc.clear(); 3848 } 3849 } 3850 3851 /** 3852 * Attempts to authenticate a user into OpenCms with the given password.<p> 3853 * 3854 * @param context the current request context 3855 * @param username the name of the user to be logged in 3856 * @param password the password of the user 3857 * @param code the additional login information for 2FA 3858 * @param remoteAddress the ip address of the request 3859 * 3860 * @return the logged in user 3861 * 3862 * @throws CmsException if the login was not successful 3863 */ 3864 public CmsUser loginUser( 3865 CmsRequestContext context, 3866 String username, 3867 String password, 3868 CmsSecondFactorInfo code, 3869 String remoteAddress) 3870 throws CmsException { 3871 3872 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3873 CmsUser result = null; 3874 try { 3875 result = m_driverManager.loginUser( 3876 dbc, 3877 CmsOrganizationalUnit.removeLeadingSeparator(username), 3878 password, 3879 code, 3880 remoteAddress, 3881 CmsDriverManager.LoginUserMode.standard); 3882 } finally { 3883 dbc.clear(); 3884 } 3885 return result; 3886 } 3887 3888 /** 3889 * Lookup and read the user or group with the given UUID.<p> 3890 * 3891 * @param context the current request context 3892 * @param principalId the UUID of the principal to lookup 3893 * 3894 * @return the principal (group or user) if found, otherwise <code>null</code> 3895 */ 3896 public I_CmsPrincipal lookupPrincipal(CmsRequestContext context, CmsUUID principalId) { 3897 3898 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3899 I_CmsPrincipal result = null; 3900 try { 3901 result = m_driverManager.lookupPrincipal(dbc, principalId); 3902 } finally { 3903 dbc.clear(); 3904 } 3905 return result; 3906 } 3907 3908 /** 3909 * Lookup and read the user or group with the given name.<p> 3910 * 3911 * @param context the current request context 3912 * @param principalName the name of the principal to lookup 3913 * 3914 * @return the principal (group or user) if found, otherwise <code>null</code> 3915 */ 3916 public I_CmsPrincipal lookupPrincipal(CmsRequestContext context, String principalName) { 3917 3918 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3919 I_CmsPrincipal result = null; 3920 try { 3921 result = m_driverManager.lookupPrincipal(dbc, CmsOrganizationalUnit.removeLeadingSeparator(principalName)); 3922 } finally { 3923 dbc.clear(); 3924 } 3925 return result; 3926 } 3927 3928 /** 3929 * Mark the given resource as visited by the user.<p> 3930 * 3931 * @param context the request context 3932 * @param poolName the name of the database pool to use 3933 * @param resource the resource to mark as visited 3934 * @param user the user that visited the resource 3935 * 3936 * @throws CmsException if something goes wrong 3937 */ 3938 public void markResourceAsVisitedBy(CmsRequestContext context, String poolName, CmsResource resource, CmsUser user) 3939 throws CmsException { 3940 3941 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3942 try { 3943 m_driverManager.markResourceAsVisitedBy(dbc, poolName, resource, user); 3944 } catch (Exception e) { 3945 dbc.report( 3946 null, 3947 Messages.get().container( 3948 Messages.ERR_MARK_RESOURCE_AS_VISITED_2, 3949 context.getSitePath(resource), 3950 user.getName()), 3951 e); 3952 } finally { 3953 dbc.clear(); 3954 } 3955 } 3956 3957 /** 3958 * Returns a new publish list that contains all resources of both given publish lists.<p> 3959 * 3960 * @param context the current request context 3961 * @param pubList1 the first publish list 3962 * @param pubList2 the second publish list 3963 * 3964 * @return a new publish list that contains all resources of both given publish lists 3965 * 3966 * @throws CmsException if something goes wrong 3967 * 3968 * @see org.opencms.publish.CmsPublishManager#mergePublishLists(CmsObject, CmsPublishList, CmsPublishList) 3969 */ 3970 public CmsPublishList mergePublishLists(CmsRequestContext context, CmsPublishList pubList1, CmsPublishList pubList2) 3971 throws CmsException { 3972 3973 CmsPublishList ret = null; 3974 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 3975 try { 3976 // get all resources from the first list 3977 Set<CmsResource> publishResources = new HashSet<CmsResource>(pubList1.getAllResources()); 3978 // get all resources from the second list 3979 publishResources.addAll(pubList2.getAllResources()); 3980 3981 // create merged publish list 3982 ret = new CmsPublishList( 3983 pubList1.getDirectPublishResources(), 3984 pubList1.isPublishSiblings(), 3985 pubList1.isPublishSubResources()); 3986 ret.addAll(publishResources, false); // ignore files that should not be published 3987 if (pubList1.isUserPublishList()) { 3988 ret.setUserPublishList(true); 3989 } 3990 ret.initialize(); // ensure sort order 3991 3992 checkPublishPermissions(dbc, ret); 3993 } catch (Exception e) { 3994 dbc.report(null, Messages.get().container(Messages.ERR_MERGING_PUBLISH_LISTS_0), e); 3995 } finally { 3996 dbc.clear(); 3997 } 3998 return ret; 3999 } 4000 4001 /** 4002 * Moves a resource.<p> 4003 * 4004 * You must ensure that the destination path is an absolute, valid and 4005 * existing VFS path. Relative paths from the source are currently not supported.<p> 4006 * 4007 * The moved resource will always be locked to the current user 4008 * after the move operation.<p> 4009 * 4010 * In case the target resource already exists, it is overwritten with the 4011 * source resource.<p> 4012 * 4013 * @param context the current request context 4014 * @param source the resource to copy 4015 * @param destination the name of the copy destination with complete path 4016 * 4017 * @throws CmsException if something goes wrong 4018 * @throws CmsSecurityException if resource could not be copied 4019 * 4020 * @see CmsObject#moveResource(String, String) 4021 * @see org.opencms.file.types.I_CmsResourceType#moveResource(CmsObject, CmsSecurityManager, CmsResource, String) 4022 */ 4023 public void moveResource(CmsRequestContext context, CmsResource source, String destination) 4024 throws CmsException, CmsSecurityException { 4025 4026 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 4027 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4028 try { 4029 checkOfflineProject(dbc); 4030 // checking if the destination folder exists and is not marked as deleted 4031 readResource(context, CmsResource.getParentFolder(destination), CmsResourceFilter.IGNORE_EXPIRATION); 4032 checkPermissions(dbc, source, CmsPermissionSet.ACCESS_READ, true, CmsResourceFilter.ALL); 4033 checkPermissions(dbc, source, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 4034 4035 checkSystemLocks(dbc, source); 4036 if (CmsModificationContext.isInOnlineFolder( 4037 source.getRootPath()) != CmsModificationContext.isInOnlineFolder(destination)) { 4038 List<CmsResource> filesToCheck = null; 4039 if (source.isFolder()) { 4040 filesToCheck = readResources(context, source, CmsResourceFilter.ALL.addRequireFile(), true); 4041 } else { 4042 filesToCheck = Collections.singletonList(source); 4043 } 4044 for (CmsResource file : filesToCheck) { 4045 if (file.getSiblingCount() > 1) { 4046 throw new CmsVfsException( 4047 Messages.get().container(Messages.ERR_MOVE_SIBLING_FROM_OR_TO_ONLINE_FOLDER_0)); 4048 } 4049 } 4050 } 4051 4052 // check write permissions for subresources in case of moving a folder 4053 if (source.isFolder()) { 4054 dbc.getRequestContext().setAttribute(I_CmsVfsDriver.REQ_ATTR_CHECK_PERMISSIONS, Boolean.TRUE); 4055 try { 4056 m_driverManager.getVfsDriver( 4057 dbc).moveResource(dbc, dbc.currentProject().getUuid(), source, destination); 4058 } catch (CmsDataAccessException e) { 4059 // unwrap the permission violation exception 4060 if (e.getCause() instanceof CmsPermissionViolationException) { 4061 throw (CmsPermissionViolationException)e.getCause(); 4062 } else { 4063 throw e; 4064 } 4065 } 4066 dbc.getRequestContext().removeAttribute(I_CmsVfsDriver.REQ_ATTR_CHECK_PERMISSIONS); 4067 } 4068 Set<CmsResource> allMovedResources = new HashSet<>(); 4069 moveResource(dbc, source, destination, allMovedResources); 4070 if (!dbc.currentProject().isOnlineProject()) { 4071 for (CmsResource movedResource : allMovedResources) { 4072 m_driverManager.repairCategories( 4073 dbc, 4074 dbc.getRequestContext().getCurrentProject().getUuid(), 4075 movedResource); 4076 } 4077 } 4078 4079 } catch (Exception e) { 4080 dbc.report( 4081 null, 4082 Messages.get().container( 4083 Messages.ERR_MOVE_RESOURCE_2, 4084 dbc.removeSiteRoot(source.getRootPath()), 4085 dbc.removeSiteRoot(destination)), 4086 e); 4087 } finally { 4088 dbc.clear(); 4089 } 4090 } 4091 } 4092 4093 /** 4094 * Moves a resource to the "lost and found" folder.<p> 4095 * 4096 * The method can also be used to check get the name of a resource 4097 * in the "lost and found" folder only without actually moving the 4098 * the resource. To do this, the <code>returnNameOnly</code> flag 4099 * must be set to <code>true</code>.<p> 4100 * 4101 * In general, it is the same name as the given resource has, the only exception is 4102 * if a resource in the "lost and found" folder with the same name already exists. 4103 * In such case, a counter is added to the resource name.<p> 4104 * 4105 * @param context the current request context 4106 * @param resource the resource to apply this operation to 4107 * @param returnNameOnly if <code>true</code>, only the name of the resource in the "lost and found" 4108 * folder is returned, the move operation is not really performed 4109 * 4110 * @return the name of the resource inside the "lost and found" folder 4111 * 4112 * @throws CmsException if something goes wrong 4113 * 4114 * @see CmsObject#moveToLostAndFound(String) 4115 * @see CmsObject#getLostAndFoundName(String) 4116 */ 4117 public String moveToLostAndFound(CmsRequestContext context, CmsResource resource, boolean returnNameOnly) 4118 throws CmsException { 4119 4120 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4121 String result = null; 4122 try { 4123 checkOfflineProject(dbc); 4124 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_READ, true, CmsResourceFilter.ALL); 4125 if (!returnNameOnly) { 4126 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 4127 } 4128 result = m_driverManager.moveToLostAndFound(dbc, resource, returnNameOnly); 4129 } catch (Exception e) { 4130 dbc.report( 4131 null, 4132 Messages.get().container( 4133 Messages.ERR_MOVE_TO_LOST_AND_FOUND_1, 4134 dbc.removeSiteRoot(resource.getRootPath())), 4135 e); 4136 } finally { 4137 dbc.clear(); 4138 } 4139 return result; 4140 } 4141 4142 /** 4143 * Publishes the resources of a specified publish list.<p> 4144 * 4145 * @param cms the current request context 4146 * @param publishList a publish list 4147 * @param report an instance of <code>{@link I_CmsReport}</code> to print messages 4148 * 4149 * @return the publish history id of the published project 4150 * 4151 * @throws CmsException if something goes wrong 4152 * 4153 * @see #fillPublishList(CmsRequestContext, CmsPublishList) 4154 */ 4155 public CmsUUID publishProject(CmsObject cms, CmsPublishList publishList, I_CmsReport report) throws CmsException { 4156 4157 CmsRequestContext context = cms.getRequestContext(); 4158 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4159 try { 4160 // check if the current user has the required publish permissions 4161 checkPublishPermissions(dbc, publishList); 4162 m_driverManager.publishProject(cms, dbc, publishList, report); 4163 } finally { 4164 dbc.clear(); 4165 } 4166 return publishList.getPublishHistoryId(); 4167 } 4168 4169 /** 4170 * Reads the alias with a given path in a given site.<p> 4171 * 4172 * @param context the current request context 4173 * @param siteRoot the site root 4174 * @param path the site relative alias path 4175 * @return the alias for the path, or null if no such alias exists 4176 * 4177 * @throws CmsException if something goes wrong 4178 */ 4179 public CmsAlias readAliasByPath(CmsRequestContext context, String siteRoot, String path) throws CmsException { 4180 4181 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4182 try { 4183 CmsAlias alias = m_driverManager.readAliasByPath(dbc, context.getCurrentProject(), siteRoot, path); 4184 return alias; 4185 } catch (Exception e) { 4186 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 4187 return null; // will never be executed 4188 } finally { 4189 dbc.clear(); 4190 } 4191 } 4192 4193 /** 4194 * Reads the aliases for a resource with a given structure id.<p> 4195 * 4196 * @param context the current request context 4197 * @param structureId the structure id for which the aliases should be read 4198 * 4199 * @return the aliases for the structure id 4200 * 4201 * @throws CmsException if something goes wrong 4202 */ 4203 public List<CmsAlias> readAliasesById(CmsRequestContext context, CmsUUID structureId) throws CmsException { 4204 4205 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4206 try { 4207 List<CmsAlias> aliases = m_driverManager.readAliasesByStructureId( 4208 dbc, 4209 context.getCurrentProject(), 4210 structureId); 4211 return aliases; 4212 } catch (Exception e) { 4213 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 4214 return null; // will never be executed 4215 } finally { 4216 dbc.clear(); 4217 } 4218 4219 } 4220 4221 /** 4222 * Reads all historical versions of a resource.<p> 4223 * 4224 * The reading excludes the file content, if the resource is a file.<p> 4225 * 4226 * @param context the current request context 4227 * @param resource the resource to be read 4228 * 4229 * @return a list of historical versions, as <code>{@link I_CmsHistoryResource}</code> objects 4230 * 4231 * @throws CmsException if something goes wrong 4232 */ 4233 public List<I_CmsHistoryResource> readAllAvailableVersions(CmsRequestContext context, CmsResource resource) 4234 throws CmsException { 4235 4236 List<I_CmsHistoryResource> result = null; 4237 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4238 try { 4239 result = m_driverManager.readAllAvailableVersions(dbc, resource); 4240 } catch (Exception e) { 4241 dbc.report( 4242 null, 4243 Messages.get().container(Messages.ERR_READ_ALL_HISTORY_FILE_HEADERS_1, context.getSitePath(resource)), 4244 e); 4245 } finally { 4246 dbc.clear(); 4247 } 4248 return result; 4249 } 4250 4251 /** 4252 * Reads all property definitions for the given mapping type.<p> 4253 * 4254 * @param context the current request context 4255 * 4256 * @return a list with the <code>{@link CmsPropertyDefinition}</code> objects (may be empty) 4257 * 4258 * @throws CmsException if something goes wrong 4259 */ 4260 public List<CmsPropertyDefinition> readAllPropertyDefinitions(CmsRequestContext context) throws CmsException { 4261 4262 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4263 List<CmsPropertyDefinition> result = null; 4264 try { 4265 result = m_driverManager.readAllPropertyDefinitions(dbc); 4266 } catch (Exception e) { 4267 dbc.report(null, Messages.get().container(Messages.ERR_READ_ALL_PROPDEF_0), e); 4268 } finally { 4269 dbc.clear(); 4270 } 4271 return result; 4272 } 4273 4274 /** 4275 * Returns all resources subscribed by the given user or group.<p> 4276 * 4277 * @param context the request context 4278 * @param poolName the name of the database pool to use 4279 * @param principal the principal to read the subscribed resources 4280 * 4281 * @return all resources subscribed by the given user or group 4282 * 4283 * @throws CmsException if something goes wrong 4284 */ 4285 public List<CmsResource> readAllSubscribedResources( 4286 CmsRequestContext context, 4287 String poolName, 4288 CmsPrincipal principal) 4289 throws CmsException { 4290 4291 List<CmsResource> result = null; 4292 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4293 try { 4294 result = m_driverManager.readAllSubscribedResources(dbc, poolName, principal); 4295 } catch (Exception e) { 4296 if (principal instanceof CmsUser) { 4297 dbc.report( 4298 null, 4299 Messages.get().container(Messages.ERR_READ_SUBSCRIBED_RESOURCES_ALL_USER_1, principal.getName()), 4300 e); 4301 } else { 4302 dbc.report( 4303 null, 4304 Messages.get().container(Messages.ERR_READ_SUBSCRIBED_RESOURCES_ALL_GROUP_1, principal.getName()), 4305 e); 4306 } 4307 } finally { 4308 dbc.clear(); 4309 } 4310 return result; 4311 } 4312 4313 /** 4314 * Reads all URL name mapping entries for a given structure id.<p> 4315 * 4316 * @param context the request context 4317 * @param id the structure id 4318 * 4319 * @return the list of URL names for the given structure id 4320 * @throws CmsException if something goes wrong 4321 */ 4322 public List<String> readAllUrlNameMappingEntries(CmsRequestContext context, CmsUUID id) throws CmsException { 4323 4324 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4325 try { 4326 List<CmsUrlNameMappingEntry> entries = m_driverManager.readUrlNameMappingEntries( 4327 dbc, 4328 context.getCurrentProject().isOnlineProject(), 4329 CmsUrlNameMappingFilter.ALL.filterStructureId(id)); 4330 List<String> result = new ArrayList<String>(); 4331 for (CmsUrlNameMappingEntry entry : entries) { 4332 result.add(entry.getName()); 4333 } 4334 return result; 4335 } catch (Exception e) { 4336 CmsMessageContainer message = Messages.get().container( 4337 Messages.ERR_READ_NEWEST_URLNAME_FOR_ID_1, 4338 id.toString()); 4339 dbc.report(null, message, e); 4340 return null; 4341 } finally { 4342 dbc.clear(); 4343 } 4344 4345 } 4346 4347 /** 4348 * Returns the first ancestor folder matching the filter criteria.<p> 4349 * 4350 * If no folder matching the filter criteria is found, null is returned.<p> 4351 * 4352 * @param context the context of the current request 4353 * @param resource the resource to start 4354 * @param filter the resource filter to match while reading the ancestors 4355 * 4356 * @return the first ancestor folder matching the filter criteria or <code>null</code> if no folder was found 4357 * 4358 * @throws CmsException if something goes wrong 4359 */ 4360 public CmsFolder readAncestor(CmsRequestContext context, CmsResource resource, CmsResourceFilter filter) 4361 throws CmsException { 4362 4363 // get the full folder path of the resource to start from 4364 String path = CmsResource.getFolderPath(resource.getRootPath()); 4365 do { 4366 // check if the current folder matches the given filter 4367 if (existsResource(context, path, filter)) { 4368 // folder matches, return it 4369 return readFolder(context, path, filter); 4370 } else { 4371 // folder does not match filter criteria, go up one folder 4372 path = CmsResource.getParentFolder(path); 4373 } 4374 4375 if (CmsStringUtil.isEmpty(path) || !path.startsWith(context.getSiteRoot())) { 4376 // site root or root folder reached and no matching folder found 4377 return null; 4378 } 4379 } while (true); 4380 } 4381 4382 /** 4383 * Reads the newest URL name which is mapped to the given structure id.<p> 4384 * 4385 * If the structure id is not mapped to any name, null will be returned.<p> 4386 * 4387 * @param context the request context 4388 * @param id the structure id for which the newest mapped name should be returned 4389 * @param locale the locale for the mapping 4390 * @param defaultLocales the default locales to use if there is no URL name mapping for the requested locale 4391 * 4392 * @return an URL name or null 4393 * 4394 * @throws CmsException if something goes wrong 4395 */ 4396 public String readBestUrlName(CmsRequestContext context, CmsUUID id, Locale locale, List<Locale> defaultLocales) 4397 throws CmsException { 4398 4399 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4400 try { 4401 return m_driverManager.readBestUrlName(dbc, id, locale, defaultLocales); 4402 } catch (Exception e) { 4403 CmsMessageContainer message = Messages.get().container( 4404 Messages.ERR_READ_NEWEST_URLNAME_FOR_ID_1, 4405 id.toString()); 4406 dbc.report(null, message, e); 4407 return null; // will never be reached 4408 } finally { 4409 dbc.clear(); 4410 } 4411 } 4412 4413 /** 4414 * Returns the child resources of a resource, that is the resources 4415 * contained in a folder.<p> 4416 * 4417 * With the parameters <code>getFolders</code> and <code>getFiles</code> 4418 * you can control what type of resources you want in the result list: 4419 * files, folders, or both.<p> 4420 * 4421 * This method is mainly used by the workplace explorer.<p> 4422 * 4423 * @param context the current request context 4424 * @param resource the resource to return the child resources for 4425 * @param filter the resource filter to use 4426 * @param getFolders if true the child folders are included in the result 4427 * @param getFiles if true the child files are included in the result 4428 * 4429 * @return a list of all child resources 4430 * 4431 * @throws CmsException if something goes wrong 4432 * @throws CmsSecurityException if the user has insufficient permission for the given resource (read is required) 4433 * 4434 */ 4435 public List<CmsResource> readChildResources( 4436 CmsRequestContext context, 4437 CmsResource resource, 4438 CmsResourceFilter filter, 4439 boolean getFolders, 4440 boolean getFiles) 4441 throws CmsException, CmsSecurityException { 4442 4443 List<CmsResource> result = null; 4444 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4445 try { 4446 // check the access permissions 4447 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_READ, true, CmsResourceFilter.ALL); 4448 result = m_driverManager.readChildResources(dbc, resource, filter, getFolders, getFiles, true); 4449 } catch (Exception e) { 4450 dbc.report( 4451 null, 4452 Messages.get().container(Messages.ERR_READ_CHILD_RESOURCES_1, context.getSitePath(resource)), 4453 e); 4454 } finally { 4455 dbc.clear(); 4456 } 4457 return result; 4458 } 4459 4460 /** 4461 * Returns the default file for the given folder.<p> 4462 * 4463 * If the given resource is a file, then this file is returned.<p> 4464 * 4465 * Otherwise, in case of a folder:<br> 4466 * <ol> 4467 * <li>the {@link CmsPropertyDefinition#PROPERTY_DEFAULT_FILE} is checked, and 4468 * <li>if still no file could be found, the configured default files in the 4469 * <code>opencms-vfs.xml</code> configuration are iterated until a match is 4470 * found, and 4471 * <li>if still no file could be found, <code>null</code> is returned 4472 * </ol><p> 4473 * 4474 * @param context the request context 4475 * @param resource the folder to get the default file for 4476 * @param resourceFilter the resource filter 4477 * 4478 * @return the default file for the given folder 4479 * 4480 * @throws CmsSecurityException if the user has no permissions to read the resulting file 4481 * 4482 * @see CmsObject#readDefaultFile(String) 4483 */ 4484 public CmsResource readDefaultFile( 4485 CmsRequestContext context, 4486 CmsResource resource, 4487 CmsResourceFilter resourceFilter) 4488 throws CmsSecurityException { 4489 4490 CmsResource result = null; 4491 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4492 try { 4493 CmsResource tempResult = m_driverManager.readDefaultFile(dbc, resource, resourceFilter); 4494 if (tempResult != null) { 4495 // check if the user has read access to the resource 4496 checkPermissions(dbc, tempResult, CmsPermissionSet.ACCESS_READ, true, resourceFilter); 4497 result = tempResult; 4498 } 4499 } catch (CmsSecurityException se) { 4500 // permissions deny access to the resource 4501 throw se; 4502 } catch (CmsException e) { 4503 // ignore all other exceptions 4504 LOG.debug(e.getLocalizedMessage(), e); 4505 } finally { 4506 dbc.clear(); 4507 } 4508 return result; 4509 } 4510 4511 /** 4512 * Reads all deleted (historical) resources below the given path, 4513 * including the full tree below the path, if required.<p> 4514 * 4515 * @param context the current request context 4516 * @param resource the parent resource to read the resources from 4517 * @param readTree <code>true</code> to read all subresources 4518 * 4519 * @return a list of <code>{@link I_CmsHistoryResource}</code> objects 4520 * 4521 * @throws CmsException if something goes wrong 4522 * 4523 * @see CmsObject#readResource(CmsUUID, int) 4524 * @see CmsObject#readResources(String, CmsResourceFilter, boolean) 4525 * @see CmsObject#readDeletedResources(String, boolean) 4526 */ 4527 public List<I_CmsHistoryResource> readDeletedResources( 4528 CmsRequestContext context, 4529 CmsResource resource, 4530 boolean readTree) 4531 throws CmsException { 4532 4533 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4534 List<I_CmsHistoryResource> result = null; 4535 try { 4536 boolean isVfsManager = hasRoleForResource(dbc, dbc.currentUser(), CmsRole.VFS_MANAGER, resource); 4537 result = m_driverManager.readDeletedResources(dbc, resource, readTree, isVfsManager); 4538 } catch (CmsException e) { 4539 dbc.report( 4540 null, 4541 Messages.get().container( 4542 Messages.ERR_READING_DELETED_RESOURCES_1, 4543 dbc.removeSiteRoot(resource.getRootPath())), 4544 e); 4545 } finally { 4546 dbc.clear(); 4547 } 4548 return result; 4549 } 4550 4551 /** 4552 * Reads a file resource (including it's binary content) from the VFS.<p> 4553 * 4554 * In case you do not need the file content, 4555 * use <code>{@link #readResource(CmsRequestContext, String, CmsResourceFilter)}</code> instead.<p> 4556 * 4557 * @param context the current request context 4558 * @param resource the resource to be read 4559 * 4560 * @return the file read from the VFS 4561 * 4562 * @throws CmsException if something goes wrong 4563 */ 4564 public CmsFile readFile(CmsRequestContext context, CmsResource resource) throws CmsException { 4565 4566 CmsFile result = null; 4567 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4568 try { 4569 result = m_driverManager.readFile(dbc, resource); 4570 } catch (Exception e) { 4571 reportReadFileException(dbc, context, resource, e); 4572 } finally { 4573 dbc.clear(); 4574 } 4575 return result; 4576 } 4577 4578 /** 4579 * Reads a file resource content from the VFS and passes it to an input stream handler.<p> 4580 * 4581 * @param context the current request context 4582 * @param resource the resource to be read 4583 * @param handler the stream handler 4584 * 4585 * @throws CmsException if something goes wrong 4586 */ 4587 public void readFileContentFrom( 4588 CmsRequestContext context, 4589 CmsResource resource, 4590 I_CmsFileContentStreamHandler handler) 4591 throws CmsException { 4592 4593 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4594 try { 4595 m_driverManager.readFileContentFrom(dbc, resource, handler); 4596 } catch (Exception e) { 4597 reportReadFileException(dbc, context, resource, e); 4598 } finally { 4599 dbc.clear(); 4600 } 4601 } 4602 4603 /** 4604 * Reads a file resource content from the VFS and writes it to an output stream.<p> 4605 * 4606 * @param context the current request context 4607 * @param resource the resource to be read 4608 * @param out the output stream to write to 4609 * 4610 * @throws CmsException if something goes wrong 4611 */ 4612 public void readFileContentTo(CmsRequestContext context, CmsResource resource, OutputStream out) 4613 throws CmsException { 4614 4615 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4616 try { 4617 m_driverManager.readFileContentTo(dbc, resource, out); 4618 } catch (Exception e) { 4619 reportReadFileException(dbc, context, resource, e); 4620 } finally { 4621 dbc.clear(); 4622 } 4623 } 4624 4625 /** 4626 * Reads a folder resource from the VFS, 4627 * using the specified resource filter.<p> 4628 * 4629 * The specified filter controls what kind of resources should be "found" 4630 * during the read operation. This will depend on the application. For example, 4631 * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently 4632 * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code> 4633 * will ignore the date release / date expired information of the resource.<p> 4634 * 4635 * @param context the current request context 4636 * @param resourcename the name of the folder to read (full path) 4637 * @param filter the resource filter to use while reading 4638 * 4639 * @return the folder that was read 4640 * 4641 * @throws CmsException if something goes wrong 4642 */ 4643 public CmsFolder readFolder(CmsRequestContext context, String resourcename, CmsResourceFilter filter) 4644 throws CmsException { 4645 4646 CmsFolder result = null; 4647 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4648 try { 4649 result = readFolder(dbc, resourcename, filter); 4650 } catch (Exception e) { 4651 dbc.report(null, Messages.get().container(Messages.ERR_READ_FOLDER_2, resourcename, filter), e); 4652 } finally { 4653 dbc.clear(); 4654 } 4655 return result; 4656 } 4657 4658 /** 4659 * Reads folder size statistis. 4660 * 4661 * @param context the request context 4662 * @param options the options that control what is actually read 4663 * @return the folder size entries 4664 * 4665 * @throws CmsException if something goes wrong 4666 */ 4667 public List<CmsFolderSizeEntry> readFolderSizeStats(CmsRequestContext context, CmsFolderSizeOptions options) 4668 throws CmsException { 4669 4670 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4671 try { 4672 return m_driverManager.readFolderSizeStats(dbc, options); 4673 } finally { 4674 dbc.clear(); 4675 } 4676 } 4677 4678 /** 4679 * Reads the group of a project.<p> 4680 * 4681 * @param context the current request context 4682 * @param project the project to read from 4683 * 4684 * @return the group of a resource 4685 */ 4686 public CmsGroup readGroup(CmsRequestContext context, CmsProject project) { 4687 4688 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4689 CmsGroup result = null; 4690 try { 4691 result = m_driverManager.readGroup(dbc, project); 4692 } finally { 4693 dbc.clear(); 4694 } 4695 return result; 4696 } 4697 4698 /** 4699 * Reads a group based on its id.<p> 4700 * 4701 * @param context the current request context 4702 * @param groupId the id of the group that is to be read 4703 * 4704 * @return the requested group 4705 * 4706 * @throws CmsException if operation was not successful 4707 */ 4708 public CmsGroup readGroup(CmsRequestContext context, CmsUUID groupId) throws CmsException { 4709 4710 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4711 CmsGroup result = null; 4712 try { 4713 result = m_driverManager.readGroup(dbc, groupId); 4714 } catch (Exception e) { 4715 dbc.report(null, Messages.get().container(Messages.ERR_READ_GROUP_FOR_ID_1, groupId.toString()), e); 4716 } finally { 4717 dbc.clear(); 4718 } 4719 return result; 4720 } 4721 4722 /** 4723 * Reads a group based on its name.<p> 4724 * 4725 * @param context the current request context 4726 * @param groupname the name of the group that is to be read 4727 * 4728 * @return the requested group 4729 * 4730 * @throws CmsException if operation was not successful 4731 */ 4732 public CmsGroup readGroup(CmsRequestContext context, String groupname) throws CmsException { 4733 4734 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4735 CmsGroup result = null; 4736 try { 4737 result = m_driverManager.readGroup(dbc, CmsOrganizationalUnit.removeLeadingSeparator(groupname)); 4738 } catch (Exception e) { 4739 dbc.report(null, Messages.get().container(Messages.ERR_READ_GROUP_FOR_NAME_1, groupname), e); 4740 } finally { 4741 dbc.clear(); 4742 } 4743 return result; 4744 } 4745 4746 /** 4747 * Reads a principal (an user or group) from the historical archive based on its ID.<p> 4748 * 4749 * @param context the current request context 4750 * @param principalId the id of the principal to read 4751 * 4752 * @return the historical principal entry with the given id 4753 * 4754 * @throws CmsException if something goes wrong, ie. {@link CmsDbEntryNotFoundException} 4755 * 4756 * @see CmsObject#readUser(CmsUUID) 4757 * @see CmsObject#readGroup(CmsUUID) 4758 * @see CmsObject#readHistoryPrincipal(CmsUUID) 4759 */ 4760 public CmsHistoryPrincipal readHistoricalPrincipal(CmsRequestContext context, CmsUUID principalId) 4761 throws CmsException { 4762 4763 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4764 CmsHistoryPrincipal result = null; 4765 try { 4766 result = m_driverManager.readHistoricalPrincipal(dbc, principalId); 4767 } catch (Exception e) { 4768 dbc.report(null, Messages.get().container(Messages.ERR_READ_HISTORY_PRINCIPAL_1, principalId), e); 4769 } finally { 4770 dbc.clear(); 4771 } 4772 return result; 4773 } 4774 4775 /** 4776 * Returns the latest historical project entry with the given id.<p> 4777 * 4778 * @param context the current request context 4779 * @param projectId the project id 4780 * 4781 * @return the requested historical project entry 4782 * 4783 * @throws CmsException if something goes wrong 4784 */ 4785 public CmsHistoryProject readHistoryProject(CmsRequestContext context, CmsUUID projectId) throws CmsException { 4786 4787 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4788 CmsHistoryProject result = null; 4789 try { 4790 result = m_driverManager.readHistoryProject(dbc, projectId); 4791 } catch (Exception e) { 4792 dbc.report( 4793 null, 4794 Messages.get().container( 4795 Messages.ERR_READ_HISTORY_PROJECT_2, 4796 projectId, 4797 dbc.currentProject().getName()), 4798 e); 4799 } finally { 4800 dbc.clear(); 4801 } 4802 return result; 4803 } 4804 4805 /** 4806 * Returns a historical project entry.<p> 4807 * 4808 * @param context the current request context 4809 * @param publishTag the publish tag of the project 4810 * 4811 * @return the requested historical project entry 4812 * 4813 * @throws CmsException if something goes wrong 4814 */ 4815 public CmsHistoryProject readHistoryProject(CmsRequestContext context, int publishTag) throws CmsException { 4816 4817 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4818 CmsHistoryProject result = null; 4819 try { 4820 result = m_driverManager.readHistoryProject(dbc, publishTag); 4821 } catch (Exception e) { 4822 dbc.report( 4823 null, 4824 Messages.get().container( 4825 Messages.ERR_READ_HISTORY_PROJECT_2, 4826 Integer.valueOf(publishTag), 4827 dbc.currentProject().getName()), 4828 e); 4829 } finally { 4830 dbc.clear(); 4831 } 4832 return result; 4833 } 4834 4835 /** 4836 * Reads the list of all <code>{@link CmsProperty}</code> objects that belong to the given historical resource.<p> 4837 * 4838 * @param context the current request context 4839 * @param resource the historical resource entry to read the properties for 4840 * 4841 * @return the list of <code>{@link CmsProperty}</code> objects 4842 * 4843 * @throws CmsException if something goes wrong 4844 */ 4845 public List<CmsProperty> readHistoryPropertyObjects(CmsRequestContext context, I_CmsHistoryResource resource) 4846 throws CmsException { 4847 4848 List<CmsProperty> result = null; 4849 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4850 try { 4851 result = m_driverManager.readHistoryPropertyObjects(dbc, resource); 4852 } catch (Exception e) { 4853 dbc.report( 4854 null, 4855 Messages.get().container( 4856 Messages.ERR_READ_PROPS_FOR_RESOURCE_1, 4857 context.getSitePath((CmsResource)resource)), 4858 e); 4859 } finally { 4860 dbc.clear(); 4861 } 4862 return result; 4863 } 4864 4865 /** 4866 * Reads the structure id which is mapped to the given URL name, or null if the name is not 4867 * mapped to any structure IDs.<p> 4868 * 4869 * @param context the request context 4870 * @param name an URL name 4871 * 4872 * @return the structure ID which is mapped to the given name 4873 * 4874 * @throws CmsException if something goes wrong 4875 */ 4876 public CmsUUID readIdForUrlName(CmsRequestContext context, String name) throws CmsException { 4877 4878 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4879 try { 4880 return m_driverManager.readIdForUrlName(dbc, name); 4881 } catch (Exception e) { 4882 CmsMessageContainer message = Messages.get().container(Messages.ERR_READ_ID_FOR_URLNAME_1, name); 4883 dbc.report(null, message, e); 4884 return null; // will never be reached 4885 } finally { 4886 dbc.clear(); 4887 } 4888 4889 } 4890 4891 /** 4892 * Reads the locks that were saved to the database in the previous run of OpenCms.<p> 4893 * 4894 * @throws CmsException if something goes wrong 4895 */ 4896 public void readLocks() throws CmsException { 4897 4898 CmsDbContext dbc = m_dbContextFactory.getDbContext(); 4899 try { 4900 m_driverManager.readLocks(dbc); 4901 } finally { 4902 dbc.clear(); 4903 } 4904 } 4905 4906 /** 4907 * Reads the manager group of a project.<p> 4908 * 4909 * @param context the current request context 4910 * @param project the project to read from 4911 * 4912 * @return the group of a resource 4913 */ 4914 public CmsGroup readManagerGroup(CmsRequestContext context, CmsProject project) { 4915 4916 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4917 CmsGroup result = null; 4918 try { 4919 result = m_driverManager.readManagerGroup(dbc, project); 4920 } finally { 4921 dbc.clear(); 4922 } 4923 return result; 4924 } 4925 4926 /** 4927 * Reads an organizational Unit based on its fully qualified name.<p> 4928 * 4929 * @param context the current request context 4930 * @param ouFqn the fully qualified name of the organizational Unit to be read 4931 * 4932 * @return the organizational Unit that with the provided fully qualified name 4933 * 4934 * @throws CmsException if something goes wrong 4935 */ 4936 public CmsOrganizationalUnit readOrganizationalUnit(CmsRequestContext context, String ouFqn) throws CmsException { 4937 4938 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4939 CmsOrganizationalUnit result = null; 4940 try { 4941 result = m_driverManager.readOrganizationalUnit(dbc, CmsOrganizationalUnit.removeLeadingSeparator(ouFqn)); 4942 } catch (Exception e) { 4943 dbc.report(null, Messages.get().container(Messages.ERR_READ_ORGUNIT_1, ouFqn), e); 4944 } finally { 4945 dbc.clear(); 4946 } 4947 return result; 4948 } 4949 4950 /** 4951 * Reads the owner of a project from the OpenCms.<p> 4952 * 4953 * @param context the current request context 4954 * @param project the project to get the owner from 4955 * 4956 * @return the owner of a resource 4957 * 4958 * @throws CmsException if something goes wrong 4959 */ 4960 public CmsUser readOwner(CmsRequestContext context, CmsProject project) throws CmsException { 4961 4962 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4963 CmsUser result = null; 4964 try { 4965 result = m_driverManager.readOwner(dbc, project); 4966 } catch (Exception e) { 4967 dbc.report( 4968 null, 4969 Messages.get().container(Messages.ERR_READ_OWNER_FOR_PROJECT_2, project.getName(), project.getUuid()), 4970 e); 4971 } finally { 4972 dbc.clear(); 4973 } 4974 return result; 4975 } 4976 4977 /** 4978 * Returns the parent folder to the given structure id.<p> 4979 * 4980 * @param context the current request context 4981 * @param structureId the child structure id 4982 * 4983 * @return the parent folder <code>{@link CmsResource}</code> 4984 * 4985 * @throws CmsException if something goes wrong 4986 */ 4987 public CmsResource readParentFolder(CmsRequestContext context, CmsUUID structureId) throws CmsException { 4988 4989 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 4990 CmsResource result = null; 4991 try { 4992 result = m_driverManager.readParentFolder(dbc, structureId); 4993 } catch (Exception e) { 4994 dbc.report( 4995 null, 4996 Messages.get().container( 4997 Messages.ERR_READ_PARENT_FOLDER_2, 4998 dbc.currentProject().getName(), 4999 structureId), 5000 e); 5001 } finally { 5002 dbc.clear(); 5003 } 5004 return result; 5005 } 5006 5007 /** 5008 * Builds a list of resources for a given path.<p> 5009 * 5010 * @param context the current request context 5011 * @param path the requested path 5012 * @param filter a filter object (only "includeDeleted" information is used!) 5013 * 5014 * @return list of <code>{@link CmsResource}</code>s 5015 * 5016 * @throws CmsException if something goes wrong 5017 */ 5018 public List<CmsResource> readPath(CmsRequestContext context, String path, CmsResourceFilter filter) 5019 throws CmsException { 5020 5021 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5022 List<CmsResource> result = null; 5023 try { 5024 result = m_driverManager.readPath(dbc, path, filter); 5025 } catch (Exception e) { 5026 dbc.report( 5027 null, 5028 Messages.get().container(Messages.ERR_READ_PATH_2, dbc.currentProject().getName(), path), 5029 e); 5030 } finally { 5031 dbc.clear(); 5032 } 5033 return result; 5034 } 5035 5036 /** 5037 * Reads a project given the projects id.<p> 5038 * 5039 * @param id the id of the project 5040 * 5041 * @return the project read 5042 * 5043 * @throws CmsException if something goes wrong 5044 */ 5045 public CmsProject readProject(CmsUUID id) throws CmsException { 5046 5047 CmsDbContext dbc = m_dbContextFactory.getDbContext(); 5048 CmsProject result = null; 5049 try { 5050 result = m_driverManager.readProject(dbc, id); 5051 } catch (Exception e) { 5052 dbc.report(null, Messages.get().container(Messages.ERR_READ_PROJECT_FOR_ID_1, id), e); 5053 } finally { 5054 dbc.clear(); 5055 } 5056 return result; 5057 } 5058 5059 /** 5060 * Reads a project.<p> 5061 * 5062 * Important: Since a project name can be used multiple times, this is NOT the most efficient 5063 * way to read the project. This is only a convenience for front end developing. 5064 * Reading a project by name will return the first project with that name. 5065 * All core classes must use the id version {@link #readProject(CmsUUID)} to ensure the right project is read.<p> 5066 * 5067 * @param name the name of the project 5068 * 5069 * @return the project read 5070 * 5071 * @throws CmsException if something goes wrong 5072 */ 5073 public CmsProject readProject(String name) throws CmsException { 5074 5075 CmsDbContext dbc = m_dbContextFactory.getDbContext(); 5076 CmsProject result = null; 5077 try { 5078 result = m_driverManager.readProject(dbc, CmsOrganizationalUnit.removeLeadingSeparator(name)); 5079 } catch (Exception e) { 5080 dbc.report(null, Messages.get().container(Messages.ERR_READ_PROJECT_FOR_NAME_1, name), e); 5081 } finally { 5082 dbc.clear(); 5083 } 5084 return result; 5085 } 5086 5087 /** 5088 * Returns the list of all resource names that define the "view" of the given project.<p> 5089 * 5090 * @param context the current request context 5091 * @param project the project to get the project resources for 5092 * 5093 * @return the list of all resources, as <code>{@link String}</code> objects 5094 * that define the "view" of the given project 5095 * 5096 * @throws CmsException if something goes wrong 5097 */ 5098 public List<String> readProjectResources(CmsRequestContext context, CmsProject project) throws CmsException { 5099 5100 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5101 List<String> result = null; 5102 try { 5103 result = m_driverManager.readProjectResources(dbc, project); 5104 } catch (Exception e) { 5105 dbc.report( 5106 null, 5107 Messages.get().container(Messages.ERR_READ_PROJECT_RESOURCES_2, project.getName(), project.getUuid()), 5108 e); 5109 } finally { 5110 dbc.clear(); 5111 } 5112 return result; 5113 } 5114 5115 /** 5116 * Reads all resources of a project that match a given state from the VFS.<p> 5117 * 5118 * Possible values for the <code>state</code> parameter are:<br> 5119 * <ul> 5120 * <li><code>{@link CmsResource#STATE_CHANGED}</code>: Read all "changed" resources in the project</li> 5121 * <li><code>{@link CmsResource#STATE_NEW}</code>: Read all "new" resources in the project</li> 5122 * <li><code>{@link CmsResource#STATE_DELETED}</code>: Read all "deleted" resources in the project</li> 5123 * <li><code>{@link CmsResource#STATE_KEEP}</code>: Read all resources either "changed", "new" or "deleted" in the project</li> 5124 * </ul><p> 5125 * 5126 * @param context the current request context 5127 * @param projectId the id of the project to read the file resources for 5128 * @param state the resource state to match 5129 * 5130 * @return a list of <code>{@link CmsResource}</code> objects matching the filter criteria 5131 * 5132 * @throws CmsException if something goes wrong 5133 * 5134 * @see CmsObject#readProjectView(CmsUUID, CmsResourceState) 5135 */ 5136 public List<CmsResource> readProjectView(CmsRequestContext context, CmsUUID projectId, CmsResourceState state) 5137 throws CmsException { 5138 5139 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5140 List<CmsResource> result = null; 5141 try { 5142 result = m_driverManager.readProjectView(dbc, projectId, state); 5143 } catch (Exception e) { 5144 dbc.report(null, Messages.get().container(Messages.ERR_READ_PROJECT_VIEW_1, projectId), e); 5145 } finally { 5146 dbc.clear(); 5147 } 5148 return result; 5149 } 5150 5151 /** 5152 * Reads a property definition.<p> 5153 * 5154 * If no property definition with the given name is found, 5155 * <code>null</code> is returned.<p> 5156 * 5157 * @param context the current request context 5158 * @param name the name of the property definition to read 5159 * 5160 * @return the property definition that was read 5161 * 5162 * @throws CmsException a CmsDbEntryNotFoundException is thrown if the property definition does not exist 5163 */ 5164 public CmsPropertyDefinition readPropertyDefinition(CmsRequestContext context, String name) throws CmsException { 5165 5166 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5167 CmsPropertyDefinition result = null; 5168 try { 5169 result = m_driverManager.readPropertyDefinition(dbc, name); 5170 } catch (Exception e) { 5171 dbc.report(null, Messages.get().container(Messages.ERR_READ_PROPDEF_1, name), e); 5172 } finally { 5173 dbc.clear(); 5174 } 5175 return result; 5176 } 5177 5178 /** 5179 * Reads a property object from a resource specified by a property name.<p> 5180 * 5181 * Returns <code>{@link CmsProperty#getNullProperty()}</code> if the property is not found.<p> 5182 * 5183 * @param context the context of the current request 5184 * @param resource the resource where the property is mapped to 5185 * @param key the property key name 5186 * @param search if <code>true</code>, the property is searched on all parent folders of the resource. 5187 * if it's not found attached directly to the resource. 5188 * 5189 * @return the required property, or <code>{@link CmsProperty#getNullProperty()}</code> if the property was not found 5190 * 5191 * @throws CmsException if something goes wrong 5192 */ 5193 public CmsProperty readPropertyObject(CmsRequestContext context, CmsResource resource, String key, boolean search) 5194 throws CmsException { 5195 5196 return readPropertyObject(context, resource, key, search, null); 5197 } 5198 5199 /** 5200 * Reads a property object from a resource specified by a property name.<p> 5201 * 5202 * Returns <code>{@link CmsProperty#getNullProperty()}</code> if the property is not found.<p> 5203 * 5204 * @param context the context of the current request 5205 * @param resource the resource where the property is mapped to 5206 * @param key the property key name 5207 * @param search if <code>true</code>, the property is searched on all parent folders of the resource. 5208 * if it's not found attached directly to the resource. 5209 * @param locale the locale for which the property should be read. 5210 * 5211 * @return the required property, or <code>{@link CmsProperty#getNullProperty()}</code> if the property was not found 5212 * 5213 * @throws CmsException if something goes wrong 5214 */ 5215 public CmsProperty readPropertyObject( 5216 CmsRequestContext context, 5217 CmsResource resource, 5218 String key, 5219 boolean search, 5220 Locale locale) 5221 throws CmsException { 5222 5223 CmsProperty result = null; 5224 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5225 try { 5226 if (null == locale) { 5227 result = m_driverManager.readPropertyObject(dbc, resource, key, search); 5228 } else { 5229 result = m_driverManager.readPropertyObject(dbc, resource, key, search, locale); 5230 } 5231 } catch (Exception e) { 5232 dbc.report( 5233 null, 5234 Messages.get().container(Messages.ERR_READ_PROP_FOR_RESOURCE_2, key, context.getSitePath(resource)), 5235 e); 5236 } finally { 5237 dbc.clear(); 5238 } 5239 return result; 5240 } 5241 5242 /** 5243 * Reads all property objects from a resource.<p> 5244 * 5245 * Returns an empty list if no properties are found.<p> 5246 * 5247 * If the <code>search</code> parameter is <code>true</code>, the properties of all 5248 * parent folders of the resource are also read. The results are merged with the 5249 * properties directly attached to the resource. While merging, a property 5250 * on a parent folder that has already been found will be ignored. 5251 * So e.g. if a resource has a property "Title" attached, and it's parent folder 5252 * has the same property attached but with a different value, the result list will 5253 * contain only the property with the value from the resource, not form the parent folder(s).<p> 5254 * 5255 * @param context the context of the current request 5256 * @param resource the resource where the property is mapped to 5257 * @param search <code>true</code>, if the properties should be searched on all parent folders if not found on the resource 5258 * 5259 * @return a list of <code>{@link CmsProperty}</code> objects 5260 * 5261 * @throws CmsException if something goes wrong 5262 */ 5263 public List<CmsProperty> readPropertyObjects(CmsRequestContext context, CmsResource resource, boolean search) 5264 throws CmsException { 5265 5266 List<CmsProperty> result = null; 5267 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5268 try { 5269 result = m_driverManager.readPropertyObjects(dbc, resource, search); 5270 } catch (Exception e) { 5271 dbc.report( 5272 null, 5273 Messages.get().container(Messages.ERR_READ_PROPS_FOR_RESOURCE_1, context.getSitePath(resource)), 5274 e); 5275 } finally { 5276 dbc.clear(); 5277 } 5278 return result; 5279 } 5280 5281 /** 5282 * Reads the resources that were published in a publish task for a given publish history ID.<p> 5283 * 5284 * @param context the current request context 5285 * @param publishHistoryId unique ID to identify each publish task in the publish history 5286 * 5287 * @return a list of <code>{@link org.opencms.db.CmsPublishedResource}</code> objects 5288 * 5289 * @throws CmsException if something goes wrong 5290 */ 5291 public List<CmsPublishedResource> readPublishedResources(CmsRequestContext context, CmsUUID publishHistoryId) 5292 throws CmsException { 5293 5294 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5295 List<CmsPublishedResource> result = null; 5296 try { 5297 result = m_driverManager.readPublishedResources(dbc, publishHistoryId); 5298 } catch (Exception e) { 5299 dbc.report( 5300 null, 5301 Messages.get().container(Messages.ERR_READ_PUBLISHED_RESOURCES_FOR_ID_1, publishHistoryId.toString()), 5302 e); 5303 } finally { 5304 dbc.clear(); 5305 } 5306 return result; 5307 } 5308 5309 /** 5310 * Reads the historical resource entry for the given resource with the given version number.<p> 5311 * 5312 * @param context the current request context 5313 * @param resource the resource to be read the version for 5314 * @param version the version number to retrieve 5315 * 5316 * @return the resource that was read 5317 * 5318 * @throws CmsException if the resource could not be read for any reason 5319 * 5320 * @see CmsObject#readFile(CmsResource) 5321 * @see CmsObject#restoreResourceVersion(CmsUUID, int) 5322 * @see CmsObject#readResource(CmsUUID, int) 5323 */ 5324 public I_CmsHistoryResource readResource(CmsRequestContext context, CmsResource resource, int version) 5325 throws CmsException { 5326 5327 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5328 I_CmsHistoryResource result = null; 5329 try { 5330 result = m_driverManager.readResource(dbc, resource, version); 5331 } catch (CmsException e) { 5332 dbc.report( 5333 null, 5334 Messages.get().container( 5335 Messages.ERR_READING_RESOURCE_VERSION_2, 5336 dbc.removeSiteRoot(resource.getRootPath()), 5337 Integer.valueOf(version)), 5338 e); 5339 } finally { 5340 dbc.clear(); 5341 } 5342 return result; 5343 } 5344 5345 /** 5346 * Reads a resource from the VFS, 5347 * using the specified resource filter.<p> 5348 * 5349 * A resource may be of type <code>{@link CmsFile}</code> or 5350 * <code>{@link CmsFolder}</code>. In case of 5351 * a file, the resource will not contain the binary file content. Since reading 5352 * the binary content is a cost-expensive database operation, it's recommended 5353 * to work with resources if possible, and only read the file content when absolutely 5354 * required. To "upgrade" a resource to a file, 5355 * use <code>{@link CmsObject#readFile(CmsResource)}</code>.<p> 5356 * 5357 * The specified filter controls what kind of resources should be "found" 5358 * during the read operation. This will depend on the application. For example, 5359 * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently 5360 * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code> 5361 * will ignore the date release / date expired information of the resource.<p> 5362 * 5363 * @param context the current request context 5364 * @param structureID the ID of the structure which will be used) 5365 * @param filter the resource filter to use while reading 5366 * 5367 * @return the resource that was read 5368 * 5369 * @throws CmsException if the resource could not be read for any reason 5370 * 5371 * @see CmsObject#readResource(CmsUUID, CmsResourceFilter) 5372 * @see CmsObject#readResource(CmsUUID) 5373 * @see CmsObject#readFile(CmsResource) 5374 */ 5375 public CmsResource readResource(CmsRequestContext context, CmsUUID structureID, CmsResourceFilter filter) 5376 throws CmsException { 5377 5378 CmsResource result = null; 5379 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5380 try { 5381 result = readResource(dbc, structureID, filter); 5382 } catch (Exception e) { 5383 dbc.report(null, Messages.get().container(Messages.ERR_READ_RESOURCE_FOR_ID_1, structureID), e); 5384 } finally { 5385 dbc.clear(); 5386 } 5387 return result; 5388 } 5389 5390 /** 5391 * Reads a resource from the VFS, 5392 * using the specified resource filter.<p> 5393 * 5394 * A resource may be of type <code>{@link CmsFile}</code> or 5395 * <code>{@link CmsFolder}</code>. In case of 5396 * a file, the resource will not contain the binary file content. Since reading 5397 * the binary content is a cost-expensive database operation, it's recommended 5398 * to work with resources if possible, and only read the file content when absolutely 5399 * required. To "upgrade" a resource to a file, 5400 * use <code>{@link CmsObject#readFile(CmsResource)}</code>.<p> 5401 * 5402 * The specified filter controls what kind of resources should be "found" 5403 * during the read operation. This will depend on the application. For example, 5404 * using <code>{@link CmsResourceFilter#DEFAULT}</code> will only return currently 5405 * "valid" resources, while using <code>{@link CmsResourceFilter#IGNORE_EXPIRATION}</code> 5406 * will ignore the date release / date expired information of the resource.<p> 5407 * 5408 * @param context the current request context 5409 * @param resourcePath the name of the resource to read (full path) 5410 * @param filter the resource filter to use while reading 5411 * 5412 * @return the resource that was read 5413 * 5414 * @throws CmsException if the resource could not be read for any reason 5415 * 5416 * @see CmsObject#readResource(String, CmsResourceFilter) 5417 * @see CmsObject#readResource(String) 5418 * @see CmsObject#readFile(CmsResource) 5419 */ 5420 public CmsResource readResource(CmsRequestContext context, String resourcePath, CmsResourceFilter filter) 5421 throws CmsException { 5422 5423 CmsResource result = null; 5424 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5425 try { 5426 result = readResource(dbc, resourcePath, filter); 5427 } catch (Exception e) { 5428 dbc.report( 5429 null, 5430 Messages.get().container(Messages.ERR_READ_RESOURCE_1, dbc.removeSiteRoot(resourcePath)), 5431 e); 5432 } finally { 5433 dbc.clear(); 5434 } 5435 return result; 5436 } 5437 5438 /** 5439 * Reads all resources below the given path matching the filter criteria, 5440 * including the full tree below the path only in case the <code>readTree</code> 5441 * parameter is <code>true</code>.<p> 5442 * 5443 * @param context the current request context 5444 * @param parent the parent path to read the resources from 5445 * @param filter the filter 5446 * @param readTree <code>true</code> to read all subresources 5447 * 5448 * @return a list of <code>{@link CmsResource}</code> objects matching the filter criteria 5449 * 5450 * @throws CmsSecurityException if the user has insufficient permission for the given resource (read is required) 5451 * @throws CmsException if something goes wrong 5452 * 5453 */ 5454 public List<CmsResource> readResources( 5455 CmsRequestContext context, 5456 CmsResource parent, 5457 CmsResourceFilter filter, 5458 boolean readTree) 5459 throws CmsException, CmsSecurityException { 5460 5461 List<CmsResource> result = null; 5462 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5463 try { 5464 // check the access permissions 5465 checkPermissions(dbc, parent, CmsPermissionSet.ACCESS_READ, true, CmsResourceFilter.ALL); 5466 result = m_driverManager.readResources(dbc, parent, filter, readTree); 5467 } catch (Exception e) { 5468 dbc.report( 5469 null, 5470 Messages.get().container(Messages.ERR_READ_RESOURCES_1, context.removeSiteRoot(parent.getRootPath())), 5471 e); 5472 } finally { 5473 dbc.clear(); 5474 } 5475 return result; 5476 } 5477 5478 /** 5479 * Returns the resources that were visited by a user set in the filter.<p> 5480 * 5481 * @param context the request context 5482 * @param poolName the name of the database pool to use 5483 * @param filter the filter that is used to get the visited resources 5484 * 5485 * @return the resources that were visited by a user set in the filter 5486 * 5487 * @throws CmsException if something goes wrong 5488 */ 5489 public List<CmsResource> readResourcesVisitedBy( 5490 CmsRequestContext context, 5491 String poolName, 5492 CmsVisitedByFilter filter) 5493 throws CmsException { 5494 5495 List<CmsResource> result = null; 5496 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5497 try { 5498 result = m_driverManager.readResourcesVisitedBy(dbc, poolName, filter); 5499 } catch (Exception e) { 5500 dbc.report(null, Messages.get().container(Messages.ERR_READ_VISITED_RESOURCES_1, filter.toString()), e); 5501 } finally { 5502 dbc.clear(); 5503 } 5504 return result; 5505 } 5506 5507 /** 5508 * Reads all resources that have a value (containing the specified value) set 5509 * for the specified property (definition) in the given path.<p> 5510 * 5511 * If the <code>value</code> parameter is <code>null</code>, all resources having the 5512 * given property set are returned.<p> 5513 * 5514 * Both individual and shared properties of a resource are checked.<p> 5515 * 5516 * @param context the current request context 5517 * @param folder the folder to get the resources with the property from 5518 * @param propertyDefinition the name of the property (definition) to check for 5519 * @param value the string to search in the value of the property 5520 * @param filter the resource filter to apply to the result set 5521 * 5522 * @return a list of all <code>{@link CmsResource}</code> objects 5523 * that have a value set for the specified property. 5524 * 5525 * @throws CmsException if something goes wrong 5526 */ 5527 public List<CmsResource> readResourcesWithProperty( 5528 CmsRequestContext context, 5529 CmsResource folder, 5530 String propertyDefinition, 5531 String value, 5532 CmsResourceFilter filter) 5533 throws CmsException { 5534 5535 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5536 List<CmsResource> result = null; 5537 try { 5538 result = m_driverManager.readResourcesWithProperty(dbc, folder, propertyDefinition, value, filter); 5539 } catch (Exception e) { 5540 dbc.report( 5541 null, 5542 Messages.get().container( 5543 Messages.ERR_READ_RESOURCES_FOR_PROP_VALUE_3, 5544 context.removeSiteRoot(folder.getRootPath()), 5545 propertyDefinition, 5546 value), 5547 e); 5548 } finally { 5549 dbc.clear(); 5550 } 5551 return result; 5552 } 5553 5554 /** 5555 * Returns a set of users that are responsible for a specific resource.<p> 5556 * 5557 * @param context the current request context 5558 * @param resource the resource to get the responsible users from 5559 * 5560 * @return the set of users that are responsible for a specific resource 5561 * 5562 * @throws CmsException if something goes wrong 5563 */ 5564 public Set<I_CmsPrincipal> readResponsiblePrincipals(CmsRequestContext context, CmsResource resource) 5565 throws CmsException { 5566 5567 Set<I_CmsPrincipal> result = null; 5568 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5569 try { 5570 result = m_driverManager.readResponsiblePrincipals(dbc, resource); 5571 } catch (Exception e) { 5572 dbc.report( 5573 null, 5574 Messages.get().container(Messages.ERR_READ_RESPONSIBLE_USERS_1, resource.getRootPath()), 5575 e); 5576 } finally { 5577 dbc.clear(); 5578 } 5579 return result; 5580 } 5581 5582 /** 5583 * Returns a set of users that are responsible for a specific resource.<p> 5584 * 5585 * @param context the current request context 5586 * @param resource the resource to get the responsible users from 5587 * 5588 * @return the set of users that are responsible for a specific resource 5589 * 5590 * @throws CmsException if something goes wrong 5591 */ 5592 public Set<CmsUser> readResponsibleUsers(CmsRequestContext context, CmsResource resource) throws CmsException { 5593 5594 Set<CmsUser> result = null; 5595 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5596 try { 5597 result = m_driverManager.readResponsibleUsers(dbc, resource); 5598 } catch (Exception e) { 5599 dbc.report( 5600 null, 5601 Messages.get().container(Messages.ERR_READ_RESPONSIBLE_USERS_1, resource.getRootPath()), 5602 e); 5603 } finally { 5604 dbc.clear(); 5605 } 5606 return result; 5607 } 5608 5609 /** 5610 * Returns a List of all siblings of the specified resource, 5611 * the specified resource being always part of the result set.<p> 5612 * 5613 * @param context the request context 5614 * @param resource the specified resource 5615 * @param filter a filter object 5616 * 5617 * @return a list of <code>{@link CmsResource}</code>s that 5618 * are siblings to the specified resource, 5619 * including the specified resource itself 5620 * 5621 * @throws CmsException if something goes wrong 5622 */ 5623 public List<CmsResource> readSiblings(CmsRequestContext context, CmsResource resource, CmsResourceFilter filter) 5624 throws CmsException { 5625 5626 List<CmsResource> result = null; 5627 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5628 try { 5629 result = m_driverManager.readSiblings(dbc, resource, filter); 5630 } catch (Exception e) { 5631 dbc.report(null, Messages.get().container(Messages.ERR_READ_SIBLINGS_1, context.getSitePath(resource)), e); 5632 } finally { 5633 dbc.clear(); 5634 } 5635 return result; 5636 } 5637 5638 /** 5639 * Returns the parameters of a resource in the table of all published template resources.<p> 5640 * 5641 * @param context the current request context 5642 * @param rfsName the rfs name of the resource 5643 * 5644 * @return the parameter string of the requested resource 5645 * 5646 * @throws CmsException if something goes wrong 5647 */ 5648 public String readStaticExportPublishedResourceParameters(CmsRequestContext context, String rfsName) 5649 throws CmsException { 5650 5651 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5652 String result = null; 5653 try { 5654 result = m_driverManager.readStaticExportPublishedResourceParameters(dbc, rfsName); 5655 } catch (Exception e) { 5656 dbc.report( 5657 null, 5658 Messages.get().container(Messages.ERR_READ_STATEXP_PUBLISHED_RESOURCE_PARAMS_1, rfsName), 5659 e); 5660 } finally { 5661 dbc.clear(); 5662 } 5663 return result; 5664 } 5665 5666 /** 5667 * Returns a list of all template resources which must be processed during a static export.<p> 5668 * 5669 * @param context the current request context 5670 * @param parameterResources flag for reading resources with parameters (1) or without (0) 5671 * @param timestamp for reading the data from the db 5672 * 5673 * @return a list of template resources as <code>{@link String}</code> objects 5674 * 5675 * @throws CmsException if something goes wrong 5676 */ 5677 public List<String> readStaticExportResources(CmsRequestContext context, int parameterResources, long timestamp) 5678 throws CmsException { 5679 5680 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5681 List<String> result = null; 5682 try { 5683 result = m_driverManager.readStaticExportResources(dbc, parameterResources, timestamp); 5684 } catch (Exception e) { 5685 dbc.report(null, Messages.get().container(Messages.ERR_READ_STATEXP_RESOURCES_1, new Date(timestamp)), e); 5686 } finally { 5687 dbc.clear(); 5688 } 5689 return result; 5690 } 5691 5692 /** 5693 * Reads information about where the file content is stored without loading the content bytes.<p> 5694 * 5695 * @param context the current request context 5696 * @param resource the resource to read 5697 * 5698 * @return the stored content info 5699 * 5700 * @throws CmsException if something goes wrong 5701 */ 5702 public CmsStoredContentInfo readStoredContentInfo(CmsRequestContext context, CmsResource resource) 5703 throws CmsException { 5704 5705 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5706 try { 5707 return m_driverManager.readStoredContentInfo(dbc, resource); 5708 } catch (Exception e) { 5709 reportReadFileException(dbc, context, resource, e); 5710 } finally { 5711 dbc.clear(); 5712 } 5713 return null; 5714 } 5715 5716 /** 5717 * Returns the subscribed history resources that were deleted.<p> 5718 * 5719 * @param context the request context 5720 * @param poolName the name of the database pool to use 5721 * @param user the user that subscribed to the resource 5722 * @param groups the groups to check subscribed resources for 5723 * @param parent the parent resource (folder) of the deleted resources, if <code>null</code> all deleted resources will be returned 5724 * @param includeSubFolders indicates if the sub folders of the specified folder path should be considered, too 5725 * @param deletedFrom the time stamp from which the resources should have been deleted 5726 * 5727 * @return the subscribed history resources that were deleted 5728 * 5729 * @throws CmsException if something goes wrong 5730 */ 5731 public List<I_CmsHistoryResource> readSubscribedDeletedResources( 5732 CmsRequestContext context, 5733 String poolName, 5734 CmsUser user, 5735 List<CmsGroup> groups, 5736 CmsResource parent, 5737 boolean includeSubFolders, 5738 long deletedFrom) 5739 throws CmsException { 5740 5741 List<I_CmsHistoryResource> result = null; 5742 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5743 try { 5744 result = m_driverManager.readSubscribedDeletedResources( 5745 dbc, 5746 poolName, 5747 user, 5748 groups, 5749 parent, 5750 includeSubFolders, 5751 deletedFrom); 5752 } catch (Exception e) { 5753 dbc.report( 5754 null, 5755 Messages.get().container(Messages.ERR_READ_SUBSCRIBED_DELETED_RESOURCES_1, user.getName()), 5756 e); 5757 } finally { 5758 dbc.clear(); 5759 } 5760 return result; 5761 } 5762 5763 /** 5764 * Returns the resources that were subscribed by a user or group set in the filter.<p> 5765 * 5766 * @param context the request context 5767 * @param poolName the name of the database pool to use 5768 * @param filter the filter that is used to get the subscribed resources 5769 * 5770 * @return the resources that were subscribed by a user or group set in the filter 5771 * 5772 * @throws CmsException if something goes wrong 5773 */ 5774 public List<CmsResource> readSubscribedResources( 5775 CmsRequestContext context, 5776 String poolName, 5777 CmsSubscriptionFilter filter) 5778 throws CmsException { 5779 5780 List<CmsResource> result = null; 5781 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5782 try { 5783 result = m_driverManager.readSubscribedResources(dbc, poolName, filter); 5784 } catch (Exception e) { 5785 dbc.report(null, Messages.get().container(Messages.ERR_READ_SUBSCRIBED_RESOURCES_1, filter.toString()), e); 5786 } finally { 5787 dbc.clear(); 5788 } 5789 return result; 5790 } 5791 5792 /** 5793 * Reads the URL name mappings matching a given filter.<p> 5794 * 5795 * @param context the current request context 5796 * @param filter the filter to match 5797 * 5798 * @return the matching URL name mappings 5799 * 5800 * @throws CmsException if something goes wrong 5801 */ 5802 public List<CmsUrlNameMappingEntry> readUrlNameMappings(CmsRequestContext context, CmsUrlNameMappingFilter filter) 5803 throws CmsException { 5804 5805 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5806 try { 5807 return m_driverManager.readUrlNameMappings(dbc, filter); 5808 } catch (Exception e) { 5809 CmsMessageContainer message = Messages.get().container( 5810 Messages.ERR_DB_OPERATION_1, 5811 e.getLocalizedMessage()); 5812 dbc.report(null, message, e); 5813 return null; // will never be reached 5814 } finally { 5815 dbc.clear(); 5816 } 5817 } 5818 5819 /** 5820 * Reads the newest URL names of a structure id for all locales.<p> 5821 * 5822 * @param context the current context 5823 * @param id a structure id 5824 * 5825 * @return the list of URL names for all 5826 * @throws CmsException if something goes wrong 5827 */ 5828 public List<String> readUrlNamesForAllLocales(CmsRequestContext context, CmsUUID id) throws CmsException { 5829 5830 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5831 try { 5832 return m_driverManager.readUrlNamesForAllLocales(dbc, id); 5833 } catch (Exception e) { 5834 CmsMessageContainer message = Messages.get().container( 5835 Messages.ERR_READ_NEWEST_URLNAME_FOR_ID_1, 5836 id.toString()); 5837 dbc.report(null, message, e); 5838 return null; // will never be reached 5839 } finally { 5840 dbc.clear(); 5841 } 5842 } 5843 5844 /** 5845 * Returns a user object based on the id of a user.<p> 5846 * 5847 * @param context the current request context 5848 * @param id the id of the user to read 5849 * 5850 * @return the user read 5851 * 5852 * @throws CmsException if something goes wrong 5853 */ 5854 public CmsUser readUser(CmsRequestContext context, CmsUUID id) throws CmsException { 5855 5856 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5857 CmsUser result = null; 5858 try { 5859 result = m_driverManager.readUser(dbc, id); 5860 } catch (Exception e) { 5861 dbc.report(null, Messages.get().container(Messages.ERR_READ_USER_FOR_ID_1, id.toString()), e); 5862 } finally { 5863 dbc.clear(); 5864 } 5865 return result; 5866 } 5867 5868 /** 5869 * Returns a user object.<p> 5870 * 5871 * @param context the current request context 5872 * @param username the name of the user that is to be read 5873 * 5874 * @return user read form the cms 5875 * 5876 * @throws CmsException if operation was not successful 5877 */ 5878 public CmsUser readUser(CmsRequestContext context, String username) throws CmsException { 5879 5880 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5881 CmsUser result = null; 5882 try { 5883 result = m_driverManager.readUser(dbc, CmsOrganizationalUnit.removeLeadingSeparator(username)); 5884 } catch (Exception e) { 5885 dbc.report(null, Messages.get().container(Messages.ERR_READ_USER_FOR_NAME_1, username), e); 5886 } finally { 5887 dbc.clear(); 5888 } 5889 return result; 5890 } 5891 5892 /** 5893 * Returns a user object if the password for the user is correct.<p> 5894 * 5895 * If the user/password pair is not valid a <code>{@link CmsException}</code> is thrown.<p> 5896 * 5897 * @param context the current request context 5898 * @param username the user name of the user that is to be read 5899 * @param password the password of the user that is to be read 5900 * 5901 * @return user read 5902 * 5903 * @throws CmsException if operation was not successful 5904 */ 5905 public CmsUser readUser(CmsRequestContext context, String username, String password) throws CmsException { 5906 5907 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5908 CmsUser result = null; 5909 try { 5910 result = m_driverManager.readUser(dbc, CmsOrganizationalUnit.removeLeadingSeparator(username), password); 5911 } catch (Exception e) { 5912 dbc.report(null, Messages.get().container(Messages.ERR_READ_USER_FOR_NAME_1, username), e); 5913 } finally { 5914 dbc.clear(); 5915 } 5916 return result; 5917 } 5918 5919 /** 5920 * Removes an access control entry for a given resource and principal.<p> 5921 * 5922 * @param context the current request context 5923 * @param resource the resource 5924 * @param principal the id of the principal to remove the the access control entry for 5925 * 5926 * @throws CmsException if something goes wrong 5927 * @throws CmsSecurityException if the user has insufficient permission for the given resource (control of access control is required). 5928 * 5929 */ 5930 public void removeAccessControlEntry(CmsRequestContext context, CmsResource resource, CmsUUID principal) 5931 throws CmsException, CmsSecurityException { 5932 5933 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5934 try { 5935 checkOfflineProject(dbc); 5936 checkPermissions( 5937 dbc, 5938 resource, 5939 CmsPermissionSet.ACCESS_CONTROL, 5940 LockCheck.shallowOnly, 5941 CmsResourceFilter.ALL); 5942 m_driverManager.removeAccessControlEntry(dbc, resource, principal); 5943 } catch (Exception e) { 5944 dbc.report( 5945 null, 5946 Messages.get().container( 5947 Messages.ERR_REMOVE_ACL_ENTRY_2, 5948 context.getSitePath(resource), 5949 principal.toString()), 5950 e); 5951 } finally { 5952 dbc.clear(); 5953 } 5954 } 5955 5956 /** 5957 * Removes a resource from the given organizational unit.<p> 5958 * 5959 * @param context the current request context 5960 * @param orgUnit the organizational unit to remove the resource from 5961 * @param resource the resource that is to be removed from the organizational unit 5962 * 5963 * @throws CmsException if something goes wrong 5964 * 5965 * @see org.opencms.security.CmsOrgUnitManager#addResourceToOrgUnit(CmsObject, String, String) 5966 * @see org.opencms.security.CmsOrgUnitManager#addResourceToOrgUnit(CmsObject, String, String) 5967 */ 5968 public void removeResourceFromOrgUnit( 5969 CmsRequestContext context, 5970 CmsOrganizationalUnit orgUnit, 5971 CmsResource resource) 5972 throws CmsException { 5973 5974 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 5975 try { 5976 checkRole(dbc, CmsRole.ADMINISTRATOR.forOrgUnit(orgUnit.getName())); 5977 checkOfflineProject(dbc); 5978 m_driverManager.removeResourceFromOrgUnit(dbc, orgUnit, resource); 5979 } catch (Exception e) { 5980 dbc.report( 5981 null, 5982 Messages.get().container( 5983 Messages.ERR_REMOVE_RESOURCE_FROM_ORGUNIT_2, 5984 orgUnit.getName(), 5985 dbc.removeSiteRoot(resource.getRootPath())), 5986 e); 5987 } finally { 5988 dbc.clear(); 5989 } 5990 } 5991 5992 /** 5993 * Removes a resource from the current project of the user.<p> 5994 * 5995 * @param context the current request context 5996 * @param resource the resource to apply this operation to 5997 * 5998 * @throws CmsException if something goes wrong 5999 * @throws CmsRoleViolationException if the current user does not have management access to the project 6000 * 6001 * @see org.opencms.file.types.I_CmsResourceType#copyResourceToProject(CmsObject, CmsSecurityManager, CmsResource) 6002 */ 6003 public void removeResourceFromProject(CmsRequestContext context, CmsResource resource) 6004 throws CmsException, CmsRoleViolationException { 6005 6006 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6007 try { 6008 checkOfflineProject(dbc); 6009 checkManagerOfProjectRole(dbc, context.getCurrentProject()); 6010 6011 m_driverManager.removeResourceFromProject(dbc, resource); 6012 } catch (Exception e) { 6013 dbc.report( 6014 null, 6015 Messages.get().container( 6016 Messages.ERR_COPY_RESOURCE_TO_PROJECT_2, 6017 context.getSitePath(resource), 6018 context.getCurrentProject().getName()), 6019 e); 6020 } finally { 6021 dbc.clear(); 6022 } 6023 } 6024 6025 /** 6026 * Removes the given resource to the given user's publish list.<p> 6027 * 6028 * @param context the request context 6029 * @param structureIds the collection of structure IDs to remove 6030 * 6031 * @throws CmsException if something goes wrong 6032 */ 6033 public void removeResourceFromUsersPubList(CmsRequestContext context, Collection<CmsUUID> structureIds) 6034 throws CmsException { 6035 6036 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6037 try { 6038 m_driverManager.removeResourceFromUsersPubList(dbc, context.getCurrentUser().getId(), structureIds); 6039 } catch (Exception e) { 6040 dbc.report( 6041 null, 6042 Messages.get().container( 6043 Messages.ERR_REMOVE_RESOURCE_FROM_PUBLIST_2, 6044 context.getCurrentUser().getName(), 6045 structureIds), 6046 e); 6047 6048 } finally { 6049 dbc.clear(); 6050 } 6051 } 6052 6053 /** 6054 * Removes a user from a group.<p> 6055 * 6056 * @param context the current request context 6057 * @param username the name of the user that is to be removed from the group 6058 * @param groupname the name of the group 6059 * @param readRoles if to read roles or groups 6060 * 6061 * @throws CmsException if operation was not successful 6062 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} 6063 * 6064 */ 6065 public void removeUserFromGroup(CmsRequestContext context, String username, String groupname, boolean readRoles) 6066 throws CmsException, CmsRoleViolationException { 6067 6068 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6069 try { 6070 CmsRole role = CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(groupname)); 6071 checkRoleForUserModification(dbc, username, role); 6072 m_driverManager.removeUserFromGroup( 6073 dbc, 6074 CmsOrganizationalUnit.removeLeadingSeparator(username), 6075 CmsOrganizationalUnit.removeLeadingSeparator(groupname), 6076 readRoles); 6077 } catch (Exception e) { 6078 dbc.report(null, Messages.get().container(Messages.ERR_REMOVE_USER_FROM_GROUP_2, username, groupname), e); 6079 } finally { 6080 dbc.clear(); 6081 } 6082 } 6083 6084 /** 6085 * Replaces the content, type and properties of a resource.<p> 6086 * 6087 * @param context the current request context 6088 * @param resource the name of the resource to apply this operation to 6089 * @param type the new type of the resource 6090 * @param content the new content of the resource 6091 * @param properties the new properties of the resource 6092 * 6093 * @throws CmsException if something goes wrong 6094 * @throws CmsSecurityException if the user has insufficient permission for the given resource (write access permission is required) 6095 * 6096 * @see CmsObject#replaceResource(String, int, byte[], List) 6097 * @see org.opencms.file.types.I_CmsResourceType#replaceResource(CmsObject, CmsSecurityManager, CmsResource, int, byte[], List) 6098 */ 6099 @SuppressWarnings("javadoc") 6100 public void replaceResource( 6101 CmsRequestContext context, 6102 CmsResource resource, 6103 int type, 6104 byte[] content, 6105 List<CmsProperty> properties) 6106 throws CmsException, CmsSecurityException { 6107 6108 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 6109 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6110 try { 6111 checkOfflineProject(dbc); 6112 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 6113 if (CmsResourceTypeJsp.isJspTypeId(type)) { 6114 // security check preventing the creation of a jsp file without permissions 6115 checkRoleForResource(dbc, CmsRole.VFS_MANAGER, resource); 6116 } 6117 m_driverManager.replaceResource(dbc, resource, type, content, properties); 6118 modContext.add(resource); 6119 } catch (Exception e) { 6120 dbc.report( 6121 null, 6122 Messages.get().container(Messages.ERR_REPLACE_RESOURCE_1, context.getSitePath(resource)), 6123 e); 6124 } finally { 6125 dbc.clear(); 6126 } 6127 } 6128 } 6129 6130 /** 6131 * Resets the password for a specified user.<p> 6132 * 6133 * @param context the current request context 6134 * @param username the name of the user 6135 * @param oldPassword the old password 6136 * @param secondFactor the additional information for 2FA 6137 * @param newPassword the new password 6138 * 6139 * @throws CmsException if the user data could not be read from the database 6140 * @throws CmsSecurityException if the specified user name and old password could not be verified 6141 */ 6142 public void resetPassword( 6143 CmsRequestContext context, 6144 String username, 6145 String oldPassword, 6146 CmsSecondFactorInfo secondFactor, 6147 String newPassword) 6148 throws CmsException, CmsSecurityException { 6149 6150 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6151 try { 6152 m_driverManager.resetPassword( 6153 dbc, 6154 CmsOrganizationalUnit.removeLeadingSeparator(username), 6155 oldPassword, 6156 secondFactor, 6157 newPassword); 6158 } catch (Exception e) { 6159 dbc.report(null, Messages.get().container(Messages.ERR_RESET_PASSWORD_1, username), e); 6160 } finally { 6161 dbc.clear(); 6162 } 6163 } 6164 6165 /** 6166 * Returns the original path of given resource, that is the online path for the resource.<p> 6167 * 6168 * If it differs from the offline path, the resource has been moved.<p> 6169 * 6170 * @param context the current request context 6171 * @param resource the resource to get the path for 6172 * 6173 * @return the online path 6174 * 6175 * @throws CmsException if something goes wrong 6176 * 6177 * @see org.opencms.workplace.commons.CmsUndoChanges#resourceOriginalPath(CmsObject, String) 6178 */ 6179 public String resourceOriginalPath(CmsRequestContext context, CmsResource resource) throws CmsException { 6180 6181 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6182 String result = null; 6183 try { 6184 checkOfflineProject(dbc); 6185 result = m_driverManager.getVfsDriver( 6186 dbc).readResource(dbc, CmsProject.ONLINE_PROJECT_ID, resource.getStructureId(), true).getRootPath(); 6187 } catch (Exception e) { 6188 dbc.report( 6189 null, 6190 Messages.get().container( 6191 Messages.ERR_TEST_MOVED_RESOURCE_1, 6192 dbc.removeSiteRoot(resource.getRootPath())), 6193 e); 6194 } finally { 6195 dbc.clear(); 6196 } 6197 return result; 6198 } 6199 6200 /** 6201 * Restores a deleted resource identified by its structure id from the historical archive.<p> 6202 * 6203 * @param context the current request context 6204 * @param structureId the structure id of the resource to restore 6205 * 6206 * @throws CmsException if something goes wrong 6207 * 6208 * @see CmsObject#restoreDeletedResource(CmsUUID) 6209 */ 6210 public void restoreDeletedResource(CmsRequestContext context, CmsUUID structureId) throws CmsException { 6211 6212 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 6213 6214 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6215 try { 6216 checkOfflineProject(dbc); 6217 // write permissions on parent folder are checked later 6218 CmsResource resource = m_driverManager.restoreDeletedResource(dbc, structureId); 6219 modContext.add(resource); 6220 } catch (Exception e) { 6221 dbc.report(null, Messages.get().container(Messages.ERR_RESTORE_DELETED_RESOURCE_1, structureId), e); 6222 } finally { 6223 dbc.clear(); 6224 } 6225 } 6226 } 6227 6228 /** 6229 * Restores a resource in the current project with the given version from the historical archive.<p> 6230 * 6231 * @param context the current request context 6232 * @param resource the resource to restore from the archive 6233 * @param version the version number to restore 6234 * 6235 * @throws CmsException if something goes wrong 6236 * @throws CmsSecurityException if the user has insufficient permission for the given resource (write access permission is required) 6237 * 6238 * @see CmsObject#restoreResourceVersion(CmsUUID, int) 6239 * @see org.opencms.file.types.I_CmsResourceType#restoreResource(CmsObject, CmsSecurityManager, CmsResource, int) 6240 */ 6241 public void restoreResource(CmsRequestContext context, CmsResource resource, int version) 6242 throws CmsException, CmsSecurityException { 6243 6244 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 6245 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6246 try { 6247 checkOfflineProject(dbc); 6248 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 6249 m_driverManager.restoreResource(dbc, resource, version); 6250 modContext.add(resource); 6251 } catch (Exception e) { 6252 dbc.report( 6253 null, 6254 Messages.get().container( 6255 Messages.ERR_RESTORE_RESOURCE_2, 6256 context.getSitePath(resource), 6257 Integer.valueOf(version)), 6258 e); 6259 } finally { 6260 dbc.clear(); 6261 } 6262 } 6263 } 6264 6265 /** 6266 * Saves the aliases for a given resource.<p> 6267 * 6268 * This method completely replaces any existing aliases for the same structure id. 6269 * 6270 * @param context the request context 6271 * @param resource the resource for which the aliases should be written 6272 * @param aliases the list of aliases to write, where all aliases must have the same structure id as the resource 6273 * 6274 * @throws CmsException if something goes wrong 6275 */ 6276 public void saveAliases(CmsRequestContext context, CmsResource resource, List<CmsAlias> aliases) 6277 throws CmsException { 6278 6279 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6280 try { 6281 if ((aliases.size() > 0) && !(resource.getStructureId().equals(aliases.get(0).getStructureId()))) { 6282 throw new IllegalArgumentException("Resource does not match aliases!"); 6283 } 6284 checkPermissions(context, resource, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.ALL); 6285 m_driverManager.saveAliases(dbc, context.getCurrentProject(), resource.getStructureId(), aliases); 6286 Map<String, Object> eventData = new HashMap<String, Object>(); 6287 eventData.put(I_CmsEventListener.KEY_RESOURCE, resource); 6288 eventData.put(I_CmsEventListener.KEY_CHANGE, Integer.valueOf(CmsDriverManager.CHANGED_RESOURCE)); 6289 OpenCms.fireCmsEvent(new CmsEvent(I_CmsEventListener.EVENT_RESOURCE_MODIFIED, eventData)); 6290 } catch (Exception e) { 6291 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 6292 } finally { 6293 dbc.clear(); 6294 } 6295 } 6296 6297 /** 6298 * Replaces the rewrite aliases for a given site root.<p> 6299 * 6300 * @param requestContext the current request context 6301 * @param siteRoot the site root for which the rewrite aliases should be replaced 6302 * @param newAliases the new list of aliases for the given site root 6303 * 6304 * @throws CmsException if something goes wrong 6305 */ 6306 public void saveRewriteAliases(CmsRequestContext requestContext, String siteRoot, List<CmsRewriteAlias> newAliases) 6307 throws CmsException { 6308 6309 CmsDbContext dbc = m_dbContextFactory.getDbContext(requestContext); 6310 try { 6311 // checkOfflineProject(dbc); 6312 // checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 6313 m_driverManager.saveRewriteAliases(dbc, siteRoot, newAliases); 6314 } catch (Exception e) { 6315 dbc.report(null, Messages.get().container(Messages.ERR_DB_OPERATION_0), e); 6316 } finally { 6317 dbc.clear(); 6318 } 6319 } 6320 6321 /** 6322 * Searches users by search criteria.<p> 6323 * 6324 * @param requestContext the request context 6325 * @param searchParams the search criteria object 6326 * 6327 * @return a list of users 6328 * @throws CmsException if something goes wrong 6329 */ 6330 public List<CmsUser> searchUsers(CmsRequestContext requestContext, CmsUserSearchParameters searchParams) 6331 throws CmsException { 6332 6333 CmsDbContext dbc = m_dbContextFactory.getDbContext(requestContext); 6334 try { 6335 return m_driverManager.searchUsers(dbc, searchParams); 6336 } catch (Exception e) { 6337 dbc.report(null, Messages.get().container(Messages.ERR_SEARCH_USERS_0), e); 6338 return null; 6339 } finally { 6340 dbc.clear(); 6341 } 6342 } 6343 6344 /** 6345 * Changes the "expire" date of a resource.<p> 6346 * 6347 * @param context the current request context 6348 * @param resource the resource to touch 6349 * @param dateExpired the new expire date of the changed resource 6350 * 6351 * @throws CmsException if something goes wrong 6352 * @throws CmsSecurityException if the user has insufficient permission for the given resource (write access permission is required) 6353 * 6354 * @see CmsObject#setDateExpired(String, long, boolean) 6355 * @see org.opencms.file.types.I_CmsResourceType#setDateExpired(CmsObject, CmsSecurityManager, CmsResource, long, boolean) 6356 */ 6357 public void setDateExpired(CmsRequestContext context, CmsResource resource, long dateExpired) 6358 throws CmsException, CmsSecurityException { 6359 6360 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 6361 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6362 try { 6363 checkOfflineProject(dbc); 6364 checkPermissions( 6365 dbc, 6366 resource, 6367 CmsPermissionSet.ACCESS_WRITE, 6368 true, 6369 CmsResourceFilter.IGNORE_EXPIRATION); 6370 m_driverManager.setDateExpired(dbc, resource, dateExpired); 6371 modContext.add(resource); 6372 } catch (Exception e) { 6373 dbc.report( 6374 null, 6375 Messages.get().container( 6376 Messages.ERR_SET_DATE_EXPIRED_2, 6377 new Object[] {new Date(dateExpired), context.getSitePath(resource)}), 6378 e); 6379 } finally { 6380 dbc.clear(); 6381 } 6382 } 6383 } 6384 6385 /** 6386 * Changes the "last modified" time stamp of a resource.<p> 6387 * 6388 * @param context the current request context 6389 * @param resource the resource to touch 6390 * @param dateLastModified the new time stamp of the changed resource 6391 * 6392 * @throws CmsException if something goes wrong 6393 * @throws CmsSecurityException if the user has insufficient permission for the given resource (write access permission is required) 6394 * 6395 * @see CmsObject#setDateLastModified(String, long, boolean) 6396 * @see org.opencms.file.types.I_CmsResourceType#setDateLastModified(CmsObject, CmsSecurityManager, CmsResource, long, boolean) 6397 */ 6398 6399 public void setDateLastModified(CmsRequestContext context, CmsResource resource, long dateLastModified) 6400 throws CmsException, CmsSecurityException { 6401 6402 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 6403 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6404 try { 6405 checkOfflineProject(dbc); 6406 checkPermissions( 6407 dbc, 6408 resource, 6409 CmsPermissionSet.ACCESS_WRITE, 6410 true, 6411 CmsResourceFilter.IGNORE_EXPIRATION); 6412 m_driverManager.setDateLastModified(dbc, resource, dateLastModified); 6413 modContext.add(resource); 6414 } catch (Exception e) { 6415 dbc.report( 6416 null, 6417 Messages.get().container( 6418 Messages.ERR_SET_DATE_LAST_MODIFIED_2, 6419 new Object[] {new Date(dateLastModified), context.getSitePath(resource)}), 6420 e); 6421 } finally { 6422 dbc.clear(); 6423 } 6424 } 6425 } 6426 6427 /** 6428 * Changes the "release" date of a resource.<p> 6429 * 6430 * @param context the current request context 6431 * @param resource the resource to touch 6432 * @param dateReleased the new release date of the changed resource 6433 * 6434 * @throws CmsException if something goes wrong 6435 * @throws CmsSecurityException if the user has insufficient permission for the given resource (write access permission is required) 6436 * 6437 * @see CmsObject#setDateReleased(String, long, boolean) 6438 * @see org.opencms.file.types.I_CmsResourceType#setDateReleased(CmsObject, CmsSecurityManager, CmsResource, long, boolean) 6439 */ 6440 public void setDateReleased(CmsRequestContext context, CmsResource resource, long dateReleased) 6441 throws CmsException, CmsSecurityException { 6442 6443 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 6444 6445 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6446 try { 6447 checkOfflineProject(dbc); 6448 checkPermissions( 6449 dbc, 6450 resource, 6451 CmsPermissionSet.ACCESS_WRITE, 6452 true, 6453 CmsResourceFilter.IGNORE_EXPIRATION); 6454 m_driverManager.setDateReleased(dbc, resource, dateReleased); 6455 modContext.add(resource); 6456 } catch (Exception e) { 6457 dbc.report( 6458 null, 6459 Messages.get().container( 6460 Messages.ERR_SET_DATE_RELEASED_2, 6461 new Object[] {new Date(dateReleased), context.getSitePath(resource)}), 6462 e); 6463 } finally { 6464 dbc.clear(); 6465 } 6466 } 6467 } 6468 6469 /** 6470 * Sets a new parent-group for an already existing group.<p> 6471 * 6472 * @param context the current request context 6473 * @param groupName the name of the group that should be written 6474 * @param parentGroupName the name of the parent group to set, 6475 * or <code>null</code> if the parent 6476 * group should be deleted. 6477 * 6478 * @throws CmsException if operation was not successful 6479 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} 6480 * 6481 */ 6482 public void setParentGroup(CmsRequestContext context, String groupName, String parentGroupName) 6483 throws CmsException, CmsRoleViolationException { 6484 6485 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6486 6487 try { 6488 checkRole(dbc, CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(groupName))); 6489 m_driverManager.setParentGroup( 6490 dbc, 6491 CmsOrganizationalUnit.removeLeadingSeparator(groupName), 6492 CmsOrganizationalUnit.removeLeadingSeparator(parentGroupName)); 6493 } catch (Exception e) { 6494 dbc.report(null, Messages.get().container(Messages.ERR_SET_PARENT_GROUP_2, parentGroupName, groupName), e); 6495 } finally { 6496 dbc.clear(); 6497 } 6498 } 6499 6500 /** 6501 * Sets the password for a user.<p> 6502 * 6503 * @param context the current request context 6504 * @param username the name of the user 6505 * @param newPassword the new password 6506 * 6507 * @throws CmsException if operation was not successful 6508 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} 6509 */ 6510 public void setPassword(CmsRequestContext context, String username, String newPassword) 6511 throws CmsException, CmsRoleViolationException { 6512 6513 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6514 try { 6515 CmsRole role = CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(username)); 6516 checkRoleForUserModification(dbc, username, role); 6517 m_driverManager.setPassword(dbc, CmsOrganizationalUnit.removeLeadingSeparator(username), newPassword); 6518 } catch (Exception e) { 6519 dbc.report(null, Messages.get().container(Messages.ERR_SET_PASSWORD_1, username), e); 6520 } finally { 6521 dbc.clear(); 6522 } 6523 } 6524 6525 /** 6526 * Sets/clears the 'restricted' status for the given resource and group. 6527 * 6528 * <p>The 'restricted' status causes files to be inaccessible to users who are not in the group if the file is expired or unreleased. 6529 * <p>It is implemented as an access control entry with the 'responsible' flag, but the permission check for this method is different from the chacc() methods: It doesn't require control 6530 * permissions on the target resource, but the user has to be a member of the given group and have write access to the resource. 6531 * 6532 * @param context the current request context 6533 * @param resource the target resource 6534 * @param group a group (current user must be a member) 6535 * @param restricted true if the restriction status should be set 6536 * @throws CmsException if something goes wrong 6537 */ 6538 public void setRestricted(CmsRequestContext context, CmsResource resource, CmsGroup group, boolean restricted) 6539 throws CmsException { 6540 6541 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 6542 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6543 try { 6544 checkOfflineProject(dbc); 6545 if (!resource.isFile()) { 6546 throw new RestrictionNotSupportedForFoldersException(); 6547 } 6548 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 6549 6550 if (!hasRole(context, context.getCurrentUser(), CmsAccessRestrictionInfo.ROLE_CAN_IGNORE_GROUP) 6551 && !userInGroup(context, context.getCurrentUser().getName(), group.getName())) { 6552 throw new RestrictionGroupMembershipException(); 6553 } 6554 List<CmsAccessControlEntry> aces = getAccessControlEntries(context, resource, false); 6555 CmsAccessControlEntry foundAce = null; 6556 for (CmsAccessControlEntry ace : aces) { 6557 if (ace.getPrincipal().equals(group.getId())) { 6558 foundAce = ace; 6559 break; 6560 } 6561 } 6562 CmsAccessControlEntry aceToWrite = null; 6563 if (foundAce != null) { 6564 // make a copy so we can compare it to the original later 6565 aceToWrite = new CmsAccessControlEntry( 6566 foundAce.getResource(), 6567 foundAce.getPrincipal(), 6568 foundAce.getAllowedPermissions(), 6569 foundAce.getDeniedPermissions(), 6570 foundAce.getFlags()); 6571 if (restricted) { 6572 aceToWrite.setFlags(CmsAccessControlEntry.ACCESS_FLAGS_RESPONSIBLE); 6573 } else { 6574 aceToWrite.resetFlags(CmsAccessControlEntry.ACCESS_FLAGS_RESPONSIBLE); 6575 } 6576 if ((aceToWrite.getAllowedPermissions() == 0) 6577 && (aceToWrite.getDeniedPermissions() == 0) 6578 && ((aceToWrite.getFlags() & ~CmsAccessControlEntry.ACCESS_FLAGS_GROUP) == 0)) { 6579 // an empty ACE (no permissions, no flags except group marker) is equivalent to no ACE at all - delete the existing one 6580 m_driverManager.removeAccessControlEntry(dbc, resource, group.getId()); 6581 modContext.add(resource); 6582 } else if (!aceToWrite.equals(foundAce)) { 6583 m_driverManager.writeAccessControlEntry(dbc, resource, aceToWrite); 6584 modContext.add(resource); 6585 } 6586 } else if (restricted) { // if restricted=false and no entry is found, we don't need to change anything 6587 int flags = CmsAccessControlEntry.ACCESS_FLAGS_GROUP 6588 | CmsAccessControlEntry.ACCESS_FLAGS_RESPONSIBLE; 6589 aceToWrite = new CmsAccessControlEntry(resource.getResourceId(), group.getId(), 0, 0, flags); 6590 m_driverManager.writeAccessControlEntry(dbc, resource, aceToWrite); 6591 modContext.add(resource); 6592 } 6593 } catch (Exception e) { 6594 dbc.report( 6595 null, 6596 Messages.get().container(Messages.ERR_WRITE_ACL_ENTRY_1, context.getSitePath(resource)), 6597 e); 6598 } finally { 6599 dbc.clear(); 6600 } 6601 } 6602 6603 } 6604 6605 /** 6606 * Marks a subscribed resource as deleted.<p> 6607 * 6608 * @param context the request context 6609 * @param poolName the name of the database pool to use 6610 * @param resource the subscribed resource to mark as deleted 6611 * 6612 * @throws CmsException if something goes wrong 6613 */ 6614 public void setSubscribedResourceAsDeleted(CmsRequestContext context, String poolName, CmsResource resource) 6615 throws CmsException { 6616 6617 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6618 try { 6619 m_driverManager.setSubscribedResourceAsDeleted(dbc, poolName, resource); 6620 } catch (Exception e) { 6621 6622 dbc.report( 6623 null, 6624 Messages.get().container( 6625 Messages.ERR_SET_SUBSCRIBED_RESOURCE_AS_DELETED_1, 6626 context.getSitePath(resource)), 6627 e); 6628 6629 } finally { 6630 dbc.clear(); 6631 } 6632 } 6633 6634 /** 6635 * Moves an user to the given organizational unit.<p> 6636 * 6637 * @param context the current request context 6638 * @param orgUnit the organizational unit to add the principal to 6639 * @param user the user that is to be move to the organizational unit 6640 * 6641 * @throws CmsException if something goes wrong 6642 * 6643 * @see org.opencms.security.CmsOrgUnitManager#setUsersOrganizationalUnit(CmsObject, String, String) 6644 */ 6645 public void setUsersOrganizationalUnit(CmsRequestContext context, CmsOrganizationalUnit orgUnit, CmsUser user) 6646 throws CmsException { 6647 6648 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6649 try { 6650 checkRole(dbc, CmsRole.ADMINISTRATOR.forOrgUnit(orgUnit.getName())); 6651 checkOfflineProject(dbc); 6652 m_driverManager.setUsersOrganizationalUnit(dbc, orgUnit, user); 6653 } catch (Exception e) { 6654 dbc.report( 6655 null, 6656 Messages.get().container(Messages.ERR_SET_USERS_ORGUNIT_2, orgUnit.getName(), user.getName()), 6657 e); 6658 } finally { 6659 dbc.clear(); 6660 } 6661 } 6662 6663 /** 6664 * Subscribes the user or group to the resource.<p> 6665 * 6666 * @param context the request context 6667 * @param poolName the name of the database pool to use 6668 * @param principal the principal that subscribes to the resource 6669 * @param resource the resource to subscribe to 6670 * 6671 * @throws CmsException if something goes wrong 6672 */ 6673 public void subscribeResourceFor( 6674 CmsRequestContext context, 6675 String poolName, 6676 CmsPrincipal principal, 6677 CmsResource resource) 6678 throws CmsException { 6679 6680 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6681 try { 6682 m_driverManager.subscribeResourceFor(dbc, poolName, principal, resource); 6683 } catch (Exception e) { 6684 if (principal instanceof CmsUser) { 6685 dbc.report( 6686 null, 6687 Messages.get().container( 6688 Messages.ERR_SUBSCRIBE_RESOURCE_FOR_USER_2, 6689 context.getSitePath(resource), 6690 principal.getName()), 6691 e); 6692 } else { 6693 dbc.report( 6694 null, 6695 Messages.get().container( 6696 Messages.ERR_SUBSCRIBE_RESOURCE_FOR_GROUP_2, 6697 context.getSitePath(resource), 6698 principal.getName()), 6699 e); 6700 } 6701 } finally { 6702 dbc.clear(); 6703 } 6704 } 6705 6706 /** 6707 * Undelete the resource by resetting it's state.<p> 6708 * 6709 * @param context the current request context 6710 * @param resource the name of the resource to apply this operation to 6711 * 6712 * @throws CmsException if something goes wrong 6713 * 6714 * @see CmsObject#undeleteResource(String, boolean) 6715 * @see org.opencms.file.types.I_CmsResourceType#undelete(CmsObject, CmsSecurityManager, CmsResource, boolean) 6716 */ 6717 public void undelete(CmsRequestContext context, CmsResource resource) throws CmsException { 6718 6719 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6720 try { 6721 checkOfflineProject(dbc); 6722 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 6723 checkSystemLocks(dbc, resource); 6724 6725 m_driverManager.undelete(dbc, resource); 6726 } catch (Exception e) { 6727 dbc.report( 6728 null, 6729 Messages.get().container(Messages.ERR_UNDELETE_FOR_RESOURCE_1, context.getSitePath(resource)), 6730 e); 6731 } finally { 6732 dbc.clear(); 6733 } 6734 } 6735 6736 /** 6737 * Undos all changes in the resource by restoring the version from the 6738 * online project to the current offline project.<p> 6739 * 6740 * @param context the current request context 6741 * @param resource the name of the resource to apply this operation to 6742 * @param mode the undo mode, one of the <code>{@link CmsResource}#UNDO_XXX</code> constants 6743 * 6744 * @throws CmsException if something goes wrong 6745 * @throws CmsSecurityException if the user has insufficient permission for the given resource (write access permission is required) 6746 * 6747 * @see CmsObject#undoChanges(String, CmsResource.CmsResourceUndoMode) 6748 * @see org.opencms.file.types.I_CmsResourceType#undoChanges(CmsObject, CmsSecurityManager, CmsResource, CmsResource.CmsResourceUndoMode) 6749 */ 6750 public void undoChanges(CmsRequestContext context, CmsResource resource, CmsResource.CmsResourceUndoMode mode) 6751 throws CmsException, CmsSecurityException { 6752 6753 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6754 try { 6755 checkOfflineProject(dbc); 6756 checkPermissions( 6757 dbc, 6758 resource, 6759 CmsPermissionSet.ACCESS_WRITE, 6760 resource.isFile() || mode.isRecursive() || (mode == CmsResource.UNDO_MOVE_CONTENT) 6761 ? LockCheck.yes 6762 : LockCheck.shallowOnly, 6763 CmsResourceFilter.ALL); 6764 checkSystemLocks(dbc, resource); 6765 6766 m_driverManager.undoChanges(dbc, resource, mode); 6767 } catch (Exception e) { 6768 dbc.report( 6769 null, 6770 Messages.get().container(Messages.ERR_UNDO_CHANGES_FOR_RESOURCE_1, context.getSitePath(resource)), 6771 e); 6772 } finally { 6773 dbc.clear(); 6774 } 6775 } 6776 6777 /** 6778 * Unlocks all resources in this project.<p> 6779 * 6780 * @param context the current request context 6781 * @param projectId the id of the project to be published 6782 * 6783 * @throws CmsException if something goes wrong 6784 * @throws CmsRoleViolationException if the current user does not own the required permissions 6785 */ 6786 public void unlockProject(CmsRequestContext context, CmsUUID projectId) 6787 throws CmsException, CmsRoleViolationException { 6788 6789 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6790 CmsProject project = m_driverManager.readProject(dbc, projectId); 6791 6792 try { 6793 checkManagerOfProjectRole(dbc, project); 6794 m_driverManager.unlockProject(project); 6795 } catch (Exception e) { 6796 dbc.report( 6797 null, 6798 Messages.get().container(Messages.ERR_UNLOCK_PROJECT_2, projectId, dbc.currentUser().getName()), 6799 e); 6800 } finally { 6801 dbc.clear(); 6802 } 6803 } 6804 6805 /** 6806 * Unlocks a resource.<p> 6807 * 6808 * @param context the current request context 6809 * @param resource the resource to unlock 6810 * 6811 * @throws CmsException if something goes wrong 6812 * @throws CmsSecurityException if the user has insufficient permission for the given resource (write access permission is required) 6813 * 6814 * @see CmsObject#unlockResource(String) 6815 * @see org.opencms.file.types.I_CmsResourceType#unlockResource(CmsObject, CmsSecurityManager, CmsResource) 6816 */ 6817 public void unlockResource(CmsRequestContext context, CmsResource resource) 6818 throws CmsException, CmsSecurityException { 6819 6820 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6821 try { 6822 checkOfflineProject(dbc); 6823 checkPermissions( 6824 dbc, 6825 resource, 6826 CmsPermissionSet.ACCESS_WRITE, 6827 LockCheck.shallowOnly, 6828 CmsResourceFilter.ALL); 6829 m_driverManager.unlockResource(dbc, resource, false, false); 6830 } catch (CmsException e) { 6831 dbc.report( 6832 null, 6833 Messages.get().container( 6834 Messages.ERR_UNLOCK_RESOURCE_3, 6835 context.getSitePath(resource), 6836 dbc.currentUser().getName(), 6837 e.getLocalizedMessage(dbc.getRequestContext().getLocale())), 6838 e); 6839 } finally { 6840 dbc.clear(); 6841 } 6842 } 6843 6844 /** 6845 * Unsubscribes all deleted resources that were deleted before the specified time stamp.<p> 6846 * 6847 * @param context the request context 6848 * @param poolName the name of the database pool to use 6849 * @param deletedTo the time stamp to which the resources have been deleted 6850 * 6851 * @throws CmsException if something goes wrong 6852 */ 6853 public void unsubscribeAllDeletedResources(CmsRequestContext context, String poolName, long deletedTo) 6854 throws CmsException { 6855 6856 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6857 try { 6858 m_driverManager.unsubscribeAllDeletedResources(dbc, poolName, deletedTo); 6859 } catch (Exception e) { 6860 6861 dbc.report(null, Messages.get().container(Messages.ERR_UNSUBSCRIBE_ALL_DELETED_RESOURCES_USER_0), e); 6862 6863 } finally { 6864 dbc.clear(); 6865 } 6866 } 6867 6868 /** 6869 * Unsubscribes the user or group from all resources.<p> 6870 * 6871 * @param context the request context 6872 * @param poolName the name of the database pool to use 6873 * @param principal the principal that unsubscribes from all resources 6874 * 6875 * @throws CmsException if something goes wrong 6876 */ 6877 public void unsubscribeAllResourcesFor(CmsRequestContext context, String poolName, CmsPrincipal principal) 6878 throws CmsException { 6879 6880 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6881 try { 6882 m_driverManager.unsubscribeAllResourcesFor(dbc, poolName, principal); 6883 } catch (Exception e) { 6884 if (principal instanceof CmsUser) { 6885 dbc.report( 6886 null, 6887 Messages.get().container(Messages.ERR_UNSUBSCRIBE_ALL_RESOURCES_USER_1, principal.getName()), 6888 e); 6889 } else { 6890 dbc.report( 6891 null, 6892 Messages.get().container(Messages.ERR_UNSUBSCRIBE_ALL_RESOURCES_GROUP_1, principal.getName()), 6893 e); 6894 } 6895 } finally { 6896 dbc.clear(); 6897 } 6898 } 6899 6900 /** 6901 * Unsubscribes the principal from the resource.<p> 6902 * 6903 * @param context the request context 6904 * @param poolName the name of the database pool to use 6905 * @param principal the principal that unsubscribes from the resource 6906 * @param resource the resource to unsubscribe from 6907 * 6908 * @throws CmsException if something goes wrong 6909 */ 6910 public void unsubscribeResourceFor( 6911 CmsRequestContext context, 6912 String poolName, 6913 CmsPrincipal principal, 6914 CmsResource resource) 6915 throws CmsException { 6916 6917 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6918 try { 6919 m_driverManager.unsubscribeResourceFor(dbc, poolName, principal, resource); 6920 } catch (Exception e) { 6921 dbc.report( 6922 null, 6923 Messages.get().container( 6924 Messages.ERR_UNSUBSCRIBE_RESOURCE_FOR_GROUP_2, 6925 context.getSitePath(resource), 6926 principal.getName()), 6927 e); 6928 } finally { 6929 dbc.clear(); 6930 } 6931 } 6932 6933 /** 6934 * Unsubscribes all groups and users from the resource.<p> 6935 * 6936 * @param context the request context 6937 * @param poolName the name of the database pool to use 6938 * @param resource the resource to unsubscribe all groups and users from 6939 * 6940 * @throws CmsException if something goes wrong 6941 */ 6942 public void unsubscribeResourceForAll(CmsRequestContext context, String poolName, CmsResource resource) 6943 throws CmsException { 6944 6945 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6946 try { 6947 m_driverManager.unsubscribeResourceForAll(dbc, poolName, resource); 6948 } catch (Exception e) { 6949 dbc.report( 6950 null, 6951 Messages.get().container(Messages.ERR_UNSUBSCRIBE_RESOURCE_ALL_1, context.getSitePath(resource)), 6952 e); 6953 } finally { 6954 dbc.clear(); 6955 } 6956 } 6957 6958 /** 6959 * Updates the last login date on the given user to the current time.<p> 6960 * 6961 * @param context the current request context 6962 * @param user the user to be updated 6963 * 6964 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} for the current project 6965 * @throws CmsException if operation was not successful 6966 */ 6967 public void updateLastLoginDate(CmsRequestContext context, CmsUser user) 6968 throws CmsException, CmsRoleViolationException { 6969 6970 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 6971 try { 6972 CmsRole role = CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(user.getName())); 6973 checkRoleForUserModification(dbc, user.getName(), role); 6974 m_driverManager.updateLastLoginDate(dbc, user); 6975 } catch (Exception e) { 6976 dbc.report(null, Messages.get().container(Messages.ERR_WRITE_USER_1, user.getName()), e); 6977 } finally { 6978 dbc.clear(); 6979 } 6980 } 6981 6982 /** 6983 * Logs everything that has not been written to DB jet.<p> 6984 * 6985 * @throws CmsException if something goes wrong 6986 */ 6987 public void updateLog() throws CmsException { 6988 6989 if (m_dbContextFactory == null) { 6990 // already shutdown 6991 return; 6992 } 6993 CmsDbContext dbc = m_dbContextFactory.getDbContext(); 6994 try { 6995 m_driverManager.updateLog(dbc); 6996 } finally { 6997 dbc.clear(); 6998 } 6999 } 7000 7001 /** 7002 * Updates/Creates the relations for the given resource.<p> 7003 * 7004 * @param context the current user context 7005 * @param resource the resource to update the relations for 7006 * @param relations the relations to update 7007 * @param updateSiblingState if true, sets the state of siblings with changed relations to 'changed' (unless they are new or deleted) 7008 * 7009 * @throws CmsException if something goes wrong 7010 * 7011 * @see CmsDriverManager#updateRelationsForResource(CmsDbContext, CmsResource, List, boolean) 7012 */ 7013 public void updateRelationsForResource( 7014 CmsRequestContext context, 7015 CmsResource resource, 7016 List<CmsLink> relations, 7017 boolean updateSiblingState) 7018 throws CmsException { 7019 7020 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7021 try { 7022 m_driverManager.updateRelationsForResource(dbc, resource, relations, updateSiblingState); 7023 } catch (Exception e) { 7024 dbc.report( 7025 null, 7026 Messages.get().container(Messages.ERR_UPDATE_RELATIONS_1, dbc.removeSiteRoot(resource.getRootPath())), 7027 e); 7028 } finally { 7029 dbc.clear(); 7030 } 7031 } 7032 7033 /** 7034 * Tests if a user is member of the given group.<p> 7035 * 7036 * @param context the current request context 7037 * @param username the name of the user to check 7038 * @param groupname the name of the group to check 7039 * 7040 * @return <code>true</code>, if the user is in the group; or <code>false</code> otherwise 7041 * 7042 * @throws CmsException if operation was not successful 7043 */ 7044 public boolean userInGroup(CmsRequestContext context, String username, String groupname) throws CmsException { 7045 7046 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7047 boolean result = false; 7048 try { 7049 result = m_driverManager.userInGroup( 7050 dbc, 7051 CmsOrganizationalUnit.removeLeadingSeparator(username), 7052 CmsOrganizationalUnit.removeLeadingSeparator(groupname), 7053 false); 7054 } catch (Exception e) { 7055 dbc.report(null, Messages.get().container(Messages.ERR_USER_IN_GROUP_2, username, groupname), e); 7056 } finally { 7057 dbc.clear(); 7058 } 7059 return result; 7060 } 7061 7062 /** 7063 * Checks if a new password follows the rules for 7064 * new passwords, which are defined by a Class implementing the 7065 * <code>{@link org.opencms.security.I_CmsPasswordHandler}</code> 7066 * interface and configured in the opencms.properties file.<p> 7067 * 7068 * If this method throws no exception the password is valid.<p> 7069 * 7070 * @param password the new password that has to be checked 7071 * 7072 * @throws CmsSecurityException if the password is not valid 7073 */ 7074 public void validatePassword(String password) throws CmsSecurityException { 7075 7076 m_driverManager.validatePassword(password); 7077 } 7078 7079 /** 7080 * Validates the relations for the given resources.<p> 7081 * 7082 * @param context the current request context 7083 * @param publishList the resources to validate during publishing 7084 * @param report a report to write the messages to 7085 * 7086 * @return a map with lists of invalid links 7087 * (<code>{@link org.opencms.relations.CmsRelation}}</code> objects) 7088 * keyed by root paths 7089 * 7090 * @throws Exception if something goes wrong 7091 */ 7092 public Map<String, List<CmsRelation>> validateRelations( 7093 CmsRequestContext context, 7094 CmsPublishList publishList, 7095 I_CmsReport report) 7096 throws Exception { 7097 7098 Map<String, List<CmsRelation>> result = null; 7099 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7100 try { 7101 result = m_driverManager.validateRelations(dbc, publishList, report); 7102 } catch (Exception e) { 7103 dbc.report(null, Messages.get().container(Messages.ERR_VALIDATE_RELATIONS_0), e); 7104 } finally { 7105 dbc.clear(); 7106 } 7107 return result; 7108 } 7109 7110 /** 7111 * Writes an access control entries to a given resource.<p> 7112 * 7113 * @param context the current request context 7114 * @param resource the resource 7115 * @param ace the entry to write 7116 * 7117 * @throws CmsSecurityException if the user has insufficient permission for the given resource ({@link CmsPermissionSet#ACCESS_CONTROL} required) 7118 * @throws CmsException if something goes wrong 7119 */ 7120 public void writeAccessControlEntry(CmsRequestContext context, CmsResource resource, CmsAccessControlEntry ace) 7121 throws CmsException, CmsSecurityException { 7122 7123 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7124 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 7125 7126 try { 7127 checkOfflineProject(dbc); 7128 checkPermissions( 7129 dbc, 7130 resource, 7131 CmsPermissionSet.ACCESS_CONTROL, 7132 LockCheck.shallowOnly, 7133 CmsResourceFilter.ALL); 7134 if (ace.getPrincipal().equals(CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID)) { 7135 // only vfs managers can set the overwrite all ACE 7136 checkRoleForResource(dbc, CmsRole.VFS_MANAGER, resource); 7137 } 7138 m_driverManager.writeAccessControlEntry(dbc, resource, ace); 7139 modContext.add(resource); 7140 } catch (Exception e) { 7141 dbc.report( 7142 null, 7143 Messages.get().container(Messages.ERR_WRITE_ACL_ENTRY_1, context.getSitePath(resource)), 7144 e); 7145 } finally { 7146 dbc.clear(); 7147 } 7148 } 7149 } 7150 7151 /** 7152 * Writes a resource to the OpenCms VFS, including it's content.<p> 7153 * 7154 * Applies only to resources of type <code>{@link CmsFile}</code> 7155 * i.e. resources that have a binary content attached.<p> 7156 * 7157 * Certain resource types might apply content validation or transformation rules 7158 * before the resource is actually written to the VFS. The returned result 7159 * might therefore be a modified version from the provided original.<p> 7160 * 7161 * @param context the current request context 7162 * @param resource the resource to apply this operation to 7163 * 7164 * @return the written resource (may have been modified) 7165 * 7166 * @throws CmsSecurityException if the user has insufficient permission for the given resource ({@link CmsPermissionSet#ACCESS_WRITE} required) 7167 * @throws CmsException if something goes wrong 7168 * 7169 * @see CmsObject#writeFile(CmsFile) 7170 * @see org.opencms.file.types.I_CmsResourceType#writeFile(CmsObject, CmsSecurityManager, CmsFile) 7171 */ 7172 public CmsFile writeFile(CmsRequestContext context, CmsFile resource) throws CmsException, CmsSecurityException { 7173 7174 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 7175 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7176 CmsFile result = null; 7177 try { 7178 checkOfflineProject(dbc); 7179 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 7180 7181 result = m_driverManager.writeFile(dbc, resource); 7182 modContext.add(result.getCopy()); 7183 } catch (Exception e) { 7184 dbc.report(null, Messages.get().container(Messages.ERR_WRITE_FILE_1, context.getSitePath(resource)), e); 7185 } finally { 7186 dbc.clear(); 7187 } 7188 return result; 7189 } 7190 } 7191 7192 /** 7193 * Writes an already existing group.<p> 7194 * 7195 * The group id has to be a valid OpenCms group id.<br> 7196 * 7197 * The group with the given id will be completely overridden 7198 * by the given data.<p> 7199 * 7200 * @param context the current request context 7201 * @param group the group that should be written 7202 * 7203 * @throws CmsRoleViolationException if the current user does not own the role {@link CmsRole#ACCOUNT_MANAGER} for the current project 7204 * @throws CmsException if operation was not successful 7205 */ 7206 public void writeGroup(CmsRequestContext context, CmsGroup group) throws CmsException, CmsRoleViolationException { 7207 7208 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7209 try { 7210 checkRole(dbc, CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(group.getName()))); 7211 m_driverManager.writeGroup(dbc, group); 7212 } catch (Exception e) { 7213 dbc.report(null, Messages.get().container(Messages.ERR_WRITE_GROUP_1, group.getName()), e); 7214 } finally { 7215 dbc.clear(); 7216 } 7217 } 7218 7219 /** 7220 * Creates a historical entry of the current project.<p> 7221 * 7222 * @param context the current request context 7223 * @param publishTag the correlative publish tag 7224 * @param publishDate the date of publishing 7225 * 7226 * @throws CmsException if operation was not successful 7227 */ 7228 public void writeHistoryProject(CmsRequestContext context, int publishTag, long publishDate) throws CmsException { 7229 7230 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7231 try { 7232 m_driverManager.writeHistoryProject(dbc, publishTag, publishDate); 7233 } catch (Exception e) { 7234 dbc.report( 7235 null, 7236 Messages.get().container( 7237 Messages.ERR_HISTORY_PROJECT_4, 7238 new Object[] { 7239 Integer.valueOf(publishTag), 7240 dbc.currentProject().getName(), 7241 dbc.currentProject().getUuid(), 7242 Long.valueOf(publishDate)}), 7243 e); 7244 } finally { 7245 dbc.clear(); 7246 } 7247 } 7248 7249 /** 7250 * Writes the locks that are currently stored in-memory to the database to allow restoring them in 7251 * later startups.<p> 7252 * 7253 * This overwrites the locks previously stored in the underlying database table.<p> 7254 * 7255 * @throws CmsException if something goes wrong 7256 */ 7257 public void writeLocks() throws CmsException { 7258 7259 if (m_dbContextFactory == null) { 7260 // already shutdown 7261 return; 7262 } 7263 CmsDbContext dbc = m_dbContextFactory.getDbContext(); 7264 try { 7265 m_driverManager.writeLocks(dbc); 7266 } finally { 7267 dbc.clear(); 7268 } 7269 } 7270 7271 /** 7272 * Writes an already existing organizational unit.<p> 7273 * 7274 * The organizational unit id has to be a valid OpenCms organizational unit id.<p> 7275 * 7276 * The organizational unit with the given id will be completely overridden 7277 * by the given data.<p> 7278 * 7279 * @param context the current request context 7280 * @param organizationalUnit the organizational unit that should be written 7281 * 7282 * @throws CmsException if operation was not successful 7283 * 7284 * @see org.opencms.security.CmsOrgUnitManager#writeOrganizationalUnit(CmsObject, CmsOrganizationalUnit) 7285 */ 7286 public void writeOrganizationalUnit(CmsRequestContext context, CmsOrganizationalUnit organizationalUnit) 7287 throws CmsException { 7288 7289 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7290 try { 7291 checkRole(dbc, CmsRole.ADMINISTRATOR.forOrgUnit(organizationalUnit.getName())); 7292 checkOfflineProject(dbc); 7293 m_driverManager.writeOrganizationalUnit(dbc, organizationalUnit); 7294 } catch (Exception e) { 7295 dbc.report(null, Messages.get().container(Messages.ERR_WRITE_ORGUNIT_1, organizationalUnit.getName()), e); 7296 } finally { 7297 dbc.clear(); 7298 } 7299 } 7300 7301 /** 7302 * Writes an already existing project.<p> 7303 * 7304 * The project id has to be a valid OpenCms project id.<br> 7305 * 7306 * The project with the given id will be completely overridden 7307 * by the given data.<p> 7308 * 7309 * @param project the project that should be written 7310 * @param context the current request context 7311 * 7312 * @throws CmsRoleViolationException if the current user does not own the required permissions 7313 * @throws CmsException if operation was not successful 7314 */ 7315 public void writeProject(CmsRequestContext context, CmsProject project) 7316 throws CmsRoleViolationException, CmsException { 7317 7318 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7319 try { 7320 checkManagerOfProjectRole(dbc, project); 7321 m_driverManager.writeProject(dbc, project); 7322 } catch (Exception e) { 7323 dbc.report(null, Messages.get().container(Messages.ERR_WRITE_PROJECT_1, project.getName()), e); 7324 } finally { 7325 dbc.clear(); 7326 } 7327 } 7328 7329 /** 7330 * Writes a property for a specified resource.<p> 7331 * 7332 * @param context the current request context 7333 * @param resource the resource to write the property for 7334 * @param property the property to write 7335 * 7336 * @throws CmsException if something goes wrong 7337 * @throws CmsSecurityException if the user has insufficient permission for the given resource ({@link CmsPermissionSet#ACCESS_WRITE} required) 7338 * 7339 * @see CmsObject#writePropertyObject(String, CmsProperty) 7340 * @see org.opencms.file.types.I_CmsResourceType#writePropertyObject(CmsObject, CmsSecurityManager, CmsResource, CmsProperty) 7341 */ 7342 public void writePropertyObject(CmsRequestContext context, CmsResource resource, CmsProperty property) 7343 throws CmsException, CmsSecurityException { 7344 7345 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 7346 7347 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7348 try { 7349 checkOfflineProject(dbc); 7350 checkPermissions( 7351 dbc, 7352 resource, 7353 CmsPermissionSet.ACCESS_WRITE, 7354 LockCheck.shallowOnly, 7355 CmsResourceFilter.IGNORE_EXPIRATION); 7356 m_driverManager.writePropertyObject(dbc, resource, property); 7357 modContext.add(resource); 7358 } catch (Exception e) { 7359 dbc.report( 7360 null, 7361 Messages.get().container( 7362 Messages.ERR_WRITE_PROP_2, 7363 property.getName(), 7364 context.getSitePath(resource)), 7365 e); 7366 } finally { 7367 dbc.clear(); 7368 } 7369 } 7370 } 7371 7372 /** 7373 * Writes a list of properties for a specified resource.<p> 7374 * 7375 * Code calling this method has to ensure that the no properties 7376 * <code>a, b</code> are contained in the specified list so that <code>a.equals(b)</code>, 7377 * otherwise an exception is thrown.<p> 7378 * 7379 * @param context the current request context 7380 * @param resource the resource to write the properties for 7381 * @param properties the list of properties to write 7382 * 7383 * @throws CmsException if something goes wrong 7384 * @throws CmsSecurityException if the user has insufficient permission for the given resource ({@link CmsPermissionSet#ACCESS_WRITE} required) 7385 * 7386 * @see CmsObject#writePropertyObjects(String, List) 7387 * @see org.opencms.file.types.I_CmsResourceType#writePropertyObjects(CmsObject, CmsSecurityManager, CmsResource, List) 7388 */ 7389 public void writePropertyObjects(CmsRequestContext context, CmsResource resource, List<CmsProperty> properties) 7390 throws CmsException, CmsSecurityException { 7391 7392 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 7393 7394 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7395 try { 7396 checkOfflineProject(dbc); 7397 checkPermissions( 7398 dbc, 7399 resource, 7400 CmsPermissionSet.ACCESS_WRITE, 7401 LockCheck.shallowOnly, 7402 CmsResourceFilter.IGNORE_EXPIRATION); 7403 // write the properties 7404 m_driverManager.writePropertyObjects(dbc, resource, properties, true); 7405 modContext.add(resource); 7406 } catch (Exception e) { 7407 dbc.report( 7408 null, 7409 Messages.get().container(Messages.ERR_WRITE_PROPS_1, context.getSitePath(resource)), 7410 e); 7411 } finally { 7412 dbc.clear(); 7413 } 7414 } 7415 } 7416 7417 /** 7418 * Writes a resource to the OpenCms VFS.<p> 7419 * 7420 * @param context the current request context 7421 * @param resource the resource to write 7422 * 7423 * @throws CmsSecurityException if the user has insufficient permission for the given resource ({@link CmsPermissionSet#ACCESS_WRITE} required) 7424 * @throws CmsException if something goes wrong 7425 */ 7426 public void writeResource(CmsRequestContext context, CmsResource resource) 7427 throws CmsException, CmsSecurityException { 7428 7429 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 7430 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7431 try { 7432 checkOfflineProject(dbc); 7433 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 7434 m_driverManager.writeResource(dbc, resource); 7435 modContext.add(resource); 7436 } catch (Exception e) { 7437 dbc.report( 7438 null, 7439 Messages.get().container(Messages.ERR_WRITE_RESOURCE_1, context.getSitePath(resource)), 7440 e); 7441 } finally { 7442 dbc.clear(); 7443 } 7444 } 7445 } 7446 7447 /** 7448 * Writes the 'projectlastmodified' field of a resource record.<p> 7449 * 7450 * @param context the current database context 7451 * @param resource the resource which should be modified 7452 * @param project the project whose project id should be written into the resource record 7453 * 7454 * @throws CmsException if something goes wrong 7455 */ 7456 public void writeResourceProjectLastModified(CmsRequestContext context, CmsResource resource, CmsProject project) 7457 throws CmsException { 7458 7459 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 7460 7461 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7462 try { 7463 checkOfflineProject(dbc); 7464 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_WRITE, true, CmsResourceFilter.ALL); 7465 m_driverManager.writeProjectLastModified(dbc, resource, project.getUuid()); 7466 modContext.add(resource); 7467 } catch (Exception e) { 7468 dbc.report( 7469 null, 7470 Messages.get().container(Messages.ERR_WRITE_RESOURCE_1, context.getSitePath(resource)), 7471 e); 7472 } finally { 7473 dbc.clear(); 7474 } 7475 } 7476 } 7477 7478 /** 7479 * Inserts an entry in the published resource table.<p> 7480 * 7481 * This is done during static export.<p> 7482 * 7483 * @param context the current request context 7484 * @param resourceName The name of the resource to be added to the static export 7485 * @param linkType the type of resource exported (0= non-parameter, 1=parameter) 7486 * @param linkParameter the parameters added to the resource 7487 * @param timestamp a time stamp for writing the data into the db 7488 * 7489 * @throws CmsException if something goes wrong 7490 */ 7491 public void writeStaticExportPublishedResource( 7492 CmsRequestContext context, 7493 String resourceName, 7494 int linkType, 7495 String linkParameter, 7496 long timestamp) 7497 throws CmsException { 7498 7499 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7500 try { 7501 m_driverManager.writeStaticExportPublishedResource(dbc, resourceName, linkType, linkParameter, timestamp); 7502 } catch (Exception e) { 7503 dbc.report( 7504 null, 7505 Messages.get().container( 7506 Messages.ERR_WRITE_STATEXP_PUBLISHED_RESOURCES_3, 7507 resourceName, 7508 linkParameter, 7509 new Date(timestamp)), 7510 e); 7511 } finally { 7512 dbc.clear(); 7513 } 7514 } 7515 7516 /** 7517 * Writes a new URL name mapping for a given resource.<p> 7518 * 7519 * The first name from the given sequence which is not already mapped to another resource will be used for 7520 * the URL name mapping.<p> 7521 * 7522 * @param context the request context 7523 * @param nameSeq the sequence of URL name candidates 7524 * @param structureId the structure id which should be mapped to the name 7525 * @param locale the locale for the mapping 7526 * @param replaceOnPublish mappings for which this is set will replace all other mappings for the same resource on publishing 7527 * 7528 * @return the name which was actually mapped to the structure id 7529 * 7530 * @throws CmsException if something goes wrong 7531 */ 7532 public String writeUrlNameMapping( 7533 CmsRequestContext context, 7534 Iterator<String> nameSeq, 7535 CmsUUID structureId, 7536 String locale, 7537 boolean replaceOnPublish) 7538 throws CmsException { 7539 7540 try (CmsModificationContext modContext = CmsModificationContext.acquire(context)) { 7541 7542 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7543 try { 7544 String result = m_driverManager.writeUrlNameMapping( 7545 dbc, 7546 nameSeq, 7547 structureId, 7548 locale, 7549 replaceOnPublish); 7550 modContext.addId(structureId); 7551 return result; 7552 } catch (Exception e) { 7553 CmsMessageContainer message = Messages.get().container( 7554 Messages.ERR_ADD_URLNAME_MAPPING_2, 7555 nameSeq.toString(), 7556 structureId.toString()); 7557 dbc.report(null, message, e); 7558 return null; 7559 } finally { 7560 dbc.clear(); 7561 } 7562 } 7563 7564 } 7565 7566 /** 7567 * Updates the user information. <p> 7568 * 7569 * The user id has to be a valid OpenCms user id.<br> 7570 * 7571 * The user with the given id will be completely overridden 7572 * by the given data.<p> 7573 * 7574 * @param context the current request context 7575 * @param user the user to be updated 7576 * 7577 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} for the current project 7578 * @throws CmsException if operation was not successful 7579 */ 7580 public void writeUser(CmsRequestContext context, CmsUser user) throws CmsException, CmsRoleViolationException { 7581 7582 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 7583 try { 7584 CmsRole role = CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(user.getName())); 7585 checkRoleForUserModification(dbc, user.getName(), role); 7586 m_driverManager.writeUser(dbc, user); 7587 } catch (Exception e) { 7588 dbc.report(null, Messages.get().container(Messages.ERR_WRITE_USER_1, user.getName()), e); 7589 } finally { 7590 dbc.clear(); 7591 } 7592 } 7593 7594 /** 7595 * Performs a blocking permission check on a resource.<p> 7596 * 7597 * If the required permissions are not satisfied by the permissions the user has on the resource, 7598 * an exception is thrown.<p> 7599 * 7600 * @param dbc the current database context 7601 * @param resource the resource on which permissions are required 7602 * @param requiredPermissions the set of permissions required to access the resource 7603 * @param checkLock if true, the lock status of the resource is also checked 7604 * @param filter the filter for the resource 7605 * 7606 * @throws CmsException in case of any i/o error 7607 * @throws CmsSecurityException if the required permissions are not satisfied 7608 * 7609 * @see #hasPermissions(CmsRequestContext, CmsResource, CmsPermissionSet, boolean, CmsResourceFilter) 7610 */ 7611 protected void checkPermissions( 7612 CmsDbContext dbc, 7613 CmsResource resource, 7614 CmsPermissionSet requiredPermissions, 7615 boolean checkLock, 7616 CmsResourceFilter filter) 7617 throws CmsException, CmsSecurityException { 7618 7619 // get the permissions 7620 I_CmsPermissionHandler.CmsPermissionCheckResult permissions = hasPermissions( 7621 dbc, 7622 resource, 7623 requiredPermissions, 7624 checkLock ? LockCheck.yes : LockCheck.no, 7625 filter); 7626 if (!permissions.isAllowed()) { 7627 checkPermissions(dbc.getRequestContext(), resource, requiredPermissions, permissions); 7628 } 7629 } 7630 7631 /** 7632 * Performs a blocking permission check on a resource.<p> 7633 * 7634 * If the required permissions are not satisfied by the permissions the user has on the resource, 7635 * an exception is thrown.<p> 7636 * 7637 * @param dbc the current database context 7638 * @param resource the resource on which permissions are required 7639 * @param requiredPermissions the set of permissions required to access the resource 7640 * @param checkLock if true, the lock status of the resource is also checked 7641 * @param filter the filter for the resource 7642 * 7643 * @throws CmsException in case of any i/o error 7644 * @throws CmsSecurityException if the required permissions are not satisfied 7645 * 7646 * @see #hasPermissions(CmsRequestContext, CmsResource, CmsPermissionSet, boolean, CmsResourceFilter) 7647 */ 7648 protected void checkPermissions( 7649 CmsDbContext dbc, 7650 CmsResource resource, 7651 CmsPermissionSet requiredPermissions, 7652 LockCheck checkLock, 7653 CmsResourceFilter filter) 7654 throws CmsException, CmsSecurityException { 7655 7656 // get the permissions 7657 I_CmsPermissionHandler.CmsPermissionCheckResult permissions = hasPermissions( 7658 dbc, 7659 resource, 7660 requiredPermissions, 7661 checkLock, 7662 filter); 7663 if (!permissions.isAllowed()) { 7664 checkPermissions(dbc.getRequestContext(), resource, requiredPermissions, permissions); 7665 } 7666 } 7667 7668 /** 7669 * Applies the permission check result of a previous call 7670 * to {@link #hasPermissions(CmsRequestContext, CmsResource, CmsPermissionSet, boolean, CmsResourceFilter)}.<p> 7671 * 7672 * @param context the current request context 7673 * @param resource the resource on which permissions are required 7674 * @param requiredPermissions the set of permissions required to access the resource 7675 * @param permissions the permissions to check 7676 * 7677 * @throws CmsSecurityException if the required permissions are not satisfied 7678 * @throws CmsLockException if the lock status is not as required 7679 * @throws CmsVfsResourceNotFoundException if the required resource has been filtered 7680 */ 7681 protected void checkPermissions( 7682 CmsRequestContext context, 7683 CmsResource resource, 7684 CmsPermissionSet requiredPermissions, 7685 I_CmsPermissionHandler.CmsPermissionCheckResult permissions) 7686 throws CmsSecurityException, CmsLockException, CmsVfsResourceNotFoundException { 7687 7688 if (permissions == I_CmsPermissionHandler.PERM_FILTERED) { 7689 throw new CmsVfsResourceNotFoundException( 7690 Messages.get().container(Messages.ERR_PERM_FILTERED_1, context.getSitePath(resource))); 7691 } 7692 if (permissions == I_CmsPermissionHandler.PERM_DENIED) { 7693 throw new CmsPermissionViolationException( 7694 Messages.get().container( 7695 Messages.ERR_PERM_DENIED_2, 7696 context.getSitePath(resource), 7697 requiredPermissions.getPermissionString())); 7698 } 7699 if (permissions == I_CmsPermissionHandler.PERM_NOTLOCKED) { 7700 throw new CmsLockException( 7701 Messages.get().container( 7702 Messages.ERR_PERM_NOTLOCKED_2, 7703 context.getSitePath(resource), 7704 context.getCurrentUser().getName())); 7705 } 7706 } 7707 7708 /** 7709 * Checks that the current user has enough permissions to modify the given user.<p> 7710 * 7711 * @param dbc the database context 7712 * @param username the name of the user to modify 7713 * @param role the needed role 7714 * 7715 * @throws CmsDataAccessException if something goes wrong accessing the database 7716 * @throws CmsRoleViolationException if the user has not the needed permissions 7717 */ 7718 protected void checkRoleForUserModification(CmsDbContext dbc, String username, CmsRole role) 7719 throws CmsDataAccessException, CmsRoleViolationException { 7720 7721 CmsUser userToModify = m_driverManager.readUser(dbc, CmsOrganizationalUnit.removeLeadingSeparator(username)); 7722 if (dbc.currentUser().equals(userToModify)) { 7723 // a user is allowed to write his own data 7724 return; 7725 } 7726 if (hasRole(dbc, dbc.currentUser(), CmsRole.ROOT_ADMIN)) { 7727 // a user with the ROOT_ADMIN role may change any other user 7728 return; 7729 } 7730 if (hasRole(dbc, userToModify, CmsRole.ADMINISTRATOR)) { 7731 // check the user that is going to do the modification is administrator 7732 checkRole(dbc, CmsRole.ADMINISTRATOR); 7733 } else { 7734 // check the user that is going to do the modification has the given role 7735 checkRole(dbc, role); 7736 } 7737 7738 } 7739 7740 /** 7741 * Checks if the given resource contains a resource that has a system lock.<p> 7742 * 7743 * @param dbc the current database context 7744 * @param resource the resource to check 7745 * 7746 * @throws CmsException in case there is a system lock contained in the given resource 7747 */ 7748 protected void checkSystemLocks(CmsDbContext dbc, CmsResource resource) throws CmsException { 7749 7750 if (m_lockManager.hasSystemLocks(dbc, resource)) { 7751 throw new CmsLockException( 7752 Messages.get().container( 7753 Messages.ERR_RESOURCE_SYSTEM_LOCKED_1, 7754 dbc.removeSiteRoot(resource.getRootPath()))); 7755 } 7756 } 7757 7758 /** 7759 * Internal recursive method for deleting a resource.<p> 7760 * 7761 * @param dbc the db context 7762 * @param resource the name of the resource to delete (full path) 7763 * @param siblingMode indicates how to handle siblings of the deleted resource 7764 * 7765 * @throws CmsException if something goes wrong 7766 */ 7767 protected void deleteResource(CmsDbContext dbc, CmsResource resource, CmsResource.CmsResourceDeleteMode siblingMode) 7768 throws CmsException { 7769 7770 try (CmsModificationContext modContext = CmsModificationContext.acquire(dbc.getRequestContext())) { 7771 if (resource.isFolder()) { 7772 // collect all resources in the folder (but exclude deleted ones) 7773 List<CmsResource> resources = m_driverManager.readChildResources( 7774 dbc, 7775 resource, 7776 CmsResourceFilter.IGNORE_EXPIRATION, 7777 true, 7778 true, 7779 false); 7780 7781 Set<CmsUUID> deletedResources = new HashSet<CmsUUID>(); 7782 // now walk through all sub-resources in the folder 7783 for (int i = 0; i < resources.size(); i++) { 7784 CmsResource childResource = resources.get(i); 7785 if ((siblingMode == CmsResource.DELETE_REMOVE_SIBLINGS) 7786 && deletedResources.contains(childResource.getResourceId())) { 7787 // sibling mode is "delete all siblings" and another sibling of the current child resource has already 7788 // been deleted- do nothing and continue with the next child resource. 7789 continue; 7790 } 7791 if (childResource.isFolder()) { 7792 // recurse into this method for subfolders 7793 deleteResource(dbc, childResource, siblingMode); 7794 } else { 7795 // handle child resources 7796 m_driverManager.deleteResource(dbc, childResource, siblingMode); 7797 modContext.add(childResource); 7798 } 7799 deletedResources.add(childResource.getResourceId()); 7800 } 7801 deletedResources.clear(); 7802 } 7803 // handle the resource itself 7804 m_driverManager.deleteResource(dbc, resource, siblingMode); 7805 modContext.add(resource); 7806 } 7807 } 7808 7809 /** 7810 * Deletes a user, where all permissions and resources attributes of the user 7811 * were transfered to a replacement user, if given.<p> 7812 * 7813 * @param context the current request context 7814 * @param user the user to be deleted 7815 * @param replacement the user to be transfered, can be <code>null</code> 7816 * 7817 * @throws CmsRoleViolationException if the current user does not own the rule {@link CmsRole#ACCOUNT_MANAGER} 7818 * @throws CmsSecurityException in case the user is a default user 7819 * @throws CmsException if something goes wrong 7820 */ 7821 protected void deleteUser(CmsRequestContext context, CmsUser user, CmsUser replacement) 7822 throws CmsException, CmsSecurityException, CmsRoleViolationException { 7823 7824 if (OpenCms.getDefaultUsers().isDefaultUser(user.getName())) { 7825 throw new CmsSecurityException( 7826 org.opencms.security.Messages.get().container( 7827 org.opencms.security.Messages.ERR_CANT_DELETE_DEFAULT_USER_1, 7828 user.getName())); 7829 } 7830 if (context.getCurrentUser().equals(user)) { 7831 throw new CmsSecurityException(Messages.get().container(Messages.ERR_USER_CANT_DELETE_ITSELF_USER_0)); 7832 } 7833 7834 CmsDbContext dbc = null; 7835 try { 7836 dbc = getDbContextForDeletePrincipal(context); 7837 CmsRole role = CmsRole.ACCOUNT_MANAGER.forOrgUnit(getParentOrganizationalUnit(user.getName())); 7838 checkRoleForUserModification(dbc, user.getName(), role); 7839 m_driverManager.deleteUser( 7840 dbc, 7841 dbc.getRequestContext().getCurrentProject(), 7842 user.getName(), 7843 null == replacement ? null : replacement.getName()); 7844 } catch (Exception e) { 7845 CmsDbContext dbcForException = m_dbContextFactory.getDbContext(context); 7846 dbcForException.report(null, Messages.get().container(Messages.ERR_DELETE_USER_1, user.getName()), e); 7847 dbcForException.clear(); 7848 } finally { 7849 if (null != dbc) { 7850 dbc.clear(); 7851 } 7852 } 7853 } 7854 7855 /** 7856 * Returns all resources of organizational units for which the current user has 7857 * the given role role.<p> 7858 * 7859 * @param dbc the current database context 7860 * @param role the role to check 7861 * 7862 * @return a list of {@link org.opencms.file.CmsResource} objects 7863 * 7864 * @throws CmsException if something goes wrong 7865 */ 7866 protected List<CmsResource> getManageableResources(CmsDbContext dbc, CmsRole role) throws CmsException { 7867 7868 CmsOrganizationalUnit ou = m_driverManager.readOrganizationalUnit(dbc, role.getOuFqn()); 7869 if (hasRole(dbc, dbc.currentUser(), role)) { 7870 return m_driverManager.getResourcesForOrganizationalUnit(dbc, ou); 7871 } 7872 List<CmsResource> resources = new ArrayList<CmsResource>(); 7873 Iterator<CmsOrganizationalUnit> it = m_driverManager.getOrganizationalUnits(dbc, ou, false).iterator(); 7874 while (it.hasNext()) { 7875 CmsOrganizationalUnit orgUnit = it.next(); 7876 resources.addAll(getManageableResources(dbc, role.forOrgUnit(orgUnit.getName()))); 7877 } 7878 return resources; 7879 } 7880 7881 /** 7882 * Returns the organizational unit for the parent of the given fully qualified name.<p> 7883 * 7884 * @param fqn the fully qualified name to get the parent organizational unit for 7885 * 7886 * @return the parent organizational unit for the fully qualified name 7887 */ 7888 protected String getParentOrganizationalUnit(String fqn) { 7889 7890 String ouFqn = CmsOrganizationalUnit.getParentFqn(CmsOrganizationalUnit.removeLeadingSeparator(fqn)); 7891 if (ouFqn == null) { 7892 ouFqn = ""; 7893 } 7894 return ouFqn; 7895 } 7896 7897 /** 7898 * Performs a non-blocking permission check on a resource.<p> 7899 * 7900 * This test will not throw an exception in case the required permissions are not 7901 * available for the requested operation. Instead, it will return one of the 7902 * following values:<ul> 7903 * <li><code>{@link I_CmsPermissionHandler#PERM_ALLOWED}</code></li> 7904 * <li><code>{@link I_CmsPermissionHandler#PERM_FILTERED}</code></li> 7905 * <li><code>{@link I_CmsPermissionHandler#PERM_DENIED}</code></li></ul><p> 7906 * 7907 * @param dbc the current database context 7908 * @param resource the resource on which permissions are required 7909 * @param requiredPermissions the set of permissions required for the operation 7910 * @param checkLock if true, a lock for the current user is required for 7911 * all write operations, if false it's ok to write as long as the resource 7912 * is not locked by another user 7913 * @param filter the resource filter to use 7914 * 7915 * @return <code>{@link I_CmsPermissionHandler#PERM_ALLOWED}</code> if the user has sufficient permissions on the resource 7916 * for the requested operation 7917 * 7918 * @throws CmsException in case of i/o errors (NOT because of insufficient permissions) 7919 */ 7920 protected I_CmsPermissionHandler.CmsPermissionCheckResult hasPermissions( 7921 CmsDbContext dbc, 7922 CmsResource resource, 7923 CmsPermissionSet requiredPermissions, 7924 LockCheck checkLock, 7925 CmsResourceFilter filter) 7926 throws CmsException { 7927 7928 return m_permissionHandler.hasPermissions(dbc, resource, requiredPermissions, checkLock, filter); 7929 } 7930 7931 /** 7932 * Returns <code>true</code> if at least one of the given group names is equal to a group name 7933 * of the given role in the given organizational unit.<p> 7934 * 7935 * This checks the given list against the group of the given role as well as against the role group 7936 * of all parent roles.<p> 7937 * 7938 * If the organizational unit is <code>null</code>, this method will check if the 7939 * given user has the given role for at least one organizational unit.<p> 7940 * 7941 * @param role the role to check 7942 * @param roles the groups to match the role groups against 7943 * 7944 * @return <code>true</code> if at last one of the given group names is equal to a group name 7945 * of this role 7946 */ 7947 protected boolean hasRole(CmsRole role, List<CmsGroup> roles) { 7948 7949 // iterates the role groups the user is in 7950 for (CmsGroup group : roles) { 7951 String groupName = group.getName(); 7952 // iterate the role hierarchy 7953 for (String distictGroupName : role.getDistinctGroupNames()) { 7954 if (distictGroupName.startsWith(CmsOrganizationalUnit.SEPARATOR)) { 7955 // this is a ou independent role 7956 // we need an exact match, and we ignore the ou parameter 7957 if (groupName.equals(distictGroupName.substring(1))) { 7958 return true; 7959 } 7960 } else { 7961 // first check if the user has the role at all 7962 if (groupName.endsWith(CmsOrganizationalUnit.SEPARATOR + distictGroupName) 7963 || groupName.equals(distictGroupName)) { 7964 // this is a ou dependent role 7965 if (role.getOuFqn() == null) { 7966 // ou parameter is null, so the user needs to have the role in at least one ou does not matter which 7967 return true; 7968 } else { 7969 // the user needs to have the role in the given ou or in a parent ou 7970 // now check that the ou matches 7971 String groupFqn = CmsOrganizationalUnit.getParentFqn(groupName); 7972 if (role.getOuFqn().startsWith(groupFqn)) { 7973 return true; 7974 } 7975 } 7976 } 7977 } 7978 } 7979 } 7980 return false; 7981 } 7982 7983 /** 7984 * Internal recursive method to move a resource.<p> 7985 * 7986 * @param dbc the db context 7987 * @param source the source resource 7988 * @param destination the destination path 7989 * @param allMovedResources a set used to collect all moved resources 7990 * 7991 * @throws CmsException if something goes wrong 7992 */ 7993 protected void moveResource( 7994 CmsDbContext dbc, 7995 CmsResource source, 7996 String destination, 7997 Set<CmsResource> allMovedResources) 7998 throws CmsException { 7999 8000 try (CmsModificationContext modContext = CmsModificationContext.acquire(dbc.getRequestContext())) { 8001 8002 List<CmsResource> resources = null; 8003 8004 if (source.isFolder()) { 8005 if (!CmsResource.isFolder(destination)) { 8006 // ensure folder name end's with a / 8007 destination = destination.concat("/"); 8008 } 8009 // collect all resources in the folder without checking permissions 8010 resources = m_driverManager.readChildResources(dbc, source, CmsResourceFilter.ALL, true, true, false); 8011 } else { 8012 8013 } 8014 8015 // target permissions will be checked later 8016 m_driverManager.moveResource(dbc, source, destination, false); 8017 8018 // make sure lock is set 8019 CmsResource destinationResource = m_driverManager.readResource(dbc, destination, CmsResourceFilter.ALL); 8020 try { 8021 // the destination must always get a new lock 8022 m_driverManager.lockResource(dbc, destinationResource, CmsLockType.EXCLUSIVE); 8023 } catch (Exception e) { 8024 // could happen with with shared locks on single files 8025 if (LOG.isWarnEnabled()) { 8026 LOG.warn(e.getLocalizedMessage(), e); 8027 } 8028 } 8029 8030 if (resources != null) { 8031 // Ensure consistent order that is not database-dependent, since readChildResources doesn't specify an ordering. 8032 // this is necessary to make test cases more useful. 8033 Collections.sort(resources, (r1, r2) -> r1.getRootPath().compareTo(r2.getRootPath())); 8034 8035 // now walk through all sub-resources in the folder 8036 for (int i = 0; i < resources.size(); i++) { 8037 CmsResource childResource = resources.get(i); 8038 String childDestination = destination.concat(childResource.getName()); 8039 // recurse with child resource 8040 moveResource(dbc, childResource, childDestination, allMovedResources); 8041 } 8042 } 8043 8044 List<CmsResource> movedResources = m_driverManager.readChildResources( 8045 dbc, 8046 destinationResource, 8047 CmsResourceFilter.ALL, 8048 true, 8049 true, 8050 false); 8051 allMovedResources.add(destinationResource); 8052 modContext.add(destinationResource); 8053 allMovedResources.addAll(movedResources); 8054 } 8055 8056 } 8057 8058 protected void publishJob(CmsObject cms, CmsDbContext dbc, CmsPublishList pubList, I_CmsReport report) 8059 throws CmsException { 8060 8061 m_driverManager.publishJob(cms, dbc, pubList, report); 8062 } 8063 8064 /** 8065 * Reads a folder from the VFS, using the specified resource filter.<p> 8066 * 8067 * @param dbc the current database context 8068 * @param resourcename the name of the folder to read (full path) 8069 * @param filter the resource filter to use while reading 8070 * 8071 * @return the folder that was read 8072 * 8073 * @throws CmsException if something goes wrong 8074 */ 8075 protected CmsFolder readFolder(CmsDbContext dbc, String resourcename, CmsResourceFilter filter) 8076 throws CmsException { 8077 8078 CmsResource resource = readResource(dbc, resourcename, filter); 8079 return m_driverManager.convertResourceToFolder(resource); 8080 } 8081 8082 /** 8083 * Reads a resource from the OpenCms VFS, using the specified resource filter.<p> 8084 * 8085 * @param dbc the current database context 8086 * @param structureID the ID of the structure to read 8087 * @param filter the resource filter to use while reading 8088 * 8089 * @return the resource that was read 8090 * 8091 * @throws CmsException if something goes wrong 8092 * 8093 * @see CmsObject#readResource(CmsUUID, CmsResourceFilter) 8094 * @see CmsObject#readResource(CmsUUID) 8095 * @see CmsObject#readFile(CmsResource) 8096 */ 8097 protected CmsResource readResource(CmsDbContext dbc, CmsUUID structureID, CmsResourceFilter filter) 8098 throws CmsException { 8099 8100 // read the resource from the VFS 8101 CmsResource resource = m_driverManager.readResource(dbc, structureID, filter); 8102 8103 // check if the user has read access to the resource 8104 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_READ, true, filter); 8105 8106 // access was granted - return the resource 8107 return resource; 8108 } 8109 8110 /** 8111 * Reads a resource from the OpenCms VFS, using the specified resource filter.<p> 8112 * 8113 * @param dbc the current database context 8114 * @param resourcePath the name of the resource to read (full path) 8115 * @param filter the resource filter to use while reading 8116 * 8117 * @return the resource that was read 8118 * 8119 * @throws CmsException if something goes wrong 8120 * 8121 * @see CmsObject#readResource(String, CmsResourceFilter) 8122 * @see CmsObject#readResource(String) 8123 * @see CmsObject#readFile(CmsResource) 8124 */ 8125 protected CmsResource readResource(CmsDbContext dbc, String resourcePath, CmsResourceFilter filter) 8126 throws CmsException { 8127 8128 // read the resource from the VFS 8129 CmsResource resource = m_driverManager.readResource(dbc, resourcePath, filter); 8130 8131 // check if the user has read access to the resource 8132 checkPermissions(dbc, resource, CmsPermissionSet.ACCESS_READ, true, filter); 8133 8134 // access was granted - return the resource 8135 return resource; 8136 } 8137 8138 /** 8139 * Determines a project where the deletion of a principal can be executed and sets it in the returned db context.<p> 8140 * 8141 * @param context the current request context 8142 * 8143 * @return the db context to use when deleting the principal. 8144 * 8145 * @throws CmsDataAccessException if determining a project that is suitable to delete the prinicipal fails. 8146 */ 8147 private CmsDbContext getDbContextForDeletePrincipal(CmsRequestContext context) throws CmsDataAccessException { 8148 8149 CmsProject currentProject = context.getCurrentProject(); 8150 CmsDbContext dbc = m_dbContextFactory.getDbContext(context); 8151 CmsUUID projectId = dbc.getProjectId(); 8152 // principal modifications are allowed if the current project is not the online project 8153 if (currentProject.isOnlineProject()) { 8154 // this is needed because 8155 // I_CmsUserDriver#removeAccessControlEntriesForPrincipal(CmsDbContext, CmsProject, CmsProject, CmsUUID) 8156 // expects an offline project, if not, data will become inconsistent 8157 8158 // if the current project is the online project, check if there is a valid offline project at all 8159 List<CmsProject> projects = m_driverManager.getProjectDriver(dbc).readProjects(dbc, ""); 8160 for (CmsProject project : projects) { 8161 if (!project.isOnlineProject()) { 8162 try { 8163 dbc.setProjectId(project.getUuid()); 8164 if (null != m_driverManager.readResource(dbc, "/", CmsResourceFilter.ALL)) { 8165 // shallow clone the context with project adjusted 8166 context = new CmsRequestContext( 8167 context.getCurrentUser(), 8168 project, 8169 context.getUri(), 8170 context.getRequestMatcher(), 8171 context.getSiteRoot(), 8172 context.isSecureRequest(), 8173 context.getLocale(), 8174 context.getEncoding(), 8175 context.getRemoteAddress(), 8176 context.getRequestTime(), 8177 context.getDirectoryTranslator(), 8178 context.getFileTranslator(), 8179 context.getOuFqn(), 8180 context.isForceAbsoluteLinks()); 8181 dbc = m_dbContextFactory.getDbContext(context); 8182 projectId = dbc.getProjectId(); 8183 break; 8184 } 8185 } catch (Exception e) { 8186 // ignore 8187 } 8188 } 8189 } 8190 } 8191 dbc.setProjectId(projectId); 8192 return dbc; 8193 } 8194 8195 /** 8196 * Reports an exception which occurred while reading file content.<p> 8197 * 8198 * @param dbc the database context 8199 * @param context the request context 8200 * @param resource the resource being read 8201 * @param e the exception to report 8202 */ 8203 private void reportReadFileException(CmsDbContext dbc, CmsRequestContext context, CmsResource resource, Exception e) 8204 throws CmsException { 8205 8206 if (resource instanceof I_CmsHistoryResource) { 8207 dbc.report( 8208 null, 8209 Messages.get().container( 8210 Messages.ERR_READ_FILE_HISTORY_2, 8211 context.getSitePath(resource), 8212 Integer.valueOf(resource.getVersion())), 8213 e); 8214 } else { 8215 dbc.report(null, Messages.get().container(Messages.ERR_READ_FILE_1, context.getSitePath(resource)), e); 8216 } 8217 } 8218 8219}