Project

General

Profile

1
/**
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: daigle $'
9
 *     '$Date: 2009-01-26 16:38:42 -0800 (Mon, 26 Jan 2009) $'
10
 * '$Revision: 4780 $'
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
import edu.ucsb.nceas.metacat.AuthSession;
36
import edu.ucsb.nceas.metacat.service.PropertyService;
37
import edu.ucsb.nceas.metacat.service.ServiceException;
38
import edu.ucsb.nceas.metacat.service.SessionService;
39
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
40
import edu.ucsb.nceas.utilities.StringUtil;
41

    
42
public class AuthUtil {
43

    
44
	private static Vector<String> administrators = null;
45
	private static Vector<String> moderators = null;
46
	private static Vector<String> allowedSubmitters = null;
47
	private static Vector<String> deniedSubmitters = null;
48

    
49
	/**
50
	 * private constructor - all methods are static so there is no no need to
51
	 * instantiate.
52
	 */
53
	private AuthUtil() {}
54

    
55
	/**
56
	 * Get the administrators from metacat.properties
57
	 * 
58
	 * @return a Vector of Strings holding the administrators
59
	 */
60
	public static Vector<String> getAdministrators() throws UtilException {
61
		if (administrators == null) {
62
			populateAdministrators();
63
		}
64
		return administrators;
65
	}
66
	
67
	/**
68
	 * Get the allowed submitters from metacat.properties
69
	 * 
70
	 * @return a Vector of Strings holding the submitters
71
	 */
72
	public static Vector<String> getAllowedSubmitters() throws UtilException {
73
		if (allowedSubmitters == null) {			
74
			populateAllowedSubmitters();	
75
		}
76
		return allowedSubmitters;
77
	}
78
	
79
	/**
80
	 * Get the denied submitters from metacat.properties
81
	 * 
82
	 * @return a Vector of Strings holding the denied submitters
83
	 */
84
	public static Vector<String> getDeniedSubmitters() throws UtilException {
85
		if (deniedSubmitters == null) {
86
			populateDeniedSubmitters();
87
		}
88
		return deniedSubmitters;
89
	}
90
	
91
	/**
92
	 * Get the moderators from metacat.properties
93
	 * 
94
	 * @return a Vector of Strings holding the moderators
95
	 */
96
	public static Vector<String> getModerators() throws UtilException {
97
		if (moderators == null) {
98
			populateModerators();
99
		}
100
		return moderators;
101
	}
102
	
103
	/**
104
	 * Get the vector of administrator credentials from metacat.properties
105
	 * and put into global administrators list
106
	 */
107
	private static void populateAdministrators() throws UtilException {
108
		String administratorString = null;
109
		try {
110
			administratorString = 
111
				PropertyService.getProperty("auth.administrators");
112
		} catch (PropertyNotFoundException pnfe) {
113
			throw new UtilException("Could not get metacat property: auth.administrators. "
114
							+ "There will be no registered metacat adminstrators: "
115
							+ pnfe.getMessage());
116
		}
117
		administrators = StringUtil.toVector(administratorString, ':');
118
	}
119
	
120
	/**
121
	 * Get the vector of allowed submitter credentials from metacat.properties
122
	 * and put into global allowedSubmitters list
123
	 */
124
	private static void populateAllowedSubmitters() throws UtilException {
125
		String allowedSubmitterString = null;
126
		try {
127
			allowedSubmitterString = PropertyService.getProperty("auth.allowedSubmitters");
128
		} catch (PropertyNotFoundException pnfe) {
129
			throw new UtilException("Could not get metacat property: auth.allowedSubmitters. "
130
					+ "Anyone will be allowed to submit: "
131
					+ pnfe.getMessage());
132
		}		
133
		allowedSubmitters = StringUtil.toVector(allowedSubmitterString, ':');		
134
	}
135
	
136
	/**
137
	 * Get the vector of denied submitter credentials from metacat.properties
138
	 * and put into global deniedSubmitters list
139
	 */
140
	private static void populateDeniedSubmitters() throws UtilException {
141
		String deniedSubmitterString = null;
142
		try {
143
			deniedSubmitterString = PropertyService.getProperty("auth.deniedSubmitters");
144
		} catch (PropertyNotFoundException pnfe) {
145
			throw new UtilException("Could not get metacat property: auth.deniedSubmitters: "
146
					+ pnfe.getMessage());
147
		}		
148
		deniedSubmitters = StringUtil.toVector(deniedSubmitterString, ':');		
149
	}
150
	
151
	/**
152
	 * Get the vector of moderator credentials from metacat.properties
153
	 * and put into global administrators list
154
	 */
155
	private static void populateModerators() throws UtilException {
156
		String moderatorString = null;
157
		try {
158
			moderatorString = 
159
				PropertyService.getProperty("auth.moderators");
160
		} catch (PropertyNotFoundException pnfe) {
161
			throw new UtilException("Could not get metacat property: auth.moderators. "
162
							+ "There will be no registered metacat moderators: "
163
							+ pnfe.getMessage());
164
		}
165
		moderators = StringUtil.toVector(moderatorString, ':');
166
	}
167

    
168
	/**
169
	 * log the user in against ldap.  If the login is successful, add
170
	 * the session information to the session list in SessionUtil.
171
	 * 
172
	 * @param request the http request.
173
	 */
174
	public static boolean logUserIn(HttpServletRequest request, String userName, String password) throws UtilException {
175
		AuthSession authSession = null;
176

    
177
		// make sure we have username and password.
178
		if (userName == null || password == null) {
179
			throw new UtilException("null username or password when logging user in");
180
		}
181

    
182
		// Create auth session
183
		try {
184
			authSession = new AuthSession();
185
		} catch (Exception e) {
186
			throw new UtilException("Could not instantiate AuthSession: "
187
					+ e.getMessage());
188
		}
189
		// authenticate user against ldap
190
		if(!authSession.authenticate(request, userName,password)) {
191
			throw new UtilException(authSession.getMessage());
192
		}
193
		
194
		// if login was successful, add the session information to the
195
		// global session list.
196
		HttpSession session = authSession.getSessions();
197
		String sessionId = session.getId();
198
		
199
		try {
200
		SessionService.registerSession(sessionId, 
201
				(String) session.getAttribute("username"), 
202
				(String[]) session.getAttribute("groupnames"),
203
				(String) session.getAttribute("password"));
204
		} catch (ServiceException se) {
205
			throw new UtilException("Problem registering session: " + se.getMessage());
206
		}
207
		
208
		return true;
209
	}
210

    
211
	/**
212
	 * Checks to see if the user is logged in by grabbing the session from the
213
	 * request and seeing if it exists in the global session list.
214
	 * 
215
	 * @param request the http request that holds the login session
216
	 * @return boolean that is true if the user is logged in, false otherwise
217
	 */
218
	public static boolean isUserLoggedIn(HttpServletRequest request) throws UtilException{
219
		SessionData sessionData = null;
220
		String sessionId = request.getSession().getId();
221

    
222
		try {
223

    
224
			if (sessionId != null && SessionService.isSessionRegistered(sessionId)) {
225
				// get the registered session data
226
				sessionData = SessionService.getRegisteredSession(sessionId);
227

    
228
				// get the timeout limit
229
				String sessionTimeout = PropertyService.getProperty("auth.timeoutMinutes");
230
				int sessionTimeoutInt = Integer.parseInt(sessionTimeout);
231

    
232
				// get the last time the session was accessed
233
				Calendar lastAccessedTime = sessionData.getLastAccessedTime();
234
				// get the current time and set back "sessionTimoutInt" minutes
235
				Calendar now = Calendar.getInstance();
236
				now.add(Calendar.MINUTE, 0 - sessionTimeoutInt);
237

    
238
				// if the last accessed time is before now minus the timeout,
239
				// the session has expired. Unregister it and return false.
240
				if (lastAccessedTime.before(now)) {
241
					SessionService.unRegisterSession(sessionId);
242
					return false;
243
				}
244

    
245
				return true;
246
			}
247
			
248
		} catch (PropertyNotFoundException pnfe) {
249
			throw new UtilException("Could not determine if user is logged in because " 
250
					+ "of property error: " + pnfe.getMessage());
251
		} catch (NumberFormatException nfe) {
252
			throw new UtilException("Could not determine if user is logged in because " 
253
					+ "of number conversion error: " + nfe.getMessage());
254
		}
255

    
256
		return false;
257
	}
258

    
259
	/**
260
	 * Checks to see if the user is logged in as admin by first checking if the
261
	 * user is logged in and then seeing if the user's account is on the
262
	 * administrators list in metacat.properties.
263
	 * 
264
	 * @param request
265
	 *            the http request that holds the login session
266
	 * @return boolean that is true if the user is logged in as admin, false
267
	 *         otherwise
268
	 */
269
	public static boolean isUserLoggedInAsAdmin(HttpServletRequest request) throws UtilException {
270
		if (!isUserLoggedIn(request)) {
271
			return false;
272
		}
273

    
274
		String userName = getUserName(request);
275
		boolean isAdmin = isAdministrator(userName, null);
276

    
277
		return isAdmin;
278
	}
279

    
280
	/**
281
	 * Gets the user name from the login session on the http request
282
	 * 
283
	 * @param request
284
	 *            the http request that holds the login session
285
	 * @return String that holds the user name
286
	 */
287
	public static String getUserName(HttpServletRequest request) {
288
		String userName = (String)request.getSession().getAttribute("username");
289

    
290
		return userName;
291
	}
292

    
293
	/**
294
	 * Gets the user group names from the login session on the http request
295
	 * 
296
	 * @param request
297
	 *            the http request that holds the login session
298
	 * @return String array that holds the user groups
299
	 */
300
	public static String[] getGroupNames(HttpServletRequest request) {
301
		String sessionId = request.getSession().getId();;
302
		SessionData sessionData = SessionService.getRegisteredSession(sessionId);
303
		String[] groupNames = { "" };
304

    
305
		if (sessionData != null) {
306
			groupNames = sessionData.getGroupNames();
307
		}
308

    
309
		return groupNames;
310
	}
311

    
312
	/**
313
	 * Creates an ldap credentail string from the username, organization
314
	 * and dn list.
315
	 * 
316
	 * @param username the user name
317
	 * @param organization the organization
318
	 * @param dnList a list of dns
319
	 * @return String holding the ldap login string
320
	 */	
321
	public static String createLDAPString(String username, String organization,
322
			Vector<String> dnList) throws UtilException {
323

    
324
		if (username == null || organization == null || dnList == null || dnList.size() == 0) {
325
			throw new UtilException("Could not generate LDAP user string.  One of the following is null: username, organization or dnlist");
326
		}
327

    
328
		String ldapString = "uid=" + username + ",o=" + organization;
329

    
330
		for (String dn : dnList) {
331
			ldapString += "," + dn;
332
		}
333

    
334
		return ldapString;
335
	}
336

    
337
	/**
338
	 * Reports whether LDAP is fully configured.
339
	 * 
340
	 * @return a boolean that is true if all sections are configured and false
341
	 *         otherwise
342
	 */
343
	public static boolean isAuthConfigured() throws UtilException {
344
		String authConfiguredString = PropertyService.UNCONFIGURED;
345
		try {
346
			authConfiguredString = PropertyService.getProperty("configutil.authConfigured");
347
		} catch (PropertyNotFoundException pnfe) {
348
			throw new UtilException("Could not determine if LDAP is configured: "
349
					+ pnfe.getMessage());
350
		}
351
		return !authConfiguredString.equals(PropertyService.UNCONFIGURED);
352
	}
353

    
354
	/**
355
	 * Check if the specified user is part of the administrators list
356
	 * 
357
	 * @param username
358
	 *            the user login credentails
359
	 * @param groups
360
	 *            a list of the user's groups
361
	 */
362
	public static boolean isAdministrator(String username, String[] groups)
363
			throws UtilException {
364
		return onAccessList(getAdministrators(), username, groups);
365
	}
366

    
367
	/**
368
	 * Check if the specified user is part of the moderators list
369
	 * 
370
	 * @param username
371
	 *            the user login credentails
372
	 * @param groups
373
	 *            a list of the user's groups
374
	 */
375
	public static boolean isModerator(String username, String[] groups) throws UtilException{
376
		return onAccessList(getModerators(), username, groups);
377
	}
378

    
379
	/**
380
	 * Check if the specified user is part of the moderators list
381
	 * 
382
	 * @param username
383
	 *            the user login credentails
384
	 * @param groups
385
	 *            a list of the user's groups
386
	 */
387
	public static boolean isAllowedSubmitter(String username, String[] groups)
388
			throws UtilException {
389
		if (getAllowedSubmitters().size() == 0) {
390
			// no allowedSubmitters list specified -
391
			// hence everyone should be allowed
392
			return true;
393
		}
394
		return (onAccessList(getAllowedSubmitters(), username, groups));
395
	}
396

    
397
	/**
398
	 * Check if the specified user is part of the moderators list
399
	 * 
400
	 * @param username
401
	 *            the user login credentails
402
	 * @param groups
403
	 *            a list of the user's groups
404
	 */
405
	public static boolean isDeniedSubmitter(String username, String[] groups)
406
			throws UtilException {
407
		return (onAccessList(getDeniedSubmitters(), username, groups));
408
	}
409

    
410
	/**
411
	 * Check if the specified user can insert the document
412
	 * 
413
	 * @param username
414
	 *            the user login credentails
415
	 * @param groups
416
	 *            a list of the user's groups
417
	 */
418
	public static boolean canInsertOrUpdate(String username, String[] groups)
419
			throws UtilException {
420
		return (isAllowedSubmitter(username, groups) && !isDeniedSubmitter(username,
421
				groups));
422
	}
423

    
424
	/**
425
	 * Check if the user is on a given access list.  This is true if either the 
426
	 * user or the user's group is on the list.
427
	 * 
428
	 * @param accessList the list we want to check against
429
	 * @param username the name of the user we want to check
430
	 * @param groups a list of the user's groups
431
	 */
432
	private static boolean onAccessList(Vector<String> accessList, String username,
433
			String[] groups) {
434

    
435
		// this should never happen.  All calls to this method should use the 
436
		// appropriate getter to retrieve the accessList.  That should guarentee
437
		// that the access is at least an empty Vector.
438
		if (accessList == null) {
439
			return false;
440
		}
441

    
442
		// Check that the user is authenticated as an administrator account
443
		for (String accessString : accessList) {
444
			// check the given admin dn is a group dn...
445
			if (groups != null && accessString.startsWith("cn=")) {
446
				// is a group dn
447
				for (int j = 0; j < groups.length; j++) {
448
					if (groups[j].equals(accessString)) {
449
						return true;
450
					}
451
				}
452
			} else {
453
				// is a user dn
454
				if (username != null && username.equals(accessString)) {
455
					return true;
456
				}
457
			}
458
		}
459
		return false;
460
	}
461

    
462
}
(1-1/12)