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.security; 029 030import org.opencms.file.CmsGroup; 031import org.opencms.file.CmsUser; 032import org.opencms.util.CmsUUID; 033 034import java.io.Serializable; 035import java.util.ArrayList; 036import java.util.Collections; 037import java.util.HashMap; 038import java.util.Iterator; 039import java.util.List; 040import java.util.Map; 041import java.util.Set; 042 043/** 044 * An access control list contains the permission sets of all principals for a distinct resource 045 * that are calculated on the permissions defined by various access control entries.<p> 046 * 047 * <p>To each single resource, access control entries of type <code>CmsAccessControlEntry</code> can be assigned. 048 * An access control entry defines the permissions (both allowed and explicitly denied) of a user or group for this resource.</p> 049 * 050 * <p>By calling the method <code>getAccessControlList</code> the list is generated on the resource. It contains the result of 051 * merging both access control entries defined immediately on the resource and inherited along the folder hierarchie in the 052 * OpenCms virtual file system (controlled by flags in the entry).</p> 053 * 054 * <p>To check the permissions of a user on a distinct resource, the method <code>hasPermissions</code> in the driver manager 055 * is called in each operation. This method acts as access guard and matches the required permissions for the operation 056 * against the allowed and denied permissions defined for the user or groups of this user.</p> 057 * 058 * @since 6.0.0 059 */ 060public class CmsAccessControlList implements Serializable { 061 062 /** The serial version id. */ 063 private static final long serialVersionUID = -8772251229957990081L; 064 /** The principal IDs of users/groups which should have exclusive access to the content outside of its released/expired range. */ 065 private Set<CmsUUID> m_exclusiveAccessPrincipals = Collections.emptySet(); 066 067 /** 068 * Collected permissions of a principal on this resource . 069 */ 070 private Map<CmsUUID, CmsPermissionSetCustom> m_permissions; 071 072 /** 073 * Constructor to create an empty access control list for a given resource.<p> 074 * 075 */ 076 public CmsAccessControlList() { 077 078 m_permissions = new HashMap<CmsUUID, CmsPermissionSetCustom>(); 079 } 080 081 /** 082 * Adds an access control entry to the access control list.<p> 083 * 084 * @param entry the access control entry to add 085 */ 086 public void add(CmsAccessControlEntry entry) { 087 088 CmsPermissionSetCustom p = m_permissions.get(entry.getPrincipal()); 089 if (p == null) { 090 p = new CmsPermissionSetCustom(); 091 m_permissions.put(entry.getPrincipal(), p); 092 } 093 p.addPermissions(entry.getPermissions()); 094 } 095 096 /** 097 * Returns a clone of this Objects instance.<p> 098 * 099 * @return a clone of this instance 100 */ 101 @Override 102 public Object clone() { 103 104 CmsAccessControlList acl = new CmsAccessControlList(); 105 Iterator<CmsUUID> i = m_permissions.keySet().iterator(); 106 while (i.hasNext()) { 107 CmsUUID id = i.next(); 108 acl.m_permissions.put(id, (CmsPermissionSetCustom)(m_permissions.get(id)).clone()); 109 } 110 return acl; 111 } 112 113 /** 114 * Gets the principal IDs of users/groups which should have exclusive access to the content outside of its released/expired range. 115 * 116 * @return the exclusive access principal IDs 117 */ 118 public Set<CmsUUID> getExclusiveAccessPrincipals() { 119 120 return m_exclusiveAccessPrincipals; 121 } 122 123 /** 124 * Returns the permission map of this access control list.<p> 125 * 126 * @return permission map 127 */ 128 public Map<CmsUUID, CmsPermissionSetCustom> getPermissionMap() { 129 130 return m_permissions; 131 } 132 133 /** 134 * Calculates the permissions of the given user and his groups from the access control list.<p> 135 * 136 * @param user the user 137 * @param groups the groups of this user 138 * @param roles the roles of this user 139 * 140 * @return the summarized permission set of the user 141 */ 142 public CmsPermissionSetCustom getPermissions(CmsUser user, List<CmsGroup> groups, List<CmsRole> roles) { 143 144 CmsPermissionSetCustom sum = new CmsPermissionSetCustom(); 145 boolean hasPermissions = false; 146 CmsPermissionSet p = m_permissions.get(user.getId()); 147 if (p != null) { 148 sum.addPermissions(p); 149 hasPermissions = true; 150 } 151 if (groups != null) { 152 int size = groups.size(); 153 for (int i = 0; i < size; i++) { 154 I_CmsPrincipal principal = groups.get(i); 155 p = m_permissions.get(principal.getId()); 156 if (p != null) { 157 sum.addPermissions(p); 158 hasPermissions = true; 159 } 160 } 161 } 162 if (roles != null) { 163 int size = roles.size(); 164 for (int i = 0; i < size; i++) { 165 CmsRole role = roles.get(i); 166 p = m_permissions.get(role.getId()); 167 if (p != null) { 168 sum.addPermissions(p); 169 hasPermissions = true; 170 } 171 } 172 } 173 if (!hasPermissions) { 174 // if no applicable entry is found check the 'all others' entry 175 p = m_permissions.get(CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID); 176 if (p != null) { 177 sum.addPermissions(p); 178 } 179 } 180 return sum; 181 } 182 183 /** 184 * Returns the permission set of a principal as stored in the access control list.<p> 185 * 186 * @param principalId the id of the principal (group or user) 187 * 188 * @return the current permissions of this single principal 189 */ 190 public CmsPermissionSetCustom getPermissions(CmsUUID principalId) { 191 192 return m_permissions.get(principalId); 193 } 194 195 /** 196 * Calculates the permissions of the given user and his groups from the access control list.<p> 197 * The permissions are returned as permission string in the format {{+|-}{r|w|v|c|i}}*. 198 * 199 * @param user the user 200 * @param groups the groups of this user 201 * @param roles the roles of this user 202 * 203 * @return a string that displays the permissions 204 */ 205 public String getPermissionString(CmsUser user, List<CmsGroup> groups, List<CmsRole> roles) { 206 207 return getPermissions(user, groups, roles).getPermissionString(); 208 } 209 210 /** 211 * Returns the principals with specific permissions stored in this access control list.<p> 212 * 213 * @return enumeration of principals (each group or user) 214 */ 215 public List<CmsUUID> getPrincipals() { 216 217 List<CmsUUID> principals = new ArrayList<CmsUUID>(m_permissions.keySet()); 218 Collections.sort(principals, CmsAccessControlEntry.COMPARATOR_PRINCIPALS); 219 return principals; 220 } 221 222 /** 223 * Sets the allowed permissions of a given access control entry as allowed permissions in the access control list.<p> 224 * The denied permissions are left unchanged. 225 * 226 * @param entry the access control entry 227 */ 228 public void setAllowedPermissions(CmsAccessControlEntry entry) { 229 230 CmsPermissionSetCustom p = m_permissions.get(entry.getPrincipal()); 231 if (p == null) { 232 p = new CmsPermissionSetCustom(); 233 m_permissions.put(entry.getPrincipal(), p); 234 } 235 p.setPermissions(entry.getAllowedPermissions(), p.getDeniedPermissions()); 236 } 237 238 /** 239 * Sets the denied permissions of a given access control entry as denied permissions in the access control list.<p> 240 * The allowed permissions are left unchanged. 241 * 242 * @param entry the access control entry 243 */ 244 public void setDeniedPermissions(CmsAccessControlEntry entry) { 245 246 CmsPermissionSetCustom p = m_permissions.get(entry.getPrincipal()); 247 if (p == null) { 248 p = new CmsPermissionSetCustom(); 249 m_permissions.put(entry.getPrincipal(), p); 250 } 251 p.setPermissions(p.getAllowedPermissions(), entry.getDeniedPermissions()); 252 } 253 254 /** 255 * Sets the exclusive access principal IDs. 256 * 257 * @param exclusiveAccessPrincipals the IDs of the exclusive access principals 258 */ 259 public void setExclusiveAccessPrincipals(Set<CmsUUID> exclusiveAccessPrincipals) { 260 261 m_exclusiveAccessPrincipals = Collections.unmodifiableSet(exclusiveAccessPrincipals); 262 } 263 264}