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