KickJava   Java API By Example, From Geeks To Geeks.

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


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.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 import org.apache.commons.lang.StringUtils;
30
31 import java.sql.Connection JavaDoc;
32 import java.sql.ResultSet JavaDoc;
33 import java.sql.PreparedStatement JavaDoc;
34 import java.util.Collections JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Map JavaDoc;
37
38 /**
39  * This action is used to authenticate user by comparing several request
40  * fields (username, password) with the values in database. The description of
41  * the process is given via external xml description file simiar to the one
42  * used for all actions derived from AbstractDatabaseAction.
43  * <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" request-param="username"
48  * to-session="username"/&gt;
49  * &lt;select dbcol="password" request-param="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>
56  * The values specified via "request-param" describe the name of HTTP request
57  * parameter, "dbcol" indicates matching database column, "nullable" means
58  * that request-param which is null or empty will not be included in the WHERE
59  * clause. This way you can enable accounts with empty passwords, etc.
60  * "to-session" attribute indicates under which name the value obtained from
61  * database should be stored in the session. Of course new session is created
62  * when authorization is successfull. The "type" attribute can be either
63  * string, long or double and alters the type of object stored in session.
64  * Additionally all parameters that are
65  * propagated to the session are made available to the sitemap via {name}
66  * expression.
67  *
68  * If there is no need to touch the session object, providing just one-time
69  * verification, you can specify action parameter "create-session" to "no" or
70  * "false". No values are then propagated to the sesion and session object is
71  * not verified.
72  *
73  * @author <a HREF="mailto:Martin.Man@seznam.cz">Martin Man</a>
74  * @version CVS $Id: DatabaseAuthenticatorAction.java 30932 2004-07-29 17:35:38Z vgritsenko $
75  */

76 public class DatabaseAuthenticatorAction extends AbstractDatabaseAction implements ThreadSafe
77 {
78     /**
79      * Main invocation routine.
80      */

81     public Map JavaDoc act (Redirector redirector, SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src,
82             Parameters parameters) throws Exception JavaDoc {
83         DataSourceComponent datasource = null;
84         Connection JavaDoc conn = null;
85         PreparedStatement JavaDoc st = null;
86         ResultSet JavaDoc rs = null;
87
88         // read global parameter settings
89
boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT;
90
91         if (this.settings.containsKey("reloadable")) {
92             reloadable = Boolean.valueOf((String JavaDoc) this.settings.get("reloadable")).booleanValue();
93         }
94
95         // read local settings
96
try {
97             Configuration conf = this.getConfiguration (
98                     parameters.getParameter ("descriptor", (String JavaDoc) this.settings.get("descriptor")),
99             resolver,
100             parameters.getParameterAsBoolean("reloadable",reloadable));
101             boolean cs = true;
102             String JavaDoc create_session = parameters.getParameter ("create-session",
103                                  (String JavaDoc) this.settings.get("create-session"));
104             if (create_session != null) {
105                 cs = BooleanUtils.toBoolean(create_session.trim());
106              }
107
108             datasource = this.getDataSource(conf);
109             conn = datasource.getConnection();
110             Request req = ObjectModelHelper.getRequest(objectModel);
111
112             /* check request validity */
113             if (req == null) {
114                 getLogger ().debug ("DBAUTH: no request object");
115                 return null;
116             }
117
118             st = this.getAuthQuery (conn, conf, req);
119             if (st == null) {
120                 getLogger ().debug ("DBAUTH: have not got query");
121                 req.setAttribute("message", "The authenticator is misconfigured");
122                 return null;
123             }
124
125             rs = st.executeQuery ();
126
127             if (rs.next ()) {
128                 getLogger ().debug ("DBAUTH: authorized successfully");
129                 Session session = null;
130
131                 if (cs) {
132                     session = req.getSession (false);
133                     if (session != null)
134                         session.invalidate ();
135                     session = req.getSession (true);
136                     if (session == null)
137                         return null;
138                     getLogger ().debug ("DBAUTH: session created");
139                 } else {
140                     getLogger ().debug ("DBAUTH: leaving session untouched");
141                 }
142
143                 HashMap JavaDoc actionMap = this.propagateParameters (conf, rs,
144                         session);
145                 if(!conn.getAutoCommit()) {
146                     conn.commit();
147                 }
148                 return Collections.unmodifiableMap (actionMap);
149             }
150             if(!conn.getAutoCommit()) {
151                 conn.rollback();
152             }
153
154             req.setAttribute("message", "The username or password were incorrect, please check your CAPS LOCK key and try again.");
155             getLogger ().debug ("DBAUTH: no results for query");
156         } catch (Exception JavaDoc e) {
157             if (conn != null) {
158                 try {
159                     if(!conn.getAutoCommit()) {
160                         conn.rollback();
161                     }
162                 } catch (Exception JavaDoc se) {/* ignore */}
163             }
164             getLogger().debug ("exception: ", e);
165             return null;
166         } finally {
167             if (rs != null) rs.close();
168             if (st != null) st.close();
169             if (conn != null) {
170                 try {
171                     conn.close();
172                 } catch (Exception JavaDoc e) {/* ignore */}
173             }
174         }
175         return null;
176     }
177
178     private PreparedStatement JavaDoc getAuthQuery(Connection JavaDoc conn, Configuration conf, Request req) {
179         StringBuffer JavaDoc queryBuffer = new StringBuffer JavaDoc("SELECT ");
180         StringBuffer JavaDoc queryBufferEnd = new StringBuffer JavaDoc("");
181         Configuration table = conf.getChild("table");
182         Configuration[] columns = table.getChildren("select");
183         try {
184             Object JavaDoc[] constraintValues = new Object JavaDoc[columns.length];
185             int constraints = 0;
186             for (int i = 0; i < columns.length; i++) {
187                 String JavaDoc dbcol = columns[i].getAttribute("dbcol");
188                 boolean nullable = false;
189                 if (i > 0) {
190                     queryBuffer.append (", ");
191                 }
192                 queryBuffer.append(dbcol);
193
194                 String JavaDoc requestParameter = columns[i].getAttribute("request-param", null);
195                 if (StringUtils.isNotBlank(requestParameter)) {
196                     String JavaDoc nullstr = columns[i].getAttribute("nullable", null);
197                     if (nullstr != null) {
198                         nullable = BooleanUtils.toBoolean(nullstr.trim());
199                     }
200                     String JavaDoc constraintValue = req.getParameter(requestParameter);
201
202                     // if there is a request parameter name,
203
// but not the value, we exit immediately do
204
// that authorization fails authomatically
205
if (StringUtils.isBlank(constraintValue) && !nullable) {
206                         getLogger().debug("DBAUTH: request-param " + requestParameter + " does not exist");
207                         return null;
208                     }
209                     if (constraints > 0) {
210                         queryBufferEnd.append(" AND ");
211                     }
212                     queryBufferEnd.append(dbcol).append("= ?");
213                     constraintValues[constraints++] = constraintValue;
214                 }
215             }
216
217             queryBuffer.append(" FROM ");
218             queryBuffer.append(table.getAttribute("name"));
219             if (StringUtils.isNotBlank(queryBufferEnd.toString())) {
220                 queryBuffer.append(" WHERE ").append(queryBufferEnd);
221             }
222
223             getLogger().debug("DBAUTH: query " + queryBuffer);
224
225             PreparedStatement JavaDoc st = conn.prepareStatement(queryBuffer.toString());
226
227             for (int i = 0; i < constraints; i++) {
228                 getLogger().debug("DBAUTH: parameter " + (i+1) + " = [" + String.valueOf(constraintValues[i]) + "]");
229                 st.setObject(i+1,constraintValues[i]);
230             }
231             return st;
232         }
233         catch (Exception JavaDoc e) {
234             getLogger().debug("DBAUTH: got exception: " + e);
235         }
236         return null;
237     }
238
239     private HashMap JavaDoc propagateParameters (Configuration conf, ResultSet JavaDoc rs,
240             Session session) {
241         Configuration table = conf.getChild ("table");
242         Configuration[] select = table.getChildren ("select");
243         String JavaDoc session_param, type;
244         HashMap JavaDoc map = new HashMap JavaDoc();
245         try {
246             for (int i = 0; i < select.length; i ++) {
247                 try {
248                     session_param = select[i].getAttribute ("to-session");
249                     if (StringUtils.isNotBlank(session_param)) {
250                         Object JavaDoc o = null;
251                         String JavaDoc s = rs.getString (i + 1);
252                         /* propagate to session */
253                             type = select[i].getAttribute("type", "");
254                         if (StringUtils.isBlank(type) || "string".equals (type)) {
255                             o = s;
256                         } else if ("long".equals (type)) {
257                             Long JavaDoc l = Long.decode (s);
258                             o = l;
259                         } else if ("double".equals (type)) {
260                             Double JavaDoc d = Double.valueOf (s);
261                             o = d;
262                         }
263                         if (session != null) {
264                             session.setAttribute (session_param, o);
265                             getLogger ().debug ("DBAUTH: propagating param "
266                                     + session_param + "=" + s);
267                         }
268                         map.put (session_param, o);
269                     }
270                 } catch (Exception JavaDoc e) {
271                     // Empty
272
}
273             }
274             return map;
275         } catch (Exception JavaDoc e) {
276             getLogger().debug("exception: ", e);
277         }
278         return null;
279     }
280 }
281
Popular Tags