]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
1d2a7d3dd9155595ea14200f7d4d6f84cf1b040c
[tmp/jakarta-migration.git] /
1 /**\r
2  *  This document is a part of the source code and related artifacts\r
3  *  for CollectionSpace, an open source collections management system\r
4  *  for museums and related institutions:\r
5 \r
6  *  http://www.collectionspace.org\r
7  *  http://wiki.collectionspace.org\r
8 \r
9  *  Copyright 2009 University of California at Berkeley\r
10 \r
11  *  Licensed under the Educational Community License (ECL), Version 2.0.\r
12  *  You may not use this file except in compliance with this License.\r
13 \r
14  *  You may obtain a copy of the ECL 2.0 License at\r
15 \r
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
17 \r
18  *  Unless required by applicable law or agreed to in writing, software\r
19  *  distributed under the License is distributed on an "AS IS" BASIS,\r
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
21  *  See the License for the specific language governing permissions and\r
22  *  limitations under the License.\r
23  */\r
24 package org.collectionspace.authentication;\r
25 \r
26 import java.lang.reflect.Constructor;\r
27 import java.security.Principal;\r
28 import java.security.acl.Group;\r
29 import java.sql.Connection;\r
30 import java.sql.PreparedStatement;\r
31 import java.sql.ResultSet;\r
32 import java.sql.SQLException;\r
33 \r
34 import java.util.HashMap;\r
35 import javax.naming.InitialContext;\r
36 import javax.naming.NamingException;\r
37 import javax.security.auth.login.FailedLoginException;\r
38 import javax.security.auth.login.LoginException;\r
39 import javax.sql.DataSource;\r
40 import org.jboss.security.SimpleGroup;\r
41 import org.jboss.security.SimplePrincipal;\r
42 import org.jboss.security.auth.spi.DatabaseServerLoginModule;\r
43 //import org.slf4j.Logger;\r
44 //import org.slf4j.LoggerFactory;\r
45 \r
46 public class CSpaceDBLoginModule extends DatabaseServerLoginModule {\r
47 \r
48     //disabled due to classloading problem\r
49 //    private Logger logger = LoggerFactory.getLogger(CSpaceDBLoginModule.class);\r
50     private boolean log = true; //logger.isDebugEnabled();\r
51 \r
52     private void log(String str) {\r
53         System.out.println(str);\r
54     }\r
55 \r
56     protected String getUsersPassword() throws LoginException {\r
57 \r
58         String username = getUsername();\r
59         String password = null;\r
60         Connection conn = null;\r
61         PreparedStatement ps = null;\r
62         ResultSet rs = null;\r
63         InitialContext ctx = null;\r
64         try {\r
65 \r
66             ctx = new InitialContext();\r
67             DataSource ds = (DataSource) ctx.lookup(dsJndiName);\r
68             if (ds == null) {\r
69                 throw new IllegalArgumentException("datasource not found: " + dsJndiName);\r
70             }\r
71             conn = ds.getConnection();\r
72             // Get the password\r
73             if (log) {\r
74                 log("Executing query: " + principalsQuery + ", with username: " + username);\r
75             }\r
76             ps = conn.prepareStatement(principalsQuery);\r
77             ps.setString(1, username);\r
78             rs = ps.executeQuery();\r
79             if (rs.next() == false) {\r
80                 if (log) {\r
81                     log("Query returned no matches from db");\r
82                 }\r
83                 throw new FailedLoginException("No matching username found");\r
84             }\r
85 \r
86             password = rs.getString(1);\r
87             password = convertRawPassword(password);\r
88             if (log) {\r
89                 log("Obtained user password");\r
90             }\r
91         } catch (NamingException ex) {\r
92             LoginException le = new LoginException("Error looking up DataSource from: " + dsJndiName);\r
93             le.initCause(ex);\r
94             throw le;\r
95         } catch (SQLException ex) {\r
96             LoginException le = new LoginException("Query failed");\r
97             le.initCause(ex);\r
98             throw le;\r
99         } catch (Exception ex) {\r
100             LoginException le = new LoginException("Unknown Exception");\r
101             le.initCause(ex);\r
102             throw le;\r
103         } finally {\r
104             if (rs != null) {\r
105                 try {\r
106                     rs.close();\r
107                 } catch (SQLException e) {\r
108                 }\r
109             }\r
110             if (ps != null) {\r
111                 try {\r
112                     ps.close();\r
113                 } catch (SQLException e) {\r
114                 }\r
115             }\r
116             if (conn != null) {\r
117                 try {\r
118                     conn.close();\r
119                 } catch (SQLException ex) {\r
120                 }\r
121             }\r
122             if (ctx != null) {\r
123                 try {\r
124                     ctx.close();\r
125                 } catch (Exception e) {\r
126                 }\r
127             }\r
128         }\r
129         return password;\r
130     }\r
131 \r
132     /** Execute the rolesQuery against the dsJndiName to obtain the roles for\r
133     the authenticated user.\r
134 \r
135     @return Group[] containing the sets of roles\r
136      */\r
137     protected Group[] getRoleSets() throws LoginException {\r
138         String username = getUsername();\r
139         if (log) {\r
140             log("getRoleSets using rolesQuery: " + rolesQuery + ", username: " + username);\r
141         }\r
142 \r
143         Connection conn = null;\r
144         HashMap setsMap = new HashMap();\r
145         PreparedStatement ps = null;\r
146         ResultSet rs = null;\r
147 \r
148         try {\r
149             InitialContext ctx = new InitialContext();\r
150             DataSource ds = (DataSource) ctx.lookup(dsJndiName);\r
151             conn = ds.getConnection();\r
152             // Get the user role names\r
153             if (log) {\r
154                 log("Executing query: " + rolesQuery + ", with username: " + username);\r
155             }\r
156 \r
157             ps = conn.prepareStatement(rolesQuery);\r
158             try {\r
159                 ps.setString(1, username);\r
160             } catch (ArrayIndexOutOfBoundsException ignore) {\r
161                 // The query may not have any parameters so just try it\r
162             }\r
163             rs = ps.executeQuery();\r
164             if (rs.next() == false) {\r
165                 if (log) {\r
166                     log("No roles found");\r
167                 }\r
168 //                if(aslm.getUnauthenticatedIdentity() == null){\r
169 //                    throw new FailedLoginException("No matching username found in Roles");\r
170 //                }\r
171                 /* We are running with an unauthenticatedIdentity so create an\r
172                 empty Roles set and return.\r
173                  */\r
174 \r
175                 Group[] roleSets = {new SimpleGroup("Roles")};\r
176                 return roleSets;\r
177             }\r
178 \r
179             do {\r
180                 String name = rs.getString(1);\r
181                 String groupName = rs.getString(2);\r
182                 if (groupName == null || groupName.length() == 0) {\r
183                     groupName = "Roles";\r
184                 }\r
185 \r
186                 Group group = (Group) setsMap.get(groupName);\r
187                 if (group == null) {\r
188                     group = new SimpleGroup(groupName);\r
189                     setsMap.put(groupName, group);\r
190                 }\r
191 \r
192                 try {\r
193 //                    Principal p = aslm.createIdentity(name);\r
194                     Principal p = createIdentity(name);\r
195                     if (log) {\r
196                         log("Assign user to role " + name);\r
197                     }\r
198 \r
199                     group.addMember(p);\r
200                 } catch (Exception e) {\r
201                     log("Failed to create principal: " + name + " " + e.toString());\r
202                 }\r
203 \r
204             } while (rs.next());\r
205         } catch (NamingException ex) {\r
206             LoginException le = new LoginException("Error looking up DataSource from: " + dsJndiName);\r
207             le.initCause(ex);\r
208             throw le;\r
209         } catch (SQLException ex) {\r
210             LoginException le = new LoginException("Query failed");\r
211             le.initCause(ex);\r
212             throw le;\r
213         } finally {\r
214             if (rs != null) {\r
215                 try {\r
216                     rs.close();\r
217                 } catch (SQLException e) {\r
218                 }\r
219             }\r
220             if (ps != null) {\r
221                 try {\r
222                     ps.close();\r
223                 } catch (SQLException e) {\r
224                 }\r
225             }\r
226             if (conn != null) {\r
227                 try {\r
228                     conn.close();\r
229                 } catch (Exception ex) {\r
230                 }\r
231             }\r
232 \r
233         }\r
234 \r
235         Group[] roleSets = new Group[setsMap.size()];\r
236         setsMap.values().toArray(roleSets);\r
237         return roleSets;\r
238     }\r
239 \r
240     /** Utility method to create a Principal for the given username. This\r
241      * creates an instance of the principalClassName type if this option was\r
242      * specified using the class constructor matching: ctor(String). If\r
243      * principalClassName was not specified, a SimplePrincipal is created.\r
244      *\r
245      * @param username the name of the principal\r
246      * @return the principal instance\r
247      * @throws java.lang.Exception thrown if the custom principal type cannot be created.\r
248      */\r
249     protected Principal createIdentity(String username)\r
250             throws Exception {\r
251         Principal p = null;\r
252         if (principalClassName == null) {\r
253             p = new SimplePrincipal(username);\r
254         } else {\r
255             ClassLoader loader = Thread.currentThread().getContextClassLoader();\r
256             Class clazz = loader.loadClass(principalClassName);\r
257             Class[] ctorSig = {String.class};\r
258             Constructor ctor = clazz.getConstructor(ctorSig);\r
259             Object[] ctorArgs = {username};\r
260             p = (Principal) ctor.newInstance(ctorArgs);\r
261         }\r
262 \r
263         return p;\r
264     }\r
265 }\r