Project

General

Profile

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.Console;
24
import java.io.File;
25
import java.io.FileOutputStream;
26
import java.io.IOException;
27
import java.io.OutputStreamWriter;
28
import java.io.UnsupportedEncodingException;
29
import java.net.ConnectException;
30
import java.util.HashMap;
31
import java.util.List;
32
import java.util.Vector;
33

    
34

    
35

    
36

    
37

    
38

    
39
import org.apache.commons.configuration.ConfigurationException;
40
import org.apache.commons.configuration.XMLConfiguration;
41
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
42
import org.apache.commons.logging.Log;
43
import org.apache.commons.logging.LogFactory;
44

    
45
import edu.ucsb.nceas.metacat.AuthInterface;
46
import edu.ucsb.nceas.metacat.AuthLdap;
47
import edu.ucsb.nceas.metacat.properties.PropertyService;
48
import edu.ucsb.nceas.metacat.util.SystemUtil;
49
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
50

    
51
/**
52
 * This an authentication class base on a username/password file.
53
 * It is an alternative authentication mechanism of the ldap authentication.
54
 * The password file looks like:
55
 *<?xml version="1.0" encoding="UTF-8" ?>
56
 * <subjects>
57
 *  <users>
58
 *      <user dn="uid=tao,o=NCEAS,dc=ecoinformatics,dc=org">
59
 *          <password>*******</password>
60
 *          <email>foo@foo.com</email>
61
 *          <surName>Smith</surName>
62
 *          <givenName>John</givenName>
63
 *          <organization>NCEAS</organization>
64
 *          <group>nceas-dev</group>
65
 *      </user>
66
 *  </users>
67
 *  <groups>
68
 *    <group name="nceas-dev">
69
 *        <description>developers at NCEAS</description>
70
 *    </group>
71
 *  </groups>
72
 * </subjects>
73
 * http://commons.apache.org/proper/commons-configuration/userguide/howto_xml.html
74
 * @author tao
75
 *
76
 */
77
public class AuthFile implements AuthInterface {
78
    private static final String ORGANIZATIONNAME = "Unknown";
79
    private static final String ORGANIZATION = "organization";
80
    private static final String NAME = "name";
81
    private static final String DN = "dn";
82
    private static final String DESCRIPTION = "description";
83
    private static final String PASSWORD = "password";
84
    private static final String SLASH = "/";
85
    private static final String AT = "@";
86
    private static final String SUBJECTS = "subjects";
87
    private static final String USERS = "users";
88
    private static final String USER = "user";
89
    private static final String GROUPS = "groups";
90
    private static final String GROUP = "group";
91
    private static final String EMAIL = "email";
92
    private static final String SURNAME = "surName";
93
    private static final String GIVENNAME = "givenName";
94
    private static final String MEMBEROF = "memberof";
95
    private static final String INITCONTENT = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"+
96
                                    "<"+SUBJECTS+">\n"+"<"+USERS+">\n"+"</"+USERS+">\n"+"<"+GROUPS+">\n"+"</"+GROUPS+">\n"+"</"+SUBJECTS+">\n";
97
   
98
    
99
    
100
    private static Log log = LogFactory.getLog(AuthFile.class);
101
    private static AuthFile authFile = null;
102
    private static XMLConfiguration userpassword = null;
103
    private String authURI = null;
104
    private static String passwordFilePath = null;
105
    private static AuthFileHashInterface hashClass = null;
106
    /**
107
     * Get the instance of the AuthFile
108
     * @return
109
     * @throws AuthenticationException
110
     */
111
    /*public static AuthFile getInstance() throws AuthenticationException {
112
        if(authFile == null) {
113
            authFile = new AuthFile();
114
        }
115
        return authFile;
116
    }*/
117
    
118
    /**
119
     * Get the instance of the AuthFile from specified password file
120
     * @return
121
     * @throws AuthenticationException
122
     */
123
    /*public static AuthFile getInstance(String passwordFile) throws AuthenticationException {
124
        passwordFilePath = passwordFile;
125
        if(authFile == null) {
126
            authFile = new AuthFile();
127
        }
128
        return authFile;
129
    }*/
130
    
131
    /**
132
     * Constructor
133
     */
134
    public AuthFile() throws AuthenticationException {
135
        try {
136
            init();
137
        } catch (Exception e) {
138
            e.printStackTrace();
139
            throw new AuthenticationException(e.getMessage());
140
        }
141
        
142
    }
143
    
144
    /**
145
     * 
146
     * @param passwordFile
147
     * @throws AuthenticationException
148
     */
149
    public  AuthFile (String passwordFile) throws AuthenticationException {
150
        passwordFilePath = passwordFile;
151
        try {
152
            init();
153
        } catch (Exception e) {
154
            e.printStackTrace();
155
            throw new AuthenticationException(e.getMessage());
156
        }
157
    }
158
    
159
    /*
160
     * Initialize the user/password configuration
161
     */
162
    private void init() throws PropertyNotFoundException, IOException, ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException {
163
        if(passwordFilePath == null) {
164
            passwordFilePath  = PropertyService.getProperty("auth.file.path");
165
        }
166
        File passwordFile = new File(passwordFilePath);
167
        
168
        authURI = SystemUtil.getContextURL();
169
        String hashClassName = PropertyService.getProperty("auth.file.hashClassName");
170
        Class classDefinition = Class.forName(hashClassName);
171
        Object object = classDefinition.newInstance();
172
        hashClass = (AuthFileHashInterface) object;
173
        
174
        //if the password file doesn't exist, create a new one and set the initial content
175
        if(!passwordFile.exists()) {
176
            File parent = passwordFile.getParentFile();
177
            if(!parent.exists()) {
178
                parent.mkdirs();
179
            }
180
            passwordFile.createNewFile();
181
            OutputStreamWriter writer = null;
182
            FileOutputStream output = null;
183
            try {
184
              output = new FileOutputStream(passwordFile);
185
              writer = new OutputStreamWriter(output, "UTF-8");
186
              writer.write(INITCONTENT);
187
            } finally {
188
              writer.close();
189
              output.close();
190
            }
191
          }
192
          userpassword = new XMLConfiguration(passwordFile);
193
          userpassword.setExpressionEngine(new XPathExpressionEngine());
194
          userpassword.setAutoSave(true);
195
          userpassword.setDelimiterParsingDisabled(true);
196
          userpassword.setAttributeSplittingDisabled(true);
197
    }
198
    
199
    @Override
200
    public boolean authenticate(String user, String password)
201
                    throws AuthenticationException {
202
        boolean match = false;
203
        String passwordRecord = userpassword.getString(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+PASSWORD);
204
        if(passwordRecord != null) {
205
            try {
206
                match = hashClass.match(password, passwordRecord);
207
            } catch (Exception e) {
208
                throw new AuthenticationException(e.getMessage());
209
            }
210
            
211
        }
212
        return match;
213
    }
214
    
215
    @Override
216
    /**
217
     * Get all users. This is two-dimmention array. Each row is a user. The first element of
218
     * a row is the user name. The second element is common name. The third one is the organization name (null).
219
     * The fourth one is the organization unit name (null). The fifth one is the email address.
220
     */
221
    public String[][] getUsers(String user, String password)
222
                    throws ConnectException {
223
        List<Object> users = userpassword.getList(USERS+SLASH+USER+SLASH+AT+DN);
224
        if(users != null && users.size() > 0) {
225
            String[][] usersArray = new String[users.size()][5];
226
            for(int i=0; i<users.size(); i++) {
227
                
228
                String dn = (String)users.get(i);
229
                usersArray[i][AuthInterface.USERDNINDEX] = dn; //dn
230
                String[] userInfo = getUserInfo(dn, password);
231
                usersArray[i][AuthInterface.USERCNINDEX] = userInfo[AuthInterface.USERINFOCNINDEX];//common name
232
                usersArray[i][AuthInterface.USERORGINDEX] = userInfo[AuthInterface.USERINFOORGANIDEX];//organization name. We set null
233
                usersArray[i][AuthInterface.USERORGUNITINDEX] = null;//organization ou name. We set null.
234
                usersArray[i][AuthInterface.USEREMAILINDEX] = userInfo[AuthInterface.USERINFOEMAILINDEX];
235
               
236
            }
237
            return usersArray;
238
        }
239
        return null;
240
    }
241
    
242
    @Override
243
    /**
244
     * Get an array about the user. The first column is the common name, the second column is the organization name.
245
     * The third column is the email address. It always returns an array. But the elements of the array can be null.
246
     */
247
    public String[] getUserInfo(String user, String password)
248
                    throws ConnectException {
249
        String[] userinfo = new String[3];
250
        User aUser = new User();
251
        aUser.setDN(user);
252
        String surname = null;
253
        List<Object> surNames = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+SURNAME);
254
        if(surNames != null && !surNames.isEmpty()) {
255
            surname = (String)surNames.get(0);
256
        }
257
        aUser.setSurName(surname);
258
        String givenName = null;
259
        List<Object> givenNames = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+GIVENNAME);
260
        if(givenNames != null && !givenNames.isEmpty()) {
261
            givenName = (String)givenNames.get(0);
262
        }
263
        aUser.setGivenName(givenName);
264
        userinfo[AuthInterface.USERINFOCNINDEX] = aUser.getCn();//common name
265
        String organization = null;
266
        List<Object> organizations = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+ORGANIZATION);
267
        if(organizations != null && !organizations.isEmpty()) {
268
            organization = (String)organizations.get(0);
269
        }
270
        userinfo[AuthInterface.USERINFOORGANIDEX] = organization;//organization name.
271
        aUser.setOrganization(organization);
272
        List<Object> emails = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+EMAIL);
273
        String email = null;
274
        if(emails != null && !emails.isEmpty() ) {
275
            email = (String)emails.get(0);
276
        }
277
        aUser.setEmail(email);
278
        userinfo[AuthInterface.USERINFOEMAILINDEX] = email;
279
        return userinfo;
280
    }
281
    
282
    
283
    @Override
284
    /**
285
     * Get the users for a particular group from the authentication service
286
     * The null will return if there is no user.
287
     * @param user
288
     *            the user for authenticating against the service
289
     * @param password
290
     *            the password for authenticating against the service
291
     * @param group
292
     *            the group whose user list should be returned
293
     * @returns string array of the user names belonging to the group
294
     */
295
    public String[] getUsers(String user, String password, String group)
296
                    throws ConnectException {
297
        List<Object> users = userpassword.getList(USERS+SLASH+USER+"["+MEMBEROF+"='"+group+"']"+SLASH+AT+DN);
298
        if(users != null && users.size() > 0) {
299
            String[] usersArray = new String[users.size()];
300
            for(int i=0; i<users.size(); i++) {
301
                usersArray[i] = (String) users.get(i);
302
            }
303
            return usersArray;
304
        }
305
        return null;
306
    }
307
    
308
    @Override
309
    /**
310
     * Get all groups from the authentication service. It returns a two dimmension array. Each row is a
311
     * group. The first column is the group name. The second column is the description. The null will return if no group found.
312
     */
313
    public String[][] getGroups(String user, String password)
314
                    throws ConnectException {
315
        List<Object> groups = userpassword.getList(GROUPS+SLASH+GROUP+SLASH+AT+NAME);
316
        if(groups!= null && groups.size() >0) {
317
            String[][] groupsArray = new String[groups.size()][2];
318
            for(int i=0; i<groups.size(); i++) {
319
                String groupName = (String) groups.get(i);
320
                groupsArray[i][AuthInterface.GROUPNAMEINDEX] = groupName;
321
                String description = null;
322
                List<Object>descriptions = userpassword.getList(GROUPS+SLASH+GROUP+"["+AT+NAME+"='"+groupName+"']"+SLASH+DESCRIPTION);
323
                if(descriptions != null && !descriptions.isEmpty()) {
324
                    description = (String)descriptions.get(0);
325
                }
326
                groupsArray[i][AuthInterface.GROUPDESINDEX] = description; 
327
            }
328
            return groupsArray;
329
        }
330
        return null;
331
    }
332
    
333
    @Override
334
    /**
335
     * Get groups from a specified user. It returns two dimmension array. Each row is a
336
     * group. The first column is the group name. The null will return if no group found.
337
     */
338
    public String[][] getGroups(String user, String password, String foruser)
339
                    throws ConnectException {
340
        List<Object> groups = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+foruser+"']"+SLASH+MEMBEROF);
341
        if(groups != null && groups.size() > 0) {
342
            String[][] groupsArray = new String[groups.size()][2];
343
            for(int i=0; i<groups.size(); i++) {
344
                String groupName = (String) groups.get(i);
345
                groupsArray[i][AuthInterface.GROUPNAMEINDEX] = groupName;
346
                String description = null;
347
                List<Object>descriptions = userpassword.getList(GROUPS+SLASH+GROUP+"["+AT+NAME+"='"+groupName+"']"+SLASH+DESCRIPTION);
348
                if(descriptions != null && !descriptions.isEmpty()) {
349
                    description = (String)descriptions.get(0);
350
                }
351
                groupsArray[i][AuthInterface.GROUPDESINDEX] = description; 
352
            }
353
            return groupsArray;
354
        }
355
        return null;
356
    }
357
    
358
    @Override
359
    public HashMap<String, Vector<String>> getAttributes(String foruser)
360
                    throws ConnectException {
361
        // TODO Auto-generated method stub
362
        return null;
363
    }
364
    
365
    @Override
366
    public HashMap<String, Vector<String>> getAttributes(String user,
367
                    String password, String foruser) throws ConnectException {
368
        // TODO Auto-generated method stub
369
        return null;
370
    }
371
    
372
    @Override
373
    public String getPrincipals(String user, String password)
374
                    throws ConnectException {
375
            StringBuffer out = new StringBuffer();
376

    
377
            out.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
378
            out.append("<principals>\n");
379
            out.append("  <authSystem URI=\"" +authURI
380
                    + "\" organization=\"" + ORGANIZATIONNAME + "\">\n");
381

    
382
            // get all groups for directory context
383
            String[][] groups = getGroups(user, password);
384
            String[][] users = getUsers(user, password);
385
            int userIndex = 0;
386

    
387
            // for the groups and users that belong to them
388
            if (groups != null && users != null && groups.length > 0) {
389
                for (int i = 0; i < groups.length; i++) {
390
                    out.append("    <group>\n");
391
                    out.append("      <groupname>" + groups[i][AuthInterface.GROUPNAMEINDEX] + "</groupname>\n");
392
                    if(groups[i].length > 1) {
393
                        out.append("      <description>" + groups[i][AuthInterface.GROUPDESINDEX] + "</description>\n");
394
                    }
395
                    String[] usersForGroup = getUsers(user, password, groups[i][0]);
396
                    if(usersForGroup != null) {
397
                        for (int j = 0; j < usersForGroup.length; j++) {
398
                            userIndex = AuthLdap.searchUser(usersForGroup[j], users);
399
                            out.append("      <user>\n");
400

    
401
                            if (userIndex < 0) {
402
                                out.append("        <username>" + usersForGroup[j]
403
                                        + "</username>\n");
404
                            } else {
405
                                out.append("        <username>" + users[userIndex][0]
406
                                        + "</username>\n");
407
                                if(users[userIndex][AuthInterface.USERCNINDEX] != null) {
408
                                    out.append("        <name>" + users[userIndex][AuthInterface.USERCNINDEX]
409
                                                    + "</name>\n");
410
                                }
411
                                if(users[userIndex][AuthInterface.USERORGINDEX] != null) {
412
                                    out.append("        <organization>" + users[userIndex][AuthInterface.USERORGINDEX]
413
                                                    + "</organization>\n");
414
                                }
415
                                
416
                                if(users[userIndex][AuthInterface.USERORGUNITINDEX] != null) {
417
                                    out.append("      <organizationUnitName>"
418
                                                    + users[userIndex][AuthInterface.USERORGUNITINDEX]
419
                                                    + "</organizationUnitName>\n");
420
                                }
421
                                if(users[userIndex][AuthInterface.USEREMAILINDEX] != null) {
422
                                    out.append("        <email>" + users[userIndex][AuthInterface.USEREMAILINDEX]
423
                                                    + "</email>\n");
424
                                }
425
                               
426
                            }
427

    
428
                            out.append("      </user>\n");
429
                        }
430
                    }
431
                   
432
                    out.append("    </group>\n");
433
                }
434
            }
435

    
436
            if (users != null) {
437
                // for the users not belonging to any grou8p
438
                for (int j = 0; j < users.length; j++) {
439
                    out.append("    <user>\n");
440
                    out.append("      <username>" + users[j][0] + "</username>\n");
441
                    if(users[j][AuthInterface.USERCNINDEX] != null) {
442
                        out.append("        <name>" + users[j][AuthInterface.USERCNINDEX]
443
                                        + "</name>\n");
444
                    }
445
                    if(users[j][AuthInterface.USERORGINDEX] != null) {
446
                        out.append("        <organization>" + users[j][AuthInterface.USERORGINDEX]
447
                                        + "</organization>\n");
448
                    }
449
                    
450
                    if(users[j][AuthInterface.USERORGUNITINDEX] != null) {
451
                        out.append("      <organizationUnitName>"
452
                                        + users[j][AuthInterface.USERORGUNITINDEX]
453
                                        + "</organizationUnitName>\n");
454
                    }
455
                    if(users[j][AuthInterface.USEREMAILINDEX] != null) {
456
                        out.append("        <email>" + users[j][AuthInterface.USEREMAILINDEX]
457
                                        + "</email>\n");
458
                    }
459
                   
460
                    out.append("    </user>\n");
461
                }
462
            }
463

    
464
            out.append("  </authSystem>\n");
465
        
466
        out.append("</principals>");
467
        return out.toString();
468
    }
469
    
470
    /**
471
     * Add a user to the file
472
     * @param userName the name of the user
473
     * @param groups  the groups the user belong to. The group should exist in the file
474
     * @param password  the password of the user
475
     */
476
    public void addUser(String dn, String[] groups, String plainPass, String hashedPass, String email, String surName, String givenName, String organization) throws AuthenticationException{
477
       User user = new User();
478
       user.setDN(dn);
479
       user.setGroups(groups);
480
       user.setPlainPass(plainPass);
481
       user.setHashedPass(hashedPass);
482
       user.setEmail(email);
483
       user.setSurName(surName);
484
       user.setGivenName(givenName);
485
       user.setOrganization(organization);
486
       user.serialize();
487
    }
488
    
489
    /**
490
     * Add a group into the file
491
     * @param groupName the name of group
492
     */
493
    public void addGroup(String groupName, String description) throws AuthenticationException{
494
        if(groupName == null || groupName.trim().equals("")) {
495
            throw new AuthenticationException("AuthFile.addGroup - can't add a group whose name is null or blank.");
496
        }
497
        if(!groupExists(groupName)) {
498
            if(userpassword != null) {
499
              userpassword.addProperty(GROUPS+" "+GROUP+AT+NAME, groupName);
500
              if(description != null && !description.trim().equals("")) {
501
                  userpassword.addProperty(GROUPS+SLASH+GROUP+"["+AT+NAME+"='"+groupName+"']"+" "+DESCRIPTION, description);
502
              }
503
              //userpassword.reload();
504
             }
505
        } else {
506
            throw new AuthenticationException("AuthFile.addGroup - can't add the group "+groupName+" since it already exists.");
507
        }
508
    }
509
    
510
   
511
    
512
    /**
513
     * Change the password of the user to the new one which is hashed
514
     * @param usrName the specified user.   
515
     * @param newPassword the new password which will be set
516
     */
517
    public void modifyPassWithHash(String userName, String newHashPassword) throws AuthenticationException {
518
       User user = new User();
519
       user.setDN(userName);
520
       user.modifyHashPass(newHashPassword);
521
    }
522
    
523
    /**
524
     * Change the password of the user to the new one which is plain. However, only the hashed version will be serialized.
525
     * @param usrName the specified user.   
526
     * @param newPassword the new password which will be set
527
     */
528
    public void modifyPassWithPlain(String userName, String newPlainPassword) throws AuthenticationException {
529
        User user = new User();
530
        user.setDN(userName);
531
        user.modifyPlainPass(newPlainPassword);
532
    }
533
    
534
    
535
    /**
536
     * Add a user to a group
537
     * @param userName  the name of the user. the user should already exist
538
     * @param group  the name of the group. the group should already exist
539
     */
540
    public void addUserToGroup(String userName, String group) throws AuthenticationException {
541
        User user = new User();
542
        user.setDN(userName);
543
        user.addToGroup(group);
544
    }
545
    
546
    /**
547
     * Remove a user from a group.
548
     * @param userName  the name of the user. the user should already exist.
549
     * @param group the name of the group
550
     */
551
    public void removeUserFromGroup(String userName, String group) throws AuthenticationException{
552
        User user = new User();
553
        user.setDN(userName);
554
        user.removeFromGroup(group);
555
    }
556
    
557
  
558
    
559
    /**
560
     * If the specified user name exist or not
561
     * @param userName the name of the user
562
     * @return true if the user eixsit
563
     */
564
    private synchronized boolean userExists(String userName) throws AuthenticationException{
565
        if(userName == null || userName.trim().equals("")) {
566
            throw new AuthenticationException("AuthFile.userExist - can't judge if a user exists when its name is null or blank.");
567
        }
568
        List<Object> users = userpassword.getList(USERS+SLASH+USER+SLASH+AT+DN);
569
        if(users != null && users.contains(userName)) {
570
            return true;
571
        } else {
572
            return false;
573
        }
574
    }
575
    
576
    /**
577
     * If the specified group exist or not
578
     * @param groupName the name of the group
579
     * @return true if the user exists
580
     */
581
    private synchronized boolean groupExists(String groupName) throws AuthenticationException{
582
        if(groupName == null || groupName.trim().equals("")) {
583
            throw new AuthenticationException("AuthFile.groupExist - can't judge if a group exists when its name is null or blank.");
584
        }
585
        List<Object> groups = userpassword.getList(GROUPS+SLASH+GROUP+SLASH+AT+NAME);
586
        if(groups != null && groups.contains(groupName)) {
587
            return true;
588
        } else {
589
            return false;
590
        }
591
    }
592
    
593
    /*
594
     * Encrypt a plain text
595
     */
596
    private static String encrypt(String plain)  {
597
      return hashClass.hash(plain);
598
    }
599
    
600
    
601
    /**
602
     * A method is used to help administrator to manage users and groups
603
     * @param argus
604
     * @throws Exception
605
     */
606
    public static void main(String[] argus) throws Exception {
607
            String USERADD = "useradd";
608
            String USERMOD = "usermod";
609
            String GROUPADD = "groupadd";
610
            String USAGE = "usage";
611
            if(argus == null || argus.length ==0) {
612
              System.out.println("Please make sure that there are two arguments - \"$BASE_WEB_INF\" and\" $@\" after the class name edu.ucsb.nceas.metacat.authentication.AuthFile in the script file.");
613
              System.exit(1);
614
            } else if(argus.length ==1) {
615
                printUsage();
616
                System.exit(1);
617
            }
618
            PropertyService.getInstance(argus[0]);
619
            AuthFile authFile = new AuthFile();
620
            if(argus[1] != null && argus[1].equals(GROUPADD)) {
621
                handleGroupAdd(authFile,argus);
622
            } else if (argus[1] != null && argus[1].equals(USERADD)) {
623
                handleUserAdd(authFile,argus);
624
            } else if (argus[1] != null && argus[1].equals(USERMOD)) {
625
                handleUserMod(authFile, argus);
626
            } else if (argus[1] != null && argus[1].equals(USAGE)) {
627
                printUsage();
628
            } else {
629
                System.out.print("Error: the unknown action "+argus[1]);
630
            }
631
    }
632
    
633
    /*
634
     * Handle the groupAdd action in the main method
635
     */
636
    private static void handleGroupAdd(AuthFile authFile, String[]argus) throws AuthenticationException {
637
        HashMap<String, String> map = null;
638
        String G = "-g";
639
        String D = "-d";
640
        Vector<String> pairedOptions = new Vector<String>();
641
        pairedOptions.add(G);
642
        pairedOptions.add(D);
643
        int startIndex = 2;
644
        try {
645
            map = parseArgus(startIndex, argus, pairedOptions, null);
646
        } catch (Exception e ) {
647
            System.out.println("Error in the groupadd command: "+e.getMessage());
648
            System.exit(1);
649
        }
650
        String groupName = null;
651
        String description = null;
652
        if(map.keySet().size() == 0) {
653
            System.out.println("Error in the groupadd command: the \""+G+" group-name\" is required.");
654
            System.exit(1);
655
        } else if(map.keySet().size() ==1 || map.keySet().size() ==2) {
656
            groupName = map.get(G);
657
            if(groupName == null || groupName.trim().equals("")) {
658
                System.out.println("Error in the groupadd command : the \""+G+" group-name\" is required.");
659
                System.exit(1);
660
            }
661
            description = map.get(D);
662
            authFile.addGroup(groupName, description);
663
            System.out.println("Successfully added a group \""+groupName+"\" to the file authentication system");
664
        } else {
665
            printError(argus);
666
            System.exit(1);
667
        }
668
    }
669
    
670
    /*
671
     * Handle the userAdd action in the main method
672
     */
673
    private static void  handleUserAdd(AuthFile authFile,String[]argus) throws UnsupportedEncodingException, AuthenticationException{
674
      
675
        String I = "-i";
676
        String H = "-h";
677
        String DN = "-dn";
678
        String G = "-g";
679
        String E = "-e";
680
        String S = "-s";
681
        String F = "-f";
682
        String O= "-o";
683
        Vector<String> pairedOptions = new Vector<String>();
684
        pairedOptions.add(H);
685
        pairedOptions.add(DN);
686
        pairedOptions.add(G);
687
        pairedOptions.add(E);
688
        pairedOptions.add(S);
689
        pairedOptions.add(F);
690
        pairedOptions.add(O);
691
        Vector<String> singleOptions = new Vector<String>();
692
        singleOptions.add(I);
693
        
694
        HashMap<String, String> map = new HashMap<String, String>();
695
        int startIndex = 2;
696
        try {
697
            map = parseArgus(startIndex, argus, pairedOptions, singleOptions);
698
        } catch (Exception e) {
699
            System.out.println("Error in the useradd command: "+e.getMessage());
700
            System.exit(1);
701
        }
702
       
703
        String dn = map.get(DN);
704
        if(dn == null || dn.trim().equals("")) {
705
            System.out.println("The \"-dn user-distinguish-name\" is requried in the useradd command ."); 
706
            System.exit(1);
707
        } 
708
        String plainPassword = null;
709
        String hashedPassword = null;
710
       
711
        
712
        String input = map.get(I);
713
        String passHash = map.get(H);
714
        if(input != null && passHash != null) {
715
            System.out.println("Error in the useradd command: you only can choose either \"-i\"(input a password) or \"-h hashed-password\"(pass through a hashed passwword).");
716
            System.exit(1);
717
        } else if (input == null && passHash == null) {
718
            System.out.println("Error in the useradd command: you must choose either \"-i\"(input a password) or \"-h hashed-password\"(pass through a hashed password).");
719
            System.exit(1);
720
        } else if(input != null) {
721
            plainPassword = inputPassword();
722
            //System.out.println("============the plain password is "+plainPassword);
723
        } else if(passHash != null) {
724
            hashedPassword = passHash;
725
        }
726
        
727
        String group = map.get(G);
728
        //System.out.println("the groups name is "+group);
729
        String[] groups = null;
730
        if(group != null && !group.trim().equals("")) {
731
            groups = new String[1];
732
            groups[0]=group;
733
            //System.out.println("set the first element of the groups to "+groups[0]);
734
        }
735
        String email = map.get(E);
736
        String surname = map.get(S);
737
        String givenname = map.get(F);
738
        String organization = map.get(O);
739
        authFile.addUser(dn, groups, plainPassword, hashedPassword, email, surname, givenname, organization);
740
        System.out.println("Successfully added a user \""+dn+"\" to the file authentication system ");
741
    }
742
    
743
    /*
744
     * Handle modify a user's password or group information.
745
     */
746
    private static void handleUserMod(AuthFile authFile, String[] argus) throws AuthenticationException, UnsupportedEncodingException {
747
        String PASSWORD = "-password";
748
        String GROUP = "-group";
749
        if(argus.length < 3) {
750
            System.out.println("Error: the sub action \"-password\" or \"-group\" should follow the action \"usermod\"");
751
            System.exit(1);
752
        } else {
753
            if(argus[2] != null && argus[2].equals(PASSWORD)) {
754
                handleModifyPass(authFile, argus);
755
            } else if (argus[2] != null && argus[2].equals(GROUP)) {
756
                handleModifyGroup(authFile, argus);
757
            } else {
758
                System.out.println("Error: the sub action \""+argus[2]+"\" is unkown in the action \"usermod\"");
759
                System.exit(1);
760
            }
761
        }
762
    }
763
    
764
    /*
765
     * Handle the action to modify the password of a user
766
     */
767
    private static void handleModifyPass(AuthFile authFile, String[] argus) throws UnsupportedEncodingException, AuthenticationException {
768
        String DN = "-dn";
769
        String I= "-i";
770
        String H = "-h";
771
        Vector<String> pairedOptions = new Vector<String>();
772
        pairedOptions.add(H);
773
        pairedOptions.add(DN);
774
        Vector<String> singleOptions = new Vector<String>();
775
        singleOptions.add(I);
776
        HashMap<String, String> map = new HashMap<String, String>();
777
        int startIndex = 3;
778
        try {
779
            map = parseArgus(startIndex, argus, pairedOptions, singleOptions);
780
        } catch (Exception e) {
781
            System.out.println("Error in the usermod -password command: "+e.getMessage());
782
            System.exit(1);
783
        }
784
      
785
        String dn = map.get(DN);
786
        if(dn == null || dn.trim().equals("")) {
787
            System.out.println("Error in the usermod -password command: The \"-dn user-distinguish-name\" is requried."); 
788
            System.exit(1);
789
        }
790
        String plainPassword = null;
791
        String hashedPassword = null;
792
        
793
        String input = map.get(I);
794
        String passHash = map.get(H);
795
        if(input != null && passHash != null) {
796
            System.out.println("Error in the usermod -password command: you only can choose either \"-i\"(input a password) or \"-h hashed-password\"(pass through a hashed password).");
797
            System.exit(1);
798
        } else if (input == null && passHash == null) {
799
            System.out.println("Error in the usermod -password command: you must choose either \"-i\"(input a password) or \"-h hashed-password\"(pass through a hashed password).");
800
            System.exit(1);
801
        } else if(input != null) {
802
            plainPassword = inputPassword();
803
            //System.out.println("============the plain password is "+plainPassword);
804
            authFile.modifyPassWithPlain(dn, plainPassword);
805
            System.out.println("Successfully modified the password for the user \""+dn+"\".");
806
        } else if(passHash != null) {
807
            hashedPassword = passHash;
808
            authFile.modifyPassWithHash(dn, hashedPassword);
809
            System.out.println("Successfully modified the password for the user "+dn+"\".");
810
        }
811
    }
812
    
813
    /*
814
     * Handle the action adding/removing a user to/from a group
815
     */
816
    private static void handleModifyGroup(AuthFile authFile, String[] argus) throws AuthenticationException {
817
        String DN = "-dn";
818
        String A= "-a";
819
        String R = "-r";
820
        String G = "-g";
821
        Vector<String> pairedOptions = new Vector<String>();
822
        pairedOptions.add(G);
823
        pairedOptions.add(DN);
824
        Vector<String> singleOptions = new Vector<String>();
825
        singleOptions.add(A);
826
        singleOptions.add(R);
827
        HashMap<String, String> map = new HashMap<String, String>();
828
        int startIndex = 3;
829
        try {
830
            map = parseArgus(startIndex, argus, pairedOptions, singleOptions);
831
        } catch (Exception e) {
832
            System.out.println("Error in the usermod -group command: "+e.getMessage());
833
            System.exit(1);
834
        }
835
               
836
        String add = map.get(A);
837
        String remove = map.get(R);
838
        String group = map.get(G);
839
        String dn = map.get(DN);
840
        if(dn == null || dn.trim().equals("")) {
841
            System.out.println("Erorr in the usermod -group command: the \"-dn user-distinguish-name\" is required.");
842
            System.exit(1);
843
        }
844
        
845
        if(group == null || group.trim().equals("")) {
846
            System.out.println("Erorr in the usermod -group command: the \"-g group-name\" is required.");
847
            System.exit(1);
848
        }
849
        
850
        if(add != null && remove!= null) {
851
            System.out.println("Erorr in the usermod -group command: You can only choose either \"-a\"(add the user to the group) or \"-r\"(remove the user from the group).");
852
            System.exit(1);
853
        } else if (add == null && remove == null) {
854
            System.out.println("Erorr in the usermod -group command: You must choose either \"-a\"(add the user to the group) or \"-r\"(remove the user from the group).");
855
            System.exit(1);
856
        } else if (remove != null) {
857
            authFile.removeUserFromGroup(dn, group);
858
            System.out.println("Successfully removed the user "+dn+" from the group \""+group+"\".");
859
        } else {
860
            authFile.addUserToGroup(dn, group);
861
            System.out.println("Successfully added the user "+dn+" to the group \""+group+"\".");
862
        }
863
    }
864
    
865
    
866
    /**
867
     * Parse the arguments to get the pairs of option/value. If it is a single option (it doesn't need a value), the pair will be switch/switch. 
868
     * @param startIndex the index of arguments where we will start.
869
     * @param argus the arguments array will be parsed.
870
     * @param pairedOptions the known options which should be a pair
871
     * @param singleOptions the know options which just has a single value
872
     * @return the empty map if there is no pairs were found
873
     * @throws Exception if there is an illegal argument.
874
     */
875
    private static HashMap<String, String> parseArgus(int startIndex, String[]argus, Vector<String>pairedOptions, Vector<String>singleOptions) throws Exception {
876
        HashMap<String, String> map = new HashMap<String, String>();
877
        if(argus != null) {
878
            for(int i=startIndex; i<argus.length; i++) {
879
                String arg = argus[i];
880
                if(map.containsKey(arg)) {
881
                    throw new Exception("The command line can't have the duplicated options \""+arg+"\".");
882
                }
883
                
884
                if(singleOptions != null && singleOptions.contains(arg)) {
885
                    //we find a single option
886
                    if(i==argus.length-1) {
887
                        //it is the last argument, this is fine.
888
                        map.put(arg, arg);
889
                    } else if (i<argus.length -1) {
890
                        //it is not the last argument. 
891
                        if ((pairedOptions != null && pairedOptions.contains(argus[i+1])) || singleOptions.contains(argus[i+1])) {
892
                            //it follows an option, this is fine
893
                            map.put(arg, arg);
894
                        } else {
895
                            //it follows a vlaue, this is illegal
896
                            throw new Exception("The option \""+arg+"\" shouldn't be followed any value, e.g. "+ argus[i+1]+".");
897
                        }
898
                    }
899
                } else if (pairedOptions != null && pairedOptions.contains(arg)) {
900
                    //we found an option which should follow a vlaue
901
                    if(i==argus.length-1) {
902
                        //it is the last argument (no value follows it)
903
                        throw new Exception("The option \""+arg+"\" must be followed by a value");
904
                    } else {
905
                        //it is not the last argument and we need to check its following value
906
                        if (!pairedOptions.contains(argus[i+1]) && (singleOptions == null || !singleOptions.contains(argus[i+1]))) {
907
                            //it is NOT followed by an option, this is fine
908
                            map.put(arg, argus[i+1]);
909
                        } else {
910
                            //it is followed by an option, this is illegal
911
                            throw new Exception("The option \""+arg+"\" shouldn't be followed the option \""+ argus[i+1]+"\". It should be followed by a value.");
912
                        }
913
                    }
914
                } else {
915
                    //we found an argument is not an option
916
                    if(pairedOptions == null || !pairedOptions.contains(argus[i-1])) {
917
                        //the previous argument is not an option switch
918
                        throw new Exception("The \""+arg+"\" is an illegal argument");
919
                    }
920
                }
921
            } 
922
        }
923
        return map;
924
    }
925
    
926
    /*
927
     * Input the password
928
     */
929
    private static String inputPassword() throws UnsupportedEncodingException {
930
        String password = null;
931
        String quit = "q";
932
        Console console = System.console();
933
        if (console == null) {
934
            System.out.println("Sorry, we can't fetch the console from the system. You can't use the option \"-i\" to input a password. You have to use the option \"-h hashed-passpwrd\" to pass through a hashed passwprd in the useradd command. ");
935
            System.exit(1);
936
        }
937
  
938
        while(true) {
939
                System.out.print("Enter your new password(input 'q' to quite): ");
940
                String password1 = new String(console.readPassword());
941
                if(password1== null || password1.trim().equals("")) {
942
                    System.out.println("Eorror: the password can't be blank or null. Please try again.");
943
                    continue;
944
                } else if (password1.equals(quit)) {
945
                    System.exit(0);
946
                }
947
                System.out.print("Confirm your new password(input 'q' to quite): ");
948
                String password2 = new String(console.readPassword());
949
                if(password2 == null || password2.trim().equals("")) {
950
                    System.out.println("Eorror: the password can't be blank or null. Please try again.");
951
                    continue;
952
                }  else if (password2.equals(quit)) {
953
                    System.exit(0);
954
                }
955
                
956
                if(!password1.equals(password2)) {
957
                    System.out.println("Eorror: The second passwords does't match the first one. Please try again.");
958
                } else {
959
                    password = password1;
960
                    break;
961
                }
962
                
963
            
964
        }
965
        
966
        return password;
967
        
968
    }
969
    /*
970
     * Print out the usage statement
971
     */
972
    private static void printUsage() {
973
        System.out.println("Usage:\n"+
974
                        "./authFileManager.sh useradd -i -dn user-distinguish-name -g group-name -e email-address -s surname -f given-name -o organizationName\n" +
975
                        "./authFileManager.sh useradd -h hashed-password -dn user-distinguish-name -g group-name -e email-address -s surname -f given-name -o organizationName\n"+
976
                        "./authFileManager.sh groupadd -g group-name -d description\n" +
977
                        "./authFileManager.sh usermod -password -dn user-distinguish-name -i\n"+
978
                        "./authFileManager.sh usermod -password -dn user-distinguish-name -h new-hashed-password\n"+
979
                        "./authFileManager.sh usermod -group -a -dn user-distinguish-name -g added-group-name\n" +
980
                        "./authFileManager.sh usermod -group -r -dn user-distinguish-name -g removed-group-name\n"+
981
                        "Note:\n1. if a value of an option has spaces, the value should be enclosed by the double quotes.\n"+
982
                        "  For example: ./authFileManager.sh groupadd -g nceas-dev -d \"Developers at NCEAS\"\n"+
983
                        "2. \"-d description\" in groupadd is optional; \"-g groupname -e email-address -s surname -f given-name -o organizationName\" in useradd are optional as well.");
984
                       
985
                        
986
    }
987
    
988
    /*
989
     * Print out the statement to say it is a illegal command
990
     */
991
    private static void printError(String[] argus) {
992
        if(argus != null) {
993
            System.out.println("Error: it is an illegal command (probably with some illegal options): ");
994
            for(int i=0; i<argus.length; i++) {
995
                if(i!= 0) {
996
                    System.out.print(argus[i]+" ");
997
                }
998
            }
999
            System.out.println("");
1000
        }
1001
       
1002
    }
1003

    
1004
    
1005
    /**
1006
     * An class represents the information for a user. 
1007
     * @author tao
1008
     *
1009
     */
1010
    private class User {
1011
        private String dn = null;//the distinguish name
1012
        private String plainPass = null;
1013
        private String hashedPass = null;
1014
        private String email = null;
1015
        private String surName = null;
1016
        private String givenName = null;
1017
        private String cn = null;//the common name
1018
        private String[] groups = null;
1019
        private String organization = null;
1020
        
1021
        /**
1022
         * Get the organization of the user
1023
         * @return
1024
         */
1025
        public String getOrganization() {
1026
            return organization;
1027
        }
1028
        
1029
        /**
1030
         * Set the organization for the user.
1031
         * @param organization
1032
         */
1033
        public void setOrganization(String organization) {
1034
            this.organization = organization;
1035
        }
1036
        /**
1037
         * Get the distinguish name of the user
1038
         * @return the distinguish name 
1039
         */
1040
        public String getDN() {
1041
            return this.dn;
1042
        }
1043
        
1044
        /**
1045
         * Set the distinguish name for the user
1046
         * @param dn the specified dn
1047
         */
1048
        public void setDN(String dn) {
1049
            this.dn = dn;
1050
        }
1051
        
1052
        /**
1053
         * Get the plain password for the user. This value will NOT be serialized to
1054
         * the password file
1055
         * @return the plain password for the user
1056
         */
1057
        public String getPlainPass() {
1058
            return plainPass;
1059
        }
1060
        
1061
        /**
1062
         * Set the plain password for the user.
1063
         * @param plainPass the plain password will be set.
1064
         */
1065
        public void setPlainPass(String plainPass) {
1066
            this.plainPass = plainPass;
1067
        }
1068
        
1069
        /**
1070
         * Get the hashed password of the user
1071
         * @return the hashed password of the user
1072
         */
1073
        public String getHashedPass() {
1074
            return hashedPass;
1075
        }
1076
        
1077
        /**
1078
         * Set the hashed the password for the user.
1079
         * @param hashedPass the hashed password will be set.
1080
         */
1081
        public void setHashedPass(String hashedPass) {
1082
            this.hashedPass = hashedPass;
1083
        }
1084
        
1085
        /**
1086
         * Get the email of the user
1087
         * @return the email of the user
1088
         */
1089
        public String getEmail() {
1090
            return email;
1091
        }
1092
        
1093
        /**
1094
         * Set the email address for the user
1095
         * @param email the eamil address will be set
1096
         */
1097
        public void setEmail(String email) {
1098
            this.email = email;
1099
        }
1100
        
1101
        /**
1102
         * Get the surname of the user
1103
         * @return the surname of the user
1104
         */
1105
        public String getSurName() {
1106
            return surName;
1107
        }
1108
        
1109
        /**
1110
         * Set the surname of the user
1111
         * @param surName
1112
         */
1113
        public void setSurName(String surName) {
1114
            this.surName = surName;
1115
        }
1116
        
1117
        /**
1118
         * Get the given name of the user
1119
         * @return the given name of the user
1120
         */
1121
        public String getGivenName() {
1122
            return givenName;
1123
        }
1124
        
1125
        /**
1126
         * Set the GivenName of the user
1127
         * @param givenName
1128
         */
1129
        public void setGivenName(String givenName) {
1130
            this.givenName = givenName;
1131
        }
1132
        
1133
        /**
1134
         * Get the common name of the user. If the cn is null, the GivenName +SurName will
1135
         * be returned
1136
         * @return the common name
1137
         */
1138
        public String getCn() {
1139
            if(cn != null) {
1140
                return cn;
1141
            } else {
1142
                if (givenName != null && surName != null) {
1143
                    return givenName+" "+surName;
1144
                } else if (givenName != null) {
1145
                    return givenName;
1146
                } else if (surName != null ) {
1147
                    return surName;
1148
                } else {
1149
                    return null;
1150
                }
1151
            }
1152
        }
1153
        
1154
        /**
1155
         * Set the common name for the user
1156
         * @param cn
1157
         */
1158
        public void setCn(String cn) {
1159
            this.cn = cn;
1160
        }
1161
        
1162
        /**
1163
         * Get the groups of the user belong to
1164
         * @return
1165
         */
1166
        public String[] getGroups() {
1167
            return groups;
1168
        }
1169
        
1170
        /**
1171
         * Set the groups of the user belong to
1172
         * @param groups
1173
         */
1174
        public void setGroups(String[] groups) {
1175
            this.groups = groups;
1176
        }
1177
        
1178
        /**
1179
         * Add the user to a group and serialize the change to the password file.
1180
         * @param group the group which the user will join
1181
         * @throws AuthenticationException 
1182
         */
1183
        public void addToGroup(String group) throws AuthenticationException {
1184
            if(group == null || group.trim().equals("")) {
1185
                throw new IllegalArgumentException("AuthFile.User.addToGroup - the group can't be null or blank");
1186
            }
1187
            if(!userExists(dn)) {
1188
                throw new AuthenticationException("AuthFile.User.addUserToGroup - the user "+dn+ " doesn't exist.");
1189
            }
1190
            if(!groupExists(group)) {
1191
                throw new AuthenticationException("AuthFile.User.addUserToGroup - the group "+group+ " doesn't exist.");
1192
            }
1193
            List<Object> existingGroups = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+SLASH+MEMBEROF);
1194
            if(existingGroups != null && existingGroups.contains(group)) {
1195
                throw new AuthenticationException("AuthFile.User.addUserToGroup - the user "+dn+ " already is the memember of the group "+group);
1196
            }
1197
            userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+MEMBEROF, group);
1198
            //add information to the memory
1199
            if(groups == null) {
1200
                if(existingGroups == null || existingGroups.isEmpty()) {
1201
                    groups = new String[1];
1202
                    groups[0] = group;
1203
                } else {
1204
                    groups = new String[existingGroups.size()+1];
1205
                    for(int i=0; i<existingGroups.size(); i++) {
1206
                        groups[i] = (String)existingGroups.get(i);
1207
                    }
1208
                    groups[existingGroups.size()] = group;
1209
                }
1210
                
1211
            } else {
1212
                String[] oldGroups = groups;
1213
                groups = new String[oldGroups.length+1];
1214
                for(int i=0; i<oldGroups.length; i++) {
1215
                    groups[i]= oldGroups[i];
1216
                }
1217
                groups[oldGroups.length] = group;
1218
                
1219
            }
1220
        }
1221
        
1222
        /**
1223
         * Remove the user from a group and serialize the change to the password file
1224
         * @param group
1225
         * @throws AuthenticationException
1226
         */
1227
        public void removeFromGroup(String group) throws AuthenticationException {
1228
            if(!userExists(dn)) {
1229
                throw new AuthenticationException("AuthFile.User.removeUserFromGroup - the user "+dn+ " doesn't exist.");
1230
            }
1231
            if(!groupExists(group)) {
1232
                throw new AuthenticationException("AuthFile.User.removeUserFromGroup - the group "+group+ " doesn't exist.");
1233
            }
1234
            String key = USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+SLASH+MEMBEROF;
1235
            List<Object> existingGroups = userpassword.getList(key);
1236
            if(!existingGroups.contains(group)) {
1237
                throw new AuthenticationException("AuthFile.User.removeUserFromGroup - the user "+dn+ " isn't the memember of the group "+group);
1238
            } else {
1239
                userpassword.clearProperty(key+"[.='"+group+"']");
1240
            }
1241
            //change the value in the memory.
1242
            if(groups != null) {
1243
                boolean contains = false;
1244
                for(int i=0; i<groups.length; i++) {
1245
                    if(groups[i].equals(group)) {
1246
                        contains = true;
1247
                        break;
1248
                    }
1249
                }
1250
                String[] newGroups = new String[groups.length-1];
1251
                int k =0;
1252
                for(int i=0; i<groups.length; i++) {
1253
                    if(!groups[i].equals(group)) {
1254
                       newGroups[k] = groups[i];
1255
                       k++;
1256
                    }
1257
                }
1258
                groups = newGroups;
1259
            }
1260
        }
1261
        
1262
        /**
1263
         * Modify the hash password and serialize it to the password file
1264
         * @param hashPass
1265
         * @throws AuthenticationException
1266
         */
1267
        public void modifyHashPass(String hashPass) throws AuthenticationException {
1268
            if(hashPass == null || hashPass.trim().equals("")) {
1269
                throw new AuthenticationException("AuthFile.User.modifyHashPass - can't change the password to the null or blank.");
1270
            }
1271
            if(!userExists(dn)) {
1272
                throw new AuthenticationException("AuthFile.User.modifyHashPass - can't change the password for the user "+dn+" since it doesn't eixt.");
1273
            }
1274
            userpassword.setProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+SLASH+PASSWORD, hashPass);
1275
            setHashedPass(hashPass);
1276
      
1277
        }
1278
        
1279
        /**
1280
         * Modify the plain password and serialize its hash version to the password file
1281
         * @param plainPass
1282
         * @throws AuthenticationException 
1283
         */
1284
        public void modifyPlainPass(String plainPass) throws AuthenticationException {
1285
            if(plainPass == null || plainPass.trim().equals("")) {
1286
                throw new AuthenticationException("AuthFile.User.modifyPlainPass - can't change the password to the null or blank.");
1287
            }
1288
            if(!userExists(dn)) {
1289
                throw new AuthenticationException("AuthFile.User.modifyPlainPass - can't change the password for the user "+dn+" since it doesn't eixt.");
1290
            }
1291
            String hashPassword = null;
1292
            try {
1293
                hashPassword = encrypt(plainPass);
1294
            } catch (Exception e) {
1295
                throw new AuthenticationException("AuthFile.User.modifyPlainPass - can't encript the password since "+e.getMessage());
1296
            }
1297
            userpassword.setProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+SLASH+PASSWORD, hashPassword);
1298
            setPlainPass(plainPass);
1299
        }
1300
        
1301
        /**
1302
         * Add the user to the password file. 
1303
         */
1304
        public void serialize() throws AuthenticationException {
1305
            if(dn == null || dn.trim().equals("")) {
1306
                throw new AuthenticationException("AuthFile.User.serialize - can't add a user whose name is null or blank.");
1307
            }
1308
            if(hashedPass == null || hashedPass.trim().equals("")) {
1309
                if(plainPass == null || plainPass.trim().equals("")) {
1310
                    throw new AuthenticationException("AuthFile.User.serialize - can't add a user whose password is null or blank.");
1311
                } else {
1312
                    try {
1313
                        hashedPass = encrypt(plainPass);
1314
                    } catch (Exception e) {
1315
                        throw new AuthenticationException("AuthFile.User.serialize - can't encript the password since "+e.getMessage());
1316
                    }
1317
                }
1318
            }
1319
            if(groups != null) {
1320
                for(int i=0; i<groups.length; i++) {
1321
                    String group = groups[i];
1322
                    if(group != null && !group.trim().equals("")) {
1323
                        if(!groupExists(group)) {
1324
                            throw new AuthenticationException("AuthFile.User.serialize - can't put the user into a non-existing group "+group);
1325
                        }
1326
                    }
1327
                }
1328
            }
1329

    
1330
            if(!userExists(dn)) {
1331
                if(userpassword != null) {
1332
                  userpassword.addProperty(USERS+" "+USER+AT+DN, dn);
1333
                  userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+PASSWORD, hashedPass);
1334
                  
1335
                  if(email != null && !email.trim().equals("")) {
1336
                      userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+EMAIL, email);
1337
                  }
1338
                  
1339
                  if(surName != null && !surName.trim().equals("")) {
1340
                      userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+SURNAME, surName);
1341
                  }
1342
                  
1343
                  if(givenName != null && !givenName.trim().equals("")) {
1344
                      userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+GIVENNAME, givenName);
1345
                  }
1346
                  
1347
                  if(organization != null && !organization.trim().equals("")) {
1348
                      userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+ORGANIZATION, organization);
1349
                  }
1350

    
1351
                  if(groups != null) {
1352
                      for(int i=0; i<groups.length; i++) {
1353
                          String group = groups[i];
1354
                          if(group != null && !group.trim().equals("")) {
1355
                              if(groupExists(group)) {
1356
                                  userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+MEMBEROF, group);
1357
                              }
1358
                          }
1359
                      }
1360
                  }
1361
                  //userpassword.reload();
1362
                 }
1363
            } else {
1364
                throw new AuthenticationException("AuthFile.User.serialize - can't add the user "+dn+" since it already exists.");
1365
            }
1366
        }
1367
    }
1368

    
1369
}
(1-1/4)