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