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

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

need to make sure recaptcha key is in service if we are a failed PERFORM_ADD

File size: 42.7 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 if (_recaptchaOpList != null && _recaptchaOpList.contains(ADD_USER)) {
583 serviceNode.setAttribute("recaptcha_key", _recaptchaSiteKey);
584 }
585 //Check the given user name
586 int error;
587 if ((error = checkUsername(newUsername)) != NO_ERROR)
588 {
589 serviceNode.setAttribute(OPERATION, ADD_USER);
590 GSXML.addError(result, getErrorTextString(error, lang));
591 return result;
592 }
593
594 //Check the given password
595 if ((error = checkPassword(newPassword)) != NO_ERROR)
596 {
597 serviceNode.setAttribute(OPERATION, ADD_USER);
598 GSXML.addError(result, getErrorTextString(error, lang));
599 return result;
600 }
601
602 newPassword = hashPassword(newPassword);
603
604 error = addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
605 if (error != NO_ERROR)
606 {
607 serviceNode.setAttribute(OPERATION, ADD_USER);
608 GSXML.addError(result, getErrorTextString(error, lang));
609 }
610 else
611 {
612 addUserInformationToNode(null, serviceNode);
613 serviceNode.setAttribute(OPERATION, LIST_USERS);
614 }
615 return result;
616 }
617
618 if (op.equals(REGISTER)) {
619 // don't need any additional info
620 return result;
621 }
622 if (op.equals(PERFORM_REGISTER))
623 {
624 String newUsername = (String) paramMap.get(USERNAME);
625 String newPassword = (String) paramMap.get(PASSWORD);
626 String newEmail = (String) paramMap.get(EMAIL);
627
628 //Check the given details
629 int error;
630 if ((error = checkUsername(newUsername)) == NO_ERROR) {
631 if ((error = checkPassword(newPassword)) == NO_ERROR) {
632 newPassword = hashPassword(newPassword);
633 if (_recaptchaSiteKey != null && _recaptchaSecretKey != null) {
634
635 String user_response = (String) paramMap.get("g-recaptcha-response");
636 if ((error= verifyRecaptcha(_recaptchaSecretKey, user_response)) == NO_ERROR) {
637 error = addUser(newUsername, newPassword, "", "true", "", newEmail);
638 }
639 }
640 }
641 }
642
643 if (error != NO_ERROR)
644 {
645 serviceNode.setAttribute(OPERATION, REGISTER);
646 if (_recaptchaOpList != null && _recaptchaOpList.contains(REGISTER)) {
647 serviceNode.setAttribute("recaptcha_key", _recaptchaSiteKey);
648 }
649 GSXML.addError(result, getErrorTextString(error, lang));
650 }
651 // otherwise everything hunky dory and we return result
652 return result;
653 }
654
655 if (op.equals(PERFORM_EDIT))
656 {
657 String previousUsername = (String) paramMap.get(PREV_USERNAME);
658 String newUsername = (String) paramMap.get(NEW_USERNAME);
659 String newPassword = (String) paramMap.get(PASSWORD);
660 String newGroups = (String) paramMap.get(GROUPS);
661 String newStatus = (String) paramMap.get(STATUS);
662 String newComment = (String) paramMap.get(COMMENT);
663 String newEmail = (String) paramMap.get(NEW_EMAIL);
664
665 //Check the given user name
666 int error;
667 if ((error = checkUsername(newUsername)) != NO_ERROR)
668 {
669 GSXML.addError(result, getErrorTextString(error, lang));
670 return result;
671 }
672
673 if (newPassword == null)
674 {
675 newPassword = retrieveDataForUser(previousUsername, PASSWORD);
676 }
677 else
678 {
679 //Check the given password
680 if ((error = checkPassword(newPassword)) != NO_ERROR)
681 {
682 GSXML.addError(result, getErrorTextString(error, lang));
683 return result;
684 }
685
686 newPassword = hashPassword(newPassword);
687 }
688
689 error = removeUser(previousUsername);
690 if (error != NO_ERROR)
691 {
692 if (error == ERROR_USERNAME_NOT_SPECIFIED)
693 {
694 addUserInformationToNode(null, serviceNode);
695 serviceNode.setAttribute(OPERATION, LIST_USERS);
696 }
697 else
698 {
699 serviceNode.setAttribute(OPERATION, EDIT_USER);
700 GSXML.addError(result, getErrorTextString(error, lang));
701 }
702 return result;
703 }
704
705 error = addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
706 if (error != NO_ERROR)
707 {
708 serviceNode.setAttribute(OPERATION, EDIT_USER);
709 GSXML.addError(result, getErrorTextString(error, lang));
710 }
711 else
712 {
713 addUserInformationToNode(null, serviceNode);
714 serviceNode.setAttribute(OPERATION, LIST_USERS);
715 }
716 return result;
717 }
718 // this operation is done by a user when editing their own details. Should not return userNode info.
719 if (op.equals(PERFORM_ACCOUNT_EDIT))
720 {
721 String previousUsername = (String) paramMap.get(PREV_USERNAME);
722 String newUsername = (String) paramMap.get(NEW_USERNAME);
723 String oldPassword = (String) paramMap.get(OLD_PASSWORD);
724 String newPassword = (String) paramMap.get(NEW_PASSWORD);
725 String newEmail = (String) paramMap.get(NEW_EMAIL);
726
727 //Make sure the user name does not already exist
728 if (!previousUsername.equals(newUsername) && checkUserExists(newUsername))
729 {
730 addUserInformationToNode(previousUsername, serviceNode);
731 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
732 GSXML.addError(result, getErrorTextString(ERROR_USER_ALREADY_EXISTS, lang));
733 return result;
734 }
735
736 String prevPassword = retrieveDataForUser(previousUsername, PASSWORD);
737
738 if (newPassword != null)
739 {
740 oldPassword = hashPassword(oldPassword);
741
742 if (oldPassword == null || !oldPassword.equals(prevPassword))
743 {
744 addUserInformationToNode(previousUsername, serviceNode);
745 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
746 GSXML.addError(result, getErrorTextString(ERROR_INCORRECT_PASSWORD, lang), "INCORRECT_PASSWORD");
747 return result;
748 }
749
750 //Check the given password
751 int error;
752 if ((error = checkPassword(newPassword)) != NO_ERROR)
753 {
754 addUserInformationToNode(previousUsername, serviceNode);
755 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
756 GSXML.addError(result, getErrorTextString(error, lang));
757 return result;
758 }
759
760 newPassword = hashPassword(newPassword);
761 }
762 else
763 {
764 newPassword = prevPassword;
765 }
766
767 //Check the given user name
768 int error;
769 if ((error = checkUsername(newUsername)) != NO_ERROR)
770 {
771 addUserInformationToNode(previousUsername, serviceNode);
772 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
773 GSXML.addError(result, getErrorTextString(error, lang));
774 return result;
775 }
776
777 String prevGroups = retrieveDataForUser(previousUsername, GROUPS);
778 String prevStatus = retrieveDataForUser(previousUsername, STATUS);
779 String prevComment = retrieveDataForUser(previousUsername, COMMENT);
780
781 error = removeUser(previousUsername);
782 if (error != NO_ERROR)
783 {
784 addUserInformationToNode(previousUsername, serviceNode);
785 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
786 GSXML.addError(result, getErrorTextString(error, lang));
787 return result;
788 }
789
790 error = addUser(newUsername, newPassword, prevGroups, prevStatus, prevComment, newEmail);
791 if (error != NO_ERROR)
792 {
793 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
794 GSXML.addError(result, getErrorTextString(error, lang));
795 }
796
797 addUserInformationToNode(newUsername, serviceNode);
798 serviceNode.setAttribute(OPERATION, ACCOUNT_SETTINGS);
799 GSXML.addError(result, getTextString("auth.success.account_settings", lang));
800 return result;
801 }
802 if (op.equals(PERFORM_RETRIEVE_PASSWORD))
803 {
804 return result;
805 }
806 if (op.equals(PERFORM_CHANGE_PASSWORD))
807 {
808 serviceNode.setAttribute(OPERATION, PERFORM_CHANGE_PASSWORD);
809 String user_name = (String) paramMap.get(USERNAME);
810 String oldPassword = (String) paramMap.get(OLD_PASSWORD);
811 String newPassword = (String) paramMap.get(NEW_PASSWORD);
812 if (user_name == null || oldPassword == null || newPassword == null)
813 {
814 GSXML.addError(result, getErrorTextString(ERROR_MISSING_PARAMS, lang));
815 return result;
816 }
817
818 String prevPassword = retrieveDataForUser(user_name, PASSWORD);
819 if (!hashPassword(oldPassword).equals(prevPassword))
820 {
821 addUserInformationToNode(user_name, serviceNode);
822 GSXML.addError(result, getErrorTextString(ERROR_INCORRECT_PASSWORD, lang), "INCORRECT_PASSWORD");
823 return result;
824 }
825
826 //Check the given password
827 int error;
828 if ((error = checkPassword(newPassword)) != NO_ERROR)
829 {
830 GSXML.addError(result, getErrorTextString(error, lang));
831 return result;
832 }
833
834 DerbyWrapper derbyWrapper = openDatabase();
835 String chpa_groups = retrieveDataForUser(user_name, GROUPS);
836 String chpa_comment = "password_changed_by_user";
837 String info = derbyWrapper.modifyUserInfo(user_name, hashPassword(newPassword), chpa_groups, null, chpa_comment, null);
838 derbyWrapper.closeDatabase();
839 if (info != "succeed")
840 {//see DerbyWrapper.modifyUserInfo
841 GSXML.addError(result, info);
842 return result;
843 }
844 return result;
845 }
846 if (op.equals(EDIT_USER))
847 {
848 String editUsername = (String) paramMap.get(USERNAME);
849 int error = addUserInformationToNode(editUsername, serviceNode);
850 if (error != NO_ERROR)
851 {
852 GSXML.addError(result, getErrorTextString(error, lang));
853 }
854 return result;
855 }
856 if (op.equals(ACCOUNT_SETTINGS))
857 {
858 String editUsername = (String) paramMap.get(USERNAME);
859
860 if (editUsername == null)
861 {
862 serviceNode.setAttribute(OPERATION, "");
863 GSXML.addError(result, getErrorTextString(ERROR_USERNAME_NOT_SPECIFIED, lang));
864 return result;
865 }
866
867 if (!editUsername.equals(username))
868 {
869 serviceNode.setAttribute(OPERATION, LOGIN);
870 GSXML.addError(result, getErrorTextString(ERROR_NOT_AUTHORISED, lang));
871 return result;
872 }
873 int error = addUserInformationToNode(editUsername, serviceNode);
874 if (error != NO_ERROR)
875 {
876 GSXML.addError(result, getErrorTextString(error, lang));
877 }
878 return result;
879 }
880 if (op.equals(PERFORM_RESET_PASSWORD))
881 {
882 String passwordResetUser = (String) paramMap.get(USERNAME);
883
884 String newPassword = UUID.randomUUID().toString();
885 newPassword = newPassword.substring(0, newPassword.indexOf("-"));
886
887 String email = retrieveDataForUser(passwordResetUser, EMAIL);
888 String from = "[email protected]";
889 String host = request.getAttribute("remoteAddress");
890
891 //TODO: FINISH THIS
892 return result;
893 }
894 if (op.equals(PERFORM_DELETE_USER))
895 {
896 String usernameToDelete = (String) paramMap.get(USERNAME);
897 int error = removeUser(usernameToDelete);
898 if (error != NO_ERROR)
899 {
900 GSXML.addError(result, getErrorTextString(error, lang));
901 }
902 addUserInformationToNode(null, serviceNode);
903 serviceNode.setAttribute(OPERATION, LIST_USERS);
904 return result;
905 }
906
907 return result; // or should we return null, as we haven't recognised the operation??
908 }
909
910 public int checkUsernameAndPassword(String username, String password)
911 {
912 int uResult = checkUsername(username);
913 int pResult = checkPassword(password);
914
915 return (uResult != NO_ERROR ? uResult : (pResult != NO_ERROR ? pResult : NO_ERROR));
916 }
917
918 public int checkUsername(String username)
919 {
920 //Check the given user name
921 if ((username == null) || (username.length() < USERNAME_MIN_LENGTH) || (username.length() > USERNAME_MAX_LENGTH) || (!(Pattern.matches("[a-zA-Z0-9//_//.]+", username))))
922 {
923 return ERROR_INVALID_USERNAME;
924 }
925 return NO_ERROR;
926 }
927
928 public int checkPassword(String password)
929 {
930 //Check the given password
931 if (password == null)
932 {
933 return ERROR_PASSWORD_NOT_ENTERED;
934 }
935 else if (password.length() < PASSWORD_MIN_LENGTH)
936 {
937 return ERROR_PASSWORD_TOO_SHORT;
938 }
939 else if (password.length() > PASSWORD_MAX_LENGTH)
940 {
941 return ERROR_PASSWORD_TOO_LONG;
942 }
943 else if (!(Pattern.matches("[\\p{ASCII}]+", password)))
944 {
945 return ERROR_PASSWORD_USES_ILLEGAL_CHARACTERS;
946 }
947 return NO_ERROR;
948 }
949
950 public static String hashPassword(String password)
951 {
952 return DigestUtils.sha1Hex(password);
953 }
954
955 public int verifyRecaptcha(String secret_key, String user_response) {
956
957 if (user_response == null || user_response.length() == 0) {
958 return ERROR_CAPTCHA_MISSING;
959 }
960
961 try{
962
963 URL obj = new URL("https://www.google.com/recaptcha/api/siteverify");
964 HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
965
966 // add reuqest header
967 con.setRequestMethod("POST");
968 con.setRequestProperty("User-Agent", "Mozilla/5.0");
969 con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
970
971 String postParams = "secret=" + secret_key + "&response="
972 + user_response;
973
974 // Send post request
975 con.setDoOutput(true);
976 DataOutputStream wr = new DataOutputStream(con.getOutputStream());
977 wr.writeBytes(postParams);
978 wr.flush();
979 wr.close();
980
981 int responseCode = con.getResponseCode();
982 //System.out.println("\nSending 'POST' request to URL : https://www.google.com/recaptcha/api/siteverify");// + url);
983 //System.out.println("Post parameters : " + postParams);
984 //System.out.println("Response Code : " + responseCode);
985
986 BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
987 String inputLine;
988 StringBuffer response = new StringBuffer();
989
990 while ((inputLine = in.readLine()) != null) {
991 response.append(inputLine);
992 }
993 in.close();
994
995 // print result
996 //System.out.println(response.toString());
997
998 JSONObject json_obj = new JSONObject(response.toString());
999 boolean res = json_obj.getBoolean("success");
1000 if (res) {
1001 return NO_ERROR;
1002 } else {
1003 return ERROR_CAPTCHA_FAILED;
1004 }
1005 }catch(Exception e){
1006 e.printStackTrace();
1007 return ERROR_CAPTCHA_FAILED;
1008 }
1009
1010 }
1011 // This method can also be used for printing out the password in hex (in case
1012 // the password used the UTF-8 Charset), or the hex values in any unicode string.
1013 // From http://stackoverflow.com/questions/923863/converting-a-string-to-hexadecimal-in-java
1014 public static String toHex(String arg)
1015 {
1016 try
1017 {
1018 return String.format("%x", new BigInteger(arg.getBytes("US-ASCII"))); // set to same charset as used by hashPassword
1019 }
1020 catch (Exception e)
1021 { // UnsupportedEncodingException
1022 e.printStackTrace();
1023 }
1024 return "Unable to print";
1025 }
1026
1027 private void checkAdminUserExists()
1028 {
1029 DerbyWrapper derbyWrapper = openDatabase();
1030 UserQueryResult userQueryResult = derbyWrapper.findUser(null, null);
1031 derbyWrapper.closeDatabase();
1032
1033 if (userQueryResult != null)
1034 {
1035 Vector userInfo = userQueryResult.users;
1036
1037 boolean adminFound = false;
1038 for (int i = 0; i < userQueryResult.getSize(); i++)
1039 {
1040 if (((UserTermInfo) userInfo.get(i)).groups != null && ((UserTermInfo) userInfo.get(i)).groups.matches(".*\\badministrator\\b.*"))
1041 {
1042 adminFound = true;
1043 }
1044 }
1045
1046 if (!adminFound)
1047 {
1048 addUser("admin", "admin", "administrator", "true", "Change the password for this account as soon as possible", "");
1049 }
1050 }
1051 }
1052
1053 private DerbyWrapper openDatabase()
1054 {
1055 // 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
1056 String usersDB_dir = GlobalProperties.getGSDL3Home() + File.separatorChar + "etc" + File.separatorChar + "usersDB";
1057 DerbyWrapper derbyWrapper = new DerbyWrapper(usersDB_dir);
1058 return derbyWrapper;
1059 }
1060
1061 private int addUserInformationToNode(String username, Element serviceNode)
1062 {
1063 DerbyWrapper derbyWrapper = openDatabase();
1064 UserQueryResult userQueryResult = derbyWrapper.findUser(username, null);
1065 derbyWrapper.closeDatabase();
1066
1067 if (userQueryResult != null)
1068 {
1069 Element user_node = getUserNodeList(serviceNode.getOwnerDocument(), userQueryResult);
1070 serviceNode.appendChild(user_node);
1071 return NO_ERROR;
1072 }
1073
1074 return ERROR_COULD_NOT_GET_USER_INFO;
1075 }
1076
1077 private int removeUser(String username)
1078 {
1079 if (username == null)
1080 {
1081 return ERROR_USERNAME_NOT_SPECIFIED;
1082 }
1083
1084 DerbyWrapper derbyWrapper = openDatabase();
1085 boolean success = derbyWrapper.deleteUser(username);
1086 derbyWrapper.closeDatabase();
1087
1088 if (success)
1089 {
1090 return NO_ERROR;
1091 }
1092
1093 return ERROR_REMOVING_USER;
1094 }
1095
1096 private int addUser(String newUsername, String newPassword, String newGroups, String newStatus, String newComment, String newEmail)
1097 {
1098 newGroups = newGroups.replaceAll(" ", "");
1099
1100 //Check if the user already exists
1101 DerbyWrapper derbyWrapper = openDatabase();
1102 UserQueryResult userQueryResult = derbyWrapper.findUser(newUsername, null);
1103
1104 if (userQueryResult != null)
1105 {
1106 derbyWrapper.closeDatabase();
1107 return ERROR_USER_ALREADY_EXISTS;
1108 }
1109 else
1110 {
1111 boolean success = derbyWrapper.addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
1112 derbyWrapper.closeDatabase();
1113
1114 if (!success)
1115 {
1116 return ERROR_ADDING_USER;
1117 }
1118 }
1119
1120 return NO_ERROR;
1121 }
1122
1123 private boolean checkUserExists(String username)
1124 {
1125 boolean check_status = false;
1126
1127 DerbyWrapper derbyWrapper = openDatabase();
1128 try
1129 {
1130 UserQueryResult result = derbyWrapper.findUser(username);
1131
1132 if (result != null)
1133 {
1134 check_status = true;
1135 }
1136
1137 }
1138 catch (Exception ex)
1139 {
1140 // some error occurred accessing the database
1141 ex.printStackTrace();
1142 }
1143 derbyWrapper.closeDatabase();
1144
1145 return check_status;
1146 }
1147
1148 private String retrieveDataForUser(String username, String dataType)
1149 {
1150 openDatabase();
1151
1152 String data = null;
1153
1154 try
1155 {
1156 DerbyWrapper derbyWrapper = openDatabase();
1157 UserQueryResult result = derbyWrapper.findUser(username);
1158 derbyWrapper.closeDatabase();
1159 Vector userInfo = result.users;
1160
1161 for (int i = 0; i < result.getSize(); i++)
1162 {
1163 if (dataType.equals(PASSWORD))
1164 {
1165 data = ((UserTermInfo) userInfo.get(i)).password;
1166 break;
1167 }
1168 else if (dataType.equals(GROUPS))
1169 {
1170 data = ((UserTermInfo) userInfo.get(i)).groups;
1171 break;
1172 }
1173 else if (dataType.equals(STATUS))
1174 {
1175 data = ((UserTermInfo) userInfo.get(i)).accountstatus;
1176 break;
1177 }
1178 else if (dataType.equals(COMMENT))
1179 {
1180 data = ((UserTermInfo) userInfo.get(i)).comment;
1181 break;
1182 }
1183 else if (dataType.equals(EMAIL))
1184 {
1185 data = ((UserTermInfo) userInfo.get(i)).email;
1186 break;
1187 }
1188 }
1189 }
1190 catch (Exception ex)
1191 {
1192 ex.printStackTrace();
1193 }
1194
1195 return data;
1196 }
1197
1198 private Element getUserNodeList(Document doc, UserQueryResult userQueryResult)
1199 {
1200 Element user_list_node = doc.createElement(GSXML.USER_NODE_ELEM + GSXML.LIST_MODIFIER);
1201
1202 Vector userInfo = userQueryResult.users;
1203
1204 for (int i = 0; i < userQueryResult.getSize(); i++)
1205 {
1206 Element user_node = doc.createElement(GSXML.USER_NODE_ELEM);
1207 String username = ((UserTermInfo) userInfo.get(i)).username;
1208 String groups = ((UserTermInfo) userInfo.get(i)).groups;
1209 String accountstatus = ((UserTermInfo) userInfo.get(i)).accountstatus;
1210 String comment = ((UserTermInfo) userInfo.get(i)).comment;
1211 String email = ((UserTermInfo) userInfo.get(i)).email;
1212 user_node.setAttribute(USERNAME, username);
1213 user_node.setAttribute(GROUPS, groups);
1214 user_node.setAttribute(STATUS, accountstatus);
1215 user_node.setAttribute(COMMENT, comment);
1216 user_node.setAttribute(EMAIL, email);
1217
1218 user_list_node.appendChild(user_node);
1219 }
1220 return user_list_node;
1221 }
1222
1223 private Element getCollectList(Document doc, String collect)
1224 {
1225 Element collect_list_node = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
1226 File[] collect_dir = (new File(collect)).listFiles();
1227 if (collect_dir != null && collect_dir.length > 0)
1228 {
1229 for (int i = 0; i < collect_dir.length; i++)
1230 {
1231 if (collect_dir[i].isDirectory() && (!collect_dir[i].getName().startsWith(".svn")))
1232 {
1233 Element collect_node = doc.createElement(GSXML.COLLECTION_ELEM);
1234 collect_node.setAttribute(GSXML.NAME_ATT, collect_dir[i].getName());
1235 collect_list_node.appendChild(collect_node);
1236 }
1237 }
1238 }
1239 return collect_list_node;
1240 }
1241
1242
1243 // main() method - calls hashPassword() on any String argument, printing this to stdout
1244 // This main() is invoked by gliserver.pl perl code to encrypt passwords identically to Java code.
1245 public static void main(String[] args)
1246 {
1247 if (args.length < 1)
1248 {
1249 System.err.println("Usage: Authentication <string to encrypt>");
1250 System.exit(-1);
1251 }
1252 // just hash the first argument
1253 String hash = Authentication.hashPassword(args[0]);
1254 System.out.println(hash);
1255 }
1256}
Note: See TracBrowser for help on using the repository browser.