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