2 * Copyright 2005-2010 the original author or authors.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.wamblee.security.authorization.jpa;
18 import javax.persistence.EntityManager;
19 import javax.persistence.NoResultException;
20 import javax.persistence.NonUniqueResultException;
22 import org.wamblee.persistence.JpaMergeSupport;
23 import org.wamblee.security.authentication.UserAccessor;
24 import org.wamblee.security.authentication.UserAdministration;
25 import org.wamblee.security.authorization.AbstractAuthorizationService;
26 import org.wamblee.security.authorization.AbstractAuthorizationRule;
27 import org.wamblee.security.authorization.AuthorizationRule;
28 import org.wamblee.security.authorization.AuthorizationService;
29 import org.wamblee.security.authorization.DefaultAuthorizationService;
30 import org.wamblee.security.authorization.Operation;
33 * Authorization service with persistent storage. This is a wrapper for
34 * {@link org.wamblee.security.authorization.DefaultAuthorizationService} which
35 * refreshes the state of the service at certain time intervals.
37 * @author Erik Brakkee
39 public class JpaAuthorizationService implements AuthorizationService {
42 * Authorization service to use.
44 private AuthorizationService service;
47 * Hibernate template to use.
49 private EntityManager entityManager;
54 private UserAccessor userAccessor;
57 * User administration.
59 private UserAdministration userAdmin;
62 * Name of the service.
67 * Refresh interval in milliseconds.
69 private final long refreshInterval;
74 private long lastRefreshTime;
77 * Constructs the persistent service.
80 * Name of the service.
81 * @param aEntityManager
85 * @param aUserAdmin User administration.
87 * Whether or not to refresh the state of the service at the
88 * start of every operation.
90 public JpaAuthorizationService(String aName, EntityManager aEntityManager,
91 UserAccessor aAccessor, UserAdministration aUserAdmin, long aRefreshInterval) {
92 entityManager = aEntityManager;
93 refreshInterval = aRefreshInterval;
94 lastRefreshTime = System.currentTimeMillis();
95 userAccessor = aAccessor;
96 userAdmin = aUserAdmin;
101 public void setUserAccessor(UserAccessor aUserAccessor) {
102 userAccessor = aUserAccessor;
106 public void setUserAdministration(UserAdministration aUserAdmin) {
107 userAdmin = aUserAdmin;
110 private AuthorizationService refreshByReload() {
111 if ( userAdmin == null ) {
112 throw new IllegalArgumentException("useradmin is null");
114 AuthorizationService svc;
116 svc = entityManager.createNamedQuery(
117 AbstractAuthorizationService.QUERY_FIND_BY_NAME,
118 AbstractAuthorizationService.class).setParameter(
119 DefaultAuthorizationService.NAME_PARAM, name).getSingleResult();
120 svc.setUserAccessor(userAccessor);
121 svc.setUserAdministration(userAdmin);
122 } catch (NonUniqueResultException e) {
123 throw new IllegalArgumentException(
124 "Returned more than one service for name '" + name + "'");
125 } catch (NoResultException e) {
126 svc = new DefaultAuthorizationService(userAccessor, userAdmin, name);
127 entityManager.persist(svc);
136 * org.wamblee.security.authorization.AuthorizationService#isAllowed(java
137 * .lang.Object, org.wamblee.security.authorization.Operation)
139 public boolean isAllowed(Object aResource, Operation aOperation) {
142 return service.isAllowed(aResource, aOperation);
148 * @see org.wamblee.security.authorization.AuthorizationService#check(T,
149 * org.wamblee.security.authorization.Operation)
151 public <T> T check(T aResource, Operation aOperation) {
154 return service.check(aResource, aOperation);
160 * @see org.wamblee.security.authorization.AuthorizationService#getRules()
162 public AuthorizationRule[] getRules() {
165 return service.getRules();
172 * org.wamblee.security.authorization.AuthorizationService#appendRule(org
173 * .wamblee.security.authorization.AuthorizationRule)
175 public void appendRule(AuthorizationRule aRule) {
176 AuthorizationService svc = refreshByReload();
177 svc.appendRule(aRule);
178 // Setting service to null will force reload the next time the
179 // service is used. This deals effectively with the case where the
180 // current transaction would roll back and the change would not have been made.
184 private synchronized AuthorizationService getService() {
188 private synchronized void setService(AuthorizationService aSvc) {
196 * org.wamblee.security.authorization.AuthorizationService#removeRule(int)
198 public void removeRule(int aIndex) {
199 AuthorizationService svc = refreshByReload();
200 svc.removeRule(aIndex);
208 * org.wamblee.security.authorization.AuthorizationService#insertRuleAfter
209 * (int, org.wamblee.security.authorization.AuthorizationRule)
211 public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
212 AuthorizationService svc = refreshByReload();
213 svc.insertRuleAfter(aIndex, aRule);
218 * Refreshes the state of the service through hibernate.
220 private synchronized void refresh() {
221 long time = System.currentTimeMillis();
223 if (service == null || (time - lastRefreshTime) > refreshInterval) {
224 service = refreshByReload();
225 lastRefreshTime = time;