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

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

changed param names to use _PARAM so easier to identify them. changed soem hard coded text into static string variables

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