1
2
3
4
5
6
7
8
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
115 List currentMembers = retrieveMembers();
116
117
118 List newMembers = new ArrayList(members);
119 newMembers.removeAll(currentMembers);
120 List oldMembers = new ArrayList(currentMembers);
121 oldMembers.removeAll(members);
122
123
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
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 }