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