1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package net.sf.hermesftp.usermanager.impl;
26
27 import java.security.NoSuchAlgorithmException;
28 import java.text.DateFormat;
29 import java.text.SimpleDateFormat;
30 import java.util.Collections;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import net.sf.hermesftp.common.FtpSessionContext;
37 import net.sf.hermesftp.exception.FtpConfigException;
38 import net.sf.hermesftp.exception.FtpQuotaException;
39 import net.sf.hermesftp.usermanager.UserManager;
40 import net.sf.hermesftp.usermanager.model.GroupData;
41 import net.sf.hermesftp.usermanager.model.GroupDataList;
42 import net.sf.hermesftp.usermanager.model.UserData;
43 import net.sf.hermesftp.usermanager.model.UserManagerData;
44 import net.sf.hermesftp.utils.SecurityUtil;
45 import net.sf.hermesftp.utils.StringUtils;
46
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49
50 /***
51 * @author Lars Behnke
52 */
53 public class XmlFileUserManager implements UserManager {
54
55 private static Log log = LogFactory.getLog(XmlFileUserManager.class);
56
57 private XmlFileReader fileReader;
58
59 private UserManagerData userManagerData;
60
61 private Map<String, Map<String, Long>> resourceConsumption = Collections
62 .synchronizedMap(new HashMap<String, Map<String, Long>>());
63
64 private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
65
66 /***
67 * {@inheritDoc}
68 */
69 public synchronized boolean authenticate(String user, String password, FtpSessionContext ctx)
70 throws FtpConfigException {
71 boolean result = false;
72 UserData userData = userManagerData.getUserData(user);
73 if (userData == null) {
74 return result;
75 }
76 if (userData.getPassword() == null) {
77 result = password != null && StringUtils.validateEmail(password);
78 } else {
79 try {
80 result = SecurityUtil.checkPassword(userData.getPassword(), password);
81 } catch (NoSuchAlgorithmException e) {
82 throw new FtpConfigException("Algorithm not supported: " + userData.getPassword());
83 }
84 }
85
86 return result;
87 }
88
89 /***
90 * {@inheritDoc}
91 */
92 public synchronized GroupDataList getGroupDataList(String username) throws FtpConfigException {
93 UserData userData = userManagerData.getUserData(username);
94 if (userData == null) {
95 throw new FtpConfigException("User " + username + " not configured.");
96 }
97 GroupDataList groupList = new GroupDataList();
98 for (String groupName : userData.getGroupNames()) {
99 GroupData groupData = userManagerData.getGroupData(groupName);
100 groupList.addGroup(groupData);
101 }
102 return groupList;
103
104 }
105
106 /***
107 * {@inheritDoc}
108 */
109 public synchronized List<UserData> getUserDataList() throws FtpConfigException {
110 return userManagerData.getUserData();
111 }
112
113 /***
114 * {@inheritDoc}
115 */
116 public synchronized void load() throws FtpConfigException {
117 userManagerData = fileReader.read();
118 }
119
120 /***
121 * Getter method for the java bean <code>fileReader</code>.
122 *
123 * @return Returns the value of the java bean <code>fileReader</code>.
124 */
125 public XmlFileReader getFileReader() {
126 return fileReader;
127 }
128
129 /***
130 * Setter method for the java bean <code>fileReader</code>.
131 *
132 * @param fileReader The value of fileReader to set.
133 */
134 public void setFileReader(XmlFileReader fileReader) {
135 this.fileReader = fileReader;
136 }
137
138 /***
139 * {@inheritDoc}
140 */
141 public void checkResourceConsumption(String user, String[] limitNames) throws FtpQuotaException {
142 Map<String, Long> userConsumptions = getUserStatistics(user);
143 for (String limitName : userConsumptions.keySet()) {
144 Long consumptionObj = userConsumptions.get(limitName);
145 long consumption = consumptionObj == null ? 0 : consumptionObj.longValue();
146 long limit;
147 try {
148 GroupDataList list = getGroupDataList(user);
149 limit = list.getUpperLimit(limitName);
150 } catch (FtpConfigException e) {
151 log.error(e);
152 limit = 0;
153 }
154 if (consumption >= limit) {
155 throw new FtpQuotaException(createQuotaMessage(limitName, consumption, limit));
156 }
157 }
158
159 }
160
161 /***
162 * {@inheritDoc}
163 */
164 public void updateIncrementalStatistics(String user, String limitName, long value)
165 throws FtpQuotaException {
166 Map<String, Long> userConsumptions = getUserStatistics(user);
167 Long consumptionObj = (Long) userConsumptions.get(limitName);
168 long consumption = consumptionObj == null ? 0 : consumptionObj.longValue();
169 consumption += value;
170 long limit;
171 try {
172 GroupDataList list = getGroupDataList(user);
173 limit = list.getUpperLimit(limitName);
174 } catch (FtpConfigException e) {
175 log.error(e);
176 limit = 0;
177 }
178 if (consumption > limit) {
179 throw new FtpQuotaException(createQuotaMessage(limitName, consumption, limit));
180 }
181 userConsumptions.put(limitName, new Long(consumption));
182
183 }
184
185 /***
186 * {@inheritDoc}
187 */
188 public void updateAverageStatistics(String user, String avgKey, long value) {
189 String countKey = "Sample count (" + avgKey + ")";
190 Map<String, Long> userConsumptions = getUserStatistics(user);
191 Long prevAvgObj = (Long) userConsumptions.get(avgKey);
192 long prevAvg = prevAvgObj == null ? 0 : prevAvgObj.longValue();
193 Long prevCountObj = (Long) userConsumptions.get(countKey);
194 long prevCount = prevCountObj == null ? 0 : prevCountObj.longValue();
195 long currentAvg = (prevAvg * prevCount + value) / (prevCount + 1);
196 userConsumptions.put(avgKey, new Long(currentAvg));
197 userConsumptions.put(countKey, new Long(prevCount + 1));
198 }
199
200 /***
201 * {@inheritDoc}
202 */
203 public Map<String, Long> getUserStatistics(String user) {
204 String userAndDate = getUserAndDateKey(user);
205 return getUserResourceConsumptions(userAndDate);
206 }
207
208 /***
209 * {@inheritDoc}
210 */
211 public Map<String, Map<String, Long>> getAllStatistics() {
212 return resourceConsumption;
213 }
214
215 /***
216 * {@inheritDoc}
217 */
218 public boolean isLoaded() throws FtpConfigException {
219 return userManagerData != null;
220
221 }
222
223 /***
224 * {@inheritDoc}
225 */
226 public synchronized UserData getUserData(String username) throws FtpConfigException {
227 return userManagerData.getUserData(username);
228 }
229
230 private String getUserAndDateKey(String user) {
231 String userAndDate = dateFormat.format(new Date()) + " " + user;
232 return userAndDate;
233 }
234
235 private Map<String, Long> getUserResourceConsumptions(String userAndDate) {
236 Map<String, Long> userConsumption = resourceConsumption.get(userAndDate);
237 if (userConsumption == null) {
238 userConsumption = Collections.synchronizedMap(new HashMap<String, Long>());
239 resourceConsumption.put(userAndDate, userConsumption);
240 }
241 return userConsumption;
242 }
243
244 private String createQuotaMessage(String limitName, long consumption, long limit) {
245 return limitName + " exceed limit of " + limit + " (current consumption is " + consumption + ")";
246 }
247
248 }