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