source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/Authentication.java@ 32390

Last change on this file since 32390 was 32390, checked in by kjdon, 6 years ago

replaced hard coded text strings with static Strings. when doing PerformRegister and changing result to Register (on error), we might need to add in recaptcha element. have a recaptchaOplist which specifies which operations require the recaptcha to be added (list comes from siteConfig)

File size: 42.5 KB
Line 
1package org.greenstone.gsdl3.service;
2
3import java.io.File;
4import java.io.Serializable;
5import java.math.BigInteger;
6import java.sql.SQLException;
7import java.util.ArrayList;
8import java.util.HashMap;
9import java.util.UUID;
10import java.util.Vector;
11import java.util.regex.Pattern;
12
13// for verifying recaptcha
14import java.io.BufferedReader;
15import java.io.DataOutputStream;
16import java.io.IOException;
17import java.io.InputStreamReader;
18import java.io.StringReader;
19import java.net.URL;
20import javax.net.ssl.HttpsURLConnection;
21// https://developer.android.com/reference/org/json/JSONObject.html
22// https://developer.android.com/reference/org/json/JSONArray.html
23import org.json.JSONArray;
24import org.json.JSONException;
25import org.json.JSONObject;
26
27import org.apache.commons.codec.digest.DigestUtils;
28import org.greenstone.gsdl3.util.DerbyWrapper;
29import org.greenstone.gsdl3.util.GSXML;
30import org.greenstone.gsdl3.util.UserQueryResult;
31import org.greenstone.gsdl3.util.UserTermInfo;
32import org.greenstone.gsdl3.util.XMLConverter;
33import org.greenstone.util.GlobalProperties;
34
35import org.w3c.dom.Document;
36import org.w3c.dom.Element;
37import org.w3c.dom.NodeList;
38
39public class Authentication extends ServiceRack
40{
41 //Some useful constants
42 protected static final int USERNAME_MIN_LENGTH = 2;
43 protected static final int USERNAME_MAX_LENGTH = 30;
44 protected static final int PASSWORD_MIN_LENGTH = 3;
45 protected static final int PASSWORD_MAX_LENGTH = 64;
46
47 //Error codes
48 protected static final int NO_ERROR = 0;
49 protected static final int ERROR_NOT_LOGGED_IN = -2;
50 protected static final int ERROR_ADMIN_NOT_LOGGED_IN = -3;
51 protected static final int ERROR_COULD_NOT_GET_USER_INFO = -4;
52 protected static final int ERROR_USERNAME_NOT_SPECIFIED = -5;
53 protected static final int ERROR_USER_NOT_FOUND = -6;
54 protected static final int ERROR_SQL_EXCEPTION = -7;
55 protected static final int ERROR_INVALID_USERNAME = -8;
56 protected static final int ERROR_PASSWORD_NOT_ENTERED = -9;
57 protected static final int ERROR_PASSWORD_TOO_SHORT = -10;
58 protected static final int ERROR_PASSWORD_TOO_LONG = -11;
59 protected static final int ERROR_PASSWORD_USES_ILLEGAL_CHARACTERS = -12;
60 protected static final int ERROR_INCORRECT_PASSWORD = -13;
61 protected static final int ERROR_USER_ALREADY_EXISTS = -14;
62 protected static final int ERROR_ADDING_USER = -15;
63 protected static final int ERROR_REMOVING_USER = -16;
64 protected static final int ERROR_CAPTCHA_FAILED = -17;
65 protected static final int ERROR_CAPTCHA_MISSING = -18;
66 protected static final int ERROR_NOT_AUTHORISED = -19;
67 protected static final int ERROR_MISSING_PARAMS = -20;
68
69 protected static final HashMap<Integer, String> _errorKeyMap;
70 static
71 {
72 //Corresponding error message keys for looking up in ServiceRack dictionary
73 HashMap<Integer, String> errorKeyMap = new HashMap<Integer, String>();
74 errorKeyMap.put(ERROR_NOT_LOGGED_IN, "auth.error.not_logged_in");
75 errorKeyMap.put(ERROR_ADMIN_NOT_LOGGED_IN, "auth.error.admin_not_logged_in");
76 errorKeyMap.put(ERROR_COULD_NOT_GET_USER_INFO, "auth.error.could_not_get_user_info");
77 errorKeyMap.put(ERROR_USERNAME_NOT_SPECIFIED, "auth.error.username_not_specified");
78 errorKeyMap.put(ERROR_USER_NOT_FOUND, "auth.error.user_not_found");
79 errorKeyMap.put(ERROR_SQL_EXCEPTION, "auth.error.sql_exception");
80 errorKeyMap.put(ERROR_INVALID_USERNAME, "auth.error.invalid_username");
81 errorKeyMap.put(ERROR_PASSWORD_NOT_ENTERED, "auth.error.no_password");
82 errorKeyMap.put(ERROR_PASSWORD_TOO_SHORT, "auth.error.password_too_short");
83 errorKeyMap.put(ERROR_PASSWORD_TOO_LONG, "auth.error.password_too_long");
84 errorKeyMap.put(ERROR_PASSWORD_USES_ILLEGAL_CHARACTERS, "auth.error.password_illegal_chars");
85 errorKeyMap.put(ERROR_INCORRECT_PASSWORD, "auth.error.incorrect_password");
86 errorKeyMap.put(ERROR_USER_ALREADY_EXISTS, "auth.error.user_already_exists");
87 errorKeyMap.put(ERROR_ADDING_USER, "auth.error.add_user_error");
88 errorKeyMap.put(ERROR_REMOVING_USER, "auth.error.remove_user_error");
89 errorKeyMap.put(ERROR_CAPTCHA_FAILED, "auth.error.captcha_failed");
90 errorKeyMap.put(ERROR_CAPTCHA_MISSING, "auth.error.captcha_missing");
91 errorKeyMap.put(ERROR_NOT_AUTHORISED, "auth.error.not_authorised");
92 errorKeyMap.put(ERROR_MISSING_PARAMS, "auth.error.missing_params"); // ???
93 _errorKeyMap = errorKeyMap;
94 }
95
96 //Admin-required operations
97 protected static final String LIST_USERS = "ListUsers";
98 protected static final String PERFORM_ADD = "PerformAdd";
99 protected static final String PERFORM_EDIT = "PerformEdit";
100 protected static final String ADD_USER = "AddUser";
101 protected static final String EDIT_USER = "EditUser";
102 protected static final String PERFORM_DELETE_USER = "PerformDeleteUser";
103
104 protected static final ArrayList<String> _adminOpList;
105 static
106 {
107 ArrayList<String> opList = new ArrayList<String>();
108 opList.add(LIST_USERS);
109 opList.add(PERFORM_ADD);
110 opList.add(PERFORM_EDIT);
111 opList.add(ADD_USER);
112 opList.add(EDIT_USER);
113 opList.add(PERFORM_DELETE_USER);
114
115 _adminOpList = opList;
116 }
117
118 //User-required operations
119 protected static final String ACCOUNT_SETTINGS = "AccountSettings";
120 protected static final String PERFORM_ACCOUNT_EDIT = "PerformAccEdit";
121 protected static final String PERFORM_RESET_PASSWORD = "PerformResetPassword";
122 protected static final String PERFORM_CHANGE_PASSWORD = "PerformChangePassword";
123 protected static final String PERFORM_RETRIEVE_PASSWORD = "PerformRetrievePassword";
124 protected static final ArrayList<String> _userOpList;
125 static
126 {
127 ArrayList<String> opList = new ArrayList<String>();
128 opList.add(ACCOUNT_SETTINGS);
129 opList.add(PERFORM_ACCOUNT_EDIT);
130 opList.add(PERFORM_RESET_PASSWORD);
131 opList.add(PERFORM_CHANGE_PASSWORD);
132 opList.add(PERFORM_RETRIEVE_PASSWORD);
133 opList.addAll(_adminOpList);
134 _userOpList = opList;
135 }
136
137 //Other operations
138 protected static final String REGISTER = "Register"; // displays the register page
139 protected static final String PERFORM_REGISTER = "PerformRegister"; // performs the registration action
140 protected static final String LOGIN = "Login";
141 protected static final String BLANK = "Info"; // a dummy page just for showing an error message
142 //the services on offer
143 protected static final String AUTHENTICATION_SERVICE = "Authentication";
144 protected static final String GET_USER_INFORMATION_SERVICE = "GetUserInformation";
145 protected static final String CHANGE_USER_EDIT_MODE_SERVICE = "ChangeUserEditMode";
146 protected static final String REMOTE_AUTHENTICATION_SERVICE = "RemoteAuthentication";
147
148 protected static boolean _derbyWrapperDoneForcedShutdown = false;
149
150 // some XML strings
151 protected static final String RECAPTCHA_ELEM = "recaptcha";
152 protected static final String SITE_KEY = "site_key";
153 protected static final String SECRET_KEY = "secret_key";
154 protected static final String OPERATIONS = "operations";
155protected static final String OPERATION = "operation";
156
157 protected static final String USERNAME = "username";
158 protected static final String PREV_USERNAME = "prevUsername";
159 protected static final String NEW_USERNAME = "newUsername";
160 protected static final String PASSWORD = "password";
161 protected static final String OLD_PASSWORD = "oldPassword";
162 protected static final String NEW_PASSWORD = "newPassword";
163
164 protected static final String GROUPS = "groups";
165 protected static final String ENABLED = "enabled";
166 protected static final String COMMENT = "comment";
167 protected static final String STATUS = "status";
168 protected static final String EMAIL = "email";
169 protected static final String NEW_EMAIL = "newEmail";
170 protected static final String ACCOUNT_STATUS = "accountstatus";
171 protected static final String EDIT_ENABLED = "editEnabled";
172
173 protected String _recaptchaSiteKey = null;
174 protected String _recaptchaSecretKey = null;
175 protected static ArrayList<String> _recaptchaOpList = null;
176 /** constructor */
177 public Authentication()
178 {
179 }
180
181 public void cleanUp()
182 {
183 super.cleanUp();
184
185 if (!_derbyWrapperDoneForcedShutdown)
186 {
187
188 // This boolean is used to ensure we always shutdown the derby server, even if it is never
189 // used by the Authentication server. This is because the Tomcat greenstone3.xml
190 // config file also specifies a connection to the database, which can result in the
191 // server being initialized when the servlet is first accessed. Note also,
192 // Authentication is a ServiceRack, meaning cleanUp() is called for each service
193 // supported, however we only need to shutdown the Derby server once. Again
194 // this boolean variable helps achieve this.
195
196 logger.info("Authentication Service performing forced shutdown of Derby Server ...");
197
198 DerbyWrapper.shutdownDatabaseServer();
199 _derbyWrapperDoneForcedShutdown = true;
200 }
201 }
202
203 public boolean configure(Element info, Element extra_info)
204 {
205 logger.info("Configuring Authentication...");
206 this.config_info = info;
207
208 // set up Authentication service info - for now just has name and type
209 Element authentication_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
210 authentication_service.setAttribute(GSXML.TYPE_ATT, "authen");
211 authentication_service.setAttribute(GSXML.NAME_ATT, AUTHENTICATION_SERVICE);
212 this.short_service_info.appendChild(authentication_service);
213
214 Element getUserInformation_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
215 getUserInformation_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
216 getUserInformation_service.setAttribute(GSXML.NAME_ATT, GET_USER_INFORMATION_SERVICE);
217 this.short_service_info.appendChild(getUserInformation_service);
218
219 Element changeEditMode_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
220 changeEditMode_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
221 changeEditMode_service.setAttribute(GSXML.NAME_ATT, CHANGE_USER_EDIT_MODE_SERVICE);
222 this.short_service_info.appendChild(changeEditMode_service);
223
224 Element remoteAuthentication_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
225 remoteAuthentication_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
226 remoteAuthentication_service.setAttribute(GSXML.NAME_ATT, REMOTE_AUTHENTICATION_SERVICE);
227 this.short_service_info.appendChild(remoteAuthentication_service);
228
229
230 DerbyWrapper.createDatabaseIfNeeded();
231
232 NodeList recaptchaElems = info.getElementsByTagName(RECAPTCHA_ELEM);
233 for (int i = 0; i < recaptchaElems.getLength(); i++)
234 {
235 Element currentElem = (Element) recaptchaElems.item(i);
236 if (currentElem.getAttribute(GSXML.NAME_ATT).equals(SITE_KEY))
237 {
238 if (!currentElem.getAttribute(GSXML.VALUE_ATT).equals(""))
239 {
240 _recaptchaSiteKey = currentElem.getAttribute(GSXML.VALUE_ATT);
241 }
242 }
243 else if (currentElem.getAttribute(GSXML.NAME_ATT).equals(SECRET_KEY))
244 {
245 if (!currentElem.getAttribute(GSXML.VALUE_ATT).equals(""))
246 {
247 _recaptchaSecretKey = currentElem.getAttribute(GSXML.VALUE_ATT);
248 }
249 }
250 else if (currentElem.getAttribute(GSXML.NAME_ATT).equals(OPERATIONS))
251 {
252 _recaptchaOpList = new ArrayList<String>();
253 String value = currentElem.getAttribute(GSXML.VALUE_ATT);
254 String[] ops = value.split(",");
255 for (int j=0; j<ops.length; j++) {
256 if (!ops[j].equals("")) {
257 _recaptchaOpList.add(ops[j]); /// value checking?
258 }
259 }
260 }
261
262 }
263 // check recaptcha
264 if (_recaptchaSecretKey == null || _recaptchaSecretKey.length() == 0 || _recaptchaSiteKey == null || _recaptchaSiteKey.length() == 0) {
265 _recaptchaOpList = null;
266 }
267
268 return true;
269 }
270
271 protected Element getServiceDescription(Document doc, String service_id, String lang, String subset)
272 {
273
274 Element authen_service = doc.createElement(GSXML.SERVICE_ELEM);
275
276 if (service_id.equals(AUTHENTICATION_SERVICE))
277 {
278 authen_service.setAttribute(GSXML.TYPE_ATT, "authen");
279 authen_service.setAttribute(GSXML.NAME_ATT, AUTHENTICATION_SERVICE);
280 }
281 else if (service_id.equals(GET_USER_INFORMATION_SERVICE))
282 {
283 authen_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
284 authen_service.setAttribute(GSXML.NAME_ATT, GET_USER_INFORMATION_SERVICE);
285 }
286 else if (service_id.equals(CHANGE_USER_EDIT_MODE_SERVICE))
287 {
288 authen_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
289 authen_service.setAttribute(GSXML.NAME_ATT, CHANGE_USER_EDIT_MODE_SERVICE);
290 }
291 else if (service_id.equals(REMOTE_AUTHENTICATION_SERVICE))
292 {
293 authen_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
294 authen_service.setAttribute(GSXML.NAME_ATT, REMOTE_AUTHENTICATION_SERVICE);
295 }
296 else
297 {
298 return null;
299 }
300
301 if (service_id.equals(AUTHENTICATION_SERVICE) && (subset == null || subset.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER)))
302 {
303 authen_service.appendChild(GSXML.createDisplayTextElement(doc, GSXML.DISPLAY_TEXT_NAME, getServiceName(service_id, lang)));
304 authen_service.appendChild(GSXML.createDisplayTextElement(doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getServiceDescription(service_id, lang)));
305 }
306 return authen_service;
307 }
308
309 protected String getServiceName(String service_id, String lang)
310 {
311 return getTextString(service_id + ".name", lang);
312 }
313
314 protected String getServiceSubmit(String service_id, String lang)
315 {
316 return getTextString(service_id + ".submit", lang);
317 }
318
319 protected String getServiceDescription(String service_id, String lang)
320 {
321 return getTextString(service_id + ".description", lang);
322 }
323 protected String getErrorTextString(int error_code, String lang) {
324 return getTextString(_errorKeyMap.get(error_code), lang);
325
326 }
327 protected Element processChangeUserEditMode(Element request)
328 {
329 // Create a new (empty) result message
330 Document result_doc = XMLConverter.newDOM();
331 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
332
333 result.setAttribute(GSXML.FROM_ATT, CHANGE_USER_EDIT_MODE_SERVICE);
334 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
335
336 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
337 if (paramList == null)
338 {
339 logger.error("ChangeUserEditMode request has no param list!!");
340 return result;
341 }
342
343 HashMap<String, Serializable> params = GSXML.extractParams(paramList, true);
344
345 String username = (String) params.get(USERNAME);
346 String editMode = (String) params.get(ENABLED);
347
348 if (!editMode.toLowerCase().equals("true") && !editMode.toLowerCase().equals("false"))
349 {
350 editMode = "false";
351 }
352
353 DerbyWrapper dw = openDatabase();
354 dw.addUserData(username, "USER_EDIT_ENABLED", editMode);
355 dw.closeDatabase();
356
357 return result;
358 }
359
360 /**
361 * This method replaces the gliserver.pl code for authenticating a user against the derby database
362 * gliserver.pl needed to instantiate its own JVM to access the derby DB, but the GS3 already has
363 * the Derby DB open and 2 JVMs are not allowed concurrent access to an open embedded Derby DB.
364 * Gliserver.pl now goes through this method (via ServletRealmCheck.java), thereby using the same
365 * connection to the DerbyDB. This method reproduces the same behaviour as gliserver.pl used to,
366 * by returning the user_groups on successful authentication, else returns the specific
367 * "Authentication failed" messages that glisever.pl would produce.
368 * http://remote-host-name:8383/greenstone3/library?a=s&sa=authenticated-ping&excerptid=gs_content&un=admin&pw=<PW>&col=demo
369 */
370 protected Element processRemoteAuthentication(Element request) {
371 //logger.info("*** Authentication::processRemoteAuthentication");
372
373 String message = "";
374
375 Element system = (Element) GSXML.getChildByTagName(request, GSXML.REQUEST_TYPE_SYSTEM);
376 String username = system.hasAttribute(USERNAME) ? system.getAttribute(USERNAME) : "";
377 String password = system.hasAttribute(PASSWORD) ? system.getAttribute(PASSWORD) : "";
378
379
380 // If we're not editing a collection then the user doesn't need to be in a particular group
381 String collection = system.hasAttribute("collection") ? system.getAttribute("collection") : "";
382
383
384 if(username.equals("") || password.equals("")) {
385 message = "Authentication failed: no (username or) password specified.";
386 //logger.error("*** Remote login failed. No username or pwd provided");
387 }
388 else {
389 String storedPassword = retrieveDataForUser(username, PASSWORD);
390 if(storedPassword != null && (password.equals(storedPassword) || hashPassword(password).equals(storedPassword))) {
391
392 // gliserver.pl used to return the groups when authentication succeeded
393 String groups = retrieveDataForUser(username, GROUPS); //comma-separated list
394
395 if(collection.equals("")) {
396 message = groups;
397 } else {
398
399 if(groups.indexOf("all-collections-editor") != -1) { // Does this user have access to all collections?
400 message = groups;
401 } else if(groups.indexOf("personal-collections-editor") != -1 && collection.startsWith(username+"-")) { // Does this user have access to personal collections, and is this one?
402 message = groups;
403 } else if(groups.indexOf(collection+"-collection-editor") != -1) { // Does this user have access to this collection?
404 message = groups;
405 }
406 else {
407 message = "Authentication failed: user is not in the required group.";
408 //logger.error("*** Remote login failed. Groups did not match for the collection specified");
409 }
410 }
411
412 } else {
413
414 if(storedPassword == null) {
415 message = "Authentication failed: no account for user '" + username + "'";
416 //logger.error("*** Remote login failed. User not found or password not set for user.");
417 } else {
418 message = "Authentication failed: incorrect password.";
419 //logger.error("*** Remote login failed. Password did not match for user");
420 }
421 }
422 }
423 Document result_doc = XMLConverter.newDOM();
424 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
425 result.setAttribute(GSXML.FROM_ATT, REMOTE_AUTHENTICATION_SERVICE);
426 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
427 Element s = GSXML.createTextElement(result_doc, GSXML.STATUS_ELEM, message);
428 result.appendChild(s);
429 return result;
430 }
431
432 protected Element processGetUserInformation(Element request)
433 {
434 // Create a new (empty) result message
435 Document result_doc = XMLConverter.newDOM();
436 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
437
438 result.setAttribute(GSXML.FROM_ATT, GET_USER_INFORMATION_SERVICE);
439 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
440
441 String lang = request.getAttribute(GSXML.LANG_ATT);
442 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
443 if (paramList == null)
444 {
445 logger.error("GetUserInformation request has no param list");
446 return result;
447 }
448
449 HashMap<String, Serializable> params = GSXML.extractParams(paramList, true);
450
451 String username = (String) params.get(USERNAME);
452
453 if (username == null)
454 {
455 GSXML.addError(result, getErrorTextString(ERROR_USERNAME_NOT_SPECIFIED, lang));
456 return result;
457 }
458
459 DerbyWrapper derbyWrapper = openDatabase();
460
461 UserQueryResult userQueryResult = derbyWrapper.findUser(username);
462 String editEnabled = derbyWrapper.getUserData(username, "USER_EDIT_ENABLED");
463
464 Vector<UserTermInfo> terms = userQueryResult.getUserTerms();
465
466 if (terms.size() == 0)
467 {
468 GSXML.addError(result, getErrorTextString(ERROR_USER_NOT_FOUND, lang));
469 return result;
470 }
471
472 UserTermInfo userInfo = terms.get(0);
473 Element userInfoList = result_doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
474 result.appendChild(userInfoList);
475
476 Element usernameField = GSXML.createParameter(result_doc, USERNAME, userInfo.username);
477 Element passwordField = GSXML.createParameter(result_doc, PASSWORD, userInfo.password);
478 Element groupsField = GSXML.createParameter(result_doc, GROUPS, userInfo.groups);
479 Element accountStatusField = GSXML.createParameter(result_doc, ACCOUNT_STATUS, userInfo.accountstatus);
480 Element commentField = GSXML.createParameter(result_doc, COMMENT, userInfo.comment);
481
482 if (editEnabled != null)
483 {
484 Element editEnabledElem = GSXML.createParameter(result_doc, EDIT_ENABLED, editEnabled);
485 userInfoList.appendChild(editEnabledElem);
486 }
487
488 userInfoList.appendChild(usernameField);
489 userInfoList.appendChild(passwordField);
490 userInfoList.appendChild(groupsField);
491 userInfoList.appendChild(accountStatusField);
492 userInfoList.appendChild(commentField);
493
494 derbyWrapper.closeDatabase();
495
496 return result;
497 }
498
499 protected Element processAuthentication(Element request)
500 {
501 checkAdminUserExists();
502
503 // Create a new (empty) result message
504 Document result_doc = XMLConverter.newDOM();
505 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
506 result.setAttribute(GSXML.FROM_ATT, AUTHENTICATION_SERVICE);
507 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
508
509 // Create an Authentication node put into the result
510 Element authenNode = result_doc.createElement(GSXML.AUTHEN_NODE_ELEM);
511 result.appendChild(authenNode);
512 result.appendChild(getCollectList(result_doc, this.site_home + File.separatorChar + "collect"));
513
514 // Create a service node added into the Authentication node
515 Element serviceNode = result_doc.createElement(GSXML.SERVICE_ELEM);
516 authenNode.appendChild(serviceNode);
517
518 // Get the parameters of the request
519 String lang = request.getAttribute(GSXML.LANG_ATT);
520 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
521 if (param_list == null)
522 {
523 serviceNode.setAttribute(OPERATION, LOGIN);
524 logger.error("Authentication request has no param list");
525 return result; // Return the empty result
526 }
527 HashMap<String, Serializable> paramMap = GSXML.extractParams(param_list, false);
528 String op = (String) paramMap.get("authpage");
529 serviceNode.setAttribute(OPERATION, op);
530
531 String username = null;
532 String groups = null;
533
534 Element userInformation = (Element) GSXML.getChildByTagName(request, GSXML.USER_INFORMATION_ELEM);
535 if (userInformation != null)
536 {
537 username = userInformation.getAttribute(GSXML.USERNAME_ATT);
538 groups = userInformation.getAttribute(GSXML.GROUPS_ATT);
539 }
540 logger.error("username="+username+", groups = "+groups);
541 if ((userInformation == null || username == null) && _userOpList.contains(op))
542 {
543 // its an operation that requires the user to be logged on - direct them to login page
544 serviceNode.setAttribute(OPERATION, LOGIN);
545 GSXML.addError(result, getErrorTextString(ERROR_NOT_LOGGED_IN, lang));
546 return result;
547 }
548
549 if (_adminOpList.contains(op) && (groups == null || !groups.matches(".*\\badministrator\\b.*")))
550 {
551 // actually, the user needs to be an admin user and they are not
552 serviceNode.setAttribute(OPERATION, LOGIN);
553 GSXML.addError(result, getErrorTextString(ERROR_ADMIN_NOT_LOGGED_IN, lang));
554 return result;
555 }
556
557 if (_recaptchaOpList != null && _recaptchaOpList.contains(op)) {
558 serviceNode.setAttribute("recaptcha_key", _recaptchaSiteKey);
559 }
560
561 if (op.equals(LIST_USERS))
562 {
563 int error = addUserInformationToNode(null, serviceNode);
564 if (error != NO_ERROR)
565 {
566 serviceNode.setAttribute(OPERATION, BLANK);
567 GSXML.addError(result, getErrorTextString(error, lang));
568 }
569 return result;
570
571 }
572
573 if (op.equals(PERFORM_ADD))
574 {
575 String newUsername = (String) paramMap.get(USERNAME);
576 String newPassword = (String) paramMap.get(PASSWORD);
577 String newGroups = (String) paramMap.get(GROUPS);
578 String newStatus = (String) paramMap.get(STATUS);
579 String newComment = (String) paramMap.get(COMMENT);
580 String newEmail = (String) paramMap.get(EMAIL);
581
582 //Check the given user name
583 int error;
584 if ((error = checkUsername(newUsername)) != NO_ERROR)
585 {
586 serviceNode.setAttribute(OPERATION, ADD_USER);
587 GSXML.addError(result, getErrorTextString(error, lang));
588 return result;
589 }
590
591 //Check the given password
592 if ((error = checkPassword(newPassword)) != NO_ERROR)
593 {
594 serviceNode.setAttribute(OPERATION, ADD_USER);
595 GSXML.addError(result, getErrorTextString(error, lang));
596 return result;
597 }
598
599 newPassword = hashPassword(newPassword);
600
601 error = addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
602 if (error != NO_ERROR)
603 {
604 serviceNode.setAttribute(OPERATION, ADD_USER);
605 GSXML.addError(result, getErrorTextString(error, lang));
606 }
607 else
608 {
609 addUserInformationToNode(null, serviceNode);
610 serviceNode.setAttribute(OPERATION, LIST_USERS);
611 }
612 return result;
613 }
614
615 if (op.equals(REGISTER)) {
616 // don't need any additional info
617 return result;
618 }
619 if (op.equals(PERFORM_REGISTER))
620 {
621 String newUsername = (String) paramMap.get(USERNAME);
622 String newPassword = (String) paramMap.get(PASSWORD);
623 String newEmail = (String) paramMap.get(EMAIL);
624
625 //Check the given details
626 int error;
627 if ((error = checkUsername(newUsername)) == NO_ERROR) {
628 if ((error = checkPassword(newPassword)) == NO_ERROR) {
629 newPassword = hashPassword(newPassword);
630 if (_recaptchaSiteKey != null && _recaptchaSecretKey != null) {
631
632 String user_response = (String) paramMap.get("g-recaptcha-response");
633 if ((error= verifyRecaptcha(_recaptchaSecretKey, user_response)) == NO_ERROR) {
634 error = addUser(newUsername, newPassword, "", "true", "", newEmail);
635 }
636 }
637 }
638 }
639
640 if (error != NO_ERROR)
641 {
642 serviceNode.setAttribute(OPERATION, REGISTER);
643 if (_recaptchaOpList != null && _recaptchaOpList.contains(REGISTER)) {
644 serviceNode.setAttribute("recaptcha_key", _recaptchaSiteKey);
645 }
646 GSXML.addError(result, getErrorTextString(error, lang));
647 }
648 // otherwise everything hunky dory and we return result
649 return result;
650 }
651
652 if (op.equals(PERFORM_EDIT))
653 {
654 String previousUsername = (String) paramMap.get(PREV_USERNAME);
655 String newUsername = (String) paramMap.get(NEW_USERNAME);
656 String newPassword = (String) paramMap.get(PASSWORD);
657 String newGroups = (String) paramMap.get(GROUPS);
658 String newStatus = (String) paramMap.get(STATUS);
659 String newComment = (String) paramMap.get(COMMENT);
660 String newEmail = (String) paramMap.get(NEW_EMAIL);
661
662 //Check the given user name
663 int error;
664 if ((error = checkUsername(newUsername)) != NO_ERROR)
665 {
666 GSXML.addError(result, getErrorTextString(error, lang));
667 return result;
668 }
669
670 if (newPassword == null)
671 {
672 newPassword = retrieveDataForUser(previousUsername, PASSWORD);
673 }
674 else
675 {
676 //Check the given password
677 if ((error = checkPassword(newPassword)) != NO_ERROR)
678 {
679 GSXML.addError(result, getErrorTextString(error, lang));
680 return result;
681 }
682
683 newPassword = hashPassword(newPassword);
684 }
685
686 error = removeUser(previousUsername);
687 if (error != NO_ERROR)
688 {
689 if (error == ERROR_USERNAME_NOT_SPECIFIED)
690 {
691 addUserInformationToNode(null, serviceNode);
692 serviceNode.setAttribute(OPERATION, LIST_USERS);
693 }
694 else
695 {
696 serviceNode.setAttribute(OPERATION, EDIT_USER);
697 GSXML.addError(result, getErrorTextString(error, lang));
698 }
699 return result;
700 }
701
702 error = addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
703 if (error != NO_ERROR)
704 {
705 serviceNode.setAttribute(OPERATION, EDIT_USER);
706 GSXML.addError(result, getErrorTextString(error, lang));
707 }
708 else
709 {
710 addUserInformationToNode(null, serviceNode);
711 serviceNode.setAttribute(OPERATION, LIST_USERS);
712 }
713 return result;
714 }
715 // this operation is done by a user when editing their own details. Should not return userNode info.
716 if (op.equals(PERFORM_ACCOUNT_EDIT))
717 {
718 String previousUsername = (String) paramMap.get(PREV_USERNAME);
719 String newUsername = (String) paramMap.get(NEW_USERNAME);
720 String oldPassword = (String) paramMap.get(OLD_PASSWORD);
721 String newPassword = (String) paramMap.get(NEW_PASSWORD);
722 String newEmail = (String) paramMap.get(NEW_EMAIL);
723
724 //Make sure the user name does not already exist
725 if (!previousUsername.equals(newUsername) && checkUserExists(newUsername))
726 {
727 addUserInformationToNode(previousUsername, serviceNode);
728 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
729 GSXML.addError(result, getErrorTextString(ERROR_USER_ALREADY_EXISTS, lang));
730 return result;
731 }
732
733 String prevPassword = retrieveDataForUser(previousUsername, PASSWORD);
734
735 if (newPassword != null)
736 {
737 oldPassword = hashPassword(oldPassword);
738
739 if (oldPassword == null || !oldPassword.equals(prevPassword))
740 {
741 addUserInformationToNode(previousUsername, serviceNode);
742 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
743 GSXML.addError(result, getErrorTextString(ERROR_INCORRECT_PASSWORD, lang), "INCORRECT_PASSWORD");
744 return result;
745 }
746
747 //Check the given password
748 int error;
749 if ((error = checkPassword(newPassword)) != NO_ERROR)
750 {
751 addUserInformationToNode(previousUsername, serviceNode);
752 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
753 GSXML.addError(result, getErrorTextString(error, lang));
754 return result;
755 }
756
757 newPassword = hashPassword(newPassword);
758 }
759 else
760 {
761 newPassword = prevPassword;
762 }
763
764 //Check the given user name
765 int error;
766 if ((error = checkUsername(newUsername)) != NO_ERROR)
767 {
768 addUserInformationToNode(previousUsername, serviceNode);
769 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
770 GSXML.addError(result, getErrorTextString(error, lang));
771 return result;
772 }
773
774 String prevGroups = retrieveDataForUser(previousUsername, GROUPS);
775 String prevStatus = retrieveDataForUser(previousUsername, STATUS);
776 String prevComment = retrieveDataForUser(previousUsername, COMMENT);
777
778 error = removeUser(previousUsername);
779 if (error != NO_ERROR)
780 {
781 addUserInformationToNode(previousUsername, serviceNode);
782 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
783 GSXML.addError(result, getErrorTextString(error, lang));
784 return result;
785 }
786
787 error = addUser(newUsername, newPassword, prevGroups, prevStatus, prevComment, newEmail);
788 if (error != NO_ERROR)
789 {
790 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
791 GSXML.addError(result, getErrorTextString(error, lang));
792 }
793
794 addUserInformationToNode(newUsername, serviceNode);
795 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
796 GSXML.addError(result, getTextString("auth.success.account_settings", lang));
797 return result;
798 }
799 if (op.equals(PERFORM_RETRIEVE_PASSWORD))
800 {
801 return result;
802 }
803 if (op.equals(PERFORM_CHANGE_PASSWORD))
804 {
805 serviceNode.setAttribute(OPERATION, PERFORM_CHANGE_PASSWORD);
806 String user_name = (String) paramMap.get(USERNAME);
807 String oldPassword = (String) paramMap.get(OLD_PASSWORD);
808 String newPassword = (String) paramMap.get(NEW_PASSWORD);
809 if (user_name == null || oldPassword == null || newPassword == null)
810 {
811 GSXML.addError(result, getErrorTextString(ERROR_MISSING_PARAMS, lang));
812 return result;
813 }
814
815 String prevPassword = retrieveDataForUser(user_name, PASSWORD);
816 if (!hashPassword(oldPassword).equals(prevPassword))
817 {
818 addUserInformationToNode(user_name, serviceNode);
819 GSXML.addError(result, getErrorTextString(ERROR_INCORRECT_PASSWORD, lang), "INCORRECT_PASSWORD");
820 return result;
821 }
822
823 //Check the given password
824 int error;
825 if ((error = checkPassword(newPassword)) != NO_ERROR)
826 {
827 GSXML.addError(result, getErrorTextString(error, lang));
828 return result;
829 }
830
831 DerbyWrapper derbyWrapper = openDatabase();
832 String chpa_groups = retrieveDataForUser(user_name, GROUPS);
833 String chpa_comment = "password_changed_by_user";
834 String info = derbyWrapper.modifyUserInfo(user_name, hashPassword(newPassword), chpa_groups, null, chpa_comment, null);
835 derbyWrapper.closeDatabase();
836 if (info != "succeed")
837 {//see DerbyWrapper.modifyUserInfo
838 GSXML.addError(result, info);
839 return result;
840 }
841 return result;
842 }
843 if (op.equals(EDIT_USER))
844 {
845 String editUsername = (String) paramMap.get(USERNAME);
846 int error = addUserInformationToNode(editUsername, serviceNode);
847 if (error != NO_ERROR)
848 {
849 GSXML.addError(result, getErrorTextString(error, lang));
850 }
851 return result;
852 }
853 if (op.equals(ACCOUNT_SETTINGS))
854 {
855 String editUsername = (String) paramMap.get(USERNAME);
856
857 if (editUsername == null)
858 {
859 serviceNode.setAttribute(OPERATION, "");
860 GSXML.addError(result, getErrorTextString(ERROR_USERNAME_NOT_SPECIFIED, lang));
861 return result;
862 }
863
864 if (!editUsername.equals(username))
865 {
866 serviceNode.setAttribute(OPERATION, LOGIN);
867 GSXML.addError(result, getErrorTextString(ERROR_NOT_AUTHORISED, lang));
868 return result;
869 }
870 int error = addUserInformationToNode(editUsername, serviceNode);
871 if (error != NO_ERROR)
872 {
873 GSXML.addError(result, getErrorTextString(error, lang));
874 }
875 return result;
876 }
877 if (op.equals(PERFORM_RESET_PASSWORD))
878 {
879 String passwordResetUser = (String) paramMap.get(USERNAME);
880
881 String newPassword = UUID.randomUUID().toString();
882 newPassword = newPassword.substring(0, newPassword.indexOf("-"));
883
884 String email = retrieveDataForUser(passwordResetUser, EMAIL);
885 String from = "[email protected]";
886 String host = request.getAttribute("remoteAddress");
887
888 //TODO: FINISH THIS
889 return result;
890 }
891 if (op.equals(PERFORM_DELETE_USER))
892 {
893 String usernameToDelete = (String) paramMap.get(USERNAME);
894 int error = removeUser(usernameToDelete);
895 if (error != NO_ERROR)
896 {
897 GSXML.addError(result, getErrorTextString(error, lang));
898 }
899 addUserInformationToNode(null, serviceNode);
900 serviceNode.setAttribute(OPERATION, LIST_USERS);
901 return result;
902 }
903
904 return result; // or should we return null, as we haven't recognised the operation??
905 }
906
907 public int checkUsernameAndPassword(String username, String password)
908 {
909 int uResult = checkUsername(username);
910 int pResult = checkPassword(password);
911
912 return (uResult != NO_ERROR ? uResult : (pResult != NO_ERROR ? pResult : NO_ERROR));
913 }
914
915 public int checkUsername(String username)
916 {
917 //Check the given user name
918 if ((username == null) || (username.length() < USERNAME_MIN_LENGTH) || (username.length() > USERNAME_MAX_LENGTH) || (!(Pattern.matches("[a-zA-Z0-9//_//.]+", username))))
919 {
920 return ERROR_INVALID_USERNAME;
921 }
922 return NO_ERROR;
923 }
924
925 public int checkPassword(String password)
926 {
927 //Check the given password
928 if (password == null)
929 {
930 return ERROR_PASSWORD_NOT_ENTERED;
931 }
932 else if (password.length() < PASSWORD_MIN_LENGTH)
933 {
934 return ERROR_PASSWORD_TOO_SHORT;
935 }
936 else if (password.length() > PASSWORD_MAX_LENGTH)
937 {
938 return ERROR_PASSWORD_TOO_LONG;
939 }
940 else if (!(Pattern.matches("[\\p{ASCII}]+", password)))
941 {
942 return ERROR_PASSWORD_USES_ILLEGAL_CHARACTERS;
943 }
944 return NO_ERROR;
945 }
946
947 public static String hashPassword(String password)
948 {
949 return DigestUtils.sha1Hex(password);
950 }
951
952 public int verifyRecaptcha(String secret_key, String user_response) {
953
954 if (user_response == null || user_response.length() == 0) {
955 return ERROR_CAPTCHA_MISSING;
956 }
957
958 try{
959
960 URL obj = new URL("https://www.google.com/recaptcha/api/siteverify");
961 HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
962
963 // add reuqest header
964 con.setRequestMethod("POST");
965 con.setRequestProperty("User-Agent", "Mozilla/5.0");
966 con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
967
968 String postParams = "secret=" + secret_key + "&response="
969 + user_response;
970
971 // Send post request
972 con.setDoOutput(true);
973 DataOutputStream wr = new DataOutputStream(con.getOutputStream());
974 wr.writeBytes(postParams);
975 wr.flush();
976 wr.close();
977
978 int responseCode = con.getResponseCode();
979 //System.out.println("\nSending 'POST' request to URL : https://www.google.com/recaptcha/api/siteverify");// + url);
980 //System.out.println("Post parameters : " + postParams);
981 //System.out.println("Response Code : " + responseCode);
982
983 BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
984 String inputLine;
985 StringBuffer response = new StringBuffer();
986
987 while ((inputLine = in.readLine()) != null) {
988 response.append(inputLine);
989 }
990 in.close();
991
992 // print result
993 //System.out.println(response.toString());
994
995 JSONObject json_obj = new JSONObject(response.toString());
996 boolean res = json_obj.getBoolean("success");
997 if (res) {
998 return NO_ERROR;
999 } else {
1000 return ERROR_CAPTCHA_FAILED;
1001 }
1002 }catch(Exception e){
1003 e.printStackTrace();
1004 return ERROR_CAPTCHA_FAILED;
1005 }
1006
1007 }
1008 // This method can also be used for printing out the password in hex (in case
1009 // the password used the UTF-8 Charset), or the hex values in any unicode string.
1010 // From http://stackoverflow.com/questions/923863/converting-a-string-to-hexadecimal-in-java
1011 public static String toHex(String arg)
1012 {
1013 try
1014 {
1015 return String.format("%x", new BigInteger(arg.getBytes("US-ASCII"))); // set to same charset as used by hashPassword
1016 }
1017 catch (Exception e)
1018 { // UnsupportedEncodingException
1019 e.printStackTrace();
1020 }
1021 return "Unable to print";
1022 }
1023
1024 private void checkAdminUserExists()
1025 {
1026 DerbyWrapper derbyWrapper = openDatabase();
1027 UserQueryResult userQueryResult = derbyWrapper.findUser(null, null);
1028 derbyWrapper.closeDatabase();
1029
1030 if (userQueryResult != null)
1031 {
1032 Vector userInfo = userQueryResult.users;
1033
1034 boolean adminFound = false;
1035 for (int i = 0; i < userQueryResult.getSize(); i++)
1036 {
1037 if (((UserTermInfo) userInfo.get(i)).groups != null && ((UserTermInfo) userInfo.get(i)).groups.matches(".*\\badministrator\\b.*"))
1038 {
1039 adminFound = true;
1040 }
1041 }
1042
1043 if (!adminFound)
1044 {
1045 addUser("admin", "admin", "administrator", "true", "Change the password for this account as soon as possible", "");
1046 }
1047 }
1048 }
1049
1050 private DerbyWrapper openDatabase()
1051 {
1052 // check the usersDb database, if it isn't existing, check the etc dir, create the etc dir if it isn't existing, then create the user database and add a "admin" user
1053 String usersDB_dir = GlobalProperties.getGSDL3Home() + File.separatorChar + "etc" + File.separatorChar + "usersDB";
1054 DerbyWrapper derbyWrapper = new DerbyWrapper(usersDB_dir);
1055 return derbyWrapper;
1056 }
1057
1058 private int addUserInformationToNode(String username, Element serviceNode)
1059 {
1060 DerbyWrapper derbyWrapper = openDatabase();
1061 UserQueryResult userQueryResult = derbyWrapper.findUser(username, null);
1062 derbyWrapper.closeDatabase();
1063
1064 if (userQueryResult != null)
1065 {
1066 Element user_node = getUserNodeList(serviceNode.getOwnerDocument(), userQueryResult);
1067 serviceNode.appendChild(user_node);
1068 return NO_ERROR;
1069 }
1070
1071 return ERROR_COULD_NOT_GET_USER_INFO;
1072 }
1073
1074 private int removeUser(String username)
1075 {
1076 if (username == null)
1077 {
1078 return ERROR_USERNAME_NOT_SPECIFIED;
1079 }
1080
1081 DerbyWrapper derbyWrapper = openDatabase();
1082 boolean success = derbyWrapper.deleteUser(username);
1083 derbyWrapper.closeDatabase();
1084
1085 if (success)
1086 {
1087 return NO_ERROR;
1088 }
1089
1090 return ERROR_REMOVING_USER;
1091 }
1092
1093 private int addUser(String newUsername, String newPassword, String newGroups, String newStatus, String newComment, String newEmail)
1094 {
1095 newGroups = newGroups.replaceAll(" ", "");
1096
1097 //Check if the user already exists
1098 DerbyWrapper derbyWrapper = openDatabase();
1099 UserQueryResult userQueryResult = derbyWrapper.findUser(newUsername, null);
1100
1101 if (userQueryResult != null)
1102 {
1103 derbyWrapper.closeDatabase();
1104 return ERROR_USER_ALREADY_EXISTS;
1105 }
1106 else
1107 {
1108 boolean success = derbyWrapper.addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
1109 derbyWrapper.closeDatabase();
1110
1111 if (!success)
1112 {
1113 return ERROR_ADDING_USER;
1114 }
1115 }
1116
1117 return NO_ERROR;
1118 }
1119
1120 private boolean checkUserExists(String username)
1121 {
1122 boolean check_status = false;
1123
1124 DerbyWrapper derbyWrapper = openDatabase();
1125 try
1126 {
1127 UserQueryResult result = derbyWrapper.findUser(username);
1128
1129 if (result != null)
1130 {
1131 check_status = true;
1132 }
1133
1134 }
1135 catch (Exception ex)
1136 {
1137 // some error occurred accessing the database
1138 ex.printStackTrace();
1139 }
1140 derbyWrapper.closeDatabase();
1141
1142 return check_status;
1143 }
1144
1145 private String retrieveDataForUser(String username, String dataType)
1146 {
1147 openDatabase();
1148
1149 String data = null;
1150
1151 try
1152 {
1153 DerbyWrapper derbyWrapper = openDatabase();
1154 UserQueryResult result = derbyWrapper.findUser(username);
1155 derbyWrapper.closeDatabase();
1156 Vector userInfo = result.users;
1157
1158 for (int i = 0; i < result.getSize(); i++)
1159 {
1160 if (dataType.equals(PASSWORD))
1161 {
1162 data = ((UserTermInfo) userInfo.get(i)).password;
1163 break;
1164 }
1165 else if (dataType.equals(GROUPS))
1166 {
1167 data = ((UserTermInfo) userInfo.get(i)).groups;
1168 break;
1169 }
1170 else if (dataType.equals(STATUS))
1171 {
1172 data = ((UserTermInfo) userInfo.get(i)).accountstatus;
1173 break;
1174 }
1175 else if (dataType.equals(COMMENT))
1176 {
1177 data = ((UserTermInfo) userInfo.get(i)).comment;
1178 break;
1179 }
1180 else if (dataType.equals(EMAIL))
1181 {
1182 data = ((UserTermInfo) userInfo.get(i)).email;
1183 break;
1184 }
1185 }
1186 }
1187 catch (Exception ex)
1188 {
1189 ex.printStackTrace();
1190 }
1191
1192 return data;
1193 }
1194
1195 private Element getUserNodeList(Document doc, UserQueryResult userQueryResult)
1196 {
1197 Element user_list_node = doc.createElement(GSXML.USER_NODE_ELEM + GSXML.LIST_MODIFIER);
1198
1199 Vector userInfo = userQueryResult.users;
1200
1201 for (int i = 0; i < userQueryResult.getSize(); i++)
1202 {
1203 Element user_node = doc.createElement(GSXML.USER_NODE_ELEM);
1204 String username = ((UserTermInfo) userInfo.get(i)).username;
1205 String groups = ((UserTermInfo) userInfo.get(i)).groups;
1206 String accountstatus = ((UserTermInfo) userInfo.get(i)).accountstatus;
1207 String comment = ((UserTermInfo) userInfo.get(i)).comment;
1208 String email = ((UserTermInfo) userInfo.get(i)).email;
1209 user_node.setAttribute(USERNAME, username);
1210 user_node.setAttribute(GROUPS, groups);
1211 user_node.setAttribute(STATUS, accountstatus);
1212 user_node.setAttribute(COMMENT, comment);
1213 user_node.setAttribute(EMAIL, email);
1214
1215 user_list_node.appendChild(user_node);
1216 }
1217 return user_list_node;
1218 }
1219
1220 private Element getCollectList(Document doc, String collect)
1221 {
1222 Element collect_list_node = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
1223 File[] collect_dir = (new File(collect)).listFiles();
1224 if (collect_dir != null && collect_dir.length > 0)
1225 {
1226 for (int i = 0; i < collect_dir.length; i++)
1227 {
1228 if (collect_dir[i].isDirectory() && (!collect_dir[i].getName().startsWith(".svn")))
1229 {
1230 Element collect_node = doc.createElement(GSXML.COLLECTION_ELEM);
1231 collect_node.setAttribute(GSXML.NAME_ATT, collect_dir[i].getName());
1232 collect_list_node.appendChild(collect_node);
1233 }
1234 }
1235 }
1236 return collect_list_node;
1237 }
1238
1239
1240 // main() method - calls hashPassword() on any String argument, printing this to stdout
1241 // This main() is invoked by gliserver.pl perl code to encrypt passwords identically to Java code.
1242 public static void main(String[] args)
1243 {
1244 if (args.length < 1)
1245 {
1246 System.err.println("Usage: Authentication <string to encrypt>");
1247 System.exit(-1);
1248 }
1249 // just hash the first argument
1250 String hash = Authentication.hashPassword(args[0]);
1251 System.out.println(hash);
1252 }
1253}
Note: See TracBrowser for help on using the repository browser.