Project

General

Profile

1 4080 daigle
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements administrative methods
4
 *  Copyright: 2008 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 *
8
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26
27
package edu.ucsb.nceas.metacat.util;
28
29
import java.util.Calendar;
30
import java.util.Vector;
31
32
import javax.servlet.http.HttpServletRequest;
33
import javax.servlet.http.HttpSession;
34
35 8208 leinfelder
import org.apache.log4j.Logger;
36
37 4080 daigle
import edu.ucsb.nceas.metacat.AuthSession;
38 5030 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
39 4080 daigle
import edu.ucsb.nceas.metacat.service.SessionService;
40 5015 daigle
import edu.ucsb.nceas.metacat.shared.MetacatUtilException;
41
import edu.ucsb.nceas.metacat.shared.ServiceException;
42 4080 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
43
import edu.ucsb.nceas.utilities.StringUtil;
44
45 4589 daigle
public class AuthUtil {
46 8208 leinfelder
47
    public static Logger logMetacat = Logger.getLogger(AuthUtil.class);
48 4080 daigle
49
	private static Vector<String> administrators = null;
50
	private static Vector<String> moderators = null;
51
	private static Vector<String> allowedSubmitters = null;
52
	private static Vector<String> deniedSubmitters = null;
53
54
	/**
55
	 * private constructor - all methods are static so there is no no need to
56
	 * instantiate.
57
	 */
58 4589 daigle
	private AuthUtil() {}
59 4080 daigle
60
	/**
61
	 * Get the administrators from metacat.properties
62
	 *
63
	 * @return a Vector of Strings holding the administrators
64
	 */
65 4854 daigle
	public static Vector<String> getAdministrators() throws MetacatUtilException {
66 4080 daigle
		if (administrators == null) {
67
			populateAdministrators();
68
		}
69
		return administrators;
70
	}
71
72
	/**
73
	 * Get the allowed submitters from metacat.properties
74
	 *
75
	 * @return a Vector of Strings holding the submitters
76
	 */
77 4854 daigle
	public static Vector<String> getAllowedSubmitters() throws MetacatUtilException {
78 4080 daigle
		if (allowedSubmitters == null) {
79
			populateAllowedSubmitters();
80
		}
81
		return allowedSubmitters;
82
	}
83
84
	/**
85
	 * Get the denied submitters from metacat.properties
86
	 *
87
	 * @return a Vector of Strings holding the denied submitters
88
	 */
89 4854 daigle
	public static Vector<String> getDeniedSubmitters() throws MetacatUtilException {
90 4080 daigle
		if (deniedSubmitters == null) {
91
			populateDeniedSubmitters();
92
		}
93
		return deniedSubmitters;
94
	}
95
96
	/**
97 4627 daigle
	 * Get the moderators from metacat.properties
98
	 *
99
	 * @return a Vector of Strings holding the moderators
100
	 */
101 4854 daigle
	public static Vector<String> getModerators() throws MetacatUtilException {
102 4627 daigle
		if (moderators == null) {
103
			populateModerators();
104
		}
105
		return moderators;
106
	}
107
108
	/**
109 4080 daigle
	 * Get the vector of administrator credentials from metacat.properties
110
	 * and put into global administrators list
111
	 */
112 4854 daigle
	private static void populateAdministrators() throws MetacatUtilException {
113 4080 daigle
		String administratorString = null;
114
		try {
115
			administratorString =
116 4589 daigle
				PropertyService.getProperty("auth.administrators");
117 4080 daigle
		} catch (PropertyNotFoundException pnfe) {
118 4854 daigle
			throw new MetacatUtilException("Could not get metacat property: auth.administrators. "
119 4080 daigle
							+ "There will be no registered metacat adminstrators: "
120
							+ pnfe.getMessage());
121
		}
122
		administrators = StringUtil.toVector(administratorString, ':');
123 8208 leinfelder
124
		String d1NodeAdmin = null;
125
		try {
126
			d1NodeAdmin = PropertyService.getProperty("dataone.subject");
127
			administrators.add(d1NodeAdmin);
128
		} catch (PropertyNotFoundException e) {
129
			String msg = "Could not get metacat property: dataone.subject "
130
					+ "There will be no registered DataONE adminstrator";
131
			logMetacat.error(msg, e);
132
133
		}
134 4080 daigle
	}
135
136
	/**
137
	 * Get the vector of allowed submitter credentials from metacat.properties
138
	 * and put into global allowedSubmitters list
139
	 */
140 4854 daigle
	private static void populateAllowedSubmitters() throws MetacatUtilException {
141 4080 daigle
		String allowedSubmitterString = null;
142
		try {
143 4589 daigle
			allowedSubmitterString = PropertyService.getProperty("auth.allowedSubmitters");
144 4080 daigle
		} catch (PropertyNotFoundException pnfe) {
145 4854 daigle
			throw new MetacatUtilException("Could not get metacat property: auth.allowedSubmitters. "
146 4080 daigle
					+ "Anyone will be allowed to submit: "
147
					+ pnfe.getMessage());
148
		}
149
		allowedSubmitters = StringUtil.toVector(allowedSubmitterString, ':');
150
	}
151
152
	/**
153
	 * Get the vector of denied submitter credentials from metacat.properties
154
	 * and put into global deniedSubmitters list
155
	 */
156 4854 daigle
	private static void populateDeniedSubmitters() throws MetacatUtilException {
157 4080 daigle
		String deniedSubmitterString = null;
158
		try {
159 4589 daigle
			deniedSubmitterString = PropertyService.getProperty("auth.deniedSubmitters");
160 4080 daigle
		} catch (PropertyNotFoundException pnfe) {
161 4854 daigle
			throw new MetacatUtilException("Could not get metacat property: auth.deniedSubmitters: "
162 4080 daigle
					+ pnfe.getMessage());
163
		}
164
		deniedSubmitters = StringUtil.toVector(deniedSubmitterString, ':');
165
	}
166 4627 daigle
167
	/**
168
	 * Get the vector of moderator credentials from metacat.properties
169
	 * and put into global administrators list
170
	 */
171 4854 daigle
	private static void populateModerators() throws MetacatUtilException {
172 4627 daigle
		String moderatorString = null;
173
		try {
174
			moderatorString =
175
				PropertyService.getProperty("auth.moderators");
176
		} catch (PropertyNotFoundException pnfe) {
177 4854 daigle
			throw new MetacatUtilException("Could not get metacat property: auth.moderators. "
178 4627 daigle
							+ "There will be no registered metacat moderators: "
179
							+ pnfe.getMessage());
180
		}
181
		moderators = StringUtil.toVector(moderatorString, ':');
182
	}
183 4080 daigle
184
	/**
185
	 * log the user in against ldap.  If the login is successful, add
186
	 * the session information to the session list in SessionUtil.
187
	 *
188
	 * @param request the http request.
189
	 */
190 4854 daigle
	public static boolean logUserIn(HttpServletRequest request, String userName, String password) throws MetacatUtilException {
191 4080 daigle
		AuthSession authSession = null;
192
193
		// make sure we have username and password.
194 4589 daigle
		if (userName == null || password == null) {
195 4854 daigle
			throw new MetacatUtilException("null username or password when logging user in");
196 4080 daigle
		}
197
198
		// Create auth session
199
		try {
200
			authSession = new AuthSession();
201
		} catch (Exception e) {
202 4854 daigle
			throw new MetacatUtilException("Could not instantiate AuthSession: "
203 4080 daigle
					+ e.getMessage());
204
		}
205
		// authenticate user against ldap
206 4628 daigle
		if(!authSession.authenticate(request, userName,password)) {
207 4854 daigle
			throw new MetacatUtilException(authSession.getMessage());
208 4628 daigle
		}
209 4080 daigle
210 4628 daigle
		// if login was successful, add the session information to the
211 4080 daigle
		// global session list.
212 4628 daigle
		HttpSession session = authSession.getSessions();
213
		String sessionId = session.getId();
214 4780 daigle
215
		try {
216 5374 berkley
		SessionService.getInstance().registerSession(sessionId,
217 4628 daigle
				(String) session.getAttribute("username"),
218
				(String[]) session.getAttribute("groupnames"),
219 5070 daigle
				(String) session.getAttribute("password"),
220
				(String) session.getAttribute("name"));
221 4780 daigle
		} catch (ServiceException se) {
222 4854 daigle
			throw new MetacatUtilException("Problem registering session: " + se.getMessage());
223 4780 daigle
		}
224 4080 daigle
225 4628 daigle
		return true;
226 4080 daigle
	}
227
228
	/**
229
	 * Checks to see if the user is logged in by grabbing the session from the
230
	 * request and seeing if it exists in the global session list.
231
	 *
232
	 * @param request the http request that holds the login session
233
	 * @return boolean that is true if the user is logged in, false otherwise
234
	 */
235 4854 daigle
	public static boolean isUserLoggedIn(HttpServletRequest request) throws MetacatUtilException{
236 4080 daigle
		SessionData sessionData = null;
237
		String sessionId = request.getSession().getId();
238
239
		try {
240
241 5374 berkley
			if (sessionId != null && SessionService.getInstance().isSessionRegistered(sessionId)) {
242 4080 daigle
				// get the registered session data
243 5374 berkley
				sessionData = SessionService.getInstance().getRegisteredSession(sessionId);
244 4080 daigle
245
				// get the timeout limit
246
				String sessionTimeout = PropertyService.getProperty("auth.timeoutMinutes");
247
				int sessionTimeoutInt = Integer.parseInt(sessionTimeout);
248
249
				// get the last time the session was accessed
250
				Calendar lastAccessedTime = sessionData.getLastAccessedTime();
251
				// get the current time and set back "sessionTimoutInt" minutes
252
				Calendar now = Calendar.getInstance();
253
				now.add(Calendar.MINUTE, 0 - sessionTimeoutInt);
254
255
				// if the last accessed time is before now minus the timeout,
256
				// the session has expired. Unregister it and return false.
257
				if (lastAccessedTime.before(now)) {
258 5374 berkley
					SessionService.getInstance().unRegisterSession(sessionId);
259 4080 daigle
					return false;
260
				}
261
262
				return true;
263
			}
264
265
		} catch (PropertyNotFoundException pnfe) {
266 4854 daigle
			throw new MetacatUtilException("Could not determine if user is logged in because "
267 4080 daigle
					+ "of property error: " + pnfe.getMessage());
268
		} catch (NumberFormatException nfe) {
269 4854 daigle
			throw new MetacatUtilException("Could not determine if user is logged in because "
270 4080 daigle
					+ "of number conversion error: " + nfe.getMessage());
271
		}
272
273
		return false;
274
	}
275
276
	/**
277
	 * Checks to see if the user is logged in as admin by first checking if the
278
	 * user is logged in and then seeing if the user's account is on the
279
	 * administrators list in metacat.properties.
280
	 *
281
	 * @param request
282
	 *            the http request that holds the login session
283
	 * @return boolean that is true if the user is logged in as admin, false
284
	 *         otherwise
285
	 */
286 4854 daigle
	public static boolean isUserLoggedInAsAdmin(HttpServletRequest request) throws MetacatUtilException {
287 4080 daigle
		if (!isUserLoggedIn(request)) {
288
			return false;
289
		}
290
291
		String userName = getUserName(request);
292
		boolean isAdmin = isAdministrator(userName, null);
293
294
		return isAdmin;
295
	}
296
297
	/**
298
	 * Gets the user name from the login session on the http request
299
	 *
300
	 * @param request
301
	 *            the http request that holds the login session
302
	 * @return String that holds the user name
303
	 */
304
	public static String getUserName(HttpServletRequest request) {
305
		String userName = (String)request.getSession().getAttribute("username");
306
307
		return userName;
308
	}
309
310
	/**
311
	 * Gets the user group names from the login session on the http request
312
	 *
313
	 * @param request
314
	 *            the http request that holds the login session
315
	 * @return String array that holds the user groups
316
	 */
317
	public static String[] getGroupNames(HttpServletRequest request) {
318
		String sessionId = request.getSession().getId();;
319 5374 berkley
		SessionData sessionData = SessionService.getInstance().getRegisteredSession(sessionId);
320 4080 daigle
		String[] groupNames = { "" };
321
322
		if (sessionData != null) {
323
			groupNames = sessionData.getGroupNames();
324
		}
325
326
		return groupNames;
327
	}
328
329
	/**
330
	 * Creates an ldap credentail string from the username, organization
331
	 * and dn list.
332
	 *
333
	 * @param username the user name
334
	 * @param organization the organization
335
	 * @param dnList a list of dns
336
	 * @return String holding the ldap login string
337
	 */
338
	public static String createLDAPString(String username, String organization,
339 4854 daigle
			Vector<String> dnList) throws MetacatUtilException {
340 4080 daigle
341
		if (username == null || organization == null || dnList == null || dnList.size() == 0) {
342 4854 daigle
			throw new MetacatUtilException("Could not generate LDAP user string.  One of the following is null: username, organization or dnlist");
343 4080 daigle
		}
344
345
		String ldapString = "uid=" + username + ",o=" + organization;
346
347
		for (String dn : dnList) {
348
			ldapString += "," + dn;
349
		}
350
351
		return ldapString;
352
	}
353
354
	/**
355
	 * Reports whether LDAP is fully configured.
356
	 *
357
	 * @return a boolean that is true if all sections are configured and false
358
	 *         otherwise
359
	 */
360 4854 daigle
	public static boolean isAuthConfigured() throws MetacatUtilException {
361 4589 daigle
		String authConfiguredString = PropertyService.UNCONFIGURED;
362 4080 daigle
		try {
363 4589 daigle
			authConfiguredString = PropertyService.getProperty("configutil.authConfigured");
364 4080 daigle
		} catch (PropertyNotFoundException pnfe) {
365 4854 daigle
			throw new MetacatUtilException("Could not determine if LDAP is configured: "
366 4080 daigle
					+ pnfe.getMessage());
367
		}
368 4589 daigle
		return !authConfiguredString.equals(PropertyService.UNCONFIGURED);
369 4080 daigle
	}
370
371
	/**
372
	 * Check if the specified user is part of the administrators list
373
	 *
374
	 * @param username
375
	 *            the user login credentails
376
	 * @param groups
377
	 *            a list of the user's groups
378
	 */
379
	public static boolean isAdministrator(String username, String[] groups)
380 4854 daigle
			throws MetacatUtilException {
381 4080 daigle
		return onAccessList(getAdministrators(), username, groups);
382
	}
383
384
	/**
385
	 * Check if the specified user is part of the moderators list
386
	 *
387
	 * @param username
388
	 *            the user login credentails
389
	 * @param groups
390
	 *            a list of the user's groups
391
	 */
392 4854 daigle
	public static boolean isModerator(String username, String[] groups) throws MetacatUtilException{
393 4627 daigle
		return onAccessList(getModerators(), username, groups);
394 4080 daigle
	}
395
396
	/**
397
	 * Check if the specified user is part of the moderators list
398
	 *
399
	 * @param username
400
	 *            the user login credentails
401
	 * @param groups
402
	 *            a list of the user's groups
403
	 */
404
	public static boolean isAllowedSubmitter(String username, String[] groups)
405 4854 daigle
			throws MetacatUtilException {
406 4080 daigle
		if (getAllowedSubmitters().size() == 0) {
407
			// no allowedSubmitters list specified -
408
			// hence everyone should be allowed
409
			return true;
410
		}
411
		return (onAccessList(getAllowedSubmitters(), username, groups));
412
	}
413
414
	/**
415
	 * Check if the specified user is part of the moderators list
416
	 *
417
	 * @param username
418
	 *            the user login credentails
419
	 * @param groups
420
	 *            a list of the user's groups
421
	 */
422
	public static boolean isDeniedSubmitter(String username, String[] groups)
423 4854 daigle
			throws MetacatUtilException {
424 4080 daigle
		return (onAccessList(getDeniedSubmitters(), username, groups));
425
	}
426
427
	/**
428
	 * Check if the specified user can insert the document
429
	 *
430
	 * @param username
431
	 *            the user login credentails
432
	 * @param groups
433
	 *            a list of the user's groups
434
	 */
435
	public static boolean canInsertOrUpdate(String username, String[] groups)
436 4854 daigle
			throws MetacatUtilException {
437 4080 daigle
		return (isAllowedSubmitter(username, groups) && !isDeniedSubmitter(username,
438
				groups));
439
	}
440
441
	/**
442
	 * Check if the user is on a given access list.  This is true if either the
443
	 * user or the user's group is on the list.
444
	 *
445
	 * @param accessList the list we want to check against
446
	 * @param username the name of the user we want to check
447
	 * @param groups a list of the user's groups
448
	 */
449
	private static boolean onAccessList(Vector<String> accessList, String username,
450
			String[] groups) {
451
452
		// this should never happen.  All calls to this method should use the
453
		// appropriate getter to retrieve the accessList.  That should guarentee
454
		// that the access is at least an empty Vector.
455
		if (accessList == null) {
456
			return false;
457
		}
458
459
		// Check that the user is authenticated as an administrator account
460
		for (String accessString : accessList) {
461
			// check the given admin dn is a group dn...
462
			if (groups != null && accessString.startsWith("cn=")) {
463
				// is a group dn
464
				for (int j = 0; j < groups.length; j++) {
465 4984 daigle
					if (groups[j] != null && groups[j].equals(accessString)) {
466 4080 daigle
						return true;
467
					}
468
				}
469
			} else {
470
				// is a user dn
471
				if (username != null && username.equals(accessString)) {
472
					return true;
473
				}
474
			}
475
		}
476
		return false;
477
	}
478
479
}