1
2
3
4
5
6
7 package gov.bnl.gums.util;
8
9 import gov.bnl.gums.GUMS;
10
11 import java.io.PrintStream;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Date;
15 import java.util.Hashtable;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19
20 import org.apache.commons.collections.MultiHashMap;
21 import org.apache.commons.collections.MultiMap;
22 import org.apache.log4j.Logger;
23
24
25
26
27
28
29
30 @SuppressWarnings({ "unchecked", "deprecation" })
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 this.expiration = expiration;
185 }
186
187 private String retrieveName(String gecos) {
188 gecos = gecos.trim();
189 int comma = gecos.indexOf(',');
190 if (comma != -1) {
191 gecos = gecos.substring(0, comma);
192 }
193 int index = gecos.lastIndexOf(' ');
194 if (index == -1) return "";
195 return gecos.substring(0, gecos.indexOf(' '));
196 }
197
198 private String retrieveSurname(String gecos) {
199 gecos = gecos.trim();
200 int comma = gecos.indexOf(',');
201 if (comma != -1) {
202 gecos = gecos.substring(0, comma);
203 }
204 int index = gecos.lastIndexOf(' ');
205 if (index == -1) return gecos;
206 return gecos.substring(gecos.lastIndexOf(' ')+1);
207 }
208
209 }