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