001: /**
002: * Copyright (C) 2001 Yasna.com. All rights reserved.
003: *
004: * ===================================================================
005: * The Apache Software License, Version 1.1
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution,
020: * if any, must include the following acknowledgment:
021: * "This product includes software developed by
022: * Yasna.com (http://www.yasna.com)."
023: * Alternately, this acknowledgment may appear in the software itself,
024: * if and wherever such third-party acknowledgments normally appear.
025: *
026: * 4. The names "Yazd" and "Yasna.com" must not be used to
027: * endorse or promote products derived from this software without
028: * prior written permission. For written permission, please
029: * contact yazd@yasna.com.
030: *
031: * 5. Products derived from this software may not be called "Yazd",
032: * nor may "Yazd" appear in their name, without prior written
033: * permission of Yasna.com.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL YASNA.COM OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of Yasna.com. For more information
051: * on Yasna.com, please see <http://www.yasna.com>.
052: */
053:
054: /**
055: * Copyright (C) 2000 CoolServlets.com. All rights reserved.
056: *
057: * ===================================================================
058: * The Apache Software License, Version 1.1
059: *
060: * Redistribution and use in source and binary forms, with or without
061: * modification, are permitted provided that the following conditions
062: * are met:
063: *
064: * 1. Redistributions of source code must retain the above copyright
065: * notice, this list of conditions and the following disclaimer.
066: *
067: * 2. Redistributions in binary form must reproduce the above copyright
068: * notice, this list of conditions and the following disclaimer in
069: * the documentation and/or other materials provided with the
070: * distribution.
071: *
072: * 3. The end-user documentation included with the redistribution,
073: * if any, must include the following acknowledgment:
074: * "This product includes software developed by
075: * CoolServlets.com (http://www.coolservlets.com)."
076: * Alternately, this acknowledgment may appear in the software itself,
077: * if and wherever such third-party acknowledgments normally appear.
078: *
079: * 4. The names "Jive" and "CoolServlets.com" must not be used to
080: * endorse or promote products derived from this software without
081: * prior written permission. For written permission, please
082: * contact webmaster@coolservlets.com.
083: *
084: * 5. Products derived from this software may not be called "Jive",
085: * nor may "Jive" appear in their name, without prior written
086: * permission of CoolServlets.com.
087: *
088: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
089: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
090: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
091: * DISCLAIMED. IN NO EVENT SHALL COOLSERVLETS.COM OR
092: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
093: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
094: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
095: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
096: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
097: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
098: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
099: * SUCH DAMAGE.
100: * ====================================================================
101: *
102: * This software consists of voluntary contributions made by many
103: * individuals on behalf of CoolServlets.com. For more information
104: * on CoolServlets.com, please see <http://www.coolservlets.com>.
105: */package com.Yasna.forum.database;
106:
107: import com.Yasna.forum.Authorization;
108: import com.Yasna.forum.AuthorizationFactory;
109: import com.Yasna.forum.UnauthorizedException;
110: import com.Yasna.forum.Exceptions.UserNotActivatedException;
111: import com.Yasna.util.StringUtils;
112:
113: import java.sql.*;
114: import java.util.Calendar;
115:
116: /**
117: * A subclass of AuthorizationFactory for the default Yazd implementation. It makes an
118: * SQL query to the Yazd user table to see if the supplied username and password
119: * match a user record. If they do, the appropaite Authorization token is
120: * returned. If no matching User record is found an UnauthorizedException is
121: * thrown.<p>
122: *
123: * Because each call to createAuthorization(String, String) makes a database
124: * connection, Authorization tokens should be cached whenever possible. When
125: * using a servlet or JSP skins, a good method is to cache the token in the
126: * session. The SkinUtils.getUserAuthorization() methods automatically handles
127: * this logic.<p>
128: *
129: * If you wish to integrate Yazd with your own user system, you'll need to
130: * either modify the class or provide your own implementation of the
131: * AuthorizationFactory interface.
132: */
133: public class DbAuthorizationFactory extends AuthorizationFactory {
134:
135: /** DATABASE QUERIES **/
136: private static final String AUTHORIZE = "SELECT "
137: + SystemProperty.getProperty("User.Column.UserID")
138: + " FROM " + SystemProperty.getProperty("User.Table")
139: + " WHERE "
140: + SystemProperty.getProperty("User.Column.Username")
141: + "=? AND "
142: + SystemProperty.getProperty("User.Column.PasswordHash")
143: + "=?";
144: private static final String CHECKLOGIN = "select * from yazdUserProp where userID=? and name=?";
145: private static final String INSERTLOGIN = "insert into yazdUserProp(userID,name,propValue) values (?,?,?)";
146: private static final String UPDATELOGIN = "update yazdUserProp set propValue=? WHERE userID=? and name=?";
147:
148: /**
149: * The same token can be used for all anonymous users, so cache it.
150: */
151: private static final Authorization anonymousAuth = new DbAuthorization(
152: -1);
153:
154: /**
155: * Creates Authorization tokens for users. This method is implemented by
156: * concrete subclasses of AuthorizationFactory.
157: *
158: * @param username the username to create an Authorization with.
159: * @param password the password to create an Authorization with.
160: * @return an Authorization token if the username and password are correct.
161: * @throws UnauthorizedException if the username and password do not match
162: * any existing user.
163: */
164: public Authorization createAuthorization(String username,
165: String password) throws UnauthorizedException {
166: if (username == null || password == null) {
167: throw new UnauthorizedException();
168: }
169: //Yazd stores all passwords in hashed form. So, hash the plain text
170: //password for comparison.
171: password = StringUtils.hash(password);
172: int userID = 0;
173: Connection con = null;
174: PreparedStatement pstmt = null;
175: try {
176: con = DbConnectionManager.getConnection();
177: pstmt = con.prepareStatement(AUTHORIZE);
178: pstmt.setString(1, username);
179: pstmt.setString(2, password);
180:
181: ResultSet rs = pstmt.executeQuery();
182: //If the query had no results, the username and password
183: //did not match a user record. Therefore, throw an exception.
184: if (!rs.next()) {
185: throw new UnauthorizedException();
186: }
187: userID = rs.getInt(1);
188:
189: pstmt = con.prepareStatement(CHECKLOGIN);
190: pstmt.setInt(1, userID);
191: pstmt.setString(2, "notactive");
192: rs = pstmt.executeQuery();
193: if (rs.next()) {
194: //This account is not activated yet and can not be authorized to login.
195: throw new UserNotActivatedException(
196: "User not yet activated");
197: }
198: //pstmt.setInt(1,userID);
199: pstmt.setString(2, "lastlogin");
200: rs = pstmt.executeQuery();
201: //If the query had no results, insert the lastlogin into properties
202: if (!rs.next()) {
203: pstmt = con.prepareStatement(INSERTLOGIN);
204: pstmt.setInt(1, userID);
205: pstmt.setString(2, "lastlogin");
206: pstmt.setString(3, Long.toString(Calendar.getInstance()
207: .getTimeInMillis()));
208: pstmt.executeUpdate();
209: } else {
210: pstmt = con.prepareStatement(UPDATELOGIN);
211: pstmt.setString(1, Long.toString(Calendar.getInstance()
212: .getTimeInMillis()));
213: pstmt.setInt(2, userID);
214: pstmt.setString(3, "lastlogin");
215: pstmt.executeUpdate();
216: }
217:
218: } catch (SQLException sqle) {
219: System.err.println("Exception in DbAuthorizationFactory:"
220: + sqle);
221: sqle.printStackTrace();
222: throw new UnauthorizedException();
223: } finally {
224: try {
225: pstmt.close();
226: } catch (Exception e) {
227: e.printStackTrace();
228: }
229: try {
230: con.close();
231: } catch (Exception e) {
232: e.printStackTrace();
233: }
234: }
235: //Got this far, so the user must be authorized.
236: return new DbAuthorization(userID);
237: }
238:
239: /**
240: * Creates anonymous Authorization tokens.
241: *
242: * @return an anonymous Authorization token.
243: */
244: public Authorization createAnonymousAuthorization() {
245: return anonymousAuth;
246: }
247: }
|