Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: gov/lanl/Web/UserMgr.java


1   // Login.java
2   /*************************************
3    * Copyright Notice
4    * Copyright (c) 2000, Regents of the University of California. All rights reserved.
5    *
6    * DISCLAIMER
7    * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
8    * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
9    * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
10   * SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
12   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
13   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
14   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
15   * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
16   * DAMAGE.
17   ***************************************/
18  package gov.lanl.Web;
19  
20  import gov.lanl.Utility.ConfigProperties;
21  import jdbm.JDBMEnumeration;
22  import jdbm.JDBMHashtable;
23  import jdbm.JDBMRecordManager;
24  
25  import java.io.*;
26  import java.util.*;
27  
28  /**
29   * This class manages a persistent storage of Users. It can add users from a file in
30   * LDAP's LDIF format.  The values required are dn (Distinguished Name), cn (Common Name), userPassword, email,
31   * and role
32   * This is intended as an interface for LDAP, but provides a simple persistent Hashtables using JDBM.
33   *
34   * The id Hashtable (name "userids") contains the User objects with the email address as the key
35   * The country (name "countries") Hashtable contains a HashSet of all the organizations in a given country
36   * To get a list of all supported countries simply get the keys of the countries Hashtable
37   * There also is a persistent Hashtable for each organization with is LDAP "o" value as its name
38   * It returns a Hashtable of users within that organization, with key the "cn" (Username) and value "email"
39   * Thus a user can be looked up by username and organization and return the "key" email address from which
40   * the full User object can be obtained from the id Hashtable
41   *
42   * When a new organization is encountered (with a user with "o" and "c" dn parameters, it is registered
43   * into the list of organizations for that country in the country Hashtable
44   *
45   * JDBM (http://jdbm.sourceforge.net) persistent hashtable implemenation is used for persistence
46   *
47   * @author $Author: dwforslund $
48   * @version $Id: UserMgr.java,v 1.7 2002/06/10 03:02:54 dwforslund Exp $
49   */
50  
51  public class UserMgr {
52  
53  
54      //private JDBMHashtable dn;
55      private JDBMHashtable id = null;
56      private JDBMHashtable users;
57      private JDBMHashtable country;
58      private String username = "";
59      // private String password = "";
60      // private String email = "";
61      private static String userfile = "login.users";
62      private String userdb = "users";
63      private static String configFile = "test";
64      private JDBMRecordManager recman;
65      private static ConfigProperties props = new ConfigProperties();
66      private Vector profile_vec = null;
67      // private Hashtable users = null;
68      private User user;
69      private static org.apache.log4j.Logger cat = org.apache.log4j.Logger.getLogger(UserMgr.class.getName());
70  
71      /**
72       * Public default constructor
73       */
74      public UserMgr() {
75          // Defer initialization for servlets
76          //  init();
77      }
78  
79      /**
80       * Constructor which specifies the configProperties to be read
81       */
82      public UserMgr(String configProperties) {
83          setConfigFile(configProperties);
84          init();
85      }
86  
87      /**
88       * Initialize Persistent storage
89       * There are two primary hashtables.   The first (country) contains a list of the organizations which are keys
90       * to user hashtables for each organization.  The organization hashtable is a map from the username
91       * key to the userId (email address).  The second (id) is the hashtable based on the email address
92       * which is used as a userId since the email address is supposed to be unique.  For each organization
93       * there is a separate hashtable of the users for that organization.  Thus one can look a user up
94       * across organizations or within an organization.  All the user objects are contained in the second (id) hashtable.
95       *
96       */
97      public void init() {
98          ResourceBundle bundle = ResourceBundle.getBundle(configFile);
99          props.setProperties(bundle);
100         cat.debug("read: " + configFile);
101         userdb = props.getProperty("users", userdb);
102         try {
103             recman = new JDBMRecordManager(userdb);
104             //dn = recman.getHashtable("usernames");
105             id = recman.getHashtable("userids");
106             country = recman.getHashtable("countries");
107         } catch (IOException e) {
108             cat.error("init: " + e);
109         }
110     }
111 
112     /**
113      * add Users from previously defined userfile
114      */
115     public void addUsers() {
116         addUsers(userfile);
117     }
118 
119     /**
120      *  Add users from an input file
121      * @param userfile
122      */
123     public void addUsers(String userfile) {
124 
125 
126         // Query using JNDI to get list of users, not implemented correctly yet.
127 
128 
129         // Read from file to get users (in ldif format)
130         // e.g.:
131         //  dn: cn= David Forslund, o=LANL, c=US
132         //  cn: David Forslund
133         //  email: dwf@lanl.gov
134         //  userPassword: test
135         // Results are put into a User object and the User into a hashtable with email/userId
136         // as the key
137         // various arrays are created for listing the users as needed.
138 
139 
140         // userfile = props.getProperty("login.users", userfile);
141         // String country = props.getProperty("country","US");
142 
143         try {
144 
145             // orgs = recman.getHashtable(country);
146             // Read in user list if not already done      ###
147 
148             String line = null;
149             InputStream is = getClass().getResourceAsStream(userfile);
150             //if (theFile.exists()) {
151             if (is != null) {
152                 cat.debug("Reading  " + userfile);
153 
154                 //  FileReader inFile = new FileReader(theFile);
155                 InputStreamReader inFile = new InputStreamReader(is);
156                 BufferedReader inReader = new BufferedReader(inFile);
157                 profile_vec = new Vector();
158                 user = null;
159                 HashSet set = null;     // unique set of organizations in a country
160                 while (((line = inReader.readLine()) != null)) {
161                     parseLine(line);
162                 }
163                 //HashSet set = (HashSet) orgs.get(country);
164 
165                 //if (set == null) set = new HashSet();
166                 inReader.close();
167                 if ((profile_vec != null)) {
168                     addProfile();
169                     for (int i = 0; i < profile_vec.size(); i++) {
170                         User u = (User) profile_vec.elementAt(i);
171                         String c = u.getCountry();
172                         //  cat.debug("addUsers: "+u.toString());
173                         String org = u.getOrg();
174                         if (c != null) set = (HashSet) country.get(c);
175                         if (set == null) set = new HashSet();
176                         // get the hashtable for that organization
177                         // Update list  of organizations for a country
178                         set.add(org);
179 
180                         //  cat.debug("organization = " + org);
181                         JDBMHashtable users = recman.getHashtable(org);
182                         // insert userID in users table with userName as key
183                         users.put(u.getUserName(), u.getUserId());   // put userId in dn with dn as key
184 
185                         id.put(u.getUserId(), u);   // put user in id with mail as key
186 
187                         country.put(c, set);
188                     }
189                     // put the list of names into the organization hashtable
190                     // cat.debug(set.size() + " organizations");
191 
192                 }
193 
194             }
195 
196         } catch (IOException e) {
197             cat.error("UserMgr reading error adding users " + e, e);
198 
199         }
200 
201 
202         //}
203     }
204 
205     /**
206      * parse the line and add the user to the list
207      * @param line to be parsed
208      */
209     public void parseLine(String line) {
210 
211         try {
212             //user = null;
213             if (line.startsWith("#") || line.startsWith("//")) return;
214             StringTokenizer tmp_st = new StringTokenizer(line, ":");
215             if (tmp_st.countTokens() == 0) return;
216             String tmp_tok = tmp_st.nextToken();
217             //   System.out.println("parseLine: "+tmp_tok);
218             if (tmp_tok.equals("dn")) {
219                 // We have a new defined person so save old data and reset
220                 if (user == null) {
221                     user = new User();
222                 } else {   // user is complete so store it
223                     addProfile();
224 
225                 }
226                 user.setDN(tmp_st.nextToken().trim());
227                 //   user.setDN(tmp_st.nextToken().trim());
228             } else if (tmp_tok.equals("cn")) {
229 
230                 user.setUserName(tmp_st.nextToken().trim());
231             } else if (tmp_tok.equals("email")) {
232 
233                 user.setUserId(tmp_st.nextToken().trim());
234             } else if (tmp_tok.equals("userPassword")) {
235 
236                 user.setPassword(tmp_st.nextToken().trim());
237             } else if (tmp_tok.equals("role")) {
238 
239                 user.setRole(tmp_st.nextToken().trim());
240             } else if (tmp_tok.equals("sn")) {
241                 user.setSurName(tmp_st.nextToken().trim());
242             }
243         } catch (Exception e) {
244             cat.error("parseLine failed:" + e);
245         }
246 
247     }
248 
249     /**
250      * Add the user profile
251      */
252     private void addProfile() {
253         profile_vec.addElement(user);
254         //  cat.debug("name: "+user.getUserName()+", email: "+user.getUserId()+", passwd: "+user.getPassword());
255         user = new User();
256     }
257 
258     /**
259      * addUser
260      * @param u String with multiple lines with all the data for a user
261      */
262     public void addUser(String u) {
263         BufferedReader reader = new BufferedReader(new StringReader(u));
264         String line = null;
265         User saveUser = user;
266         try {
267             while ((line = reader.readLine()) != null)
268                 parseLine(line);
269             if (user != null) addUser(user);
270         } catch (IOException e) {
271             cat.error("addUser: " + e);
272         }
273         user = saveUser;
274 
275     }
276 
277     /**
278      * add User to the Persistent Hashtable
279      * @param theDN The distinguished name (cn= "name", o="organization", c="country")
280      * @param cn  LDAP username
281      * @param sn   LDAP surname
282      * @param email   LDAP email address (userId)
283      * @param role
284      * @param password
285      */
286     public void addUser(String theDN, String cn, String sn, String email, String role, String password) {
287         User newUser = new User(email, cn);
288         newUser.setRole(role);
289         newUser.setPassword(password);
290         newUser.setSurName(sn);
291         newUser.setDN(theDN);
292         addUser(newUser);
293     }
294 
295     /**
296      *  Add a User already constructed
297      * @param newUser
298      */
299 
300     public void addUser(User newUser) {
301 
302         String c = newUser.getCountry();
303         String org = newUser.getOrg();
304         String userName = newUser.getUserName();
305         String email = newUser.getUserId();
306         cat.debug("addUser: " + newUser.toString());
307         User oldUser = getUser(newUser);
308         if (oldUser == null) oldUser = new User();
309 
310         oldUser.update(newUser);
311         try {
312             // First make sure the organization is in the country list
313             HashSet set = (HashSet) country.get(c);
314             if (set == null) set = new HashSet();
315             set.add(org);
316             country.put(c, set);
317             // get the users Hashtable based on the organization
318             users = recman.getHashtable(org);
319 
320             users.put(userName, email);
321             id.put(email, oldUser);
322             cat.debug("User: " + oldUser.toString() + " added!");
323         } catch (IOException e) {
324             cat.error("addUser: " + e);
325         }
326     }
327 
328 
329     /**
330      * delete User based on the unique UserId
331      * @param userId corresponding to email address
332      */
333     public void delUser(String userId) {
334         try {
335             cat.debug("delUser trying to remove: " + userId);
336             User delUser = (User) id.get(userId);
337             if (delUser != null) {
338                 id.remove(userId);
339                 cat.debug("delUser removed from id: " + userId);
340                 String uName = delUser.getUserName();
341                 users = recman.getHashtable(delUser.getOrg());
342                 cat.debug("removing " + uName + " from dn");
343                 String u = (String) users.get(uName);
344                 if (u != null) {
345                     users.remove(uName);
346                     cat.debug("delUser removed from dn: " + uName);
347                 }
348             } else
349                 cat.debug("delUser: id='" + userId + "' not found");
350         } catch (IOException e) {
351             cat.error("delUser: " + userId + " " + e);
352         }
353 
354 
355     }
356 
357     /**
358      * get the User based on name and organization
359      * @param userName
360      * @param org
361      * @return User
362      */
363     public User getUser(String userName, String org) {
364         User user = null;
365         try {
366             users = recman.getHashtable(org);
367             String userId = (String) users.get(username);
368             if (userId != null) user = (User) id.get(userId);
369             if (user == null) cat.warn("getUser(" + userName + "," + org + "): not found");
370         } catch (IOException e) {
371             cat.error("getUser: " + e);
372         }
373         return user;
374     }
375 
376     /**
377      * get User by the unique userId (email)
378      * @param userId
379      * @return User
380      */
381     public User getUser(String userId) {
382         User user = null;
383         try {
384             user = (User) id.get(userId);
385         } catch (IOException e) {
386             cat.error("setUserId: " + e);
387         }
388         return user;
389     }
390 
391     /**
392      * get User with username, org and email
393      * @param username  cn variable
394      * @param org       o variable
395      * @param email       email variable
396      * @return User
397      */
398     public User getUser(String username, String org, String email) {
399         User user = null;
400         try {
401             // try unique email first (this should always return the user)
402             if (email != null && !email.equals(""))
403                 user = (User) id.get(email);
404             if ((user == null) && (org != null) && (username != null)) {
405                 // get the user list for the organization
406                 users = recman.getHashtable(org);
407                 if (users != null) {
408                     String userid = (String) users.get(username);
409                     if (userid != null) user = (User) id.get(userid);
410                 }
411             }
412             if (user == null) cat.warn("getUser(" + username + "," + org + "," + email + "): user not found, ");
413         } catch (IOException e) {
414             cat.error("getUser: " + e);
415         }
416         return user;
417     }
418 
419     /**
420      * Find a User given a partially completed User object as a template
421      * @param findUser
422      * @return User
423      */
424     public User getUser(User findUser) {
425         User user = new User();
426         String email = findUser.getUserId();
427         try {
428             if (email != null && !email.equals(""))
429                 user = (User) id.get(email);
430             if ((user == null) && (findUser.getOrg() != null) && findUser.getUserName() != null) {
431                 users = recman.getHashtable(findUser.getOrg());
432                 if (users != null) {
433                     String userid = (String) users.get(username);
434                     if (userid != null) user = (User) id.get(userid);
435                 }
436             }
437             if (user == null) {
438                 cat.warn("getUser(" + findUser.toString() + "): user not found");
439 
440             }
441         } catch (IOException e) {
442             cat.error("getUser: " + e);
443         }
444         return user;
445 
446     }
447 
448     /**
449      * Get all the userNames for a given organization
450      * @param org the organization name (o field in LDAP);
451      * @return String[] list of names within the organization
452      */
453     public String[] getNamesbyOrg(String org) {
454         Vector v = new Vector();
455         try {
456             JDBMHashtable users = recman.getHashtable(org);
457             JDBMEnumeration e = users.keys();
458             while (e.hasMoreElements()) {
459                 v.addElement(e.nextElement());
460             }
461         } catch (IOException e1) {
462             cat.error("getNamesbyOrg: " + e1);
463         }
464         String[] s = new String[v.size()];
465         v.copyInto(s);
466         return s;
467     }
468 
469     /**
470      * get the email addresses of all users in an organization
471      * @param org name of the organization (o LDAP field)
472      * @return String[] array of email addresses
473      */
474     public String[] getMailbyOrg(String org) {
475         Vector v = new Vector();
476         try {
477             JDBMHashtable users = recman.getHashtable(org);
478             JDBMEnumeration e = users.values();
479             while (e.hasMoreElements()) {
480                 v.addElement(e.nextElement());
481             }
482         } catch (IOException e1) {
483             cat.error("getMailbyOrg: " + e1);
484         }
485         String[] s = new String[v.size()];
486         v.copyInto(s);
487         return s;
488     }
489 
490     /**
491      * get list of all UserIds in DB
492      * @return String[] list of UserIds
493      */
494     public String[] getUserIds() {
495         String[] mail;
496         if (id == null) init();
497         ArrayList v = null;
498         try {
499             JDBMEnumeration e = id.keys();
500             v = new ArrayList();
501             while (e.hasMoreElements()) {
502                 v.add(e.nextElement());
503             }
504         } catch (IOException e1) {
505             cat.error("getUserIds: " + e1);
506             return new String[0];
507         }
508         mail = new String[v.size()];
509         v.toArray(mail);
510         // cat.debug("getUserIds: "+mail.length +" mail: "+mail[0]);
511         return mail;
512     }
513 
514     /** obtain list of valid users
515      * @return String[] list of known users
516      */
517     public String[] getUserNames() {
518         String[] names;
519         if (id == null) init();
520         ArrayList v = null;
521         try {
522             JDBMEnumeration e = id.values();
523             v = new ArrayList();
524             while (e.hasMoreElements()) {
525                 v.add(((User) e.nextElement()).getUserName());
526             }
527         } catch (IOException e1) {
528             cat.error("getUserNames: " + e1);
529             return new String[0];
530         }
531         // for (int i = 0;i< v.size(); i++)
532         //      cat.debug("name: "+v.get(i));
533         names = new String[v.size()];
534         cat.debug("getUserNames: found " + names.length + " elements");
535         v.toArray(names);
536 
537 
538         return names;
539     }
540 
541     /**
542      * Bean setter  and getter methods
543      * @param theConfigFile the properties file
544      */
545 
546     public static void setConfigFile(String theConfigFile) {
547         configFile = theConfigFile;
548     }
549 
550 
551     /**
552      *  set the file of users to be read.
553      * @param file to be read
554      */
555     public static void setUserfile(String file) {
556         userfile = file;
557     }
558 
559     /**
560      * get all the users in in the persistent hashtable
561      * @return String
562      */
563     public String export() {
564         try {
565             JDBMEnumeration c = id.values();
566             StringBuffer buff = new StringBuffer();
567             while (c.hasMoreElements()) {
568                 buff.append(c.nextElement().toString() + '\n');
569             }
570             return buff.toString();
571         } catch (IOException e) {
572             cat.error("getUsers: " + e);
573             return null;
574         }
575     }
576 
577     public static void main(String[] argv) {
578         if (argv.length < 1) {
579            System.out.println("usage: UserMgr 'file' where 'file' is a ResourceBundle (file.properties) '\n"
580             + "and has a property: 'login.users' which is a file containing the users \n"
581            + "and optionally the property 'users' which is the name of the database to be created or read");
582             System.exit(0);
583         }
584             UserMgr.setConfigFile(argv[0]);
585             UserMgr userMgr = new UserMgr();
586             userMgr.init();
587             String file = props.getProperty("login.users");
588             if (file != null && file != "") userMgr.addUsers(props.getProperty("login.users"));
589             System.out.println(userMgr.export());
590 
591 
592     }
593 }