Index: /main/trunk/greenstone3/resources/tomcat/greenstone3.xml.svn
===================================================================
--- /main/trunk/greenstone3/resources/tomcat/greenstone3.xml.svn	(revision 36022)
+++ /main/trunk/greenstone3/resources/tomcat/greenstone3.xml.svn	(revision 36023)
@@ -1,2 +1,3 @@
+<!-- For deployment-time modifications ensure that you are editing greenstone3.xml.in, found in resources/tomcat. -->
 <!-- set allowLinking to true if you want to use symlinks to files or directories outside the docBase directory -->
 <!-- set reloadable to false for a production version. if true, automatically reloads the webapp if it detects changes in classes or lib directories -->
@@ -10,19 +11,41 @@
 	allowLinking="@allowlinking@"
 	xmlBlockExternal="false">
+
 	<Resources allowLinking="@allowlinking@" />
 
-<!--
-   For embedded derby db:
-   driverName="org.apache.derby.jdbc.EmbeddedDriver"
-   connectionURL="jdbc:derby:@gsdl3webhome@/etc/usersDB"
--->  
-	<Realm className="org.greenstone.gsdl3.GoogleSigninJDBCRealm" 
-		driverName="org.apache.derby.jdbc.ClientDriver"
-		connectionURL="jdbc:derby://@derbyserver@:@derbyserverport@/@gsdl3webhome@/etc/usersDB"
-		userTable="users" userNameCol="username" userCredCol="password"		
-		userRoleTable="roles" roleNameCol="role"
-		userEmailCol="email"
-		googlesigninClientId="@googlesigninclientid@"
-		/>
+	<!--
+		For embedded derby db:
+		driverName="org.apache.derby.jdbc.EmbeddedDriver"
+		connectionURL="jdbc:derby:@gsdl3webhome@/etc/usersDB"
+	-->
+	<!--
+		JNDI resources require the validationQuery parameter if you are using validations (which we are).
+		A list of values for this parameter, depending on your database driver, can be found here:
+		https://stackoverflow.com/questions/10684244/dbcp-validationquery-for-different-databases
+		For more info about why you need the parameter value, see here:
+		https://stackoverflow.com/a/41232124
+	-->
+    <Resource 
+        name="jdbc/realmDB"
+        auth="Container"
+        type="javax.sql.DataSource"
+        maxActive="10"
+        maxIdle="4"
+        maxWaitMillis="10000"
+		validationQuery="values 1"
+        driverClassName="org.apache.derby.jdbc.ClientDriver"
+        url="jdbc:derby://@derbyserver@:@derbyserverport@/@gsdl3webhome@/etc/usersDB" />
+
+    <Realm className="org.apache.catalina.realm.LockOutRealm">
+		<Realm
+			className="org.greenstone.gsdl3.GoogleSigninJDBCRealm"
+			userTable="USERS" userNameCol="USERNAME" userCredCol="PASSWORD"
+			userRoleTable="ROLES" roleNameCol="ROLE"
+			userEmailCol="email"
+			googlesigninClientId="@googlesigninclientid@"
+			localDataSource="true"
+			dataSourceName="jdbc/realmDB" />
+	</Realm>
+
 	<!-- Session Manager. Default values are used. See
 	     packages/tomcat/webapps/docs/config/manager.html for more info.
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/GoogleSigninJDBCRealm.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/GoogleSigninJDBCRealm.java	(revision 36022)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/GoogleSigninJDBCRealm.java	(revision 36023)
@@ -21,30 +21,13 @@
 
 import java.security.Principal;
-import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
 import java.sql.Connection;
-import java.sql.Driver;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.apache.catalina.realm.JDBCRealm;
-import org.apache.catalina.realm.GenericPrincipal;
+
+import org.apache.catalina.realm.DataSourceRealm;
 import org.apache.catalina.LifecycleException;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.ExceptionUtils;
 
@@ -58,8 +41,5 @@
 
 
-import org.greenstone.gsdl3.util.GSParams;
-
-
-// Custome Realm class desgin loosely based off (in order) details in:
+// Custom Realm class desgin loosely based off (in order) details in:
 //   https://dzone.com/articles/how-to-implement-a-new-realm-in-tomcat
 //   https://blog.krybot.com/a?ID=01300-14edb945-73b0-433b-8e80-c6870e350cf2
@@ -71,5 +51,5 @@
 //
 
-// In terms of addin in DEBUG statements, you need to trigger this through
+// In terms of adding in DEBUG statements, you need to trigger this through
 //   tomcat/conf/logging.properies:
 // Otherwise even the 'old faithful' approach of printing all debug statements
@@ -106,5 +86,5 @@
 
 	    
-public class GoogleSigninJDBCRealm extends JDBCRealm
+public class GoogleSigninJDBCRealm extends DataSourceRealm
 {
 
@@ -223,9 +203,9 @@
      * @exception SQLException if a database error occurs
      */
-    protected PreparedStatement emailToUsername(Connection dbConnection,
-						String emailAddress)
-	throws SQLException
-    {
-        if (preparedEmailToUsername == null) {
+    protected PreparedStatement emailToUsername(Connection dbConnection, String emailAddress)
+	    throws SQLException
+    {
+        if (preparedEmailToUsername == null)
+        {
             StringBuilder sb = new StringBuilder("SELECT ");
             sb.append(userNameCol);
@@ -259,6 +239,6 @@
      * @return the username associated with the given principal's email address
      */
-    protected synchronized String getUsernameFromEmail(String email_address) {
-
+    protected synchronized String getUsernameFromEmail(String email_address)
+    {
         // Look up the username
         String dbUsername = null;
@@ -274,48 +254,55 @@
         int numberOfTries = 2;
 
-	// Note: The following code is based on that in JDBCRealm for running SQL queries,
-	//       however, it has by changed from the try-resource code pattern to using
-	//       to a more explictly laid out version so it is compatible with versions
-	//       of JDK prior to 1.8
-	
-	ResultSet rs = null;
-        while (numberOfTries > 0) {
-            try {
-                // Ensure that we have an open database connection
-                open();
-
+        // Note: The following code is based on that in JDBCRealm for running SQL queries,
+        //       however, it has by changed from the try-resource code pattern to using
+        //       to a more explictly laid out version so it is compatible with versions
+        //       of JDK prior to 1.8
+        // Note (cstephen, 14/01/2022): The code has been updated to work with a DataSourceRealm
+        
+        ResultSet rs = null;
+        while (numberOfTries > 0)
+        {
+            Connection dbConnection = open();
+            if (dbConnection == null) {
+                continue;
+            }
+
+            try
+            {
                 PreparedStatement stmt = emailToUsername(dbConnection, email_address);
-		rs = stmt.executeQuery();
-		
-		if (rs.next()) {
-		    dbUsername = rs.getString(1);
-		}
-		
-		dbConnection.commit();
-		
-		if (dbUsername != null) {
-		    dbUsername = dbUsername.trim();
-		}
-		
-		rs.close();
-		rs = null;
-		
-		return dbUsername;
-	    }
-	    catch (SQLException e) {
+		        rs = stmt.executeQuery();
+		
+                if (rs.next()) {
+                    dbUsername = rs.getString(1);
+                }
+                
+                dbConnection.commit();
+                
+                if (dbUsername != null) {
+                    dbUsername = dbUsername.trim();
+                }
+                
+                rs.close();
+                rs = null;
+                
+                return dbUsername;
+            }
+            catch (SQLException e)
+            {
                 // Log the problem for posterity
-                containerLog.error(sm.getString("jdbcRealm.exception"), e);
-		
-            }
-
-	    if (rs != null) {
-		try {
-		    rs.close();
-		}
-		catch (SQLException e) {
-		    containerLog.error(sm.getString("jdbcRealm.exception trying to close() ResultSet"), e);
-		}
-		rs = null;
-	    }
+                containerLog.error(sm.getString("dataSourceRealm.exception"), e);
+            }
+
+            if (rs != null)
+            {
+                try {
+                    rs.close();
+                }
+                catch (SQLException e) {
+                    containerLog.error(sm.getString("dataSourceRealm.exception trying to close() ResultSet"), e);
+                }
+
+                rs = null;
+            }
 
             // Close the connection so that it gets reopened next time
@@ -420,5 +407,6 @@
 	}
 	else {
-	    // Regular Greenstone3 User Login case
+        // Regular Greenstone3 User Login case
+        System.out.println("***> beginning normal authentication");
 	    principal = super.authenticate(username,credentials);
 	}
