1
2
3
4
5
6
7 package gov.bnl.gums.account;
8
9 import gov.bnl.gums.GUMS;
10 import gov.bnl.gums.account.NISClient;
11
12 import java.io.PrintStream;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Date;
16 import java.util.Hashtable;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20
21 import org.apache.commons.collections.MultiHashMap;
22 import org.apache.commons.collections.MultiMap;
23 import org.apache.log4j.Logger;
24
25
26
27
28
29
30
31 public class GecosMap {
32 private Logger log = Logger.getLogger(NISClient.class);
33 private Logger gumsAdminLog = Logger.getLogger(GUMS.gumsAdminLogName);
34 private Map accountToGecos = new Hashtable();
35 private Map accountToName = new Hashtable();
36 private Map accountToSurname = new Hashtable();
37 private MultiMap nameToAccount = new MultiHashMap();
38 private MultiMap surnameToAccount = new MultiHashMap();
39 private Date lastUpdate = null;
40 private long expiration = 60*60*1000;
41
42 public void addEntry(String account, String gecos) {
43 String name = retrieveName(gecos);
44 String surname = retrieveSurname(gecos);
45 log.trace("Adding user '" + account + "': GECOS='" + gecos + "' name='" + name + "' surname='" + surname + "'");
46 accountToGecos.put(account, gecos);
47 if (name != null) {
48 accountToName.put(account, name);
49 nameToAccount.put(name.toLowerCase(), account);
50 }
51 accountToSurname.put(account, surname);
52 surnameToAccount.put(surname.toLowerCase(), account);
53 lastUpdate = new Date();
54 }
55
56 public String findAccount(String name, String surname) {
57 Collection accountsWithName = (Collection) nameToAccount.get(name.toLowerCase());
58 Collection accountsWithSurname = (Collection) surnameToAccount.get(surname.toLowerCase());
59 log.trace("Account matching. Name: " + accountsWithName + "- Surname: " + accountsWithSurname);
60 if ((accountsWithName != null) && (accountsWithSurname != null)) {
61
62 List commonAccounts = new ArrayList(accountsWithName);
63 commonAccounts.retainAll(accountsWithSurname);
64 if (commonAccounts.size() == 1) {
65
66
67 String account = (String) commonAccounts.get(0);
68 log.trace("NIS account Name/Surname single match. Name: " + name + " - Surname: " + surname + " - account: " + account);
69 return account;
70 } else if (commonAccounts.size() > 1) {
71
72
73
74
75 Iterator iter = commonAccounts.iterator();
76 String matchingAccount = null;
77 while (iter.hasNext()) {
78 String account = (String) iter.next();
79 if (account.indexOf(surname.toLowerCase()) != -1) {
80 if (matchingAccount == null) {
81 matchingAccount = account;
82 } else {
83
84 log.trace("NIS account Name/Surname multiple match, multiple account with surname." +
85 " Name: " + name + " - Surname: " + surname + " - account: not defined");
86 gumsAdminLog.debug("NIS/LDAP mapping: couldn't find single match for surname='" + surname + "' name='" + name + "'. Undecided between " + commonAccounts);
87 return null;
88 }
89 }
90 }
91 if (matchingAccount != null) {
92
93
94 log.trace("NIS account Name/Surname multiple match, single account with surname." +
95 " Name: " + name + " - Surname: " + surname + " - account: " + matchingAccount);
96 return matchingAccount;
97 }
98
99 log.trace("NIS account Name/Surname multiple match, no account with surname." +
100 " Name: " + name + " - Surname: " + surname + " - account: not defined");
101 gumsAdminLog.debug("NIS/LDAP mapping: couldn't find single match for surname='" + surname + "' name='" + name + "'. Undecided between " + commonAccounts);
102 return null;
103 }
104
105 }
106 if (accountsWithSurname != null) {
107 if (accountsWithSurname.size() == 1) {
108 String account = (String) accountsWithSurname.iterator().next();
109 log.trace("NIS account Surname single match, no match on Name. Name: " + name + " - Surname: " + surname + " - account: " + account);
110 return account;
111 } else {
112 log.trace("NIS account Surname multiple match, no match on Name. Name: " + name + " - Surname: " + surname + " - account: undefined");
113 gumsAdminLog.debug("NIS/LDAP mapping: couldn't find single match for surname='" + surname + "' name='" + name + "'. Undecided between " + accountsWithSurname);
114 return null;
115 }
116 }
117 log.trace("NIS account no match on Surname. Name: " + name + " - Surname: " + surname + " - account: undefined");
118
119 accountsWithName = (Collection) nameToAccount.get(surname.toLowerCase());
120 accountsWithSurname = (Collection) surnameToAccount.get(name.toLowerCase());
121 if ((accountsWithName != null) && (accountsWithSurname != null)) {
122
123 List commonAccounts = new ArrayList(accountsWithName);
124 commonAccounts.retainAll(accountsWithSurname);
125 if (commonAccounts.size() == 1) {
126
127
128 String account = (String) commonAccounts.get(0);
129 log.trace("NIS account inverted Name/Surname single match. Name: " + surname + " - Surname: " + name + " - account: " + account);
130 return account;
131 }
132 }
133 return null;
134 }
135
136
137
138
139
140
141
142 public long getExpiration() {
143
144 return this.expiration;
145 }
146
147 public boolean isValid() {
148 if (lastUpdate == null) return false;
149 if ((System.currentTimeMillis() - lastUpdate.getTime()) > expiration) return false;
150 return true;
151 }
152
153 public void printMaps(PrintStream out) {
154 out.println("account to gecos map");
155 out.println("---------------------");
156 out.println();
157 Iterator accounts = accountToGecos.keySet().iterator();
158 while (accounts.hasNext()) {
159 String account = (String) accounts.next();
160 String gecos = (String) accountToGecos.get(account);
161 String name = (String) accountToName.get(account);
162 String surname = (String) accountToSurname.get(account);
163 out.print(account);
164 for (int n = account.length(); n < 15; n++) {
165 out.print(' ');
166 }
167 out.print(gecos);
168 for (int n = gecos.length(); n < 30; n++) {
169 out.print(' ');
170 }
171 out.print(name);
172 for (int n = name.length(); n < 15; n++) {
173 out.print(' ');
174 }
175 out.println(surname);
176 }
177 }
178
179
180
181
182
183 public void setExpiration(long expiration) {
184
185 this.expiration = expiration;
186 }
187
188 private void printMap(PrintStream out, Map map, int offset) {
189 Iterator accounts = map.keySet().iterator();
190 while (accounts.hasNext()) {
191 String account = (String) accounts.next();
192 String gecos = (String) map.get(account);
193 out.print(account);
194 for (int n = account.length(); n < offset; n++) {
195 out.print(' ');
196 }
197 out.println(gecos);
198
199 }
200 }
201
202 private String retrieveName(String gecos) {
203 gecos = gecos.trim();
204 int comma = gecos.indexOf(',');
205 if (comma != -1) {
206 gecos = gecos.substring(0, comma);
207 }
208 int index = gecos.lastIndexOf(' ');
209 if (index == -1) return "";
210 return gecos.substring(0, gecos.indexOf(' '));
211 }
212
213 private String retrieveSurname(String gecos) {
214 gecos = gecos.trim();
215 int comma = gecos.indexOf(',');
216 if (comma != -1) {
217 gecos = gecos.substring(0, comma);
218 }
219 int index = gecos.lastIndexOf(' ');
220 if (index == -1) return gecos;
221 return gecos.substring(gecos.lastIndexOf(' ')+1);
222 }
223
224 }