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

Last change on this file since 33179 was 33179, checked in by kjdon, 5 years ago

making recaptcha response string public so others can use it

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