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.io.BufferedReader;
28 import java.io.File;
29 import java.io.FileReader;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.util.List;
34
35 import net.sf.hermesftp.exception.FtpConfigException;
36 import net.sf.hermesftp.usermanager.model.GroupData;
37 import net.sf.hermesftp.usermanager.model.PermissionData;
38 import net.sf.hermesftp.usermanager.model.UserData;
39 import net.sf.hermesftp.usermanager.model.UserManagerData;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.dom4j.Document;
44 import org.dom4j.DocumentException;
45 import org.dom4j.Element;
46 import org.dom4j.io.SAXReader;
47
48 /***
49 * Reads the user management configuration data from a file.
50 *
51 * @author Lars Behnke
52 */
53 public class XmlFileReader {
54
55 private static Log log = LogFactory.getLog(XmlFileReader.class);
56
57 private static final String DEFAULT_HERMESFTP_USERS_FILE = "hermesftp-users.xml";
58
59 private static final String ATTR_PATH = "path";
60
61 private static final String XPATH_PERMISSIONS = "permissions/permission";
62
63 private static final String ATTR_VALUE = "value";
64
65 private static final String ATTR_FLAG = "flag";
66
67 private static final String XPATH_LIMITS = "limits/limit";
68
69 private static final String XPATH_GROUPS = "/user-manager/groups/group";
70
71 private static final String ATTR_NAME = "name";
72
73 private static final String ELEM_GROUP_REF = "group-ref";
74
75 private static final String ATTR_DIR = "dir";
76
77 private static final String ATTR_PASSWORD = "password";
78
79 private static final String ATTR_FULLNAME = "fullname";
80
81 private static final String ATTR_ADMINROLE = "adminrole";
82
83 private static final String ATTR_UID = "uid";
84
85 private static final String ELEM_USER = "user";
86
87 private static final String ATTR_DEFAULT_DIR = "default-dir";
88
89 private static final String XPATH_USERS = "/user-manager/users";
90
91 private String filename;
92
93 /***
94 * Getter method for the java bean <code>filename</code>.
95 *
96 * @return Returns the value of the java bean <code>filename</code>.
97 */
98 public String getFilename() {
99 if (filename == null || filename.length() == 0) {
100 String ctxDir = System.getProperty("hermes.ctx.dir");
101 File file;
102 if (ctxDir != null) {
103 file = new File(ctxDir, DEFAULT_HERMESFTP_USERS_FILE);
104 } else {
105 file = new File(DEFAULT_HERMESFTP_USERS_FILE);
106 }
107 filename = file.getAbsolutePath();
108 }
109 log.info("User configuration file: " + filename);
110 return filename;
111 }
112
113 /***
114 * Setter method for the java bean <code>filename</code>.
115 *
116 * @param filename The value of filename to set.
117 */
118 public void setFilename(String filename) {
119 this.filename = filename;
120 }
121
122 /***
123 * Reads the user management data from a file. If the file was not found the classpath is
124 * searched.
125 *
126 * @return The user management data.
127 * @throws FtpConfigException Error on reading or processing a configuration file.
128 */
129 public UserManagerData read() throws FtpConfigException {
130 UserManagerData result;
131 File file = null;
132 try {
133 SAXReader reader = new SAXReader();
134 file = new File(getFilename());
135 BufferedReader br;
136 if (file.exists()) {
137 br = new BufferedReader(new FileReader(file));
138 } else {
139 InputStream is = getClass().getResourceAsStream("/" + DEFAULT_HERMESFTP_USERS_FILE);
140 br = new BufferedReader(new InputStreamReader(is));
141 }
142 Document doc = reader.read(br);
143 result = process(doc);
144 } catch (IOException e) {
145 throw new FtpConfigException("Reading " + getFilename() + " failed.");
146 } catch (DocumentException e) {
147 throw new FtpConfigException("Error while processing the configuration file " + file + ".");
148 }
149
150 return result;
151 }
152
153 private UserManagerData process(Document doc) {
154 UserManagerData result = new UserManagerData();
155 processUserData(doc, result);
156 processGroupData(doc, result);
157
158 return result;
159 }
160
161 @SuppressWarnings("unchecked")
162 private void processUserData(Document doc, UserManagerData umd) {
163 Element usersElement = (Element) doc.selectSingleNode(XPATH_USERS);
164 String defaultDir = usersElement.attributeValue(ATTR_DEFAULT_DIR);
165
166 List<Element> userElements = usersElement.selectNodes(ELEM_USER);
167 for (Element userElement : userElements) {
168 String uid = userElement.attributeValue(ATTR_UID);
169 String fullName = userElement.attributeValue(ATTR_FULLNAME);
170 String password = userElement.attributeValue(ATTR_PASSWORD);
171 String adminrole = userElement.attributeValue(ATTR_ADMINROLE);
172 String dir = userElement.attributeValue(ATTR_DIR);
173 if (dir == null || dir.length() == 0) {
174 dir = defaultDir;
175 }
176 UserData userData = new UserData();
177 userData.setFullName(fullName);
178 userData.setUid(uid);
179 userData.setPassword(password);
180 userData.setAdminRole(new Boolean(adminrole).booleanValue());
181 userData.setDir(dir);
182 List<Element> groupRefElements = userElement.selectNodes(ELEM_GROUP_REF);
183 for (Element element : groupRefElements) {
184 String groupRefName = element.attributeValue(ATTR_NAME);
185 if (groupRefName != null) {
186 userData.addGroupName(groupRefName.trim());
187 }
188 }
189 umd.getUserData().add(userData);
190
191 }
192 }
193
194 @SuppressWarnings("unchecked")
195 private void processGroupData(Document doc, UserManagerData umd) {
196 List<Element> groupElements = doc.selectNodes(XPATH_GROUPS);
197 for (Element groupElement : groupElements) {
198 String name = groupElement.attributeValue(ATTR_NAME);
199 GroupData groupData = new GroupData();
200 groupData.setName(name);
201
202 List<Element> limitElements = groupElement.selectNodes(XPATH_LIMITS);
203 for (Element limitElement : limitElements) {
204 String limitName = limitElement.attributeValue(ATTR_NAME);
205 String limitValue = limitElement.attributeValue(ATTR_VALUE);
206 if (limitName != null && limitValue != null) {
207 Long limitLong = new Long(limitValue);
208 groupData.getLimits().put(limitName, limitLong);
209 }
210 }
211 List<Element> permissionElements = groupElement.selectNodes(XPATH_PERMISSIONS);
212 for (Element permissionElement : permissionElements) {
213 String path = permissionElement.attributeValue(ATTR_PATH);
214
215
216 String value = permissionElement.attributeValue(ATTR_VALUE);
217 String flag = permissionElement.attributeValue(ATTR_FLAG);
218 int permissionValue = getPermissionValue(value, flag);
219 PermissionData pd = new PermissionData();
220 pd.setPermission(permissionValue);
221 pd.setTemplate(path);
222 groupData.getPermissions().add(pd);
223 }
224 umd.getGroupData().addGroup(groupData);
225 }
226 }
227
228 /***
229 * Decides on the permission value based on the passed arguments. Value attribute is supported
230 * for backward compatibility
231 *
232 * @param value The permission value 1=read, 3=read/write.
233 * @param flag The permission flag R=read, RW=read/write.
234 * @return The permission value.
235 */
236 private int getPermissionValue(String value, String flag) {
237 flag = flag == null ? "" : flag.toUpperCase().trim();
238 int permissionValue = 0;
239 if (value != null && value.length() > 0) {
240 permissionValue = Integer.parseInt(value);
241 }
242 if (flag.indexOf('R') >= 0) {
243 permissionValue |= 1;
244 }
245 if (flag.indexOf('W') >= 0) {
246 permissionValue |= 2;
247 }
248 return permissionValue;
249 }
250
251 }