001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH (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, 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.security; 029 030import org.opencms.db.CmsSecurityManager; 031import org.opencms.file.CmsGroup; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsResource; 034import org.opencms.file.CmsResourceFilter; 035import org.opencms.file.CmsUser; 036import org.opencms.main.CmsException; 037import org.opencms.main.OpenCms; 038 039import java.util.ArrayList; 040import java.util.Iterator; 041import java.util.List; 042import java.util.Set; 043 044import com.google.common.collect.Lists; 045 046/** 047 * This manager provide access to the role related operations.<p> 048 * 049 * @since 6.5.6 050 */ 051public class CmsRoleManager { 052 053 /** The security manager. */ 054 private final CmsSecurityManager m_securityManager; 055 056 /** 057 * Default constructor.<p> 058 * 059 * @param securityManager the security manager 060 */ 061 public CmsRoleManager(CmsSecurityManager securityManager) { 062 063 m_securityManager = securityManager; 064 } 065 066 /** 067 * Adds a user to the given role.<p> 068 * 069 * @param cms the opencms context 070 * @param role the role 071 * @param username the name of the user that is to be added to the role 072 * 073 * @throws CmsException if something goes wrong 074 */ 075 public void addUserToRole(CmsObject cms, CmsRole role, String username) throws CmsException { 076 077 m_securityManager.addUserToGroup(cms.getRequestContext(), username, role.getGroupName(), true); 078 } 079 080 /** 081 * Checks if the user of this OpenCms context is a member of the given role 082 * for the given organizational unit.<p> 083 * 084 * The user must have the given role in at least one parent organizational unit.<p> 085 * 086 * @param cms the opencms context 087 * @param role the role to check 088 * 089 * @throws CmsRoleViolationException if the user does not have the required role permissions 090 */ 091 public void checkRole(CmsObject cms, CmsRole role) throws CmsRoleViolationException { 092 093 m_securityManager.checkRole(cms.getRequestContext(), role); 094 } 095 096 /** 097 * Checks if the user of this OpenCms context is a member of the given role 098 * for the given resource.<p> 099 * 100 * The user must have the given role in at least one organizational unit to which this resource belongs.<p> 101 * 102 * @param cms the opencms context 103 * @param role the role to check 104 * @param resourceName the name of the resource to check the role for 105 * 106 * @throws CmsRoleViolationException if the user does not have the required role permissions 107 * @throws CmsException if something goes wrong, while reading the resource 108 */ 109 public void checkRoleForResource(CmsObject cms, CmsRole role, String resourceName) 110 throws CmsException, CmsRoleViolationException { 111 112 CmsResource resource = cms.readResource(resourceName); 113 m_securityManager.checkRoleForResource(cms.getRequestContext(), role, resource); 114 } 115 116 /** 117 * Returns all groups of organizational units for which the current user 118 * has the {@link CmsRole#ACCOUNT_MANAGER} role.<p> 119 * 120 * @param cms the current cms context 121 * @param ouFqn the fully qualified name of the organizational unit 122 * @param includeSubOus if sub organizational units should be included in the search 123 * 124 * @return a list of {@link org.opencms.file.CmsGroup} objects 125 * 126 * @throws CmsException if something goes wrong 127 */ 128 public List<CmsGroup> getManageableGroups(CmsObject cms, String ouFqn, boolean includeSubOus) throws CmsException { 129 130 List<CmsGroup> groups = new ArrayList<CmsGroup>(); 131 Iterator<CmsOrganizationalUnit> it = getOrgUnitsForRole( 132 cms, 133 CmsRole.ACCOUNT_MANAGER.forOrgUnit(ouFqn), 134 includeSubOus).iterator(); 135 while (it.hasNext()) { 136 CmsOrganizationalUnit orgUnit = it.next(); 137 groups.addAll(OpenCms.getOrgUnitManager().getGroups(cms, orgUnit.getName(), false)); 138 } 139 return groups; 140 } 141 142 /** 143 * Returns a list of those organizational units whose members can be managed by the current user.<p> 144 * 145 * @param cms the current CMS context 146 * @param ouFqn the fully qualified name of the organizational unit 147 * @param includeSubOus if sub organizational units should be included in the search 148 * @param includeWebusers if webuser organizational units should be included in the search 149 * 150 * @return a list of organizational units 151 * 152 * @throws CmsException if something goes wrong 153 */ 154 public List<CmsOrganizationalUnit> getManageableOrgUnits( 155 CmsObject cms, 156 String ouFqn, 157 boolean includeSubOus, 158 boolean includeWebusers) throws CmsException { 159 160 List<CmsOrganizationalUnit> result = Lists.newArrayList(); 161 List<CmsOrganizationalUnit> ous = getOrgUnitsForRole( 162 cms, 163 CmsRole.ACCOUNT_MANAGER.forOrgUnit(ouFqn), 164 includeSubOus); 165 for (CmsOrganizationalUnit ou : ous) { 166 if (includeWebusers || !ou.hasFlagWebuser()) { 167 result.add(ou); 168 } 169 } 170 return result; 171 } 172 173 /** 174 * Returns all resources of organizational units for which the current user has 175 * the given role role.<p> 176 * 177 * @param cms the current cms context 178 * @param role the role to check 179 * 180 * @return a list of {@link org.opencms.file.CmsResource} objects 181 * 182 * @throws CmsException if something goes wrong 183 */ 184 public List<CmsResource> getManageableResources(CmsObject cms, CmsRole role) throws CmsException { 185 186 return m_securityManager.getManageableResources(cms.getRequestContext(), role); 187 } 188 189 /** 190 * Returns all users of organizational units for which the current user has 191 * the {@link CmsRole#ACCOUNT_MANAGER} role.<p> 192 * 193 * @param cms the current cms context 194 * @param ouFqn the fully qualified name of the organizational unit 195 * @param includeSubOus if sub organizational units should be included in the search 196 * 197 * @return a list of {@link org.opencms.file.CmsUser} objects 198 * 199 * @throws CmsException if something goes wrong 200 */ 201 public List<CmsUser> getManageableUsers(CmsObject cms, String ouFqn, boolean includeSubOus) throws CmsException { 202 203 return getManageableUsers(cms, ouFqn, includeSubOus, false); 204 } 205 206 /** 207 * Returns all users of organizational units for which the current user has 208 * the {@link CmsRole#ACCOUNT_MANAGER} role.<p> 209 * 210 * @param cms the current cms context 211 * @param ouFqn the fully qualified name of the organizational unit 212 * @param includeSubOus if sub organizational units should be included in the search 213 * @param includeWebusers if webuser organizational units should be included in the search 214 * 215 * @return a list of {@link org.opencms.file.CmsUser} objects 216 * 217 * @throws CmsException if something goes wrong 218 */ 219 public List<CmsUser> getManageableUsers(CmsObject cms, String ouFqn, boolean includeSubOus, boolean includeWebusers) 220 throws CmsException { 221 222 List<CmsOrganizationalUnit> ous = getManageableOrgUnits(cms, ouFqn, includeSubOus, includeWebusers); 223 List<CmsUser> users = new ArrayList<CmsUser>(); 224 Iterator<CmsOrganizationalUnit> it = ous.iterator(); 225 while (it.hasNext()) { 226 CmsOrganizationalUnit orgUnit = it.next(); 227 users.addAll(OpenCms.getOrgUnitManager().getUsers(cms, orgUnit.getName(), false)); 228 } 229 return users; 230 } 231 232 /** 233 * Returns all the organizational units for which the current user has the given role.<p> 234 * 235 * @param cms the current cms context 236 * @param role the role to check 237 * @param includeSubOus if sub organizational units should be included in the search 238 * 239 * @return a list of {@link org.opencms.security.CmsOrganizationalUnit} objects 240 * 241 * @throws CmsException if something goes wrong 242 */ 243 public List<CmsOrganizationalUnit> getOrgUnitsForRole(CmsObject cms, CmsRole role, boolean includeSubOus) 244 throws CmsException { 245 246 return m_securityManager.getOrgUnitsForRole(cms.getRequestContext(), role, includeSubOus); 247 } 248 249 /** 250 * Returns the groups which constitute a given role, i.e. the set of groups such that a member of any of them 251 * has the given role.<p> 252 * 253 * @param cms the CMS context 254 * @param role the role 255 * @param directUsersOnly if true, only the role's direct group will be returned 256 * 257 * @return the groups constituting the given role 258 * 259 * @throws CmsException if something goes wrong 260 */ 261 public Set<CmsGroup> getRoleGroups(CmsObject cms, CmsRole role, boolean directUsersOnly) throws CmsException { 262 263 return m_securityManager.getRoleGroups(cms.getRequestContext(), role, directUsersOnly); 264 } 265 266 /** 267 * Returns all roles, in the given organizational unit.<p> 268 * 269 * @param cms the opencms context 270 * @param ouFqn the fully qualified name of the organizational unit of the role 271 * @param includeSubOus include roles of child organizational units 272 * 273 * @return a list of all <code>{@link CmsRole}</code> objects 274 * 275 * @throws CmsException if operation was not successful 276 */ 277 public List<CmsRole> getRoles(CmsObject cms, String ouFqn, boolean includeSubOus) throws CmsException { 278 279 CmsOrganizationalUnit ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ouFqn); 280 List<CmsGroup> groups = m_securityManager.getGroups(cms.getRequestContext(), ou, includeSubOus, true); 281 List<CmsRole> roles = new ArrayList<CmsRole>(groups.size()); 282 Iterator<CmsGroup> itGroups = groups.iterator(); 283 while (itGroups.hasNext()) { 284 CmsGroup group = itGroups.next(); 285 roles.add(CmsRole.valueOf(group)); 286 } 287 return roles; 288 } 289 290 /** 291 * Returns all roles the given user has over the given resource.<p> 292 * 293 * @param cms the current cms context 294 * @param user the user 295 * @param resource the resource 296 * 297 * @return a list of {@link CmsRole} objects 298 * 299 * @throws CmsException if something goes wrong 300 */ 301 public List<CmsRole> getRolesForResource(CmsObject cms, CmsUser user, CmsResource resource) throws CmsException { 302 303 return m_securityManager.getRolesForResource(cms.getRequestContext(), user, resource); 304 } 305 306 /** 307 * Returns all roles the given user has over the given resource.<p> 308 * 309 * @param cms the current cms context 310 * @param userFqn the user name to check 311 * @param resourceName the resource name 312 * 313 * @return a list of {@link CmsRole} objects 314 * 315 * @throws CmsException if something goes wrong 316 */ 317 public List<CmsRole> getRolesForResource(CmsObject cms, String userFqn, String resourceName) throws CmsException { 318 319 CmsUser user = cms.readUser(userFqn); 320 CmsResource resource = cms.readResource(resourceName, CmsResourceFilter.ALL); 321 return m_securityManager.getRolesForResource(cms.getRequestContext(), user, resource); 322 } 323 324 /** 325 * Returns all roles the given user belongs to, in the given organizational unit.<p> 326 * 327 * @param cms the opencms context 328 * @param username the name of the user to get all roles for 329 * @param ouFqn the fully qualified name of the organizational unit to restrict the search to 330 * @param includeChildOus include roles of child organizational units 331 * @param directRolesOnly if set only the direct assigned roles will be returned, if not also indirect roles 332 * @param recursive if this is set, also roles of higher organizational unit are considered 333 * 334 * @return a list of <code>{@link org.opencms.security.CmsRole}</code> objects 335 * 336 * @throws CmsException if operation was not successful 337 */ 338 public List<CmsRole> getRolesOfUser( 339 CmsObject cms, 340 String username, 341 String ouFqn, 342 boolean includeChildOus, 343 boolean directRolesOnly, 344 boolean recursive) throws CmsException { 345 346 List<CmsGroup> groups; 347 ouFqn = CmsOrganizationalUnit.removeLeadingSeparator(ouFqn); 348 if (!recursive) { 349 groups = m_securityManager.getGroupsOfUser( 350 cms.getRequestContext(), 351 username, 352 ouFqn, 353 includeChildOus, 354 true, 355 directRolesOnly, 356 cms.getRequestContext().getRemoteAddress()); 357 } else { 358 groups = new ArrayList<CmsGroup>(); 359 Iterator<CmsGroup> itAllGroups = m_securityManager.getGroupsOfUser( 360 cms.getRequestContext(), 361 username, 362 "", 363 true, 364 true, 365 directRolesOnly, 366 cms.getRequestContext().getRemoteAddress()).iterator(); 367 while (itAllGroups.hasNext()) { 368 CmsGroup role = itAllGroups.next(); 369 if (!includeChildOus && role.getOuFqn().equals(ouFqn)) { 370 groups.add(role); 371 } 372 if (includeChildOus && role.getOuFqn().startsWith(ouFqn)) { 373 groups.add(role); 374 } 375 } 376 } 377 List<CmsRole> roles = new ArrayList<CmsRole>(groups.size()); 378 Iterator<CmsGroup> itGroups = groups.iterator(); 379 while (itGroups.hasNext()) { 380 CmsGroup group = itGroups.next(); 381 roles.add(CmsRole.valueOf(group)); 382 } 383 return roles; 384 } 385 386 /** 387 * Returns all direct users of a given role, in the given organizational unit.<p> 388 * 389 * Users that are "indirectly" in the role are not returned in the result.<p> 390 * 391 * @param cms the opencms context 392 * @param role the role to get all users for 393 * @param includeOtherOuUsers include users of other organizational units 394 * @param directUsersOnly if set only the direct assigned users will be returned, 395 * if not also indirect users, ie. members of child groups 396 * 397 * @return all <code>{@link org.opencms.file.CmsUser}</code> objects in the group 398 * 399 * @throws CmsException if operation was not successful 400 */ 401 public List<CmsUser> getUsersOfRole( 402 CmsObject cms, 403 CmsRole role, 404 boolean includeOtherOuUsers, 405 boolean directUsersOnly) throws CmsException { 406 407 return m_securityManager.getUsersOfGroup( 408 cms.getRequestContext(), 409 role.getGroupName(), 410 includeOtherOuUsers, 411 directUsersOnly, 412 true); 413 } 414 415 /** 416 * Checks if the given context user has the given role in the given organizational unit.<p> 417 * 418 * @param cms the opencms context 419 * @param role the role to check 420 * 421 * @return <code>true</code> if the given context user has the given role in the given organizational unit 422 */ 423 public boolean hasRole(CmsObject cms, CmsRole role) { 424 425 return m_securityManager.hasRole(cms.getRequestContext(), cms.getRequestContext().getCurrentUser(), role); 426 } 427 428 /** 429 * Checks if the given user has the given role in the given organizational unit.<p> 430 * 431 * @param cms the opencms context 432 * @param userName the name of the user to check the role for 433 * @param role the role to check 434 * 435 * @return <code>true</code> if the given user has the given role in the given organizational unit 436 */ 437 public boolean hasRole(CmsObject cms, String userName, CmsRole role) { 438 439 CmsUser user; 440 try { 441 user = cms.readUser(userName); 442 } catch (CmsException e) { 443 // ignore 444 return false; 445 } 446 return m_securityManager.hasRole(cms.getRequestContext(), user, role); 447 } 448 449 /** 450 * Checks if the given context user has the given role for the given resource.<p> 451 * 452 * @param cms the opencms context 453 * @param role the role to check 454 * @param resourceName the name of the resource to check 455 * 456 * @return <code>true</code> if the given context user has the given role for the given resource 457 */ 458 public boolean hasRoleForResource(CmsObject cms, CmsRole role, String resourceName) { 459 460 CmsResource resource; 461 try { 462 resource = cms.readResource(resourceName, CmsResourceFilter.ALL); 463 } catch (CmsException e) { 464 // ignore 465 return false; 466 } 467 return m_securityManager.hasRoleForResource( 468 cms.getRequestContext(), 469 cms.getRequestContext().getCurrentUser(), 470 role, 471 resource); 472 } 473 474 /** 475 * Checks if the given context user has the given role for the given resource.<p> 476 * 477 * @param cms the opencms context 478 * @param userName the name of the user to check the role for 479 * @param role the role to check 480 * @param resourceName the name of the resource to check 481 * 482 * @return <code>true</code> if the given context user has the given role for the given resource 483 */ 484 public boolean hasRoleForResource(CmsObject cms, String userName, CmsRole role, String resourceName) { 485 486 CmsResource resource; 487 try { 488 resource = cms.readResource(resourceName); 489 } catch (CmsException e) { 490 // ignore 491 return false; 492 } 493 CmsUser user; 494 try { 495 user = cms.readUser(userName); 496 } catch (CmsException e) { 497 // ignore 498 return false; 499 } 500 return m_securityManager.hasRoleForResource(cms.getRequestContext(), user, role, resource); 501 } 502 503 /** 504 * Removes a user from a role, in the given organizational unit.<p> 505 * 506 * @param cms the opencms context 507 * @param role the role to remove the user from 508 * @param username the name of the user that is to be removed from the group 509 * 510 * @throws CmsException if operation was not successful 511 */ 512 public void removeUserFromRole(CmsObject cms, CmsRole role, String username) throws CmsException { 513 514 m_securityManager.removeUserFromGroup(cms.getRequestContext(), username, role.getGroupName(), true); 515 } 516 517}