001: /*
002: * Copyright (c) JForum Team
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms,
006: * with or without modification, are permitted provided
007: * that the following conditions are met:
008: *
009: * 1) Redistributions of source code must retain the above
010: * copyright notice, this list of conditions and the
011: * following disclaimer.
012: * 2) Redistributions in binary form must reproduce the
013: * above copyright notice, this list of conditions and
014: * the following disclaimer in the documentation and/or
015: * other materials provided with the distribution.
016: * 3) Neither the name of "Rafael Steil" nor
017: * the names of its contributors may be used to endorse
018: * or promote products derived from this software without
019: * specific prior written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
022: * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
023: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
025: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
026: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
027: * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
028: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
029: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
031: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
032: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
033: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
034: * IN CONTRACT, STRICT LIABILITY, OR TORT
035: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
036: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
037: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
038: *
039: * This file creation date: 18/11/2003 / 23:09:15
040: * The JForum Project
041: * http://www.jforum.net
042: */
043: package net.jforum.repository;
044:
045: import net.jforum.JForumExecutionContext;
046: import net.jforum.SessionFacade;
047: import net.jforum.cache.CacheEngine;
048: import net.jforum.cache.Cacheable;
049: import net.jforum.dao.DataAccessDriver;
050: import net.jforum.dao.GroupSecurityDAO;
051: import net.jforum.dao.UserDAO;
052: import net.jforum.entities.User;
053: import net.jforum.entities.UserSession;
054: import net.jforum.exceptions.SecurityLoadException;
055: import net.jforum.security.PermissionControl;
056:
057: import org.apache.log4j.Logger;
058:
059: /**
060: * @author Rafael Steil
061: * @version $Id: SecurityRepository.java,v 1.25 2006/08/27 01:22:02 rafaelsteil Exp $
062: */
063: public class SecurityRepository implements Cacheable {
064: private static final Logger logger = Logger
065: .getLogger(SecurityRepository.class);
066: private static CacheEngine cache;
067: private static final String FQN = "security";
068:
069: /**
070: * @see net.jforum.cache.Cacheable#setCacheEngine(net.jforum.cache.CacheEngine)
071: */
072: public void setCacheEngine(CacheEngine engine) {
073: cache = engine;
074: }
075:
076: /***
077: * Load user's roles.
078: *
079: * @param userId The user's id
080: * @param force If <code>true</code>, forces a reload. If <code>false</code>, the call
081: * will be ignored if the roles are already loaded.
082: *
083: * @see SecurityRepository#load(int)
084: * @see SecurityRepository#load(User)
085: * @see SecurityRepository#load(User, boolean)
086: * @return PermissionControl
087: */
088: public static PermissionControl load(int userId, boolean force) {
089: if (force || cache.get(FQN, Integer.toString(userId)) == null) {
090: UserDAO um = DataAccessDriver.getInstance().newUserDAO();
091:
092: return SecurityRepository
093: .load(um.selectById(userId), force);
094: }
095:
096: return SecurityRepository.get(userId);
097: }
098:
099: /**
100: * Load user's roles.
101: *
102: * @param userId The users's id
103: *
104: * @see SecurityRepository#load(int, boolean)
105: * @see SecurityRepository#load(User)
106: * @see SecurityRepository#load(User, boolean)
107: * @return PermissionControl
108: */
109: public static PermissionControl load(int userId) {
110: return SecurityRepository.load(userId, false);
111: }
112:
113: /**
114: * Load user's roles.
115: *
116: * @param user The <code>User</code> to load.
117: *
118: * @see SecurityRepository#load(int)
119: * @see SecurityRepository#load(int, boolean),
120: * @see SecurityRepository#load(User, boolean)
121: * @return PermissionControl
122: */
123: public static PermissionControl load(User user) {
124: return SecurityRepository.load(user, false);
125: }
126:
127: /**
128: * Load user's roles.
129: *
130: * @param user The <code>User</code> to load
131: * @param force If <code>true</code>, forces a reload. If <code>false</code>, the call
132: * will be ignored if the roles are already loaded.
133: *
134: * @see SecurityRepository#load(int)
135: * @see SecurityRepository#load(int, boolean)
136: * @see SecurityRepository#load(User)
137: * @return PermissionControl
138: */
139: public static PermissionControl load(User user, boolean force) {
140: String userId = Integer.toString(user.getId());
141:
142: if (force || cache.get(FQN, userId) == null) {
143: PermissionControl pc = new PermissionControl();
144:
145: // load roles
146: GroupSecurityDAO dao = DataAccessDriver.getInstance()
147: .newGroupSecurityDAO();
148: pc.setRoles(dao.loadRolesByUserGroups(user));
149:
150: cache.add(FQN, userId, pc);
151:
152: return pc;
153: }
154:
155: return SecurityRepository.get(user.getId());
156: }
157:
158: /**
159: * Check if the logged user has access to the role.
160: * This method gets user's id from its session.
161: *
162: * @param roleName The role name to verity
163: * @return <code>true</code> if the user has access to the role, <code>false</code> if access is denied
164: * @throws SecurityLoadException if case of erros while trying
165: * to load the roles
166: * @see #canAccess(String, String)
167: * @see #canAccess(int, String, String)
168: */
169: public static boolean canAccess(String roleName) {
170: return canAccess(roleName, null);
171: }
172:
173: public static boolean canAccess(int userId, String roleName) {
174: return canAccess(userId, roleName, null);
175: }
176:
177: /**
178: * Check if the logged user has access to the role.
179: * This method gets user's id from its session.
180: *
181: * @param roleName The role name to verify
182: * @param value The value relacted to the role to verify for access
183: * @return <code>true</code> if the user has access to the role, <code>false</code> if access is denied
184: */
185: public static boolean canAccess(String roleName, String value) {
186: UserSession us = SessionFacade.getUserSession();
187:
188: if (us == null) {
189: logger
190: .warn("Found null userSession. Going anonymous. Session id #"
191: + JForumExecutionContext.getRequest()
192: .getSessionContext().getId());
193: us = new UserSession();
194: us.makeAnonymous();
195: }
196:
197: return canAccess(us.getUserId(), roleName, value);
198: }
199:
200: public static boolean canAccess(int userId, String roleName,
201: String value) {
202: PermissionControl pc = SecurityRepository.get(userId);
203:
204: if (pc == null) {
205: throw new SecurityLoadException(
206: "Failed to load security roles for userId "
207: + userId
208: + " (null PermissionControl returned). "
209: + "roleName=" + roleName + ", roleValue="
210: + value);
211: }
212:
213: return (value != null ? pc.canAccess(roleName, value) : pc
214: .canAccess(roleName));
215: }
216:
217: /**
218: * Gets the permssion schema of some specific user.
219: * If the roles of the user aren't loaded yet, a call
220: * to {@link #load(int)} will be made.
221: *
222: * @param userId The user's id to get the permissions
223: * @return The <code>PermissionControl</code> instance related
224: * to the user id passed as argument
225: * @throws SecurityLoadException if case of erros while trying
226: * to load the roles
227: */
228: public static PermissionControl get(int userId) {
229: PermissionControl pc = (PermissionControl) cache.get(FQN,
230: Integer.toString(userId));
231:
232: if (pc == null) {
233: try {
234: pc = load(userId);
235: } catch (Exception e) {
236: throw new SecurityLoadException(e);
237: }
238: }
239:
240: return pc;
241: }
242:
243: /**
244: * Adds a new permission control schema to the cache
245: *
246: * @param userId The user's id to associate with the schema
247: * @param pc The <code>PermissionControl</code> instance to add
248: */
249: public static synchronized void add(int userId, PermissionControl pc) {
250: cache.add(FQN, Integer.toString(userId), pc);
251: }
252:
253: /**
254: * Remove the cached roles from a specific user.
255: *
256: * @param userId The id of the user to remove from the cache
257: */
258: public static synchronized void remove(int userId) {
259: cache.remove(FQN, Integer.toString(userId));
260: }
261:
262: /**
263: * Clear all cached security entries.
264: */
265: public static synchronized void clean() {
266: cache.remove(FQN);
267: }
268: }
|