1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.eclipse.jetty.plus.security;
16
17 import java.sql.Connection;
18 import java.sql.DatabaseMetaData;
19 import java.sql.PreparedStatement;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import javax.naming.InitialContext;
26 import javax.naming.NameNotFoundException;
27 import javax.naming.NamingException;
28 import javax.sql.DataSource;
29
30 import org.eclipse.jetty.http.security.Password;
31 import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
32 import org.eclipse.jetty.security.IdentityService;
33 import org.eclipse.jetty.security.MappedLoginService;
34 import org.eclipse.jetty.server.Server;
35 import org.eclipse.jetty.server.UserIdentity;
36 import org.eclipse.jetty.util.log.Log;
37
38
39
40
41
42
43
44
45
46
47 public class DataSourceLoginService extends MappedLoginService
48 {
49 private String _jndiName = "javax.sql.DataSource/default";
50 private DataSource _datasource;
51 private Server _server;
52 private String _userTableName = "users";
53 private String _userTableKey = "id";
54 private String _userTableUserField = "username";
55 private String _userTablePasswordField = "pwd";
56 private String _roleTableName = "roles";
57 private String _roleTableKey = "id";
58 private String _roleTableRoleField = "role";
59 private String _userRoleTableName = "user_roles";
60 private String _userRoleTableUserKey = "user_id";
61 private String _userRoleTableRoleKey = "role_id";
62 private int _cacheMs = 30000;
63 private long _lastHashPurge = 0;
64 private String _userSql;
65 private String _roleSql;
66 private boolean _createTables = false;
67
68
69 public DataSourceLoginService()
70 {
71 }
72
73
74 public DataSourceLoginService(String name)
75 {
76 setName(name);
77 }
78
79
80 public DataSourceLoginService(String name, IdentityService identityService)
81 {
82 setName(name);
83 setIdentityService(identityService);
84 }
85
86
87 public void setJndiName (String jndi)
88 {
89 _jndiName = jndi;
90 }
91
92
93 public String getJndiName ()
94 {
95 return _jndiName;
96 }
97
98
99 public void setServer (Server server)
100 {
101 _server=server;
102 }
103
104
105 public Server getServer()
106 {
107 return _server;
108 }
109
110
111 public void setCreateTables(boolean createTables)
112 {
113 _createTables = createTables;
114 }
115
116
117 public boolean getCreateTables()
118 {
119 return _createTables;
120 }
121
122
123 public void setUserTableName (String name)
124 {
125 _userTableName=name;
126 }
127
128
129 public String getUserTableName()
130 {
131 return _userTableName;
132 }
133
134
135 public String getUserTableKey()
136 {
137 return _userTableKey;
138 }
139
140
141
142 public void setUserTableKey(String tableKey)
143 {
144 _userTableKey = tableKey;
145 }
146
147
148
149 public String getUserTableUserField()
150 {
151 return _userTableUserField;
152 }
153
154
155
156 public void setUserTableUserField(String tableUserField)
157 {
158 _userTableUserField = tableUserField;
159 }
160
161
162
163 public String getUserTablePasswordField()
164 {
165 return _userTablePasswordField;
166 }
167
168
169
170 public void setUserTablePasswordField(String tablePasswordField)
171 {
172 _userTablePasswordField = tablePasswordField;
173 }
174
175
176
177 public String getRoleTableName()
178 {
179 return _roleTableName;
180 }
181
182
183
184 public void setRoleTableName(String tableName)
185 {
186 _roleTableName = tableName;
187 }
188
189
190
191 public String getRoleTableKey()
192 {
193 return _roleTableKey;
194 }
195
196
197
198 public void setRoleTableKey(String tableKey)
199 {
200 _roleTableKey = tableKey;
201 }
202
203
204
205 public String getRoleTableRoleField()
206 {
207 return _roleTableRoleField;
208 }
209
210
211
212 public void setRoleTableRoleField(String tableRoleField)
213 {
214 _roleTableRoleField = tableRoleField;
215 }
216
217
218
219 public String getUserRoleTableName()
220 {
221 return _userRoleTableName;
222 }
223
224
225
226 public void setUserRoleTableName(String roleTableName)
227 {
228 _userRoleTableName = roleTableName;
229 }
230
231
232
233 public String getUserRoleTableUserKey()
234 {
235 return _userRoleTableUserKey;
236 }
237
238
239
240 public void setUserRoleTableUserKey(String roleTableUserKey)
241 {
242 _userRoleTableUserKey = roleTableUserKey;
243 }
244
245
246
247 public String getUserRoleTableRoleKey()
248 {
249 return _userRoleTableRoleKey;
250 }
251
252
253
254 public void setUserRoleTableRoleKey(String roleTableRoleKey)
255 {
256 _userRoleTableRoleKey = roleTableRoleKey;
257 }
258
259
260 public void setCacheMs (int ms)
261 {
262 _cacheMs=ms;
263 }
264
265
266 public int getCacheMs ()
267 {
268 return _cacheMs;
269 }
270
271
272 @Override
273 protected void loadUsers()
274 {
275 }
276
277
278
279
280
281
282 @Override
283 protected UserIdentity loadUser (String userName)
284 {
285 Connection connection = null;
286 try
287 {
288 initDb();
289 connection = getConnection();
290
291 PreparedStatement statement = connection.prepareStatement(_userSql);
292 statement.setObject(1, userName);
293 ResultSet rs = statement.executeQuery();
294
295 if (rs.next())
296 {
297 int key = rs.getInt(_userTableKey);
298 String credentials = rs.getString(_userTablePasswordField);
299 statement.close();
300
301 statement = connection.prepareStatement(_roleSql);
302 statement.setInt(1, key);
303 rs = statement.executeQuery();
304 List<String> roles = new ArrayList<String>();
305 while (rs.next())
306 roles.add(rs.getString(_roleTableRoleField));
307 statement.close();
308 return putUser(userName,new Password(credentials), roles.toArray(new String[roles.size()]));
309 }
310 }
311 catch (NamingException e)
312 {
313 Log.warn("No datasource for "+_jndiName, e);
314 }
315 catch (SQLException e)
316 {
317 Log.warn("Problem loading user info for "+userName, e);
318 }
319 finally
320 {
321 if (connection != null)
322 {
323 try
324 {
325 connection.close();
326 }
327 catch (SQLException x)
328 {
329 Log.warn("Problem closing connection", x);
330 }
331 finally
332 {
333 connection = null;
334 }
335 }
336 }
337 return null;
338 }
339
340
341
342
343
344
345
346
347
348 public void initDb() throws NamingException, SQLException
349 {
350 if (_datasource != null)
351 return;
352
353 InitialContext ic = new InitialContext();
354
355
356
357
358 if (_server != null)
359 {
360 try
361 {
362 _datasource = (DataSource)NamingEntryUtil.lookup(_server, _jndiName);
363 }
364 catch (NameNotFoundException e)
365 {
366
367 }
368 }
369
370
371
372 if (_datasource==null)
373 {
374 _datasource = (DataSource)NamingEntryUtil.lookup(null, _jndiName);
375 }
376
377
378 _userSql = "select " + _userTableKey + "," + _userTablePasswordField
379 + " from " + _userTableName
380 + " where "+ _userTableUserField + " = ?";
381
382 _roleSql = "select r." + _roleTableRoleField
383 + " from " + _roleTableName + " r, " + _userRoleTableName
384 + " u where u."+ _userRoleTableUserKey + " = ?"
385 + " and r." + _roleTableKey + " = u." + _userRoleTableRoleKey;
386
387 prepareTables();
388 }
389
390
391
392 private void prepareTables()
393 throws NamingException, SQLException
394 {
395 Connection connection = null;
396 boolean autocommit = true;
397
398 if (_createTables)
399 {
400 try
401 {
402 connection = getConnection();
403 autocommit = connection.getAutoCommit();
404 connection.setAutoCommit(false);
405 DatabaseMetaData metaData = connection.getMetaData();
406
407
408 String tableName = (metaData.storesLowerCaseIdentifiers()? _userTableName.toLowerCase(): (metaData.storesUpperCaseIdentifiers()?_userTableName.toUpperCase(): _userTableName));
409 ResultSet result = metaData.getTables(null, null, tableName, null);
410 if (!result.next())
411 {
412
413
414
415
416
417
418 connection.createStatement().executeUpdate("create table "+_userTableName+ "("+_userTableKey+" integer,"+
419 _userTableUserField+" varchar(100) not null unique,"+
420 _userTablePasswordField+" varchar(20) not null, primary key("+_userTableKey+"))");
421 if (Log.isDebugEnabled()) Log.debug("Created table "+_userTableName);
422 }
423
424 result.close();
425
426 tableName = (metaData.storesLowerCaseIdentifiers()? _roleTableName.toLowerCase(): (metaData.storesUpperCaseIdentifiers()?_roleTableName.toUpperCase(): _roleTableName));
427 result = metaData.getTables(null, null, tableName, null);
428 if (!result.next())
429 {
430
431
432
433
434
435 String str = "create table "+_roleTableName+" ("+_roleTableKey+" integer, "+
436 _roleTableRoleField+" varchar(100) not null unique, primary key("+_roleTableKey+"))";
437 connection.createStatement().executeUpdate(str);
438 if (Log.isDebugEnabled()) Log.debug("Created table "+_roleTableName);
439 }
440
441 result.close();
442
443 tableName = (metaData.storesLowerCaseIdentifiers()? _userRoleTableName.toLowerCase(): (metaData.storesUpperCaseIdentifiers()?_userRoleTableName.toUpperCase(): _userRoleTableName));
444 result = metaData.getTables(null, null, tableName, null);
445 if (!result.next())
446 {
447
448
449
450
451
452
453
454
455 connection.createStatement().executeUpdate("create table "+_userRoleTableName+" ("+_userRoleTableUserKey+" integer, "+
456 _userRoleTableRoleKey+" integer, "+
457 "primary key ("+_userRoleTableUserKey+", "+_userRoleTableRoleKey+"))");
458 connection.createStatement().executeUpdate("create index indx_user_role on "+_userRoleTableName+"("+_userRoleTableUserKey+")");
459 if (Log.isDebugEnabled()) Log.debug("Created table "+_userRoleTableName +" and index");
460 }
461
462 result.close();
463 connection.commit();
464 }
465 finally
466 {
467 if (connection != null)
468 {
469 try
470 {
471 connection.setAutoCommit(autocommit);
472 connection.close();
473 }
474 catch (SQLException e)
475 {
476 if (Log.isDebugEnabled()) Log.debug("Prepare tables", e);
477 }
478 finally
479 {
480 connection = null;
481 }
482 }
483 }
484 }
485 else if (Log.isDebugEnabled())
486 {
487 Log.debug("createTables false");
488 }
489 }
490
491
492 private Connection getConnection ()
493 throws NamingException, SQLException
494 {
495 initDb();
496 return _datasource.getConnection();
497 }
498
499 }