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 String _userSql;
64 private String _roleSql;
65 private boolean _createTables = false;
66
67
68 public DataSourceLoginService()
69 {
70 }
71
72
73 public DataSourceLoginService(String name)
74 {
75 setName(name);
76 }
77
78
79 public DataSourceLoginService(String name, IdentityService identityService)
80 {
81 setName(name);
82 setIdentityService(identityService);
83 }
84
85
86 public void setJndiName (String jndi)
87 {
88 _jndiName = jndi;
89 }
90
91
92 public String getJndiName ()
93 {
94 return _jndiName;
95 }
96
97
98 public void setServer (Server server)
99 {
100 _server=server;
101 }
102
103
104 public Server getServer()
105 {
106 return _server;
107 }
108
109
110 public void setCreateTables(boolean createTables)
111 {
112 _createTables = createTables;
113 }
114
115
116 public boolean getCreateTables()
117 {
118 return _createTables;
119 }
120
121
122 public void setUserTableName (String name)
123 {
124 _userTableName=name;
125 }
126
127
128 public String getUserTableName()
129 {
130 return _userTableName;
131 }
132
133
134 public String getUserTableKey()
135 {
136 return _userTableKey;
137 }
138
139
140
141 public void setUserTableKey(String tableKey)
142 {
143 _userTableKey = tableKey;
144 }
145
146
147
148 public String getUserTableUserField()
149 {
150 return _userTableUserField;
151 }
152
153
154
155 public void setUserTableUserField(String tableUserField)
156 {
157 _userTableUserField = tableUserField;
158 }
159
160
161
162 public String getUserTablePasswordField()
163 {
164 return _userTablePasswordField;
165 }
166
167
168
169 public void setUserTablePasswordField(String tablePasswordField)
170 {
171 _userTablePasswordField = tablePasswordField;
172 }
173
174
175
176 public String getRoleTableName()
177 {
178 return _roleTableName;
179 }
180
181
182
183 public void setRoleTableName(String tableName)
184 {
185 _roleTableName = tableName;
186 }
187
188
189
190 public String getRoleTableKey()
191 {
192 return _roleTableKey;
193 }
194
195
196
197 public void setRoleTableKey(String tableKey)
198 {
199 _roleTableKey = tableKey;
200 }
201
202
203
204 public String getRoleTableRoleField()
205 {
206 return _roleTableRoleField;
207 }
208
209
210
211 public void setRoleTableRoleField(String tableRoleField)
212 {
213 _roleTableRoleField = tableRoleField;
214 }
215
216
217
218 public String getUserRoleTableName()
219 {
220 return _userRoleTableName;
221 }
222
223
224
225 public void setUserRoleTableName(String roleTableName)
226 {
227 _userRoleTableName = roleTableName;
228 }
229
230
231
232 public String getUserRoleTableUserKey()
233 {
234 return _userRoleTableUserKey;
235 }
236
237
238
239 public void setUserRoleTableUserKey(String roleTableUserKey)
240 {
241 _userRoleTableUserKey = roleTableUserKey;
242 }
243
244
245
246 public String getUserRoleTableRoleKey()
247 {
248 return _userRoleTableRoleKey;
249 }
250
251
252
253 public void setUserRoleTableRoleKey(String roleTableRoleKey)
254 {
255 _userRoleTableRoleKey = roleTableRoleKey;
256 }
257
258
259 public void setCacheMs (int ms)
260 {
261 _cacheMs=ms;
262 }
263
264
265 public int getCacheMs ()
266 {
267 return _cacheMs;
268 }
269
270
271 @Override
272 protected void loadUsers()
273 {
274 }
275
276
277
278
279
280
281 @Override
282 protected UserIdentity loadUser (String userName)
283 {
284 Connection connection = null;
285 try
286 {
287 initDb();
288 connection = getConnection();
289
290 PreparedStatement statement = connection.prepareStatement(_userSql);
291 statement.setObject(1, userName);
292 ResultSet rs = statement.executeQuery();
293
294 if (rs.next())
295 {
296 int key = rs.getInt(_userTableKey);
297 String credentials = rs.getString(_userTablePasswordField);
298 statement.close();
299
300 statement = connection.prepareStatement(_roleSql);
301 statement.setInt(1, key);
302 rs = statement.executeQuery();
303 List<String> roles = new ArrayList<String>();
304 while (rs.next())
305 roles.add(rs.getString(_roleTableRoleField));
306 statement.close();
307 return putUser(userName,new Password(credentials), roles.toArray(new String[roles.size()]));
308 }
309 }
310 catch (NamingException e)
311 {
312 Log.warn("No datasource for "+_jndiName, e);
313 }
314 catch (SQLException e)
315 {
316 Log.warn("Problem loading user info for "+userName, e);
317 }
318 finally
319 {
320 if (connection != null)
321 {
322 try
323 {
324 connection.close();
325 }
326 catch (SQLException x)
327 {
328 Log.warn("Problem closing connection", x);
329 }
330 finally
331 {
332 connection = null;
333 }
334 }
335 }
336 return null;
337 }
338
339
340
341
342
343
344
345
346
347 public void initDb() throws NamingException, SQLException
348 {
349 if (_datasource != null)
350 return;
351
352 @SuppressWarnings("unused")
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 }