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.log4j.Logger;
23
24 import gov.bnl.gums.persistence.LDAPPersistenceFactory;
25
26
27
28
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
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
72 List currentMembers = retrieveMembers();
73
74
75 List newMembers = new ArrayList(members);
76 newMembers.removeAll(currentMembers);
77 List oldMembers = new ArrayList(currentMembers);
78 oldMembers.removeAll(members);
79
80
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
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 }