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

Last change on this file since 35286 was 35286, checked in by anupama, 3 years ago

First commit to do with supporting user groups of the form nz.ac.waikato.cs.pinky or katoa.maori.place.iwi.hapu.person, which need to get expanded out as nz, nz.ac, nz.ac.waikato, nz.ac.waikato.cs, nz.ac.waikato.cs.pinky (no duplicates). 1. Added a function that expands the existing groups and a new member variable to UserTermInfo that holds the expanded groups. 2. As also advised by Dr Bainbridge: refactored the existing UserTermInfo class to have getter and setter functions as needed and constructor so its member vars don't remain public as that also made it hard to track down in which classes/methods these member vars get (re)set. This commit should not have functionally altered the code: the origGroups (and not expandedGroups) is used everywhere still. In a subsequent commit will work out where the expandedGroups need to get used.

File size: 45.6 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 gliserver.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.getUsername());
513 Element passwordField = GSXML.createParameter(result_doc, PASSWORD_PARAM, userInfo.getPassword());
514 Element groupsField = GSXML.createParameter(result_doc, GROUPS_PARAM, userInfo.getOrigGroups());
515 Element accountStatusField = GSXML.createParameter(result_doc, ACCOUNT_STATUS_PARAM, userInfo.getAccountStatus());
516 Element commentField = GSXML.createParameter(result_doc, COMMENT_PARAM, userInfo.getComment());
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)).getOrigGroups() != null && ((UserTermInfo) userInfo.get(i)).getOrigGroups().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)).getPassword();
1206 break;
1207 }
1208 else if (dataType.equals(GROUPS))
1209 {
1210 data = ((UserTermInfo) userInfo.get(i)).getOrigGroups();
1211 break;
1212 }
1213 else if (dataType.equals(STATUS))
1214 {
1215 data = ((UserTermInfo) userInfo.get(i)).getAccountStatus();
1216 break;
1217 }
1218 else if (dataType.equals(COMMENT))
1219 {
1220 data = ((UserTermInfo) userInfo.get(i)).getComment();
1221 break;
1222 }
1223 else if (dataType.equals(EMAIL))
1224 {
1225 data = ((UserTermInfo) userInfo.get(i)).getEmail();
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)).getUsername();
1248 String groups = ((UserTermInfo) userInfo.get(i)).getOrigGroups();
1249 String accountstatus = ((UserTermInfo) userInfo.get(i)).getAccountStatus();
1250 String comment = ((UserTermInfo) userInfo.get(i)).getComment();
1251 String email = ((UserTermInfo) userInfo.get(i)).getEmail();
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.