Moved over some of the security stuff from Photos.
[utils] / security / src / main / java / org / wamblee / security / authorization / hibernate / PersistentAuthorizationService.java
1 /*
2  * Copyright 2005 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.wamblee.security.authorization.hibernate;
18
19 import java.util.List;
20
21 import org.springframework.orm.hibernate3.HibernateTemplate;
22 import org.wamblee.persistence.AbstractPersistent;
23 import org.wamblee.persistence.hibernate.HibernateSupport;
24 import org.wamblee.security.authorization.AuthorizationRule;
25 import org.wamblee.security.authorization.AuthorizationService;
26 import org.wamblee.security.authorization.DefaultAuthorizationService;
27 import org.wamblee.security.authorization.Operation;
28 import org.wamblee.usermgt.UserAccessor;
29
30 /**
31  * Authorization service with persistent storage.
32  * This is a wrapper for {@link org.wamblee.security.authorization.DefaultAuthorizationService}
33  * which refreshes the state of the service at certain time intervals. 
34  */
35 public class PersistentAuthorizationService extends AbstractPersistent
36         implements AuthorizationService {
37
38     /**
39      * Name of query to find the service by name.
40      */
41     private static final String FIND_QUERY = "findAuthorizationServiceByName";
42
43     /**
44      * Name of the query parameter for the service name.
45      */
46     private static final String NAME_PARAM = "name";
47
48     /**
49      * Authorization service to use.
50      */
51     private DefaultAuthorizationService _service;
52
53     /**
54      * Hibernate template to use.
55      */
56     private HibernateTemplate _template;
57
58     /**
59      * User accessor.
60      */
61     private UserAccessor _userAccessor;
62     
63     /**
64      * Name of the service. 
65      */
66     private String _name; 
67
68     /**
69      * Refresh interval in milliseconds. 
70      */
71     private final long _refreshInterval;
72     
73     /**
74      * Last refresh time. 
75      */
76     private long _lastRefreshTime; 
77
78     /**
79      * Constructs the persistent service.
80      * 
81      * @param aName
82      *            Name of the service.
83      * @param aTemplate
84      *            Hibernate template for hibernate usage.
85      * @param aAccessor
86      *            User accessor.
87      * @param aRefresh
88      *            Whether or not to refresh the state of the service at the
89      *            start of every operation.
90      */
91     public PersistentAuthorizationService(String aName,
92             HibernateTemplate aTemplate, UserAccessor aAccessor,
93             long aRefreshInterval) {
94         _template = aTemplate;
95         _refreshInterval = aRefreshInterval;
96         _lastRefreshTime = System.currentTimeMillis(); 
97         _userAccessor = aAccessor;
98         _name = aName; 
99     }
100
101     /**
102      * Initialize service if needed. 
103      */
104     private void initialize() {
105         if (_service == null) {
106             List<DefaultAuthorizationService> result = _template
107                     .findByNamedQueryAndNamedParam(FIND_QUERY, NAME_PARAM,
108                             _name);
109
110             if (result.size() > 1) {
111                 throw new IllegalArgumentException(
112                         "Returned more than one service for name '" + _name
113                                 + "' (" + result.size() + ")");
114             }
115
116             if (result.size() == 0) {
117                 _service = new DefaultAuthorizationService(_userAccessor, _name);
118                 _template.persist(_service);
119             } else {
120                 _service = result.get(0);
121                 _service.setUserAccessor(_userAccessor);
122             }
123         }
124     }
125
126     /*
127      * (non-Javadoc)
128      * 
129      * @see org.wamblee.security.authorization.AuthorizationService#isAllowed(java.lang.Object,
130      *      org.wamblee.security.authorization.Operation)
131      */
132     public boolean isAllowed(Object aResource, Operation aOperation) {
133         initialize();
134         refresh();
135         return _service.isAllowed(aResource, aOperation);
136     }
137     
138     /* (non-Javadoc)
139      * @see org.wamblee.security.authorization.AuthorizationService#check(T, org.wamblee.security.authorization.Operation)
140      */
141     public <T> T check(T aResource, Operation aOperation) {
142         initialize();
143         refresh();
144         return _service.check(aResource, aOperation);
145     }
146
147     /*
148      * (non-Javadoc)
149      * 
150      * @see org.wamblee.security.authorization.AuthorizationService#getRules()
151      */
152     public AuthorizationRule[] getRules() {
153         initialize();
154         refresh();
155         return _service.getRules();
156     }
157
158     /*
159      * (non-Javadoc)
160      * 
161      * @see org.wamblee.security.authorization.AuthorizationService#appendRule(org.wamblee.security.authorization.AuthorizationRule)
162      */
163     public void appendRule(AuthorizationRule aRule) {
164         initialize();
165         refresh();
166         _service.appendRule(aRule);
167         save();
168     }
169
170     /*
171      * (non-Javadoc)
172      * 
173      * @see org.wamblee.security.authorization.AuthorizationService#removeRule(int)
174      */
175     public void removeRule(int aIndex) {
176         initialize();
177         refresh();
178         _service.removeRule(aIndex);
179         save();
180     }
181
182     /*
183      * (non-Javadoc)
184      * 
185      * @see org.wamblee.security.authorization.AuthorizationService#insertRuleAfter(int,
186      *      org.wamblee.security.authorization.AuthorizationRule)
187      */
188     public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
189         initialize();
190         refresh();
191         _service.insertRuleAfter(aIndex, aRule);
192         save();
193     }
194
195     /**
196      * Refreshes the state of the service through hibernate.
197      * 
198      */
199     private synchronized void refresh() {
200         long time = System.currentTimeMillis(); 
201         if ( time - _lastRefreshTime > _refreshInterval ) { 
202             _template.refresh(_service);
203             _lastRefreshTime = time; 
204         }
205     }
206
207     /**
208      * Saves any changes to the service state if necessary.
209      */
210     private void save() {
211         HibernateSupport.merge(_template, _service);
212     }
213 }