Source code: com/obinary/cms/admin/SessionAccessControl.java
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-2003 obinary Ltd. (http://www.obinary.com) All rights reserved.
11 *
12 * */
13
14
15
16
17 package com.obinary.cms.admin;
18
19
20 import com.obinary.cms.beans.ConfigLoader;
21 import com.obinary.cms.beans.ServerInfo;
22 import com.obinary.cms.beans.Permission;
23
24 import javax.jcr.*;
25 import javax.jcr.access.AccessDeniedException;
26 import javax.servlet.http.HttpServletRequest;
27
28 import org.apache.slide.jcr.core.SudoCredentials;
29 import org.apache.slide.jcr.core.AccessManagerImpl;
30
31 import java.util.regex.Pattern;
32 import java.util.ArrayList;
33
34
35 /**
36 * User: sameercharles
37 * Date: Sep 14, 2003
38 * Time: 11:50:16 AM
39 * @author Sameer Charles
40 * @version 1.0
41 */
42
43
44 /**
45 * Re-implement this class once jcr AccessManager is implemented
46 *
47 */
48
49 public class SessionAccessControl {
50
51
52 private static final String WEBSITE_REPOSITORY_TICKET = "ticket";
53 private static final String USERS_REPOSITORY_TICKET = "usersticket";
54 private static final String ROLES_REPOSITORY_TICKET = "rolesticket";
55
56 private static final String ACL_USERS_REPOSITORY = "aclUsersRepository";
57 private static final String ACL_ROLES_REPOSITORY = "aclRolesRepository";
58 private static final String ACL_WEBSITE_REPOSITORY = "acl";
59
60
61 public static final int WEBSITE_REPOSITORY = 0;
62 public static final int USERS_REPOSITORY = 1;
63 public static final int ROLES_REPOSITORY = 2;
64
65
66
67
68
69 /**
70 * <p>
71 * gets the ticket creted while login, creates a new ticket if not existing<br>
72 * </p>
73 *
74 * @param request
75 */
76 public static Ticket getTicket(HttpServletRequest request)
77 throws LoginException,
78 AccessDeniedException,
79 RepositoryException {
80 Object ticket = request.getSession().getAttribute(WEBSITE_REPOSITORY_TICKET);
81 if (ticket == null) {
82 createTicket(request);
83 return (Ticket)request.getSession().getAttribute(WEBSITE_REPOSITORY_TICKET);
84 }
85 return (Ticket)ticket;
86 }
87
88
89 /**
90 * <p>
91 * gets the ticket creted while login, creates a new ticket if not existing<br>
92 * </p>
93 *
94 * @param request
95 */
96 public static Ticket getTicket(HttpServletRequest request, int type)
97 throws LoginException,
98 AccessDeniedException,
99 RepositoryException {
100 if (type == USERS_REPOSITORY)
101 return getUserRepositoryTicket(request);
102 else if (type == ROLES_REPOSITORY)
103 return getRolesRepositoryTicket(request);
104 return getTicket(request);
105 }
106
107
108
109 private static Ticket getUserRepositoryTicket(HttpServletRequest request)
110 throws LoginException,
111 AccessDeniedException,
112 RepositoryException {
113 Object ticket = request.getSession().getAttribute(USERS_REPOSITORY_TICKET);
114 if (ticket == null) {
115 createUsersRepositoryTicket(request);
116 return (Ticket)request.getSession().getAttribute(USERS_REPOSITORY_TICKET);
117 }
118 return (Ticket)ticket;
119 }
120
121
122 private static Ticket getRolesRepositoryTicket(HttpServletRequest request)
123 throws LoginException,
124 AccessDeniedException,
125 RepositoryException {
126 Object ticket = request.getSession().getAttribute(ROLES_REPOSITORY_TICKET);
127 if (ticket == null) {
128 createRolesRepositoryTicket(request);
129 return (Ticket)request.getSession().getAttribute(ROLES_REPOSITORY_TICKET);
130 }
131 return (Ticket)ticket;
132 }
133
134
135 /**
136 * <p>gets the master ticket which has been created on server startup</p>
137 *
138 * @param request
139 */
140 public static Ticket getMasterTicket(HttpServletRequest request) throws LoginException {
141 return ServerInfo.getMasterTicket();
142 }
143
144
145 /**
146 * @param request
147 * @deprecated master ticket is creted by the system startup
148 * @see ServerInfo#getMasterTicket()
149 */
150 public static void createMasterTicket(HttpServletRequest request)
151 throws LoginException {
152 throw new LoginException();
153 }
154
155
156 /**
157 * <p>create user ticket and set ACL (user + group) in the session</p>
158 *
159 * @param request
160 */
161 public static void createTicket(HttpServletRequest request)
162 throws LoginException,
163 AccessDeniedException,
164 RepositoryException {
165 SudoCredentials sc = new SudoCredentials(getMasterTicket(request),getUserNode(request));
166 Ticket ticket = ConfigLoader.websiteRepository.connect(sc);
167 request.getSession().setAttribute(WEBSITE_REPOSITORY_TICKET,ticket);
168 Node userNode = ticket.getUserNode();
169 ArrayList acl = new ArrayList();
170 updateACL(userNode,acl,WEBSITE_REPOSITORY);
171 updateRolesACL(userNode,acl);
172 ((AccessManagerImpl)ticket.getAccessManager()).setUserPermissions(acl);
173 }
174
175
176 /**
177 * <p>create user ticket and set ACL (user + group) in the session</p>
178 *
179 * @param request
180 */
181 public static void createUsersRepositoryTicket(HttpServletRequest request)
182 throws LoginException,
183 AccessDeniedException,
184 RepositoryException {
185 SudoCredentials sc = new SudoCredentials(getMasterTicket(request),getUserNode(request));
186 Ticket ticket = ConfigLoader.usersRepository.connect(sc);
187 request.getSession().setAttribute(USERS_REPOSITORY_TICKET,ticket);
188 Node userNode = ticket.getUserNode();
189 ArrayList acl = new ArrayList();
190 updateACL(userNode,acl,USERS_REPOSITORY);
191 ((AccessManagerImpl)ticket.getAccessManager()).setUserPermissions(acl);
192 }
193
194
195 /**
196 * <p>create user ticket and set ACL (user + group) in the session</p>
197 *
198 * @param request
199 */
200 public static void createRolesRepositoryTicket(HttpServletRequest request)
201 throws LoginException,
202 AccessDeniedException,
203 RepositoryException {
204 SudoCredentials sc = new SudoCredentials(getMasterTicket(request),getUserNode(request));
205 Ticket ticket = ConfigLoader.userRolesRepository.connect(sc);
206 request.getSession().setAttribute(ROLES_REPOSITORY_TICKET,ticket);
207 Node userNode = ticket.getUserNode();
208 ArrayList acl = new ArrayList();
209 updateACL(userNode,acl,ROLES_REPOSITORY);
210 ((AccessManagerImpl)ticket.getAccessManager()).setUserPermissions(acl);
211 }
212
213
214 /**
215 *
216 * @param request
217 * @return Node representing currently logged in user
218 */
219 public static Node getUserNode(HttpServletRequest request)
220 throws LoginException,
221 AccessDeniedException,
222 RepositoryException {
223 Ticket userTicket = ConfigLoader.usersRepository.connect(new PasswordCredentials("superuser", "".toCharArray()));
224 Node userRoot = userTicket.getRootNode();
225 return userRoot.getNode("/"+Authenticator.getUserId(request));
226 }
227
228
229
230 /**
231 * @param request
232 * @return true is user has a valid session
233 */
234 public static boolean isValidSession(HttpServletRequest request) {
235 Object ticket = request.getSession().getAttribute(WEBSITE_REPOSITORY_TICKET);
236 return !(ticket == null);
237 }
238
239
240
241 /**
242 * <p>Adds user acl of the specified user to the given userACL</p>
243 *
244 * @param userNode
245 * @param userACL
246 */
247 private static void updateACL(Node userNode, ArrayList userACL, int type) {
248 try {
249 Node acl = null;
250 /* get access rights of this user */
251 if (type == WEBSITE_REPOSITORY)
252 acl = userNode.getNode("acl");
253 else if (type == USERS_REPOSITORY)
254 acl = userNode.getNode("aclUsersRepository");
255 else if (type == ROLES_REPOSITORY)
256 acl = userNode.getNode("aclRolesRepository");
257 ElementIterator children = acl.getElements(1);
258 /* find the exact match for the current url and acl for it */
259 while (children.hasNext()) {
260 Node map = (Node)children.nextElement();
261 if (map.getName().indexOf("jcr:") == 0)
262 continue;
263 StringBuffer URIStringBuffer = new StringBuffer();
264 char[] chars = map.getProperty("path").getValue().getString().toCharArray();
265 int i = 0, last = 0;
266 while (i < chars.length) {
267 char c = chars[i];
268 if (c == '*') {
269 URIStringBuffer.append(chars, last, i - last);
270 URIStringBuffer.append("[a-z[A-Z[./[0-9[_-[:]]]]]]*");
271 last = i+1;
272 }
273 i++;
274 }
275 URIStringBuffer.append(chars, last, i - last);
276 Pattern p = Pattern.compile(URIStringBuffer.toString());
277 Permission permission = new Permission();
278 permission.setPattern(p);
279 permission.setPermissions(map.getProperty("permissions").getValue().getLong());
280 userACL.add(permission);
281 }
282 /* check for the permissions */
283 } catch(RepositoryException re) {
284 re.printStackTrace();
285 }
286 }
287
288
289 /**
290 * <p>Adds group acl of the specified user to the given groupACL</p>
291 *
292 * @param userNode
293 * @param groupACL
294 */
295 private static void updateRolesACL(Node userNode, ArrayList groupACL) {
296 Ticket ticket = null;
297 try {
298 ticket = ConfigLoader.userRolesRepository.connect(new PasswordCredentials("superuser", "".toCharArray()));
299 Node userGroupRoot = ticket.getRootNode();
300 /* get access rights of this user */
301 Node acl = userNode.getNode("roles");
302 ElementIterator children = acl.getElements(1);
303 /* find the exact match for the current url and acl for it */
304 while (children.hasNext()) {
305 Node map = (Node)children.nextElement();
306 if (map.getName().indexOf("jcr:") == 0)
307 continue;
308 String groupPath = map.getProperty("path").getValue().getString();
309 Node groupNode = userGroupRoot.getNode(groupPath);
310 updateACL(groupNode,groupACL,WEBSITE_REPOSITORY);
311 }
312 } catch (RepositoryException re) {
313 re.printStackTrace();
314 } finally {
315 if (ticket != null)
316 ticket.close();
317 }
318 }
319
320
321
322 }