01: package com.technoetic.xplanner.domain.repository;
02:
03: import net.sf.hibernate.HibernateException;
04: import org.apache.commons.beanutils.PropertyUtils;
05: import org.springframework.dao.DataAccessException;
06: import org.springframework.orm.hibernate.HibernateObjectRetrievalFailureException;
07: import org.springframework.orm.hibernate.support.HibernateDaoSupport;
08:
09: import com.technoetic.xplanner.domain.DomainObject;
10: import com.technoetic.xplanner.filters.ThreadServletRequest;
11: import com.technoetic.xplanner.security.SecurityHelper;
12: import com.technoetic.xplanner.security.auth.AuthorizationException;
13: import com.technoetic.xplanner.security.auth.Authorizer;
14: import com.technoetic.xplanner.tags.DomainContext;
15:
16: // dao -- how should other methods be protected? repository-specific ones?
17:
18: public class RepositorySecurityAdapter extends HibernateDaoSupport
19: implements ObjectRepository {
20: private Class objectClass;
21: private ObjectRepository delegate;
22: private Authorizer authorizer;
23:
24: public void setAuthorizer(Authorizer authorizer) {
25: this .authorizer = authorizer;
26: }
27:
28: public RepositorySecurityAdapter(Class objectClass,
29: ObjectRepository delegate) throws HibernateException {
30: this .objectClass = objectClass;
31: this .delegate = delegate;
32: }
33:
34: public void delete(final int objectIdentifier)
35: throws RepositoryException {
36: try {
37: // todo How should the project ID be obtained without refs to Hibernate?
38: Object object = getHibernateTemplate().load(objectClass,
39: new Integer(objectIdentifier));
40: checkAuthorization(object, "delete");
41: } catch (HibernateObjectRetrievalFailureException e) {
42: throw new ObjectNotFoundException(e.getMessage());
43: } catch (DataAccessException e) {
44: throw new RepositoryException(e);
45: }
46: delegate.delete(objectIdentifier);
47: }
48:
49: public int insert(DomainObject object) throws RepositoryException {
50: // do-before-release Fix insert authorization - problem with missing project context
51: // checkAuthorization(object, "create");
52: return delegate.insert(object);
53: }
54:
55: public Object load(int objectIdentifier) throws RepositoryException {
56: Object loadedObject = delegate.load(objectIdentifier);
57: checkAuthorization(loadedObject, "read");
58: return loadedObject;
59: }
60:
61: private void checkAuthorization(Object object, String permission)
62: throws RepositoryException {
63: DomainContext context = new DomainContext();
64: try {
65: context.populate(object);
66: int objectIdentifier = ((Integer) PropertyUtils
67: .getProperty(object, "id")).intValue();
68: if (!authorizer.hasPermission(context.getProjectId(),
69: SecurityHelper.getRemoteUserId(ThreadServletRequest
70: .get()), object, permission)) {
71: throw new AuthorizationException(
72: "not authorized for object " + permission
73: + ": " + objectClass + " "
74: + objectIdentifier);
75: }
76: } catch (RuntimeException e) {
77: throw e;
78: } catch (Exception e) {
79: throw new RepositoryException(e);
80: }
81: }
82:
83: public void update(DomainObject object) throws RepositoryException {
84: checkAuthorization(object, "edit");
85: delegate.update(object);
86: }
87: }
|