1
2
3
4
5
6
7
8
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
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
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
73 List currentMembers = retrieveMembers();
74
75
76 List newMembers = new ArrayList(members);
77 newMembers.removeAll(currentMembers);
78 List oldMembers = new ArrayList(currentMembers);
79 oldMembers.removeAll(members);
80
81
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
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 }