KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > security > SessionAccessControl


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2005 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.cms.security;
14
15 import info.magnolia.cms.beans.config.ContentRepository;
16 import info.magnolia.cms.core.Content;
17 import info.magnolia.cms.core.HierarchyManager;
18 import info.magnolia.cms.core.search.QueryManager;
19 import info.magnolia.cms.core.search.SearchFactory;
20 import info.magnolia.cms.util.SimpleUrlPattern;
21 import info.magnolia.cms.util.UrlPattern;
22
23 import java.util.ArrayList JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27
28 import javax.jcr.LoginException;
29 import javax.jcr.PathNotFoundException;
30 import javax.jcr.RepositoryException;
31 import javax.jcr.Session;
32 import javax.jcr.SimpleCredentials;
33 import javax.servlet.http.HttpServletRequest JavaDoc;
34
35 import org.apache.commons.lang.StringUtils;
36 import org.apache.log4j.Logger;
37
38
39 /**
40  * @author Sameer Charles
41  * @version 2.0
42  */

43 public final class SessionAccessControl {
44
45     private static Logger log = Logger.getLogger(SessionAccessControl.class);
46
47     private static final String JavaDoc ATTRIBUTE_REPOSITORY_SESSION_PREFIX = "mgnlRepositorySession_"; //$NON-NLS-1$
48

49     private static final String JavaDoc ATTRIBUTE_HM_PREFIX = "mgnlHMgr_"; //$NON-NLS-1$
50

51     private static final String JavaDoc ATTRIBUTE_AM_PREFIX = "mgnlAccessMgr_"; //$NON-NLS-1$
52

53     private static final String JavaDoc ATTRIBUTE_QM_PREFIX = "mgnlQueryMgr_"; //$NON-NLS-1$
54

55     private static final String JavaDoc DEFAULT_REPOSITORY = ContentRepository.WEBSITE;
56
57     private static final String JavaDoc DEFAULT_WORKSPACE = ContentRepository.DEFAULT_WORKSPACE;
58
59     /**
60      * Utility class, don't instantiate.
61      */

62     private SessionAccessControl() {
63         // unused
64
}
65
66     /**
67      * Gets the ticket creted while login, creates a new ticket if not existing.
68      * @param request
69      */

70     protected static Session getSession(HttpServletRequest JavaDoc request) throws LoginException, RepositoryException {
71         return getSession(request, DEFAULT_REPOSITORY);
72     }
73
74     /**
75      * Gets the ticket creted while login, creates a new ticket if not existing.
76      * @param request
77      * @param repositoryID
78      */

79     protected static Session getSession(HttpServletRequest JavaDoc request, String JavaDoc repositoryID) throws LoginException,
80         RepositoryException {
81         return getSession(request, repositoryID, DEFAULT_WORKSPACE);
82     }
83
84     /**
85      * Gets the ticket creted while login, creates a new ticket if not existing .
86      * @param request
87      * @param repositoryID
88      */

89     protected static Session getSession(HttpServletRequest JavaDoc request, String JavaDoc repositoryID, String JavaDoc workspaceID)
90         throws LoginException, RepositoryException {
91         return getRepositorySession(request, repositoryID, workspaceID);
92     }
93
94     /**
95      * Gets hierarchy manager for the default repository using session ticket. Creates a new ticket and hierarchy
96      * manager if not exist.
97      * @see SessionAccessControl#DEFAULT_REPOSITORY
98      * @param request
99      */

100     public static HierarchyManager getHierarchyManager(HttpServletRequest JavaDoc request) {
101         return getHierarchyManager(request, DEFAULT_REPOSITORY);
102     }
103
104     /**
105      * Gets hierarchy manager for the default repository using session ticket. Creates a new ticket and hierarchy
106      * manager if not exist.
107      * @param request
108      * @param repositoryID
109      */

110     public static HierarchyManager getHierarchyManager(HttpServletRequest JavaDoc request, String JavaDoc repositoryID) {
111         return getHierarchyManager(request, repositoryID, DEFAULT_WORKSPACE);
112     }
113
114     /**
115      * Gets hierarchy manager for the default repository using session ticket. Creates a new ticket and hierarchy
116      * manager if not exist.
117      * @param request
118      * @param repositoryID
119      */

120     public static HierarchyManager getHierarchyManager(HttpServletRequest JavaDoc request, String JavaDoc repositoryID,
121         String JavaDoc workspaceID) {
122         HierarchyManager hm = (HierarchyManager) request.getSession().getAttribute(
123             ATTRIBUTE_HM_PREFIX + repositoryID + "_" + workspaceID); //$NON-NLS-1$
124
if (hm == null) {
125             createHierarchyManager(request, repositoryID, workspaceID);
126             return (HierarchyManager) request.getSession().getAttribute(
127                 ATTRIBUTE_HM_PREFIX + repositoryID + "_" + workspaceID); //$NON-NLS-1$
128
}
129         return hm;
130     }
131
132     /**
133      * gets AccessManager for the current user session for the default repository and workspace
134      * @param request
135      */

136     public static AccessManager getAccessManager(HttpServletRequest JavaDoc request) {
137         return getAccessManager(request, DEFAULT_REPOSITORY);
138     }
139
140     /**
141      * gets AccessManager for the current user session for the specified repository default workspace
142      * @param request
143      * @param repositoryID
144      */

145     public static AccessManager getAccessManager(HttpServletRequest JavaDoc request, String JavaDoc repositoryID) {
146         return getAccessManager(request, repositoryID, DEFAULT_WORKSPACE);
147     }
148
149     /**
150      * gets AccessManager for the current user session for the specified repository and workspace
151      * @param request
152      * @param repositoryID
153      * @param workspaceID
154      */

155     public static AccessManager getAccessManager(HttpServletRequest JavaDoc request, String JavaDoc repositoryID, String JavaDoc workspaceID) {
156
157         AccessManager accessManager = (AccessManager) request.getSession().getAttribute(
158             ATTRIBUTE_AM_PREFIX + repositoryID + "_" + workspaceID); //$NON-NLS-1$
159

160         if (accessManager == null) {
161             // initialize appropriate repository/workspace session, which will create access manager for it
162
getHierarchyManager(request, repositoryID, workspaceID);
163             // now session value for access manager must be set
164
accessManager = (AccessManager) request.getSession().getAttribute(
165                 ATTRIBUTE_AM_PREFIX + repositoryID + "_" + workspaceID); //$NON-NLS-1$
166
}
167
168         return accessManager;
169     }
170
171     /**
172      * Gets access controlled query manager
173      * @param request
174      */

175     public static QueryManager getQueryManager(HttpServletRequest JavaDoc request) throws RepositoryException {
176         return getQueryManager(request, DEFAULT_REPOSITORY);
177     }
178
179     /**
180      * Gets access controlled query manager
181      * @param request
182      * @param repositoryID
183      */

184     public static QueryManager getQueryManager(HttpServletRequest JavaDoc request, String JavaDoc repositoryID)
185         throws RepositoryException {
186         return getQueryManager(request, repositoryID, DEFAULT_WORKSPACE);
187     }
188
189     /**
190      * Gets access controlled query manager
191      * @param request
192      * @param repositoryID
193      * @param workspaceID
194      */

195     public static QueryManager getQueryManager(HttpServletRequest JavaDoc request, String JavaDoc repositoryID, String JavaDoc workspaceID)
196         throws RepositoryException {
197         QueryManager queryManager = (QueryManager) request.getSession().getAttribute(
198             ATTRIBUTE_QM_PREFIX + repositoryID + "_" + workspaceID); //$NON-NLS-1$
199
if (queryManager == null) {
200             javax.jcr.query.QueryManager qm = getSession(request, repositoryID, workspaceID)
201                 .getWorkspace()
202                 .getQueryManager();
203             queryManager = SearchFactory.getAccessControllableQueryManager(qm, getAccessManager(
204                 request,
205                 repositoryID,
206                 workspaceID));
207             request.getSession().setAttribute(ATTRIBUTE_QM_PREFIX + repositoryID + "_" + workspaceID, queryManager); //$NON-NLS-1$
208
}
209         return queryManager;
210     }
211
212     private static Session getRepositorySession(HttpServletRequest JavaDoc request, String JavaDoc repositoryID, String JavaDoc workspaceID)
213         throws LoginException, RepositoryException {
214         Object JavaDoc ticket = request.getSession().getAttribute(
215             ATTRIBUTE_REPOSITORY_SESSION_PREFIX + repositoryID + "_" + workspaceID); //$NON-NLS-1$
216
if (ticket == null) {
217             createRepositorySession(request, repositoryID, workspaceID);
218             return (Session) request.getSession().getAttribute(
219                 ATTRIBUTE_REPOSITORY_SESSION_PREFIX + repositoryID + "_" + workspaceID); //$NON-NLS-1$
220
}
221         return (Session) ticket;
222     }
223
224     /**
225      * create user ticket and set ACL (user + group) in the session
226      * @param request
227      */

228     public static void createSession(HttpServletRequest JavaDoc request) throws LoginException, RepositoryException {
229         createRepositorySession(request, DEFAULT_REPOSITORY);
230     }
231
232     /**
233      * create user ticket and set ACL (user + group) in the session
234      * @param request
235      */

236     private static void createRepositorySession(HttpServletRequest JavaDoc request, String JavaDoc repositoryID) throws LoginException,
237         RepositoryException {
238         createRepositorySession(request, repositoryID, DEFAULT_WORKSPACE);
239     }
240
241     /**
242      * create user ticket and set ACL (user + group) in the session
243      * @param request
244      */

245     private static void createRepositorySession(HttpServletRequest JavaDoc request, String JavaDoc repositoryID, String JavaDoc workspaceID)
246         throws LoginException, RepositoryException {
247         SimpleCredentials sc = new SimpleCredentials(ContentRepository.SYSTEM_USER, ContentRepository.SYSTEM_PSWD);
248         Session session = ContentRepository.getRepository(repositoryID).login(sc, workspaceID);
249         request.getSession().setAttribute(ATTRIBUTE_REPOSITORY_SESSION_PREFIX + repositoryID + "_" + workspaceID, //$NON-NLS-1$
250
session);
251         Content userNode = getUserNode(request);
252
253         if (userNode != null) {
254             List JavaDoc acl = new ArrayList JavaDoc();
255             updateRolesACL(userNode, acl, repositoryID);
256             AccessManagerImpl accessManager = new AccessManagerImpl();
257             accessManager.setPermissionList(acl);
258             request.getSession().setAttribute(ATTRIBUTE_AM_PREFIX + repositoryID + "_" + workspaceID, accessManager); //$NON-NLS-1$
259
}
260     }
261
262     private static void createHierarchyManager(HttpServletRequest JavaDoc request, String JavaDoc repositoryID, String JavaDoc workspaceID) {
263         HierarchyManager hm = new HierarchyManager(Authenticator.getUserId(request));
264         try {
265             hm.init(getSession(request, repositoryID, workspaceID).getRootNode());
266             hm.setAccessManager((AccessManager) request.getSession().getAttribute(
267                 ATTRIBUTE_AM_PREFIX + repositoryID + "_" + workspaceID)); //$NON-NLS-1$
268
request.getSession().setAttribute(ATTRIBUTE_HM_PREFIX + repositoryID + "_" + workspaceID, hm); //$NON-NLS-1$
269
}
270         catch (RepositoryException re) {
271             log.error(re.getMessage(), re);
272         }
273     }
274
275     /**
276      * @param request
277      * @return Node representing currently logged in user
278      */

279     public static Content getUserNode(HttpServletRequest JavaDoc request) {
280         Content userPage = Authenticator.getUserPage(request);
281         try {
282             if (userPage == null) {
283                 String JavaDoc userid = Authenticator.getUserId(request);
284                 if (StringUtils.isNotBlank(userid)) {
285                     userPage = ContentRepository.getHierarchyManager(ContentRepository.USERS).getContent(userid);
286                 }
287             }
288         }
289         catch (Exception JavaDoc e) {
290             log.error(e.getMessage(), e);
291         }
292         return userPage;
293     }
294
295     /**
296      * @param request
297      * @return true is user has a valid session
298      */

299     public static boolean isSecuredSession(HttpServletRequest JavaDoc request) {
300         return Authenticator.isAuthenticated(request);
301     }
302
303     /**
304      * Adds user acl of the specified user to the given userACL
305      * @param roleNode
306      * @param userACL
307      */

308     private static void updateACL(Content roleNode, List JavaDoc userACL, String JavaDoc repositoryID) {
309         try {
310             // get access rights of this node (role)
311
Content acl = null;
312             try {
313                 acl = roleNode.getContent("acl_" + repositoryID); //$NON-NLS-1$
314
}
315             catch (PathNotFoundException e) {
316                 log.warn("No acl defined for role " + roleNode.getHandle() + " on repository \"" + repositoryID + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
317
return;
318             }
319
320             Collection JavaDoc aclCollection = acl.getChildren();
321             if (aclCollection == null) {
322                 return;
323             }
324             Iterator JavaDoc children = aclCollection.iterator();
325             while (children.hasNext()) {
326                 Content map = (Content) children.next();
327                 String JavaDoc path = map.getNodeData("path").getString(); //$NON-NLS-1$
328

329                 UrlPattern p = new SimpleUrlPattern(path);
330                 Permission permission = new PermissionImpl();
331                 permission.setPattern(p);
332                 permission.setPermissions(map.getNodeData("permissions").getLong()); //$NON-NLS-1$
333
userACL.add(permission);
334             }
335         }
336         catch (RepositoryException re) {
337             log.error(re.getMessage(), re);
338         }
339     }
340
341     /**
342      * Adds group acl of the specified user to the given groupACL
343      * @param userNode
344      * @param groupACL
345      */

346     private static void updateRolesACL(Content userNode, List JavaDoc groupACL, String JavaDoc repositoryID) {
347
348         if (userNode == null) {
349             log.error("Called updateRolesACL with a null userNode"); //$NON-NLS-1$
350
return;
351         }
352
353         try {
354             HierarchyManager rolesHierarchy = ContentRepository.getHierarchyManager(ContentRepository.USER_ROLES);
355             // get access rights of this user
356

357             Content acl = null;
358             try {
359                 acl = userNode.getContent("roles"); //$NON-NLS-1$
360
}
361             catch (PathNotFoundException e) {
362                 log.warn("No roles defined for user " + userNode.getHandle()); //$NON-NLS-1$
363
return;
364             }
365
366             Collection JavaDoc aclCollection = acl.getChildren();
367             if (aclCollection == null) {
368                 return;
369             }
370             Iterator JavaDoc children = aclCollection.iterator();
371             /* find the exact match for the current url and acl for it */
372             while (children.hasNext()) {
373                 Content map = (Content) children.next();
374                 String JavaDoc groupPath = map.getNodeData("path").getString(); //$NON-NLS-1$
375
if (StringUtils.isNotEmpty(groupPath)) {
376                     Content roleNode = rolesHierarchy.getContent(groupPath);
377                     updateACL(roleNode, groupACL, repositoryID);
378                 }
379             }
380         }
381         catch (RepositoryException e) {
382             log.error("Failed to update roles ACL"); //$NON-NLS-1$
383
log.error(e.getMessage(), e);
384         }
385     }
386
387     /**
388      * invalidates user session
389      * @param request
390      */

391     public static void invalidateUser(HttpServletRequest JavaDoc request) {
392         request.getSession().invalidate();
393     }
394
395     /**
396      * logout user (as in request) from the specified repository session
397      * @param request
398      * @param repositoryID
399      */

400     public static void logout(HttpServletRequest JavaDoc request, String JavaDoc repositoryID) {
401         try {
402             getSession(request, repositoryID).logout();
403         }
404         catch (RepositoryException re) {
405             log.error(re.getMessage(), re);
406         }
407     }
408 }
409
Popular Tags