2 * Copyright 2009 University of California at Berkeley
\r
4 package org.collectionspace.authentication;
\r
6 import java.lang.reflect.Constructor;
\r
7 import java.security.Principal;
\r
8 import java.security.acl.Group;
\r
9 import java.sql.Connection;
\r
10 import java.sql.DriverManager;
\r
11 import java.sql.PreparedStatement;
\r
12 import java.sql.ResultSet;
\r
13 import java.sql.SQLException;
\r
15 import java.util.HashMap;
\r
16 import javax.naming.InitialContext;
\r
17 import javax.security.auth.login.FailedLoginException;
\r
18 import javax.security.auth.login.LoginException;
\r
19 import org.jboss.security.SimpleGroup;
\r
20 import org.jboss.security.SimplePrincipal;
\r
21 import org.jboss.security.auth.spi.DatabaseServerLoginModule;
\r
22 import org.slf4j.Logger;
\r
23 import org.slf4j.LoggerFactory;
\r
25 public class CSpaceDBLoginModule extends DatabaseServerLoginModule {
\r
27 //disabled due to classloading problem
\r
28 //private Logger logger = LoggerFactory.getLogger(CSpaceDBLoginModule.class);
\r
29 private boolean log = true;
\r
31 private void log(String str) {
\r
32 System.out.println(str);
\r
35 protected String getUsersPassword() throws LoginException {
\r
37 String username = getUsername();
\r
38 String password = null;
\r
39 Connection conn = null;
\r
40 PreparedStatement ps = null;
\r
41 ResultSet rs = null;
\r
42 InitialContext ctx = null;
\r
44 // Properties env = new Properties();
\r
45 // env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
\r
46 // env.setProperty(Context.PROVIDER_URL, "jnp://localhost:1199/");
\r
47 // env.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
\r
48 // ctx = new InitialContext(env);
\r
49 //// ctx = new InitialContext();
\r
50 // DataSource ds = (DataSource) ctx.lookup(dsJndiName);
\r
52 // throw new IllegalArgumentException("datasource not found: " + dsJndiName);
\r
54 // conn = ds.getConnection();
\r
55 Class.forName("com.mysql.jdbc.Driver");
\r
56 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/cspace", "test", "test");
\r
60 log("Excuting query: " + principalsQuery + ", with username: " + username);
\r
62 ps = conn.prepareStatement(principalsQuery);
\r
63 ps.setString(1, username);
\r
64 rs = ps.executeQuery();
\r
65 if(rs.next() == false){
\r
67 log("Query returned no matches from db");
\r
69 throw new FailedLoginException("No matching username found");
\r
72 password = rs.getString(1);
\r
73 password = convertRawPassword(password);
\r
75 log("Obtained user password");
\r
77 // }catch(NamingException ex){
\r
78 // LoginException le = new LoginException("Error looking up DataSource from: " + dsJndiName);
\r
79 // le.initCause(ex);
\r
81 }catch(SQLException ex){
\r
82 LoginException le = new LoginException("Query failed");
\r
85 }catch(Exception ex){
\r
86 LoginException le = new LoginException("Unknown Exception");
\r
93 }catch(SQLException e){
\r
99 }catch(SQLException e){
\r
105 }catch(SQLException ex){
\r
111 }catch(Exception e){
\r
118 /** Execute the rolesQuery against the dsJndiName to obtain the roles for
\r
119 the authenticated user.
\r
121 @return Group[] containing the sets of roles
\r
123 protected Group[] getRoleSets() throws LoginException {
\r
124 String username = getUsername();
\r
126 log("getRoleSets using rolesQuery: " + rolesQuery + ", username: " + username);
\r
129 Connection conn = null;
\r
130 HashMap setsMap = new HashMap();
\r
131 PreparedStatement ps = null;
\r
132 ResultSet rs = null;
\r
135 // InitialContext ctx = new InitialContext();
\r
136 // DataSource ds = (DataSource) ctx.lookup(dsJndiName);
\r
137 // conn = ds.getConnection();
\r
138 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/cspace", "test", "test");
\r
139 // Get the user role names
\r
141 log("Excuting query: " + rolesQuery + ", with username: " + username);
\r
145 conn.prepareStatement(rolesQuery);
\r
147 ps.setString(1, username);
\r
148 }catch(ArrayIndexOutOfBoundsException ignore){
\r
149 // The query may not have any parameters so just try it
\r
151 rs = ps.executeQuery();
\r
152 if(rs.next() == false){
\r
154 log("No roles found");
\r
156 // if(aslm.getUnauthenticatedIdentity() == null){
\r
157 // throw new FailedLoginException("No matching username found in Roles");
\r
159 /* We are running with an unauthenticatedIdentity so create an
\r
160 empty Roles set and return.
\r
163 Group[] roleSets = {new SimpleGroup("Roles")};
\r
168 String name = rs.getString(1);
\r
169 String groupName = rs.getString(2);
\r
170 if(groupName == null || groupName.length() == 0){
\r
171 groupName = "Roles";
\r
174 Group group = (Group) setsMap.get(groupName);
\r
176 group = new SimpleGroup(groupName);
\r
177 setsMap.put(groupName, group);
\r
181 // Principal p = aslm.createIdentity(name);
\r
182 Principal p = createIdentity(name);
\r
184 log("Assign user to role " + name);
\r
187 group.addMember(p);
\r
188 }catch(Exception e){
\r
189 log("Failed to create principal: " + name + " " + e.toString());
\r
193 } // catch(NamingException ex)
\r
195 // LoginException le = new LoginException("Error looking up DataSource from: "+dsJndiName);
\r
196 // le.initCause(ex);
\r
199 catch(SQLException ex){
\r
200 LoginException le = new LoginException("Query failed");
\r
207 }catch(SQLException e){
\r
213 }catch(SQLException e){
\r
219 }catch(Exception ex){
\r
225 Group[] roleSets = new Group[setsMap.size()];
\r
226 setsMap.values().toArray(roleSets);
\r
230 /** Utility method to create a Principal for the given username. This
\r
231 * creates an instance of the principalClassName type if this option was
\r
232 * specified using the class constructor matching: ctor(String). If
\r
233 * principalClassName was not specified, a SimplePrincipal is created.
\r
235 * @param username the name of the principal
\r
236 * @return the principal instance
\r
237 * @throws java.lang.Exception thrown if the custom principal type cannot be created.
\r
239 protected Principal createIdentity(String username)
\r
241 Principal p = null;
\r
242 if(principalClassName == null){
\r
243 p = new SimplePrincipal(username);
\r
245 ClassLoader loader = Thread.currentThread().getContextClassLoader();
\r
246 Class clazz = loader.loadClass(principalClassName);
\r
247 Class[] ctorSig = {String.class};
\r
248 Constructor ctor = clazz.getConstructor(ctorSig);
\r
249 Object[] ctorArgs = {username};
\r
251 (Principal) ctor.newInstance(ctorArgs);
\r