View Javadoc
1   package org.apache.fulcrum.security.torque.dynamic;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  import java.sql.Connection;
22  
23  import org.apache.fulcrum.security.entity.Group;
24  import org.apache.fulcrum.security.entity.Permission;
25  import org.apache.fulcrum.security.entity.Role;
26  import org.apache.fulcrum.security.entity.User;
27  import org.apache.fulcrum.security.model.dynamic.AbstractDynamicModelManager;
28  import org.apache.fulcrum.security.model.dynamic.DynamicModelManager;
29  import org.apache.fulcrum.security.model.dynamic.entity.DynamicGroup;
30  import org.apache.fulcrum.security.model.dynamic.entity.DynamicPermission;
31  import org.apache.fulcrum.security.model.dynamic.entity.DynamicRole;
32  import org.apache.fulcrum.security.model.dynamic.entity.DynamicUser;
33  import org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity;
34  import org.apache.fulcrum.security.util.DataBackendException;
35  import org.apache.fulcrum.security.util.UnknownEntityException;
36  import org.apache.torque.TorqueException;
37  import org.apache.torque.util.Transaction;
38  
39  /**
40   * This implementation persists to a database via Torque.
41   *
42   * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
43   * @version $Id:$
44   */
45  public class TorqueDynamicModelManagerImpl extends AbstractDynamicModelManager implements DynamicModelManager {
46  	
47  	/**
48  	 * Serial ID
49  	 */
50  	private static final long serialVersionUID = -4102444603078107928L;
51  
52  	/**
53  	 * Revokes a Role from a Group.
54  	 *
55  	 * @param group the Group.
56  	 * @param role  the Role.
57  	 * @throws DataBackendException   if there was an error accessing the data
58  	 *                                backend.
59  	 * @throws UnknownEntityException if group or role is not present.
60  	 */
61  	@Override
62  	public synchronized void revoke(Group group, Role role) throws DataBackendException, UnknownEntityException {
63  		boolean groupExists = getGroupManager().checkExists(group);
64  		boolean roleExists = getRoleManager().checkExists(role);
65  
66  		if (groupExists && roleExists) {
67  			((DynamicGroup) group).removeRole(role);
68  			((DynamicRole) role).removeGroup(group);
69  
70  			Connection con = null;
71  
72  			try {
73  				con = Transaction.begin();
74  
75  				((TorqueAbstractSecurityEntity) role).update(con);
76  				((TorqueAbstractSecurityEntity) group).update(con);
77  
78  				Transaction.commit(con);
79  				con = null;
80  			} catch (TorqueException e) {
81  				throw new DataBackendException("revoke('" + group.getName() + "', '" + role.getName() + "') failed", e);
82  			} finally {
83  				if (con != null) {
84  					Transaction.safeRollback(con);
85  				}
86  			}
87  
88  			return;
89  		}
90  
91  		if (!groupExists) {
92  			throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
93  		}
94  
95  		if (!roleExists) {
96  			throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
97  		}
98  	}
99  
100 	/**
101 	 * Grants a Role a Permission
102 	 *
103 	 * @param role       the Role.
104 	 * @param permission the Permission.
105 	 * @throws DataBackendException   if there was an error accessing the data
106 	 *                                backend.
107 	 * @throws UnknownEntityException if role or permission is not present.
108 	 */
109 	@Override
110 	public synchronized void grant(Role role, Permission permission)
111 			throws DataBackendException, UnknownEntityException {
112 		boolean roleExists = getRoleManager().checkExists(role);
113 		boolean permissionExists = getPermissionManager().checkExists(permission);
114 
115 		if (roleExists && permissionExists) {
116 			((DynamicRole) role).addPermission(permission);
117 			((DynamicPermission) permission).addRole(role);
118 
119 			Connection con = null;
120 
121 			try {
122 				con = Transaction.begin();
123 
124 				((TorqueAbstractSecurityEntity) role).update(con);
125 				((TorqueAbstractSecurityEntity) permission).update(con);
126 
127 				Transaction.commit(con);
128 				con = null;
129 			} catch (TorqueException e) {
130 				throw new DataBackendException("grant('" + role.getName() + "', '" + permission.getName() + "') failed",
131 						e);
132 			} finally {
133 				if (con != null) {
134 					Transaction.safeRollback(con);
135 				}
136 			}
137 
138 			return;
139 		}
140 
141 		if (!roleExists) {
142 			throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
143 		}
144 
145 		if (!permissionExists) {
146 			throw new UnknownEntityException("Unknown permission '" + permission.getName() + "'");
147 		}
148 	}
149 
150 	/**
151 	 * Revokes a Permission from a Role.
152 	 *
153 	 * @param role       the Role.
154 	 * @param permission the Permission.
155 	 * @throws DataBackendException   if there was an error accessing the data
156 	 *                                backend.
157 	 * @throws UnknownEntityException if role or permission is not present.
158 	 */
159 	@Override
160 	public synchronized void revoke(Role role, Permission permission)
161 			throws DataBackendException, UnknownEntityException {
162 		boolean roleExists = getRoleManager().checkExists(role);
163 		boolean permissionExists = getPermissionManager().checkExists(permission);
164 
165 		if (roleExists && permissionExists) {
166 			((DynamicRole) role).removePermission(permission);
167 			((DynamicPermission) permission).removeRole(role);
168 
169 			Connection con = null;
170 
171 			try {
172 				con = Transaction.begin();
173 				;
174 
175 				((TorqueAbstractSecurityEntity) role).update(con);
176 				((TorqueAbstractSecurityEntity) permission).update(con);
177 
178 				Transaction.commit(con);
179 				con = null;
180 			} catch (TorqueException e) {
181 				throw new DataBackendException(
182 						"revoke('" + role.getName() + "', '" + permission.getName() + "') failed", e);
183 			} finally {
184 				if (con != null) {
185 					Transaction.safeRollback(con);
186 				}
187 			}
188 
189 			return;
190 		}
191 
192 		if (!roleExists) {
193 			throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
194 		}
195 
196 		if (!permissionExists) {
197 			throw new UnknownEntityException("Unknown permission '" + permission.getName() + "'");
198 		}
199 	}
200 
201 	/**
202 	 * Puts a user in a group.
203 	 *
204 	 * This method is used when adding a user to a group
205 	 *
206 	 * @param user  the User.
207 	 * @param group the Group
208 	 * @throws DataBackendException   if there was an error accessing the data
209 	 *                                backend.
210 	 * @throws UnknownEntityException if the account is not present.
211 	 */
212 	@Override
213 	public synchronized void grant(User user, Group group) throws DataBackendException, UnknownEntityException {
214 		boolean groupExists = getGroupManager().checkExists(group);
215 		boolean userExists = getUserManager().checkExists(user);
216 
217 		if (groupExists && userExists) {
218 			((DynamicUser) user).addGroup(group);
219 			((DynamicGroup) group).addUser(user);
220 
221 			Connection con = null;
222 
223 			try {
224 				con = Transaction.begin();
225 
226 				((TorqueAbstractSecurityEntity) user).update(con);
227 				((TorqueAbstractSecurityEntity) group).update(con);
228 
229 				Transaction.commit(con);
230 				con = null;
231 			} catch (TorqueException e) {
232 				throw new DataBackendException("grant('" + user.getName() + "', '" + group.getName() + "') failed", e);
233 			} finally {
234 				if (con != null) {
235 					Transaction.safeRollback(con);
236 				}
237 			}
238 
239 			return;
240 		}
241 
242 		if (!groupExists) {
243 			throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
244 		}
245 
246 		if (!userExists) {
247 			throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
248 		}
249 	}
250 
251 	/**
252 	 * Removes a user in a group.
253 	 *
254 	 * This method is used when removing a user to a group
255 	 *
256 	 * @param user  the User.
257 	 * @param group the Group
258 	 * @throws DataBackendException   if there was an error accessing the data
259 	 *                                backend.
260 	 * @throws UnknownEntityException if the user or group is not present.
261 	 */
262 	@Override
263 	public synchronized void revoke(User user, Group group) throws DataBackendException, UnknownEntityException {
264 		boolean groupExists = getGroupManager().checkExists(group);
265 		boolean userExists = getUserManager().checkExists(user);
266 
267 		if (groupExists && userExists) {
268 			((DynamicUser) user).removeGroup(group);
269 			((DynamicGroup) group).removeUser(user);
270 
271 			Connection con = null;
272 
273 			try {
274 				con = Transaction.begin();
275 
276 				((TorqueAbstractSecurityEntity) user).update(con);
277 				((TorqueAbstractSecurityEntity) group).update(con);
278 
279 				Transaction.commit(con);
280 				con = null;
281 			} catch (TorqueException e) {
282 				throw new DataBackendException("revoke('" + user.getName() + "', '" + group.getName() + "') failed", e);
283 			} finally {
284 				if (con != null) {
285 					Transaction.safeRollback(con);
286 				}
287 			}
288 
289 			return;
290 		}
291 
292 		if (!groupExists) {
293 			throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
294 		}
295 
296 		if (!userExists) {
297 			throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
298 		}
299 	}
300 
301 	/**
302 	 * Grants a Group a Role
303 	 *
304 	 * @param group the Group.
305 	 * @param role  the Role.
306 	 * @throws DataBackendException   if there was an error accessing the data
307 	 *                                backend.
308 	 * @throws UnknownEntityException if group or role is not present.
309 	 */
310 	@Override
311 	public synchronized void grant(Group group, Role role) throws DataBackendException, UnknownEntityException {
312 		boolean groupExists = getGroupManager().checkExists(group);
313 		boolean roleExists = getRoleManager().checkExists(role);
314 
315 		if (groupExists && roleExists) {
316 			((DynamicGroup) group).addRole(role);
317 			((DynamicRole) role).addGroup(group);
318 
319 			Connection con = null;
320 
321 			try {
322 				con = Transaction.begin();
323 
324 				((TorqueAbstractSecurityEntity) role).update(con);
325 				((TorqueAbstractSecurityEntity) group).update(con);
326 
327 				Transaction.commit(con);
328 				con = null;
329 			} catch (TorqueException e) {
330 				throw new DataBackendException("grant('" + group.getName() + "', '" + role.getName() + "') failed", e);
331 			} finally {
332 				if (con != null) {
333 					Transaction.safeRollback(con);
334 				}
335 			}
336 
337 			return;
338 		}
339 
340 		if (!groupExists) {
341 			throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
342 		}
343 
344 		if (!roleExists) {
345 			throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
346 		}
347 	}
348 
349 	/**
350 	 * Allow B to assumes A's roles, groups and permissions
351 	 * 
352 	 * @param delegator A
353 	 * @param delegatee B
354 	 * @throws DataBackendException   if there was an error accessing the data
355 	 *                                backend.
356 	 * @throws UnknownEntityException if delegator or delagatee is not present.
357 	 */
358 	@Override
359 	public synchronized void addDelegate(User delegator, User delegatee)
360 			throws DataBackendException, UnknownEntityException {
361 		boolean delegatorExists = getUserManager().checkExists(delegator);
362 		boolean delegateeExists = getUserManager().checkExists(delegatee);
363 
364 		if (delegatorExists && delegateeExists) {
365 			super.addDelegate(delegator, delegatee);
366 
367 			Connection con = null;
368 
369 			try {
370 				con = Transaction.begin();
371 
372 				((TorqueAbstractSecurityEntity) delegator).update(con);
373 				((TorqueAbstractSecurityEntity) delegatee).update(con);
374 
375 				Transaction.commit(con);
376 				con = null;
377 			} catch (TorqueException e) {
378 				throw new DataBackendException(
379 						"addDelegate('" + delegator.getName() + "', '" + delegatee.getName() + "') failed", e);
380 			} finally {
381 				if (con != null) {
382 					Transaction.safeRollback(con);
383 				}
384 			}
385 
386 			return;
387 		}
388 
389 		if (!delegatorExists) {
390 			throw new UnknownEntityException("Unknown user '" + delegator.getName() + "'");
391 		}
392 
393 		if (!delegateeExists) {
394 			throw new UnknownEntityException("Unknown user '" + delegatee.getName() + "'");
395 		}
396 	}
397 
398 	/**
399 	 * Stop A having B's roles, groups and permissions
400 	 * 
401 	 * @param delegator  A
402 	 * @param delegatee  B
403 	 * 
404 	 * @throws DataBackendException   if there was an error accessing the data
405 	 *                                backend.
406 	 * @throws UnknownEntityException if delegator or delagatee is not present.
407 	 */
408 	@Override
409 	public synchronized void removeDelegate(User delegator, User delegatee)
410 			throws DataBackendException, UnknownEntityException {
411 		boolean delegatorExists = getUserManager().checkExists(delegator);
412 		boolean delegateeExists = getUserManager().checkExists(delegatee);
413 
414 		if (delegatorExists && delegateeExists) {
415 			super.removeDelegate(delegator, delegatee);
416 
417 			Connection con = null;
418 
419 			try {
420 				con = Transaction.begin();
421 
422 				((TorqueAbstractSecurityEntity) delegator).update(con);
423 				((TorqueAbstractSecurityEntity) delegatee).update(con);
424 
425 				Transaction.commit(con);
426 				con = null;
427 			} catch (TorqueException e) {
428 				throw new DataBackendException(
429 						"removeDelegate('" + delegator.getName() + "', '" + delegatee.getName() + "') failed", e);
430 			} finally {
431 				if (con != null) {
432 					Transaction.safeRollback(con);
433 				}
434 			}
435 
436 			return;
437 		}
438 
439 		if (!delegatorExists) {
440 			throw new UnknownEntityException("Unknown user '" + delegator.getName() + "'");
441 		}
442 
443 		if (!delegateeExists) {
444 			throw new UnknownEntityException("Unknown user '" + delegatee.getName() + "'");
445 		}
446 	}
447 }