View Javadoc

1   /*
2    * LDAPUserGroupDB.java
3    *
4    * Created on August 1, 2005, 10:32 AM
5    *
6    * To change this template, choose Tools | Options and locate the template under
7    * the Source Creation and Management node. Right-click the template and choose
8    * Open. You can then make changes to the template in the Source Editor.
9    */
10  
11  package gov.bnl.gums.db;
12  
13  import gov.bnl.gums.FQAN;
14  import gov.bnl.gums.GridUser;
15  
16  import java.util.ArrayList;
17  import java.util.Iterator;
18  import java.util.List;
19  import java.util.StringTokenizer;
20  import javax.naming.*;
21  import javax.naming.directory.*;
22  import org.apache.log4j.Logger;
23  
24  import gov.bnl.gums.persistence.LDAPPersistenceFactory;
25  
26  /**
27   *
28   * @author Gabriele Carcassi, Jay Packard
29   */
30  public class LDAPUserGroupDB implements UserGroupDB, ManualUserGroupDB {
31      private Logger log = Logger.getLogger(LDAPUserGroupDB.class);
32      private LDAPPersistenceFactory factory;
33      private String group;
34      private String groupDN;
35      private List addedMembers;
36      private List removedMembers;
37      
38      /** Creates a new instance of LDAPUserGroupDB */
39      public LDAPUserGroupDB(LDAPPersistenceFactory factory, String group) {
40          this.factory = factory;
41          this.group = group;
42          this.groupDN = "group=" + group + "," + factory.getGumsObject();
43  	createGroupIfNotExists();
44          log.trace("LDAPUserGroupDB object create: group '" + group + "' factory " + factory);
45      }
46      
47      public void addMember(gov.bnl.gums.GridUser user) {
48          factory.addUserGroupEntry(gridID(user), group, groupDN);
49      }
50      
51      public boolean isMemberInGroup(gov.bnl.gums.GridUser user) {
52          DirContext context = factory.retrieveGumsDirContext();
53          try {
54              SearchControls ctrls = new SearchControls();
55              ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
56              NamingEnumeration result = context.search(factory.getGumsObject(), "(&(group={0})(user={1}))", new Object[] {group, gridID(user)}, ctrls);
57              log.trace("Checking whether user '" + user + "' belongs to group '" + group + "': " + result.hasMore());
58              return result.hasMore();
59          } catch (Exception e) {
60              log.info("Couldn't check whether user '" + user + "' belongs to group '" + group + "'", e);
61              throw new RuntimeException("Couldn't check whether user '" + user + "' belongs to group ': " + e.getMessage(), e);
62          } finally {
63              factory.releaseContext(context);
64          }
65      }
66  
67      public void loadUpdatedList(java.util.List members) {
68          Exception lastException = null;
69  
70          try {
71              // Retrieving the current list of members
72              List currentMembers = retrieveMembers();
73  
74              // Calculating the deltas
75              List newMembers = new ArrayList(members);
76              newMembers.removeAll(currentMembers);
77              List oldMembers = new ArrayList(currentMembers);
78              oldMembers.removeAll(members);
79  
80              // Removing old members
81              if (log.isTraceEnabled()) {
82                  log.trace("Removing old members from group " + group + ": " + oldMembers);
83              }
84              Iterator iter = oldMembers.iterator();
85              while (iter.hasNext()) {
86                  GridUser user = (GridUser) iter.next();
87                  try {
88                      removeMember(user);
89                  } catch (Exception e) {
90                      lastException = e;
91                  }
92              }
93  
94              // Adding new members
95              if (log.isTraceEnabled()) {
96                  log.trace("Adding new members from group " + group + ": " + newMembers);
97              }
98              iter = newMembers.iterator();
99              while (iter.hasNext()) {
100                 GridUser user = (GridUser) iter.next();
101                 try {
102                     addMember(user);
103                 } catch (Exception e) {
104                     lastException = e;
105                 }
106             }
107 
108             addedMembers = newMembers;
109             removedMembers = oldMembers;
110             
111         } catch (Exception e) {
112             log.error("Updating member list in LDAP group '" + group + "' failed", e);
113             throw new RuntimeException("Updating member list in LDAP group '" + group + "' failed", e);
114         }
115         
116         if (lastException != null) {
117             throw new RuntimeException("Updating member list in LDAP group '" + group + "' wasn't completely successful: " + lastException.getMessage(), lastException);
118         }
119     }
120     
121     public boolean removeMember(gov.bnl.gums.GridUser user) {
122         try {
123             factory.removeUserGroupEntry(gridID(user), group, groupDN);
124             return true;
125         } catch (RuntimeException e) {
126             if (e.getCause() instanceof NoSuchAttributeException) {
127                 log.trace("No entry to remove for user '" + user + "' from group '" + group + "'");
128                 return false;
129             }
130             throw e;
131         }
132     }
133 
134     public java.util.List retrieveMembers() {
135         DirContext context = factory.retrieveGumsDirContext();
136         try {
137             DirContext groupContext = (DirContext) context.lookup(groupDN);
138             Attributes atts = groupContext.getAttributes("");
139             Attribute users = atts.get("user");
140             List members = new ArrayList();
141             if (users == null)
142                 return members;
143             NamingEnumeration result = users.getAll();
144             while (result.hasMore()) {
145                 GridUser user = new GridUser();
146                 String userGridID = (String) result.next();
147                 StringTokenizer tokens = new StringTokenizer(userGridID, "[]");
148                 user.setCertificateDN(tokens.nextToken());
149                 if (tokens.hasMoreTokens())
150                     user.setVoFQAN(new FQAN(tokens.nextToken()));
151                 members.add(user);
152             }
153             if (log.isTraceEnabled()) {
154                 log.trace("Retrieved full list of members from LDAP group '" + group + "': " + members);
155             }
156             return members;
157         } catch (Exception e) {
158             log.info("Couldn't retrieve full list of members from LDAP group '" + group + "'", e);
159             throw new RuntimeException("Couldn't retrieve full list of members from LDAP group '" + group + "': " + e.getMessage(), e);
160         } finally {
161             factory.releaseContext(context);
162         }
163     }
164 
165     public java.util.List retrieveNewMembers() {
166         return addedMembers;
167     }
168 
169     public java.util.List retrieveRemovedMembers() {
170         return removedMembers;
171     }
172 
173     private void createGroupIfNotExists() {
174         if (!doesGroupExist())
175             factory.createUserGroup(group, groupDN);
176     }
177 
178     private boolean doesGroupExist() {
179         DirContext context = factory.retrieveGumsDirContext();
180         try {
181             SearchControls ctrls = new SearchControls();
182             ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
183 	    NamingEnumeration result = context.search(factory.getGumsObject(), "(group={0})", new Object[] {group}, ctrls);
184 	    log.trace("Checking whether group '" + group + "' exists: " + result.hasMore());
185             return result.hasMore();
186         } catch (Exception e) {
187             log.info("Couldn't determine whether group '" + group + "' exists", e);
188             throw new RuntimeException("Couldn't determine whether group '" + group + "' exists: " + e.getMessage(), e);
189         } finally {
190             factory.releaseContext(context);
191         }
192     }
193 
194     private String gridID(GridUser user) {
195         if (user.getVoFQAN() == null)
196             return user.getCertificateDN();
197         else
198             return user.getCertificateDN()+"["+user.getVoFQAN()+"]";
199     }
200     
201 }