KickJava   Java API By Example, From Geeks To Geeks.

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


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.framework.configuration.Configuration;
19 import org.apache.avalon.framework.parameters.Parameters;
20 import org.apache.avalon.framework.thread.ThreadSafe;
21
22 import org.apache.cocoon.Constants;
23 import org.apache.cocoon.environment.ObjectModelHelper;
24 import org.apache.cocoon.environment.Redirector;
25 import org.apache.cocoon.environment.Request;
26 import org.apache.cocoon.environment.Session;
27 import org.apache.cocoon.environment.SourceResolver;
28 import org.apache.commons.lang.BooleanUtils;
29
30 import org.apache.xpath.XPathAPI;
31 import org.apache.xpath.objects.XObject;
32 import org.w3c.dom.Node JavaDoc;
33 import org.xmldb.api.DatabaseManager;
34 import org.xmldb.api.base.Collection;
35 import org.xmldb.api.base.Database;
36 import org.xmldb.api.base.ResourceIterator;
37 import org.xmldb.api.base.ResourceSet;
38 import org.xmldb.api.base.XMLDBException;
39 import org.xmldb.api.modules.XMLResource;
40 import org.xmldb.api.modules.XPathQueryService;
41
42 import java.util.Collections JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.Map JavaDoc;
45
46 /**
47  * This action is used to authenticate user by comparing several request
48  * fields (username, password) with the values in a DBXML compliant database.
49  * The description of the process is given via external xml description file
50  * simiar to the one used for all actions derived from AbstractDatabaseAction.
51  *
52  * <pre>
53  * <root>
54  * <connection>
55  * <driver>org.apache.xindice.client.xmldb.DatabaseImpl</driver>
56  * <base>xmldb:xindice:///db/beta</base>
57  * </connection>
58  *
59  * <root name="users">
60  * <select element="username" request-param="username" to-session="username"/>
61  * <select element="password" request-param="password" nullable="yes"/>
62  *
63  * <select element="role" to-session="role" type="string"/>
64  * <select element="skin" to-session="skin" type="string"/>
65  * </root>
66  * </root>
67  * </pre>
68  *
69  * The values specified via "request-param" describe the name of HTTP request
70  * parameter, "element" indicates matching document node, "nullable" means
71  * that request-param which is null or empty will not be included in the WHERE
72  * clause. This way you can enable accounts with empty passwords, etc.
73  * "to-session" attribute indicates under which name the value obtained from
74  * database should be stored in the session. Of course new session is created
75  * when authorization is successfull. The "type" attribute can be either
76  * string, long or double and alters the type of object stored in session.
77  * Additionally all parameters that are
78  * propagated to the session are made available to the sitemap via {name}
79  * expression.
80  *
81  * If there is no need to touch the session object, providing just one-time
82  * verification, you can specify action parameter "create-session" to "no" or
83  * "false". No values are then propagated to the sesion and session object is
84  * not verified.
85  *
86  * @author <a HREF="mailto:czoffoli@littlepenguin.org">Christian Zoffoli</a>
87  * @author <a HREF="mailto:Martin.Man@seznam.cz">Martin Man</a>
88  * @since 2002/02/03
89  * @version CVS $Id: DbXMLAuthenticatorAction.java 124717 2005-01-09 07:37:36Z antonio $
90  *
91  * based on DatabaseAuthenticatorAction created by Martin Man <Martin.Man@seznam.cz>
92  */

93 public class DbXMLAuthenticatorAction extends AbstractDatabaseAction implements ThreadSafe
94 {
95
96   /**
97   * Main invocation routine.
98   */

99   public Map JavaDoc act (Redirector redirector, SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src,
100         Parameters parameters) throws Exception JavaDoc {
101
102     ResourceSet rs = null;
103
104     // read global parameter settings
105
boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT;
106
107     if (this.settings.containsKey("reloadable")) {
108         reloadable = Boolean.valueOf((String JavaDoc) this.settings.get("reloadable")).booleanValue();
109     }
110
111     // read local settings
112
try {
113         Configuration conf = this.getConfiguration (
114           parameters.getParameter ("descriptor", (String JavaDoc) this.settings.get("descriptor")),
115           resolver,
116           parameters.getParameterAsBoolean("reloadable",
117           reloadable));
118
119
120         boolean cs = true;
121         String JavaDoc create_session = parameters.getParameter ("create-session", (String JavaDoc) this.settings.get("create-session"));
122
123         if (create_session != null && ("no".equals (create_session.trim ()) || "false".equals (create_session.trim ()))) {
124           cs = false;
125         }
126
127         Request req = ObjectModelHelper.getRequest(objectModel);
128
129         /* check request validity */
130         if (req == null) {
131           getLogger ().debug ("DBXMLAUTH: no request object");
132           return null;
133         }
134
135         rs = this.Authenticate( conf, req );
136
137         if (rs != null )
138         {
139           getLogger ().debug ("DBXMLAUTH: authorized successfully");
140           Session session = null;
141
142           if (cs) {
143             session = req.getSession (false);
144             if (session != null)
145                 session.invalidate ();
146             session = req.getSession (true);
147             if (session == null)
148                 return null;
149             getLogger ().debug ("DBXMLAUTH: session created");
150           } else {
151             getLogger ().debug ("DBXMLAUTH: leaving session untouched");
152           }
153
154           HashMap JavaDoc actionMap = this.propagateParameters (conf, rs, session);
155           return Collections.unmodifiableMap (actionMap);
156         } else {
157           //getLogger ().debug ("DBXMLAUTH: error ResourceSet is null");
158
}
159
160         req.setAttribute("message", "The username or password were incorrect, please check your CAPS LOCK key and try again.");
161         getLogger ().debug ("DBXMLAUTH: no results for query");
162
163     } catch (Exception JavaDoc e) {
164
165         getLogger().debug ("exception: ", e);
166         return null;
167     }
168
169     return null;
170   }
171
172
173   private String JavaDoc getAuthQuery ( Configuration conf, Request req )
174   {
175
176     StringBuffer JavaDoc queryBuffer = new StringBuffer JavaDoc ("//");
177     StringBuffer JavaDoc queryBufferEnd = new StringBuffer JavaDoc ("");
178
179     String JavaDoc dbcol, request_param, request_value, nullstr;
180     boolean nullable = false;
181
182     Configuration table = conf.getChild ("root");
183     Configuration[] select = table.getChildren ("select");
184
185     try {
186
187         queryBuffer.append (table.getAttribute ("name"));
188
189         for (int i = 0; i < select.length; i ++)
190         {
191
192           dbcol = "[" + select[i].getAttribute ("element");
193
194           try {
195             request_param = select[i].getAttribute ("request-param");
196             if (request_param == null ||
197                   request_param.trim().equals ("")) {
198                 continue;
199             }
200           } catch (Exception JavaDoc e) {
201             continue;
202           }
203
204           try {
205             nullstr = select[i].getAttribute ("nullable");
206
207             if (nullstr != null) nullstr = nullstr.trim ();
208
209             if (BooleanUtils.toBoolean(nullstr)) {
210                 nullable = true;
211             }
212
213           } catch (Exception JavaDoc e1) {
214           }
215
216           /* if there is a request parameter name,
217           * but not the value, we exit immediately do
218           * that authorization fails authomatically */

219           request_value = req.getParameter (request_param);
220
221           if (request_value == null || request_value.trim().equals ("")) {
222             // value is null
223
if (!nullable) {
224                 getLogger ().debug ("DBXMLAUTH: request-param " + request_param + " does not exist");
225                 return null;
226             }
227           } else {
228             queryBufferEnd.append (dbcol).append("='").append(request_value).append("']");
229           }
230         }
231
232         if (!queryBufferEnd.toString ().trim ().equals (""))
233           queryBuffer.append (queryBufferEnd);
234
235         return queryBuffer.toString ();
236     } catch (Exception JavaDoc e) {
237         getLogger ().debug ("DBXMLAUTH: got exception: " + e);
238         return null;
239     }
240   }
241
242
243   private ResourceSet Authenticate( Configuration conf, Request req) throws Exception JavaDoc, XMLDBException {
244
245      ResourceSet rs = null;
246
247     String JavaDoc query = this.getAuthQuery (conf, req);
248     if (query == null) {
249       getLogger ().debug ("DBXMLAUTH: have not got query");
250       req.setAttribute("message", "The authenticator is misconfigured");
251       return null;
252     }
253     getLogger ().debug ("DBXMLAUTH: query is: " + query);
254
255
256     Collection col = CreateConnection(conf);
257
258     if (col != null) {
259       if (col.isOpen()) {
260         try {
261           XPathQueryService service = (XPathQueryService) col.getService("XPathQueryService", "1.0");
262
263           rs = service.query(query);
264           ResourceIterator results = rs.getIterator();
265
266           if (results.hasMoreResources() == false) {
267               getLogger ().debug ("DBXMLAUTH: auth failed");
268               return null;
269           } else {
270             getLogger ().debug ("DBXMLAUTH: auth OK");
271             return rs;
272           }
273         } catch (XMLDBException e) {
274           getLogger ().debug ("DBXMLAUTH: got exception: " + e);
275           return null;
276         } finally {
277           // close col
278
try {
279             col.close();
280           } catch (Exception JavaDoc e) { /* ignore */ }
281           getLogger ().debug ("DBXMLAUTH: collection closed");
282
283         }
284
285       } else {
286         getLogger ().debug ("DBXMLAUTH: error: collection closed !!");
287       }
288
289     } else {
290       getLogger ().debug ("DBXMLAUTH: couldn't open a connection with DB");
291
292     }
293
294     return null;
295   }
296
297
298   private Collection CreateConnection( Configuration conf ) throws Exception JavaDoc, XMLDBException {
299
300     Collection col = null;
301
302     Configuration conn = conf.getChild ("connection");
303
304     try {
305
306       Class JavaDoc c = Class.forName( conn.getChild("driver").getValue() );
307
308       Database database = (Database) c.newInstance();
309       DatabaseManager.registerDatabase(database);
310
311       col = DatabaseManager.getCollection( conn.getChild("base").getValue() );
312
313     } catch (XMLDBException e) {
314       getLogger ().debug ("DBXMLAUTH: Exception occured " + e.errorCode);
315     }
316
317     return col;
318   }
319
320   private HashMap JavaDoc propagateParameters (Configuration conf, ResourceSet resultSet, Session session) {
321
322       Configuration table = conf.getChild ("root");
323       Configuration[] select = table.getChildren ("select");
324       String JavaDoc session_param, type;
325       HashMap JavaDoc map = new HashMap JavaDoc();
326
327       XObject xo;
328       Node JavaDoc originalnode = null;
329
330       try {
331
332         ResourceIterator results = resultSet.getIterator();
333
334         // Create an XObject to be used in Xpath query
335
xo = new XObject();
336
337         // Retrieve the next node
338
XMLResource resource = (XMLResource) results.nextResource();
339
340         originalnode = resource.getContentAsDOM();
341
342       }
343       catch (Exception JavaDoc e) {
344         getLogger ().debug ("DBXMLAUTH: error creating XObject ");
345       }
346
347
348       try {
349           for (int i = 0; i < select.length; i ++) {
350             try {
351               session_param = select[i].getAttribute ("to-session");
352               if (session_param != null && !session_param.trim().equals (""))
353               {
354
355                   String JavaDoc s = "";
356
357                   try {
358                     // Use Xalan xpath parser to extract data
359
xo = XPathAPI.eval(originalnode, "/" + table.getAttribute ("name") + "/" + select[i].getAttribute ("element") );
360                     s = xo.toString();
361                   }
362                   catch (Exception JavaDoc e) {
363                   }
364
365                   /* propagate to session */
366                   try {
367                     type = select[i].getAttribute ("type");
368                   } catch (Exception JavaDoc e) {
369                     type = null;
370                   }
371
372                   if (type == null || "".equals (type.trim ())) {
373                     type = "string";
374                   }
375                   Object JavaDoc o = null;
376
377                   if ("string".equals (type)) {
378                     o = s;
379                   } else if ("long".equals (type)) {
380                     Long JavaDoc l = Long.decode (s);
381                     o = l;
382                   } else if ("double".equals (type)) {
383                     Double JavaDoc d = Double.valueOf (s);
384                     o = d;
385                   }
386
387                   if (session != null) {
388                     session.setAttribute (session_param, o);
389                     getLogger ().debug ("DBXMLAUTH: propagating param " + session_param + "=" + s);
390                   }
391                   map.put (session_param, o);
392               }
393             } catch (Exception JavaDoc e) {
394             }
395           }
396           return map;
397       } catch (Exception JavaDoc e) {
398           getLogger().debug("exception: ", e);
399       }
400       return null;
401     }
402 }
403
Popular Tags