1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.security;
20
21 import java.io.File;
22 import java.io.FilenameFilter;
23 import java.io.IOException;
24 import java.security.Principal;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Properties;
32 import java.util.Set;
33
34 import javax.security.auth.Subject;
35
36 import org.eclipse.jetty.security.MappedLoginService.KnownUser;
37 import org.eclipse.jetty.security.MappedLoginService.RolePrincipal;
38 import org.eclipse.jetty.server.UserIdentity;
39 import org.eclipse.jetty.util.Scanner;
40 import org.eclipse.jetty.util.Scanner.BulkListener;
41 import org.eclipse.jetty.util.StringUtil;
42 import org.eclipse.jetty.util.component.AbstractLifeCycle;
43 import org.eclipse.jetty.util.log.Log;
44 import org.eclipse.jetty.util.log.Logger;
45 import org.eclipse.jetty.util.resource.Resource;
46 import org.eclipse.jetty.util.security.Credential;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public class PropertyUserStore extends AbstractLifeCycle
63 {
64 private static final Logger LOG = Log.getLogger(PropertyUserStore.class);
65
66 private String _config;
67 private Resource _configResource;
68 private Scanner _scanner;
69 private int _refreshInterval = 0;
70
71 private IdentityService _identityService = new DefaultIdentityService();
72 private boolean _firstLoad = true;
73 private final List<String> _knownUsers = new ArrayList<String>();
74 private final Map<String, UserIdentity> _knownUserIdentities = new HashMap<String, UserIdentity>();
75 private List<UserListener> _listeners;
76
77
78 public String getConfig()
79 {
80 return _config;
81 }
82
83
84 public void setConfig(String config)
85 {
86 _config = config;
87 }
88
89
90 public UserIdentity getUserIdentity(String userName)
91 {
92 return _knownUserIdentities.get(userName);
93 }
94
95
96
97
98
99 public Resource getConfigResource() throws IOException
100 {
101 if (_configResource == null)
102 {
103 _configResource = Resource.newResource(_config);
104 }
105
106 return _configResource;
107 }
108
109
110
111
112
113 public void setRefreshInterval(int msec)
114 {
115 _refreshInterval = msec;
116 }
117
118
119
120
121
122 public int getRefreshInterval()
123 {
124 return _refreshInterval;
125 }
126
127
128 private void loadUsers() throws IOException
129 {
130 if (_config == null)
131 return;
132
133 if (LOG.isDebugEnabled())
134 LOG.debug("Load " + this + " from " + _config);
135 Properties properties = new Properties();
136 if (getConfigResource().exists())
137 properties.load(getConfigResource().getInputStream());
138 Set<String> known = new HashSet<String>();
139
140 for (Map.Entry<Object, Object> entry : properties.entrySet())
141 {
142 String username = ((String)entry.getKey()).trim();
143 String credentials = ((String)entry.getValue()).trim();
144 String roles = null;
145 int c = credentials.indexOf(',');
146 if (c > 0)
147 {
148 roles = credentials.substring(c + 1).trim();
149 credentials = credentials.substring(0,c).trim();
150 }
151
152 if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0)
153 {
154 String[] roleArray = IdentityService.NO_ROLES;
155 if (roles != null && roles.length() > 0)
156 {
157 roleArray = StringUtil.csvSplit(roles);
158 }
159 known.add(username);
160 Credential credential = Credential.getCredential(credentials);
161
162 Principal userPrincipal = new KnownUser(username,credential);
163 Subject subject = new Subject();
164 subject.getPrincipals().add(userPrincipal);
165 subject.getPrivateCredentials().add(credential);
166
167 if (roles != null)
168 {
169 for (String role : roleArray)
170 {
171 subject.getPrincipals().add(new RolePrincipal(role));
172 }
173 }
174
175 subject.setReadOnly();
176
177 _knownUserIdentities.put(username,_identityService.newUserIdentity(subject,userPrincipal,roleArray));
178 notifyUpdate(username,credential,roleArray);
179 }
180 }
181
182 synchronized (_knownUsers)
183 {
184
185
186
187 if (!_firstLoad)
188 {
189 Iterator<String> users = _knownUsers.iterator();
190 while (users.hasNext())
191 {
192 String user = users.next();
193 if (!known.contains(user))
194 {
195 _knownUserIdentities.remove(user);
196 notifyRemove(user);
197 }
198 }
199 }
200
201
202
203
204
205 _knownUsers.clear();
206 _knownUsers.addAll(known);
207
208 }
209
210
211
212
213 _firstLoad = false;
214 }
215
216
217
218
219
220
221
222
223
224 protected void doStart() throws Exception
225 {
226 super.doStart();
227
228 if (getRefreshInterval() > 0)
229 {
230 _scanner = new Scanner();
231 _scanner.setScanInterval(getRefreshInterval());
232 List<File> dirList = new ArrayList<File>(1);
233 dirList.add(getConfigResource().getFile().getParentFile());
234 _scanner.setScanDirs(dirList);
235 _scanner.setFilenameFilter(new FilenameFilter()
236 {
237 public boolean accept(File dir, String name)
238 {
239 File f = new File(dir,name);
240 try
241 {
242 if (f.compareTo(getConfigResource().getFile()) == 0)
243 {
244 return true;
245 }
246 }
247 catch (IOException e)
248 {
249 return false;
250 }
251
252 return false;
253 }
254
255 });
256
257 _scanner.addListener(new BulkListener()
258 {
259 public void filesChanged(List<String> filenames) throws Exception
260 {
261 if (filenames == null)
262 return;
263 if (filenames.isEmpty())
264 return;
265 if (filenames.size() == 1)
266 {
267 Resource r = Resource.newResource(filenames.get(0));
268 if (r.getFile().equals(_configResource.getFile()))
269 loadUsers();
270 }
271 }
272
273 public String toString()
274 {
275 return "PropertyUserStore$Scanner";
276 }
277
278 });
279
280 _scanner.setReportExistingFilesOnStartup(true);
281 _scanner.setRecursive(false);
282 _scanner.start();
283 }
284 else
285 {
286 loadUsers();
287 }
288 }
289
290
291
292
293
294 protected void doStop() throws Exception
295 {
296 super.doStop();
297 if (_scanner != null)
298 _scanner.stop();
299 _scanner = null;
300 }
301
302
303
304
305
306
307
308
309 private void notifyUpdate(String username, Credential credential, String[] roleArray)
310 {
311 if (_listeners != null)
312 {
313 for (Iterator<UserListener> i = _listeners.iterator(); i.hasNext();)
314 {
315 i.next().update(username,credential,roleArray);
316 }
317 }
318 }
319
320
321
322
323
324
325 private void notifyRemove(String username)
326 {
327 if (_listeners != null)
328 {
329 for (Iterator<UserListener> i = _listeners.iterator(); i.hasNext();)
330 {
331 i.next().remove(username);
332 }
333 }
334 }
335
336
337
338
339 public void registerUserListener(UserListener listener)
340 {
341 if (_listeners == null)
342 {
343 _listeners = new ArrayList<UserListener>();
344 }
345 _listeners.add(listener);
346 }
347
348
349
350
351 public interface UserListener
352 {
353 public void update(String username, Credential credential, String[] roleArray);
354
355 public void remove(String username);
356 }
357 }