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