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