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

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

making some methods/variables public so we can access them from other places. Making verifyRecaptcha static so can be called from anywhere

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