KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > acting > DatabaseCookieAuthenticatorAction


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
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 package org.apache.cocoon.acting;
17
18 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
19 import org.apache.avalon.framework.configuration.Configuration;
20 import org.apache.avalon.framework.parameters.Parameters;
21 import org.apache.avalon.framework.thread.ThreadSafe;
22 import org.apache.cocoon.Constants;
23 import org.apache.cocoon.environment.Cookie;
24 import org.apache.cocoon.environment.ObjectModelHelper;
25 import org.apache.cocoon.environment.Redirector;
26 import org.apache.cocoon.environment.Request;
27 import org.apache.cocoon.environment.Session;
28 import org.apache.cocoon.environment.SourceResolver;
29 import org.apache.commons.lang.BooleanUtils;
30 import org.apache.commons.lang.StringUtils;
31
32 import java.sql.Connection JavaDoc;
33 import java.sql.ResultSet JavaDoc;
34 import java.sql.Statement JavaDoc;
35 import java.util.Collections JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.Map JavaDoc;
38
39 /**
40  * This action is used to authenticate user by comparing several cookie values
41  * (username, password) with the values in database. The description of the
42  * process is given via external xml description file simiar to the one used
43  * for all actions derived from AbstractDatabaseAction. <pre>
44  * &lt;root&gt;
45  * &lt;connection&gt;personnel&lt;/connection&gt;
46  * &lt;table name="users_table&gt;
47  * &lt;select dbcol="username" cookie-name="username"
48  * to-session="username"/&gt;
49  * &lt;select dbcol="password" cookie-name="password"
50  * nullable="yes"/&gt;
51  * &lt;select dbcol="role" to-session="role" type="string"/&gt;
52  * &lt;select dbcol="skin" to-session="skin" type="string"/&gt;
53  * &lt;/table&gt;
54  * &lt;/root&gt;
55  * </pre> The values specified via "cookie-name" describe the name of the
56  * cookie, "dbcol" indicates matching database column, "nullable" means that
57  * cookie-name which is null or empty will not be included in the WHERE clause.
58  * This way you can enable accounts with empty passwords, etc. "to-session"
59  * attribute indicates under which name the value obtained from database should
60  * be stored in the session. Of course new session is created when
61  * authorization is successfull. The "type" attribute can be either string,
62  * long or double and alters the type of object stored in session. Additionally
63  * all parameters that are propagated to the session are made available to the
64  * sitemap via {name} expression. If there is no need to touch the session
65  * object, providing just one-time verification, you can specify action
66  * parameter "create-session" to "no" or "false". No values are then propagated
67  * to the sesion and session object is not verified. If you want to append
68  * attributes to the session without creating a new one, specify action
69  * parameter "append-session" to "yes" or "true".
70  *
71  * @author <a HREF="mailto:paolo@arsenio.net">Paolo Scaffardi</a>
72  * @version CVS $Id: DatabaseCookieAuthenticatorAction.java 312661 2005-10-10 14:58:44Z sylvain $
73  */

74 public class DatabaseCookieAuthenticatorAction extends AbstractDatabaseAction implements ThreadSafe {
75
76     /**
77      * Main invocation routine.
78      *
79      * @param redirector Description of Parameter
80      * @param resolver Description of Parameter
81      * @param objectModel Description of Parameter
82      * @param src Description of Parameter
83      * @param parameters Description of Parameter
84      * @return Description of the Returned Value
85      * @exception Exception Description of Exception
86      */

87     public Map JavaDoc act(Redirector redirector, SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src,
88             Parameters parameters)
89         throws Exception JavaDoc {
90         DataSourceComponent datasource = null;
91         Connection JavaDoc conn = null;
92         Statement JavaDoc st = null;
93         ResultSet JavaDoc rs = null;
94
95         // read global parameter settings
96
boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT;
97
98         if (this.settings.containsKey("reloadable")) {
99             reloadable = Boolean.valueOf((String JavaDoc) this.settings.get("reloadable")).booleanValue();
100         }
101
102         // read local settings
103
try {
104             Configuration conf = this.getConfiguration(
105                     parameters.getParameter("descriptor", (String JavaDoc) this.settings.get("descriptor")),
106                     resolver,
107                     parameters.getParameterAsBoolean("reloadable", reloadable));
108             String JavaDoc create_session = parameters.getParameter("create-session",
109                     (String JavaDoc)this.settings.get("create-session"));
110             String JavaDoc append_session = parameters.getParameter("append-session",
111                     (String JavaDoc)this.settings.get("append-session"));
112             boolean cs = true;
113             if (create_session != null) {
114                 cs = BooleanUtils.toBoolean(create_session.trim());
115             }
116             boolean as = BooleanUtils.toBoolean(append_session.trim());
117
118             datasource = this.getDataSource(conf);
119             conn = datasource.getConnection();
120             Request req = ObjectModelHelper.getRequest(objectModel);
121
122             /*
123              * check request validity
124              */

125             if (req == null) {
126                 if (getLogger().isDebugEnabled()) {
127                     getLogger().debug("DBCOOKIEAUTH: no request object");
128                 }
129                 return null;
130             }
131
132             String JavaDoc query = this.getAuthQuery(objectModel, conf, req);
133             if (query == null) {
134                 if (getLogger().isDebugEnabled()) {
135                     getLogger().debug("DBCOOKIEAUTH: have not got query");
136                 }
137                 req.setAttribute("message", "The authenticator is misconfigured");
138                 return null;
139             }
140
141             if (getLogger().isDebugEnabled()) {
142                 getLogger().debug("DBCOOKIEAUTH: query is: " + query);
143             }
144             st = conn.createStatement();
145             rs = st.executeQuery(query);
146
147             if (rs.next()) {
148                 if (getLogger().isDebugEnabled()) {
149                     getLogger().debug("DBCOOKIEAUTH: authorized successfully");
150                 }
151                 Session session = null;
152
153                 if (cs) {
154                     session = req.getSession(false);
155                     if (session != null) {
156                         if (as == false) {
157                             session.invalidate();
158                             session = req.getSession(true);
159                             if (getLogger().isDebugEnabled()) {
160                                 getLogger().debug("DBCOOKIEAUTH: session invalidated");
161                             }
162                         }
163                     } else {
164                         session = req.getSession(true);
165                     }
166
167                     if (session == null) {
168                         return null;
169                     }
170
171                     if (getLogger().isDebugEnabled()) {
172                         if (as) {
173                             getLogger().debug("DBCOOKIEAUTH: appending to session");
174                         } else {
175                             getLogger().debug("DBCOOKIEAUTH: session created");
176                         }
177                     }
178                 } else {
179                     if (getLogger().isDebugEnabled()) {
180                         getLogger().debug("DBCOOKIEAUTH: leaving session untouched");
181                     }
182                 }
183
184                 HashMap JavaDoc actionMap = this.propagateParameters(conf, rs, session);
185                 if (!conn.getAutoCommit()) {
186                     conn.commit();
187                 }
188                 return Collections.unmodifiableMap(actionMap);
189             }
190             if (!conn.getAutoCommit()) {
191                 conn.rollback();
192             }
193
194             req.setAttribute("message", "The username or password were incorrect, please check your CAPS LOCK key and try again.");
195             if (getLogger().isDebugEnabled()) {
196                 getLogger().debug("DBCOOKIEAUTH: no results for query");
197             }
198         } catch (Exception JavaDoc e) {
199             if (conn != null) {
200                 try {
201                     if (!conn.getAutoCommit()) {
202                         conn.rollback();
203                     }
204                 } catch (Exception JavaDoc se) {
205                     // ignore
206
}
207             }
208             getLogger().error("Exception: ", e);
209             return null;
210         } finally {
211             if (rs != null) {
212                 rs.close();
213             }
214             if (st != null) {
215                 st.close();
216             }
217             if (conn != null) {
218                 try {
219                     conn.close();
220                 } catch (Exception JavaDoc e) {
221                     // ignore
222
}
223             }
224         }
225         return null;
226     }
227
228     /**
229      * Gets the authQuery attribute of the DatabaseCookieAuthenticatorAction
230      * object
231      *
232      * @param objectModel Description of Parameter
233      * @param conf Description of Parameter
234      * @param req Description of Parameter
235      * @return The authQuery value
236      */

237     private String JavaDoc getAuthQuery(Map JavaDoc objectModel, Configuration conf, Request req) {
238         boolean first_constraint = true;
239         StringBuffer JavaDoc queryBuffer = new StringBuffer JavaDoc("SELECT ");
240         StringBuffer JavaDoc queryBufferEnd = new StringBuffer JavaDoc("");
241         String JavaDoc dbcol;
242         String JavaDoc cookie_name;
243         String JavaDoc cookie_value;
244         String JavaDoc nullstr;
245         boolean nullable = false;
246         Configuration table = conf.getChild("table");
247         Configuration[] select = table.getChildren("select");
248         try {
249             for (int i = 0; i < select.length; i++) {
250                 if (i != 0) {
251                     queryBuffer.append(", ");
252                 }
253                 dbcol = select[i].getAttribute("dbcol");
254                 queryBuffer.append(dbcol);
255                 cookie_name = select[i].getAttribute("cookie-name", "");
256                 if (StringUtils.isEmpty(cookie_name.trim())) {
257                     continue;
258                 }
259                 nullstr = select[i].getAttribute("nullable", "");
260                 if (BooleanUtils.toBoolean(nullstr.trim())) {
261                     nullable = true;
262                 }
263                 /*
264                  * if there is a cookie name,
265                  * but not the value, we exit immediately do
266                  * that authorization fails authomatically
267                  */

268                 cookie_value = getCookie(objectModel, cookie_name).getValue();
269
270                 if (cookie_value == null || cookie_value.trim().equals("")) {
271                     // value is null
272
if (!nullable) {
273                         if (getLogger().isDebugEnabled()) {
274                             getLogger().debug("DBCOOKIEAUTH: cookie-name "
275                                         + cookie_name + " does not exist");
276                         }
277                         return null;
278                     }
279                 } else {
280                     if (!first_constraint) {
281                         queryBufferEnd.append(" AND ");
282                     }
283                     queryBufferEnd.append(dbcol + "='" + cookie_value + "'");
284                     first_constraint = false;
285                 }
286             }
287             queryBuffer.append(" FROM ");
288             queryBuffer.append(table.getAttribute("name"));
289             if (!queryBufferEnd.toString().trim().equals("")) {
290                 queryBuffer.append(" WHERE ").append(queryBufferEnd);
291             }
292             return queryBuffer.toString();
293         } catch (Exception JavaDoc e) {
294             getLogger().error("Exception: ",e);
295             return null;
296         }
297     }
298
299     public static Cookie getCookie(Map JavaDoc objectModel, String JavaDoc cookieName) {
300         
301         Request request = ObjectModelHelper.getRequest(objectModel);
302         
303         Cookie[] cookies = request.getCookies();
304         if (cookies != null) {
305             for(int count = 0; count < cookies.length; count++) {
306                 Cookie currentCookie = cookies[count];
307                 if (currentCookie.getName().equals(cookieName)) {
308                     return currentCookie;
309                 }
310             }
311         }
312         
313         return null;
314     }
315
316     /**
317      * Description of the Method
318      *
319      * @param conf Description of Parameter
320      * @param rs Description of Parameter
321      * @param session Description of Parameter
322      * @return Description of the Returned Value
323      */

324     private HashMap JavaDoc propagateParameters(Configuration conf, ResultSet JavaDoc rs,
325             Session session) {
326         Configuration table = conf.getChild("table");
327         Configuration[] select = table.getChildren("select");
328         String JavaDoc session_param;
329         HashMap JavaDoc map = new HashMap JavaDoc();
330         try {
331             for (int i = 0; i < select.length; i++) {
332                 try {
333                     session_param = select[i].getAttribute("to-session");
334                     if (session_param != null &&
335                             !session_param.trim().equals("")) {
336                         String JavaDoc s = rs.getString(i + 1);
337                         /*
338                          * propagate to session
339                          */

340                         Object JavaDoc o = null;
341                         String JavaDoc type = select[i].getAttribute("type", "");
342                         // "string" is the default type
343
if (StringUtils.isEmpty(type.trim()) || "string".equals(type)) {
344                             o = s;
345                         } else if ("long".equals(type)) {
346                             Long JavaDoc l = Long.decode(s);
347                             o = l;
348                         } else if ("double".equals(type)) {
349                             Double JavaDoc d = Double.valueOf(s);
350                             o = d;
351                         }
352                         if (session != null) {
353                             session.setAttribute(session_param, o);
354                             if (getLogger().isDebugEnabled()) {
355                                 getLogger().debug("DBCOOKIEAUTH: propagating param "
356                                             + session_param + "=" + s);
357                             }
358                         }
359                         map.put(session_param, o);
360                     }
361                 } catch (Exception JavaDoc e) {
362                     // ignore
363
}
364             }
365             return map;
366         } catch (Exception JavaDoc e) {
367             getLogger().error("Exception: ", e);
368         }
369         return null;
370     }
371 }
372
Popular Tags