001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/workplace/explorer/CmsExplorerTypeAccess.java,v $
003: * Date : $Date: 2008-02-27 12:05:21 $
004: * Version: $Revision: 1.16 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.workplace.explorer;
033:
034: import org.opencms.file.CmsGroup;
035: import org.opencms.file.CmsObject;
036: import org.opencms.file.CmsResource;
037: import org.opencms.file.CmsUser;
038: import org.opencms.main.CmsException;
039: import org.opencms.main.CmsLog;
040: import org.opencms.main.OpenCms;
041: import org.opencms.security.CmsAccessControlEntry;
042: import org.opencms.security.CmsAccessControlList;
043: import org.opencms.security.CmsPermissionSet;
044: import org.opencms.security.CmsPermissionSetCustom;
045: import org.opencms.security.CmsRole;
046: import org.opencms.security.I_CmsPrincipal;
047: import org.opencms.util.CmsUUID;
048:
049: import java.util.Collections;
050: import java.util.HashMap;
051: import java.util.Iterator;
052: import java.util.List;
053: import java.util.Map;
054:
055: import org.apache.commons.collections.map.LRUMap;
056: import org.apache.commons.logging.Log;
057:
058: /**
059: * Explorer type access object, encapsulates access control entires and lists of a explorer type.<p>
060: *
061: * @author Michael Emmerich
062: *
063: * @version $Revision: 1.16 $
064: *
065: * @since 6.0.0
066: */
067: public class CmsExplorerTypeAccess {
068:
069: /** Principal key name for the default permission settings. */
070: public static final String PRINCIPAL_DEFAULT = "DEFAULT";
071:
072: /** The log object for this class. */
073: private static final Log LOG = CmsLog
074: .getLog(CmsExplorerTypeAccess.class);
075:
076: /** The map of configured access control entries. */
077: private Map m_accessControl;
078:
079: /** The acl based on the map of configured access control entries. */
080: private CmsAccessControlList m_accessControlList;
081:
082: /** Cached permissions based on roles. */
083: private Map m_permissionsCache;
084:
085: /**
086: * Constructor, creates an empty, CmsExplorerTypeAccess object.<p>
087: */
088: public CmsExplorerTypeAccess() {
089:
090: m_accessControl = new HashMap();
091: }
092:
093: /**
094: * Adds a single access entry to the map of access entries of the explorer type setting.<p>
095: *
096: * This stores the configuration data in a map which is used in the initialize process
097: * to create the access control list.<p>
098: *
099: * @param key the principal of the ace
100: * @param value the permissions for the principal
101: */
102: public void addAccessEntry(String key, String value) {
103:
104: m_accessControl.put(key, value);
105: if (LOG.isDebugEnabled()) {
106: LOG.debug(Messages.get().getBundle().key(
107: Messages.LOG_ADD_ACCESS_ENTRY_2, key, value));
108: }
109: }
110:
111: /**
112: * Creates the access control list from the temporary map.<p>
113: *
114: * @param resourceType the name of the resource type
115: *
116: * @throws CmsException if something goes wrong
117: */
118: public void createAccessControlList(String resourceType)
119: throws CmsException {
120:
121: if (OpenCms.getRunLevel() < OpenCms.RUNLEVEL_2_INITIALIZING) {
122: // we don't need this for simple test cases
123: return;
124: }
125: if (m_permissionsCache == null) {
126: LRUMap lruMap = new LRUMap(2048);
127: m_permissionsCache = Collections.synchronizedMap(lruMap);
128: OpenCms.getMemoryMonitor().register(
129: this .getClass().getName() + "." + resourceType,
130: lruMap);
131: } else {
132: m_permissionsCache.clear();
133: }
134:
135: m_accessControlList = new CmsAccessControlList();
136: Iterator i = m_accessControl.keySet().iterator();
137: while (i.hasNext()) {
138: String key = (String) i.next();
139: if (!PRINCIPAL_DEFAULT.equals(key)) {
140: String value = (String) m_accessControl.get(key);
141: // get the principal name from the principal String
142: String principal = key.substring(key.indexOf('.') + 1,
143: key.length());
144:
145: // create an OpenCms user context with "Guest" permissions
146: CmsObject cms = OpenCms.initCmsObject(OpenCms
147: .getDefaultUsers().getUserGuest());
148:
149: CmsUUID principalId = null;
150: if (key.startsWith(I_CmsPrincipal.PRINCIPAL_GROUP)) {
151: // read the group
152: principal = OpenCms.getImportExportManager()
153: .translateGroup(principal);
154: try {
155: principalId = cms.readGroup(principal).getId();
156: } catch (CmsException e) {
157: if (LOG.isErrorEnabled()) {
158: LOG.error(e.getLocalizedMessage(), e);
159: }
160: }
161: } else if (key
162: .startsWith(I_CmsPrincipal.PRINCIPAL_USER)) {
163: // read the user
164: principal = OpenCms.getImportExportManager()
165: .translateUser(principal);
166: try {
167: principalId = cms.readUser(principal).getId();
168: } catch (CmsException e) {
169: if (LOG.isErrorEnabled()) {
170: LOG.error(e.getLocalizedMessage(), e);
171: }
172: }
173: } else {
174: // read the role with role name
175: CmsRole role = CmsRole.valueOfRoleName(principal);
176: if (role == null) {
177: // try to read the role in the old fashion with group name
178: role = CmsRole.valueOfGroupName(principal);
179: }
180: principalId = role.getId();
181: }
182: if (principalId != null) {
183: // create a new entry for the principal
184: CmsAccessControlEntry entry = new CmsAccessControlEntry(
185: null, principalId, value);
186: m_accessControlList.add(entry);
187: }
188: }
189: }
190: }
191:
192: /**
193: * Returns the computed access Control List.<p>
194: *
195: * @return the computed access Control List
196: */
197: public CmsAccessControlList getAccessControlList() {
198:
199: return m_accessControlList;
200: }
201:
202: /**
203: * Returns the map of access entries of the explorer type setting.<p>
204: *
205: * @return the map of access entries of the explorer type setting
206: */
207: public Map getAccessEntries() {
208:
209: return m_accessControl;
210: }
211:
212: /**
213: * Calculates the permissions for this explorer type settings
214: * for the user in the given OpenCms user context.<p>
215: *
216: * @param cms the OpenCms user context to calculate the permissions for
217: * @param resource the resource to check the permissions for
218: *
219: * @return the permissions for this explorer type settings for the user in the given OpenCms user context
220: */
221: public CmsPermissionSet getPermissions(CmsObject cms,
222: CmsResource resource) {
223:
224: Object cacheKey = getPermissionsCacheKey(cms, resource);
225: CmsPermissionSetCustom permissions;
226: if (cacheKey != null) {
227: permissions = (CmsPermissionSetCustom) m_permissionsCache
228: .get(cacheKey);
229: if (permissions != null) {
230: return permissions;
231: }
232: }
233: CmsAccessControlList acl = (CmsAccessControlList) m_accessControlList
234: .clone();
235:
236: CmsUser user = cms.getRequestContext().currentUser();
237: List groups = null;
238: try {
239: groups = cms.getGroupsOfUser(user.getName(), false);
240: } catch (CmsException e) {
241: // error reading the groups of the current user
242: LOG.error(Messages.get().getBundle().key(
243: Messages.LOG_READ_GROUPS_OF_USER_FAILED_1,
244: user.getName()), e);
245: }
246: List roles = null;
247: try {
248: roles = OpenCms.getRoleManager().getRolesForResource(cms,
249: user.getName(), cms.getSitePath(resource));
250: } catch (CmsException e) {
251: // error reading the roles of the current user
252: LOG.error(Messages.get().getBundle().key(
253: Messages.LOG_READ_GROUPS_OF_USER_FAILED_1,
254: user.getName()), e);
255: }
256: String defaultPermissions = (String) m_accessControl
257: .get(PRINCIPAL_DEFAULT);
258: // add the default permissions to the acl
259: if ((defaultPermissions != null) && !user.isGuestUser()) {
260: boolean found = false;
261: if (acl.getPermissions(user.getId()) != null) {
262: // acl already contains the user, no need for default
263: found = true;
264: }
265: if (!found && (groups != null)) {
266: // look up all groups to see if we need the default
267: Iterator itGroups = groups.iterator();
268: while (itGroups.hasNext()) {
269: CmsGroup group = (CmsGroup) itGroups.next();
270: if (acl.getPermissions(group.getId()) != null) {
271: // acl already contains the group, no need for default
272: found = true;
273: break;
274: }
275: }
276: }
277: if (!found && (roles != null)) {
278: // look up all roles to see if we need the default
279: Iterator itRoles = roles.iterator();
280: while (itRoles.hasNext()) {
281: CmsRole role = (CmsRole) itRoles.next();
282: if (acl.getPermissions(role.getId()) != null) {
283: // acl already contains the group, no need for default
284: found = true;
285: break;
286: }
287: }
288: }
289: if (!found) {
290: // add default access control settings for current user
291: CmsAccessControlEntry entry = new CmsAccessControlEntry(
292: null, user.getId(), defaultPermissions);
293: acl.add(entry);
294: }
295: }
296: permissions = acl.getPermissions(user, groups, roles);
297:
298: if (cacheKey != null) {
299: m_permissionsCache.put(cacheKey, permissions);
300: }
301: return permissions;
302: }
303:
304: /**
305: * Tests if there are any access information stored.<p>
306: *
307: * @return true or false
308: */
309: public boolean isEmpty() {
310:
311: return m_accessControl.isEmpty();
312: }
313:
314: /**
315: * Returns the cache key for the roles and groups of the current user and the given resource.<p>
316: *
317: * In this way, it does not matter if the resource and/or user permissions changes, so we never need to clean the cache.<p>
318: *
319: * And since the cache is a LRU map, old trash entries will be automatically removed.<p>
320: *
321: * @param cms the current cms context
322: * @param resource the resource
323: *
324: * @return the cache key
325: */
326: private String getPermissionsCacheKey(CmsObject cms,
327: CmsResource resource) {
328:
329: try {
330: String userName = cms.getRequestContext().currentUser()
331: .getName();
332: StringBuffer key = new StringBuffer(256);
333: key.append(resource.getRootPath()).append("_");
334: Iterator itGroups = cms.getGroupsOfUser(userName, true)
335: .iterator();
336: while (itGroups.hasNext()) {
337: CmsGroup group = (CmsGroup) itGroups.next();
338: key.append(group.getName()).append("_");
339: }
340: Iterator itRoles = OpenCms.getRoleManager().getRolesOfUser(
341: cms, userName, "", true, true, false).iterator();
342: while (itRoles.hasNext()) {
343: CmsRole role = (CmsRole) itRoles.next();
344: key.append(role.getGroupName()).append("_");
345: }
346: return key.toString();
347: } catch (CmsException e) {
348: return null;
349: }
350: }
351: }
|