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