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: 2008-11-25 09:54:32 -0800 (Tue, 25 Nov 2008) $'
10
 * '$Revision: 4628 $'
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.SessionService;
38
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
39
import edu.ucsb.nceas.utilities.StringUtil;
40

    
41
public class AuthUtil {
42

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

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

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

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

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

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

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

    
216
		try {
217

    
218
			if (sessionId != null && SessionService.isSessionRegistered(sessionId)) {
219
				// get the registered session data
220
				sessionData = SessionService.getRegisteredSession(sessionId);
221

    
222
				// get the timeout limit
223
				String sessionTimeout = PropertyService.getProperty("auth.timeoutMinutes");
224
				int sessionTimeoutInt = Integer.parseInt(sessionTimeout);
225

    
226
				// get the last time the session was accessed
227
				Calendar lastAccessedTime = sessionData.getLastAccessedTime();
228
				// get the current time and set back "sessionTimoutInt" minutes
229
				Calendar now = Calendar.getInstance();
230
				now.add(Calendar.MINUTE, 0 - sessionTimeoutInt);
231

    
232
				// if the last accessed time is before now minus the timeout,
233
				// the session has expired. Unregister it and return false.
234
				if (lastAccessedTime.before(now)) {
235
					SessionService.unRegisterSession(sessionId);
236
					return false;
237
				}
238

    
239
				return true;
240
			}
241
			
242
		} catch (PropertyNotFoundException pnfe) {
243
			throw new UtilException("Could not determine if user is logged in because " 
244
					+ "of property error: " + pnfe.getMessage());
245
		} catch (NumberFormatException nfe) {
246
			throw new UtilException("Could not determine if user is logged in because " 
247
					+ "of number conversion error: " + nfe.getMessage());
248
		}
249

    
250
		return false;
251
	}
252

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

    
268
		String userName = getUserName(request);
269
		boolean isAdmin = isAdministrator(userName, null);
270

    
271
		return isAdmin;
272
	}
273

    
274
	/**
275
	 * Gets the user name from the login session on the http request
276
	 * 
277
	 * @param request
278
	 *            the http request that holds the login session
279
	 * @return String that holds the user name
280
	 */
281
	public static String getUserName(HttpServletRequest request) {
282
		String userName = (String)request.getSession().getAttribute("username");
283

    
284
		return userName;
285
	}
286

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

    
299
		if (sessionData != null) {
300
			groupNames = sessionData.getGroupNames();
301
		}
302

    
303
		return groupNames;
304
	}
305

    
306
	/**
307
	 * Creates an ldap credentail string from the username, organization
308
	 * and dn list.
309
	 * 
310
	 * @param username the user name
311
	 * @param organization the organization
312
	 * @param dnList a list of dns
313
	 * @return String holding the ldap login string
314
	 */	
315
	public static String createLDAPString(String username, String organization,
316
			Vector<String> dnList) throws UtilException {
317

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

    
322
		String ldapString = "uid=" + username + ",o=" + organization;
323

    
324
		for (String dn : dnList) {
325
			ldapString += "," + dn;
326
		}
327

    
328
		return ldapString;
329
	}
330

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

    
348
	/**
349
	 * Check if the specified user is part of the administrators list
350
	 * 
351
	 * @param username
352
	 *            the user login credentails
353
	 * @param groups
354
	 *            a list of the user's groups
355
	 */
356
	public static boolean isAdministrator(String username, String[] groups)
357
			throws UtilException {
358
		return onAccessList(getAdministrators(), username, groups);
359
	}
360

    
361
	/**
362
	 * Check if the specified user is part of the moderators list
363
	 * 
364
	 * @param username
365
	 *            the user login credentails
366
	 * @param groups
367
	 *            a list of the user's groups
368
	 */
369
	public static boolean isModerator(String username, String[] groups) throws UtilException{
370
		return onAccessList(getModerators(), username, groups);
371
	}
372

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

    
391
	/**
392
	 * Check if the specified user is part of the moderators list
393
	 * 
394
	 * @param username
395
	 *            the user login credentails
396
	 * @param groups
397
	 *            a list of the user's groups
398
	 */
399
	public static boolean isDeniedSubmitter(String username, String[] groups)
400
			throws UtilException {
401
		return (onAccessList(getDeniedSubmitters(), username, groups));
402
	}
403

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

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

    
429
		// this should never happen.  All calls to this method should use the 
430
		// appropriate getter to retrieve the accessList.  That should guarentee
431
		// that the access is at least an empty Vector.
432
		if (accessList == null) {
433
			return false;
434
		}
435

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

    
456
}
(1-1/12)