Project

General

Profile

Revision 8419

Added by Jing Tao about 6 years ago

Add a file based authentication mechanism.

View differences:

src/edu/ucsb/nceas/metacat/authentication/AuthFile.java
1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2013 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
package edu.ucsb.nceas.metacat.authentication;
22

  
23
import java.io.File;
24
import java.io.FileOutputStream;
25
import java.io.IOException;
26
import java.io.OutputStreamWriter;
27
import java.net.ConnectException;
28
import java.util.HashMap;
29
import java.util.List;
30
import java.util.Properties;
31
import java.util.Vector;
32

  
33
import org.apache.commons.configuration.ConfigurationException;
34
import org.apache.commons.configuration.XMLConfiguration;
35
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
36

  
37
import edu.ucsb.nceas.metacat.AuthInterface;
38
import edu.ucsb.nceas.metacat.properties.PropertyService;
39
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
40

  
41
/**
42
 * This an authentication class base on a username/password file.
43
 * It is an alternative authentication mechanism of the ldap authentication.
44
 * This is a singleton class and the password file looks like:
45
 *<?xml version="1.0" encoding="UTF-8" ?>
46
 * <subjects>
47
 *  <users>
48
 *      <user name="uid=tao,o=NCEAS,dc=ecoinformatics,dc=org">
49
 *          <password>*******</password>
50
 *          <group>nceas-dev</group>
51
 *      </user>
52
 *  </users>
53
 *  <groups>
54
 *    <group name="nceas-dev"/>
55
 *  </groups>
56
 * </subjects>
57
 * http://commons.apache.org/proper/commons-configuration/userguide/howto_xml.html
58
 * @author tao
59
 *
60
 */
61
public class AuthFile implements AuthInterface {
62
    private static final String NAME = "name";
63
    private static final String PASSWORD = "password";
64
    private static final String SLASH = "/";
65
    private static final String AT = "@";
66
    private static final String SUBJECTS = "subjects";
67
    private static final String USERS = "users";
68
    private static final String USER = "user";
69
    private static final String GROUPS = "groups";
70
    private static final String GROUP = "group";
71
    private static final String INITCONTENT = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"+
72
                                    "<"+SUBJECTS+">\n"+"<"+USERS+">\n"+"</"+USERS+">\n"+"<"+GROUPS+">\n"+"</"+GROUPS+">\n"+"</"+SUBJECTS+">\n";
73
    
74
    private static AuthFile authFile = null;
75
    private XMLConfiguration userpassword = null;
76
    private static String passwordFilePath = null;
77
    /**
78
     * Get the instance of the AuthFile
79
     * @return
80
     * @throws AuthenticationException
81
     */
82
    public static AuthFile getInstance() throws AuthenticationException {
83
        if(authFile == null) {
84
            authFile = new AuthFile();
85
        }
86
        return authFile;
87
    }
88
    
89
    /**
90
     * Get the instance of the AuthFile from specified password file
91
     * @return
92
     * @throws AuthenticationException
93
     */
94
    public static AuthFile getInstance(String passwordFile) throws AuthenticationException {
95
        passwordFilePath = passwordFile;
96
        if(authFile == null) {
97
            authFile = new AuthFile();
98
        }
99
        return authFile;
100
    }
101
    
102
    /**
103
     * Constructor
104
     */
105
    private AuthFile() throws AuthenticationException {
106
        try {
107
            init();
108
        } catch (Exception e) {
109
            throw new AuthenticationException(e.getMessage());
110
        }
111
        
112
    }
113
    
114
    /*
115
     * Initialize the user/password configuration
116
     */
117
    private void init() throws PropertyNotFoundException, IOException, ConfigurationException {
118
        if(passwordFilePath == null) {
119
            passwordFilePath  = PropertyService.getProperty("auth.file.path");
120
        }
121
        File passwordFile = new File(passwordFilePath);
122
        //if the password file doesn't exist, create a new one and set the initial content
123
        if(!passwordFile.exists()) {
124
            passwordFile.createNewFile();
125
            OutputStreamWriter writer = null;
126
            FileOutputStream output = null;
127
            try {
128
              output = new FileOutputStream(passwordFile);
129
              writer = new OutputStreamWriter(output, "UTF-8");
130
              writer.write(INITCONTENT);
131
            } finally {
132
              writer.close();
133
              output.close();
134
            }
135
          }
136
          userpassword = new XMLConfiguration(passwordFile);
137
          userpassword.setExpressionEngine(new XPathExpressionEngine());
138
          userpassword.setAutoSave(true);
139
          userpassword.setDelimiterParsingDisabled(true);
140
          userpassword.setAttributeSplittingDisabled(true);
141
    }
142
    
143
    @Override
144
    public boolean authenticate(String user, String password)
145
                    throws AuthenticationException {
146
        String passwordRecord = userpassword.getString(USERS+SLASH+USER+"["+AT+NAME+"='"+user+"']"+SLASH+PASSWORD);
147
        if(passwordRecord != null) {
148
            if(passwordRecord.equals(password)) {
149
                return true;
150
            }
151
        }
152
        return false;
153
    }
154
    
155
    @Override
156
    public String[][] getUsers(String user, String password)
157
                    throws ConnectException {
158
        // TODO Auto-generated method stub
159
        return null;
160
    }
161
    
162
    @Override
163
    public String[] getUserInfo(String user, String password)
164
                    throws ConnectException {
165
        // TODO Auto-generated method stub
166
        return null;
167
    }
168
    
169
    @Override
170
    public String[] getUsers(String user, String password, String group)
171
                    throws ConnectException {
172
        // TODO Auto-generated method stub
173
        return null;
174
    }
175
    
176
    @Override
177
    public String[][] getGroups(String user, String password)
178
                    throws ConnectException {
179
        // TODO Auto-generated method stub
180
        return null;
181
    }
182
    
183
    @Override
184
    public String[][] getGroups(String user, String password, String foruser)
185
                    throws ConnectException {
186
        // TODO Auto-generated method stub
187
        return null;
188
    }
189
    
190
    @Override
191
    public HashMap<String, Vector<String>> getAttributes(String foruser)
192
                    throws ConnectException {
193
        // TODO Auto-generated method stub
194
        return null;
195
    }
196
    
197
    @Override
198
    public HashMap<String, Vector<String>> getAttributes(String user,
199
                    String password, String foruser) throws ConnectException {
200
        // TODO Auto-generated method stub
201
        return null;
202
    }
203
    
204
    @Override
205
    public String getPrincipals(String user, String password)
206
                    throws ConnectException {
207
        // TODO Auto-generated method stub
208
        return null;
209
    }
210
    
211
    /**
212
     * Add a user to the file
213
     * @param userName the name of the user
214
     * @param groups  the groups the user belong to. The group should exist in the file
215
     * @param password  the password of the user
216
     */
217
    public void addUser(String userName, String[] groups, String password) throws AuthenticationException{
218
        if(userName == null || userName.trim().equals("")) {
219
            throw new AuthenticationException("AuthFile.addUser - can't add a user whose name is null or blank.");
220
        }
221
        if(password == null || password.trim().equals("")) {
222
            throw new AuthenticationException("AuthFile.addUser - can't add a user whose password is null or blank.");
223
        }
224
        if(!userExists(userName)) {
225
            if(userpassword != null) {
226
              userpassword.addProperty(USERS+" "+USER+AT+NAME, userName);
227
              userpassword.addProperty(USERS+SLASH+USER+"["+AT+NAME+"='"+userName+"']"+" "+PASSWORD, password);
228
              if(groups != null) {
229
                  for(int i=0; i<groups.length; i++) {
230
                      String group = groups[i];
231
                      if(group != null && !group.trim().equals("")) {
232
                          if(groupExists(group)) {
233
                              userpassword.addProperty(USERS+SLASH+USER+"["+AT+NAME+"='"+userName+"']"+" "+GROUP, group);
234
                          }
235
                      }
236
                  }
237
              }
238
              userpassword.reload();
239
             }
240
        } else {
241
            throw new AuthenticationException("AuthFile.addUser - can't add the user "+userName+" since it already exists.");
242
        }
243
    }
244
    
245
    /**
246
     * Add a group into the file
247
     * @param groupName the name of group
248
     */
249
    public void addGroup(String groupName) throws AuthenticationException{
250
        if(groupName == null || groupName.trim().equals("")) {
251
            throw new AuthenticationException("AuthFile.addGroup - can't add a group whose name is null or blank.");
252
        }
253
        if(!groupExists(groupName)) {
254
            if(userpassword != null) {
255
              userpassword.addProperty(GROUPS+" "+GROUP+AT+NAME, groupName);
256
              userpassword.reload();
257
             }
258
        } else {
259
            throw new AuthenticationException("AuthFile.addGroup - can't add the group "+groupName+" since it already exists.");
260
        }
261
    }
262
    
263
    /**
264
     * Reset the password for the user
265
     * @param userName  the name of the user. The user should already exist
266
     * @param password  the password of the user.
267
     * @return
268
     */
269
    public String modifyUserPassword(String userName, String password) {
270
        return password;
271
    }
272
    
273
    /**
274
     * Add a user to a group
275
     * @param userName  the name of the user. the user should already exist
276
     * @param group  the name of the group. the group should already exist
277
     */
278
    public void addUserToGroup(String userName, String group) {
279
        
280
    }
281
    
282
    /**
283
     * Remove a user from a group.
284
     * @param userName  the name of the user. the user should already exist.
285
     * @param group the name of the group
286
     */
287
    public void removeUserFromGroup(String userName, String group) {
288
        
289
    }
290
    
291
    /**
292
     * If the specified user name exist or not
293
     * @param userName the name of the user
294
     * @return true if the user eixsit
295
     */
296
    private boolean userExists(String userName) throws AuthenticationException{
297
        if(userName == null || userName.trim().equals("")) {
298
            throw new AuthenticationException("AuthFile.userExist - can't judge if a user exists when its name is null or blank.");
299
        }
300
        List<Object> users = userpassword.getList(SLASH+SLASH+USERS+SLASH+USER+"["+AT+NAME+"='"+userName+"']");
301
        if(users != null && users.size() >0) {
302
            return true;
303
        } else {
304
            return false;
305
        }
306
    }
307
    
308
    /**
309
     * If the specified group exist or not
310
     * @param groupName the name of the group
311
     * @return true if the user exists
312
     */
313
    private boolean groupExists(String groupName) throws AuthenticationException{
314
        if(groupName == null || groupName.trim().equals("")) {
315
            throw new AuthenticationException("AuthFile.groupExist - can't judge if a group exists when its name is null or blank.");
316
        }
317
        List<Object> groups = userpassword.getList(GROUPS+SLASH+GROUP+SLASH+AT+NAME);
318
        if(groups != null && groups.contains(groupName)) {
319
            return true;
320
        } else {
321
            return false;
322
        }
323
    }
324
}
src/edu/ucsb/nceas/metacat/authentication/AuthenticationException.java
1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2013 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
package edu.ucsb.nceas.metacat.authentication;
22

  
23
import java.net.ConnectException;
24

  
25
/**
26
 * Exception class will be used in the authentication process
27
 * @author tao
28
 *
29
 */
30
public class AuthenticationException extends ConnectException {
31
    
32
    /**
33
     * Constructor
34
     * @param error
35
     */
36
    public AuthenticationException(String error) {
37
        super(error);
38
    }
39
}

Also available in: Unified diff