001: package org.esupportail.cas.server.handlers.database;
002:
003: import org.dom4j.Element;
004: import org.esupportail.cas.server.util.MisconfiguredHandlerException;
005: import org.esupportail.cas.server.util.crypt.Crypt;
006: import org.esupportail.cas.server.util.log.Log;
007:
008: /**
009: * This class implements a query database handler class.
010: *
011: * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
012: * @author Arunas Stockus <arunas.stockus at univ-lr.fr>
013: */
014: public class QueryDatabaseHandler extends DatabaseHandler {
015:
016: /**
017: * This token is replaced by the users' login when executing queries on the database.
018: */
019: static final String SQL_LOGIN_TOKEN = "%u";
020:
021: /**
022: * the string used to query the database. This query is supposed
023: * to return a single VARCHAR column.
024: */
025: private String sqlQuery;
026: /**
027: * the encryption used for stored passwords.
028: */
029: private String encryption;
030: /**
031: * the username to use to bind to the database.
032: */
033: private String bindUsername;
034: /**
035: * the password to use to bind to the database.
036: */
037: private String bindPassword;
038:
039: /**
040: * Constructor.
041: *
042: * @param handlerElement the XML element that declares the handler
043: * in the configuration file
044: * @param configDebug debugging mode of the global configuration
045: * @throws Exception Exception
046: */
047: public QueryDatabaseHandler(final Element handlerElement,
048: final Boolean configDebug) throws Exception {
049: super (handlerElement, configDebug);
050: traceBegin();
051:
052: sqlQuery = readSqlQueryFromConfig();
053: trace("sql_query = " + sqlQuery);
054: if (sqlQuery.indexOf(SQL_LOGIN_TOKEN) < 0) {
055: Log.warn("The SQL query should contain at least one \""
056: + SQL_LOGIN_TOKEN
057: + "\"; assuming the user knows what he does.");
058: }
059:
060: bindUsername = getConfigSubElementContent("bind_username",
061: false/*not needed*/);
062: if (bindUsername.equals("")) {
063: trace("An anonymous connection to the database will be used.");
064: bindPassword = "";
065: } else {
066: bindPassword = getConfigSubElementContent("bind_password",
067: false/*not needed*/);
068: }
069: trace("bind_username = " + bindUsername);
070: trace("bind_password = " + bindPassword);
071:
072: encryption = getConfigSubElementContent("encryption", false/*not needed*/);
073: if (encryption.equals("")) {
074: encryption = "md5";
075: }
076: if (!Crypt.isEncryptionSupported(encryption)) {
077: traceThrow(new MisconfiguredHandlerException(
078: "Encryption \"" + encryption
079: + "\" is not supported."));
080: }
081: trace("encryption = " + encryption);
082: if (encryption.equals("plain")) {
083: Log
084: .warn("Passwords should be encrypted. Be sure to keep the database out of danger!");
085: }
086:
087: // add the database servers
088: addServers(true/*serverElementNeeded*/, getClass()
089: .getPackage().getName()
090: + ".QueryDatabaseServer");
091:
092: traceEnd();
093: }
094:
095: /**
096: * Read the SQL query from the configuration.
097: * @return a String.
098: * @throws Exception Exception
099: */
100: protected String readSqlQueryFromConfig() throws Exception {
101: traceBegin();
102: String query = getConfigSubElementContent("sql_query", true/*needed*/);
103: // Remove all tailing semi-colons (they hurt some JDBC drivers).
104: boolean semiColonFound = false;
105: while (query.endsWith(";")) {
106: query.substring(0, query.length() - 1).trim();
107: semiColonFound = true;
108: }
109: if (semiColonFound) {
110: Log
111: .warn("Trailing semi-colons are not allowed in SQL queries, they will be ignored.");
112: }
113: traceEnd(query);
114: return query;
115: }
116:
117: /**
118: * Returns the SQL expression that must be executed to
119: * retrieve the password of the user with the given name.
120: * @param username the user's id
121: * @return a String.
122: */
123: final String getUserSqlQuery(final String username) {
124: return sqlQuery.replaceAll(SQL_LOGIN_TOKEN, username);
125: }
126:
127: /**
128: * Retrieve the encryption used to store passwords.
129: *
130: * @return a String Object.
131: */
132: final String getEncryption() {
133: return encryption;
134: }
135:
136: /**
137: * Retrieve the username to use to bind to the database.
138: *
139: * @return a String Object.
140: */
141: final String getBindUsername() {
142: return bindUsername;
143: }
144:
145: /**
146: * Retrieve the password to use to bind to the database.
147: *
148: * @return a String Object.
149: */
150: final String getBindPassword() {
151: return bindPassword;
152: }
153:
154: }
|