Source code: com/RuntimeCollective/permission/bean/SimplePermissionRule.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/permission/bean/SimplePermissionRule.java,v 1.14 2003/09/30 15:12:49 joe Exp $
2 * $Revision: 1.14 $
3 * $Date: 2003/09/30 15:12:49 $
4 *
5 * ====================================================================
6 *
7 * Josephine : http://www.runtime-collective.com/josephine/index.html
8 *
9 * Copyright (C) 2003 Runtime Collective
10 *
11 * This product includes software developed by the
12 * Apache Software Foundation (http://www.apache.org/).
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30 package com.RuntimeCollective.permission.bean;
31
32 import com.RuntimeCollective.permission.PermissionException;
33 import com.RuntimeCollective.permission.bean.PermissionRule;
34 import com.RuntimeCollective.webapps.bean.LoginCookie;
35 import com.RuntimeCollective.webapps.bean.User;
36 import com.RuntimeCollective.webapps.RuntimeDataSource;
37 import com.RuntimeCollective.webapps.RuntimeParameters;
38 import com.RuntimeCollective.webapps.ReturnPathContainer;
39 import com.RuntimeCollective.webapps.HttpSessionReturnPathContainer;
40 import com.RuntimeCollective.webapps.bean.Session;
41
42 import java.net.MalformedURLException;
43 import java.net.URL;
44 import java.sql.SQLException;
45 import java.util.HashMap;
46 import javax.servlet.http.HttpSession;
47
48 /**
49 * A very simple implementation of PermissionRule.
50 * It only uses permission criteria from the Webapps module, that is, for now:<br>
51 * - whether the user has logged in
52 * <p>
53 * One can extend this class and adds a Role criterion when we have decided
54 * on how we're going to do that Role mechanism.
55 *
56 * @version $Id: SimplePermissionRule.java,v 1.14 2003/09/30 15:12:49 joe Exp $
57 */
58 public class SimplePermissionRule implements PermissionRule {
59
60 // ---Inherited from EntityBean---------------------------
61
62 /** The name of the database table for this bean type. */
63 public static final String DATABASE_TABLE = "permission_prule";
64
65 /** This object's id */
66 protected int id;
67
68 /** Set the unique id of this bean instance. */
69 public void setId(int id) {
70 this.id = id;
71 }
72
73 /** Get the unique id of this bean instance. */
74 public int getId() {
75 return this.id;
76 }
77
78 /** Save this bean to the database. */
79 public void save() {
80 try {
81 // write PermissionRule data
82 RuntimeDataSource.save(id, this.DATABASE_TABLE, new String[] { "pkey", "need_login" }, new Object[] { Key, new Boolean(NeedLogin) } );
83 } catch (SQLException e) {
84 throw new PermissionException("SimplePermissionRule "+id+" could not save() : "+e);
85 }
86 }
87
88 /** Delete this bean from the database. */
89 public void delete() {
90 try {
91 String[] updates = new String[] { "delete from "+this.DATABASE_TABLE+" where id = "+this.id };
92 RuntimeDataSource.update(updates);
93 } catch (SQLException e) {
94 throw new PermissionException("SimplePermissionRule "+id+" could not delete() : "+e);
95 }
96 }
97
98 /** Construct a new blank SimplePermissionRule, giving it a new unique ID. */
99 public SimplePermissionRule() {
100 try {
101 this.setId(RuntimeDataSource.nextId());
102 this.setNeedLogin(false);
103 this.setKey(null);
104 } catch (SQLException e) {
105 throw new PermissionException("SimplePermissionRule could not SimpleSiteLocationRule() : "+e);
106 }
107 }
108
109 /** Get a current SimplePermissionRule from the RuntimeDataSource, given an id.
110 * @param id ID of the SimplePermissionRule.
111 */
112 public SimplePermissionRule(int id) {
113 try {
114
115 // load the SimplePermissionRule data
116 int no_fields = 3;
117 Object[] result = RuntimeDataSource.queryRow("select t.id, t.pkey, t.need_login from "+this.DATABASE_TABLE+" t where t.id = "+id);
118 if (result.length != no_fields)
119 throw new PermissionException("SimplePermissionRule could not SimplePermissionRule("+id+"), : "+result.length+" fields found in "+DATABASE_TABLE+" instead of "+no_fields+".");
120 setId(Integer.parseInt(result[0].toString()));
121 if (result[1] != null)
122 setKey(result[1].toString());
123 else
124 setKey(null);
125 if (result[2] != null)
126 setNeedLogin(RuntimeDataSource.toboolean(result[2].toString()));
127 else
128 setNeedLogin(false);
129
130 } catch (SQLException e) {
131 throw new PermissionException("SimplePermissionRule could not SimplePermissionRule("+id+") : "+e);
132 }
133 }
134
135
136 //---PermissionRule specific methods---------------------
137
138 /** The Key identifier */
139 protected String Key;
140
141 /**
142 * Set the key, which will be an identifier of what kind of PermissionRule
143 * this one is. This is particularly intended for when a User has to choose
144 * one of many PermissionRule prototype in a checkbox list. Thanks to this key,
145 * we can later recognise which one he chose, and let him chose a different one.
146 * This can be kept to null if judged not necessary.
147 * @param key, a String representing the key
148 */
149 public void setKey(String key) {
150 Key = key;
151 }
152
153 /**
154 * Get the key, which will be an identifier of what kind of PermissionRule
155 * this one is.
156 * @return a String representing the key
157 */
158 public String getKey() {
159 return Key;
160 }
161
162 /**
163 * Checks whether a User is accepted by this PermissionRule.
164 * <p>
165 * Override this method in subclasses, to add further permission criteria.
166 *
167 * @param user, the user who would like to be authorised, may be null if not logged in
168 * @return a boolean, whether the user is accepted or not
169 */
170 public boolean accepts(User user) {
171 //return (getAuthorisationPath(user) == null);
172
173 // all we can ask for is the user to be logged on
174 if ((user == null) && (getNeedLogin())) {
175 return false;
176 } else {
177 // all fine
178 return true;
179 }
180 }
181
182 /**
183 * Get the path of the page where the user should be sent in order
184 * to (maybe) get authorised.
185 * <p>
186 * On submission of that page, the user should be checked again,
187 * as there may be more than one page to go to.
188 * <p>
189 * Override this method in subclasses, to redirect the user to more relevent
190 * places depending on why he was not accepted.
191 *
192 * @param user, the user who would like to be authorised
193 * @return a String, the local path to go to, or null if the user is accepted
194 */
195 protected String getAuthorisationPath(User user) {
196
197 // is the user accepted?
198 if (accepts(user)) {
199 return null;
200 } else {
201 return getPathToLogon();
202 }
203 }
204
205 /**
206 * Get the path of the page where the session should be sent in order
207 * to (maybe) get authorised. Also sets required attributes in the Session.<p>
208 * On submission of that page, the session should be checked again,
209 * as there may be more than one page to go to.
210 * <p>
211 * This method should not be overridden, override getAuthorisationPath(User) instead.
212 *
213 * @deprecated This method was modified not to refer to Client Tier classes (HttpSession). Use instead:
214 * <code>getAuthorisationPath((User) session.getAttribute(RuntimeParameters.get("logonUserKey")), (Session) session.getAttribute(Session.SESSION_KEY), new HttpSessionReturnPathContainer(session), returnPath)</code>
215 * @param session, the session who would like to be authorised
216 * @param returnPath, where the session should be sent back after going to that page
217 * @return a String, the local path to go to, or null if the session is accepted
218 */
219 public String getAuthorisationPath(HttpSession session, String returnPath) {
220
221 // is the session null
222 if (session == null)
223 throw new PermissionException("SimplePermissionRule cannot getAuthorisationPath for a null session.");
224
225 Object sessionUser = session.getAttribute(RuntimeParameters.get("logonUserKey"));
226 if (sessionUser != null) {
227 RuntimeParameters.getStore().get(User.class.getName(), ((User)sessionUser).getId());
228 }
229 return getAuthorisationPath((User) sessionUser, (Session) session.getAttribute(Session.SESSION_KEY), new HttpSessionReturnPathContainer(session), returnPath);
230 }
231
232 /**
233 * Get the path of the page where a User should be sent in order
234 * to (maybe) get authorised.
235 * <p>
236 * On submission of that resulting page, the user should be checked again,
237 * as there may be more than one page to go to before he/she is authorised.
238 * <p>
239 * The session parameter is only checked/verified (not null, not timed out, correct user) if the <b>permissionRuleChecksSession</b> parameter is set to <b>true</b> in web.xml, for backwards compatibility.
240 *
241 * @param user, the user, possibly null if the user hasn't been identified
242 * @param session, the general purpose webapps session that the user is using ATM, possibly null
243 * @param rpContainer, something on which to put the return path, if necessaru
244 * @param returnPath, where the user should be sent back after going to that page
245 * @return a String, the local path to go to, or null if the session is accepted
246 */
247 public String getAuthorisationPath(User user, Session session, ReturnPathContainer rpContainer, String returnPath) {
248
249 String path = null;
250
251 // check the session, if required
252 boolean mustTestSession = false;
253 try {
254 if ("true".equals(RuntimeParameters.get("permissionRuleChecksSession")))
255 mustTestSession = true;
256 } catch (Exception e) {
257 }
258
259 if (mustTestSession) {
260 RuntimeParameters.logInfo(this, "Checking the webapps session.");
261
262 if (session == null) {
263 // no session at all
264 path = getPathToLogon();
265
266 } else if (session.hasTimedOut()) {
267 // session has timed out
268 path = RuntimeParameters.get(Session.TIMEOUT_PAGE_KEY);
269
270 } else if (session.getTheUser() == null) {
271 // session has no user
272 path = getPathToLogon();
273
274 } else if ((user == null) || (session.getTheUser().getId() != user.getId())) {
275 // no user, or wrong one
276 path = getPathToLogon();
277 }
278 }
279
280 // if everything is fine so far, check as normal
281 if (path == null)
282 path = getAuthorisationPath(user);
283
284 // set the returnUrl if necessary
285 if (path != null) {
286 RuntimeParameters.logInfo(this, "Setting return path to : "+returnPath);
287 setReturnUrl(rpContainer, returnPath);
288 }
289
290 return path;
291 }
292
293
294 //---SimplePermissionRule specific methods---------------------
295
296 /** Whether the User has to be logged in */
297 protected boolean NeedLogin;
298
299 /**
300 * Set whether the User has to be logged in
301 * @param needLogin, a boolean representing the needLogin
302 */
303 public void setNeedLogin(boolean needLogin) {
304 NeedLogin = needLogin;
305 }
306
307 /**
308 * Get whether the User has to be logged in
309 * @return a boolean representing the needLogin
310 */
311 public boolean getNeedLogin() {
312 return NeedLogin;
313 }
314
315 /**
316 * Get the path to the logon page.
317 * @return a String, the path to go to to log on
318 */
319 protected static String getPathToLogon() {
320 return RuntimeParameters.get("logonPath");
321 }
322
323 /**
324 * Get the path to the logon-again page.
325 * @return a String, the path to go to to re-log on
326 */
327 protected static String getPathToRelogon() {
328 return RuntimeParameters.get("relogonPath");
329 }
330
331 /**
332 * Set the return url in the session.
333 *
334 * @deprecated This method was modified not to refer to Client Tier classes (HttpSession). Use instead:
335 * <code>setReturnUrl((ReturnPathContainer) new HttpSessionReturnPathContainer(session), returnPath)</code>
336 * @param returnPath, where to go after logging in again
337 * @return a String, the path to go to to re-log in
338 */
339 protected static void setReturnUrl(HttpSession session, String returnPath) {
340 setReturnUrl((ReturnPathContainer) new HttpSessionReturnPathContainer(session), returnPath);
341 }
342
343 /**
344 * Set the return url in the session.
345 * @param returnPath, where to go after logging in again
346 * @return a String, the path to go to to re-log in
347 */
348 protected static void setReturnUrl(ReturnPathContainer rpContainer, String returnPath) {
349
350 // let's be a bit careful and ensure right now that the return url is a correct url
351 try {
352 new URL((new StringBuffer(70)).append("http://").append(RuntimeParameters.get("pageRoot")).append(returnPath).toString());
353 } catch (MalformedURLException e) {
354 throw new PermissionException("SimplePermissionRule cannot setReturnUrl(session, "+returnPath+") : "+e);
355 }
356
357 // set the return url
358 rpContainer.setReturnPath(returnPath);
359 }
360 }
361
362
363
364