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

Last change on this file since 25311 was 25311, checked in by sjm84, 12 years ago

Fixed some bugs in the administration service

File size: 29.6 KB
Line 
1package org.greenstone.gsdl3.service;
2
3import org.greenstone.gsdl3.util.GSXML;
4import org.greenstone.gsdl3.util.DerbyWrapper;
5import org.greenstone.gsdl3.util.UserQueryResult;
6import org.greenstone.gsdl3.util.UserTermInfo;
7
8import org.w3c.dom.Element;
9import org.w3c.dom.NodeList;
10
11import java.util.ArrayList;
12import java.util.HashMap;
13import java.util.UUID;
14import java.util.Vector;
15import java.security.MessageDigest;
16import java.sql.SQLException;
17import java.util.regex.Pattern;
18import java.io.File;
19
20import net.tanesha.recaptcha.ReCaptchaImpl;
21import net.tanesha.recaptcha.ReCaptchaResponse;
22
23public class Authentication extends ServiceRack
24{
25 //Error codes
26 protected static final int NO_ERROR = 0;
27 protected static final int ERROR_REQUEST_HAS_NO_PARAM_LIST = -1;
28 protected static final int ERROR_NOT_LOGGED_IN = -2;
29 protected static final int ERROR_ADMIN_NOT_LOGGED_IN = -3;
30 protected static final int ERROR_COULD_NOT_GET_USER_INFO = -4;
31 protected static final int ERROR_USERNAME_NOT_SPECIFIED = -5;
32 protected static final int ERROR_REQUESTED_USER_NOT_FOUND = -6;
33 protected static final int ERROR_SQL_EXCEPTION = -7;
34 protected static final int ERROR_INVALID_USERNAME = -8;
35 protected static final int ERROR_INVALID_PASSWORD = -9;
36 protected static final int ERROR_INCORRECT_PASSWORD = -10;
37 protected static final int ERROR_USER_ALREADY_EXISTS = -11;
38 protected static final int ERROR_ADDING_USER = -12;
39 protected static final int ERROR_REMOVING_USER = -13;
40 protected static final int ERROR_CAPTCHA_DOES_NOT_MATCH = -14;
41 protected static final int ERROR_CAPTCHA_MISSING = -15;
42 protected static final int ERROR_NOT_AUTHORISED = -16;
43
44 protected static final HashMap<Integer, String> _errorMessageMap;
45 static
46 {
47 //Corresponding error messages
48 HashMap<Integer, String> errorMessageMap = new HashMap<Integer, String>();
49 errorMessageMap.put(ERROR_REQUEST_HAS_NO_PARAM_LIST, "The list of parameters for this request was empty.");
50 errorMessageMap.put(ERROR_NOT_LOGGED_IN, "You must be logged in to access this page.");
51 errorMessageMap.put(ERROR_ADMIN_NOT_LOGGED_IN, "You must be logged in as an administrator to access this page.");
52 errorMessageMap.put(ERROR_COULD_NOT_GET_USER_INFO, "There was a error getting the user information.");
53 errorMessageMap.put(ERROR_USERNAME_NOT_SPECIFIED, "No username was specified.");
54 errorMessageMap.put(ERROR_REQUESTED_USER_NOT_FOUND, "The requested user was not found in the database.");
55 errorMessageMap.put(ERROR_SQL_EXCEPTION, "There was an SQL exception while accessing the database.");
56 errorMessageMap.put(ERROR_INVALID_USERNAME, "The username specified was invalid.");
57 errorMessageMap.put(ERROR_INVALID_PASSWORD, "The password specified was invalid.");
58 errorMessageMap.put(ERROR_INCORRECT_PASSWORD, "The password specified was incorrect.");
59 errorMessageMap.put(ERROR_USER_ALREADY_EXISTS, "This user already exists and therefore cannot be added.");
60 errorMessageMap.put(ERROR_ADDING_USER, "There was an error adding this user to the database.");
61 errorMessageMap.put(ERROR_REMOVING_USER, "There was an error removing this user from the database.");
62 errorMessageMap.put(ERROR_CAPTCHA_DOES_NOT_MATCH, "The words you entered did not match the image, please try again.");
63 errorMessageMap.put(ERROR_CAPTCHA_MISSING, "The information from the captcha is missing.");
64 errorMessageMap.put(ERROR_NOT_AUTHORISED, "You are not authorised to access this page.");
65
66 _errorMessageMap = errorMessageMap;
67 }
68
69 //Admin-required operations
70 protected static final String LIST_USERS = "ListUsers";
71 protected static final String PERFORM_ADD = "PerformAdd";
72 protected static final String PERFORM_EDIT = "PerformEdit";
73 protected static final String ADD_USER = "AddUser";
74 protected static final String EDIT_USER = "EditUser";
75 protected static final String PERFORM_DELETE_USER = "PerformDeleteUser";
76
77 protected static final ArrayList<String> _adminOpList;
78 static
79 {
80 ArrayList<String> opList = new ArrayList<String>();
81 opList.add(LIST_USERS);
82 opList.add(PERFORM_ADD);
83 opList.add(PERFORM_EDIT);
84 opList.add(EDIT_USER);
85 opList.add(PERFORM_DELETE_USER);
86
87 _adminOpList = opList;
88 }
89
90 //User-required operations
91 protected static final String ACCOUNT_SETTINGS = "AccountSettings";
92 protected static final String PERFORM_ACCOUNT_EDIT = "PerformAccEdit";
93 protected static final String PERFORM_RESET_PASSWORD = "PerformResetPassword";
94 protected static final ArrayList<String> _userOpList;
95 static
96 {
97 ArrayList<String> opList = new ArrayList<String>();
98 opList.add(ACCOUNT_SETTINGS);
99 opList.add(PERFORM_ACCOUNT_EDIT);
100 opList.add(PERFORM_RESET_PASSWORD);
101 opList.addAll(_adminOpList);
102 _userOpList = opList;
103 }
104
105 //Other operations
106 protected static final String REGISTER = "Register";
107 protected static final String PERFORM_REGISTER = "PerformRegister";
108 protected static final String LOGIN = "Login";
109
110 //the services on offer
111 protected static final String AUTHENTICATION_SERVICE = "Authentication";
112 protected static final String GET_USER_INFORMATION_SERVICE = "GetUserInformation";
113
114 protected DerbyWrapper _derbyWrapper = null;
115
116 protected String _recaptchaPrivateKey = null;
117 protected String _recaptchaPublicKey = null;
118
119 /** constructor */
120 public Authentication()
121 {
122 }
123
124 public boolean configure(Element info, Element extra_info)
125 {
126 logger.info("Configuring Authentication...");
127 this.config_info = info;
128
129 // set up Authentication service info - for now just has name and type
130 Element authentication_service = this.doc.createElement(GSXML.SERVICE_ELEM);
131 authentication_service.setAttribute(GSXML.TYPE_ATT, "authen");
132 authentication_service.setAttribute(GSXML.NAME_ATT, AUTHENTICATION_SERVICE);
133 this.short_service_info.appendChild(authentication_service);
134
135 // set up Authentication service info - for now just has name and type
136 Element getUserInformation_service = this.doc.createElement(GSXML.SERVICE_ELEM);
137 getUserInformation_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
138 getUserInformation_service.setAttribute(GSXML.NAME_ATT, GET_USER_INFORMATION_SERVICE);
139 this.short_service_info.appendChild(getUserInformation_service);
140
141 NodeList recaptchaElems = info.getElementsByTagName("recaptcha");
142
143 for (int i = 0; i < recaptchaElems.getLength(); i++)
144 {
145 Element currentElem = (Element) recaptchaElems.item(i);
146 if (currentElem.getAttribute(GSXML.NAME_ATT) != null && currentElem.getAttribute(GSXML.NAME_ATT).equals("public_key"))
147 {
148 if (currentElem.getAttribute(GSXML.VALUE_ATT) != null)
149 {
150 _recaptchaPublicKey = currentElem.getAttribute(GSXML.VALUE_ATT);
151 }
152 }
153 else if (currentElem.getAttribute(GSXML.NAME_ATT) != null && currentElem.getAttribute(GSXML.NAME_ATT).equals("private_key"))
154 {
155 if (currentElem.getAttribute(GSXML.VALUE_ATT) != null)
156 {
157 _recaptchaPrivateKey = currentElem.getAttribute(GSXML.VALUE_ATT);
158 }
159 }
160 }
161
162 return true;
163 }
164
165 protected Element getServiceDescription(String service_id, String lang, String subset)
166 {
167
168 Element authen_service = this.doc.createElement(GSXML.SERVICE_ELEM);
169
170 if (service_id.equals(AUTHENTICATION_SERVICE))
171 {
172 authen_service.setAttribute(GSXML.TYPE_ATT, "authen");
173 authen_service.setAttribute(GSXML.NAME_ATT, AUTHENTICATION_SERVICE);
174 }
175 else if (service_id.equals(GET_USER_INFORMATION_SERVICE))
176 {
177 authen_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_PROCESS);
178 authen_service.setAttribute(GSXML.NAME_ATT, GET_USER_INFORMATION_SERVICE);
179 }
180 else
181 {
182 return null;
183 }
184
185 if (service_id.equals(AUTHENTICATION_SERVICE) && (subset == null || subset.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER)))
186 {
187 authen_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, getServiceName(service_id, lang)));
188 authen_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getServiceDescription(service_id, lang)));
189 }
190 return authen_service;
191 }
192
193 protected String getServiceName(String service_id, String lang)
194 {
195 return getTextString(service_id + ".name", lang);
196 }
197
198 protected String getServiceSubmit(String service_id, String lang)
199 {
200 return getTextString(service_id + ".submit", lang);
201 }
202
203 protected String getServiceDescription(String service_id, String lang)
204 {
205 return getTextString(service_id + ".description", lang);
206 }
207
208 protected void addCustomParams(String service, Element param_list, String lang)
209 {
210 }
211
212 protected void createParameter(String name, Element param_list, String lang)
213 {
214 }
215
216 protected Element processGetUserInformation(Element request)
217 {
218 // Create a new (empty) result message
219 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
220
221 result.setAttribute(GSXML.FROM_ATT, GET_USER_INFORMATION_SERVICE);
222 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
223
224 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
225 if (paramList == null)
226 {
227 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_REQUEST_HAS_NO_PARAM_LIST));
228 return result;
229 }
230
231 HashMap params = GSXML.extractParams(paramList, true);
232
233 String username = (String) params.get("username");
234
235 if (username == null)
236 {
237 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_USERNAME_NOT_SPECIFIED));
238 return result;
239 }
240
241 DerbyWrapper dbWrapper = new DerbyWrapper();
242
243 String usersDB_dir = this.site_home + File.separatorChar + "etc" + File.separatorChar + "usersDB";
244 dbWrapper.connectDatabase(usersDB_dir, true);
245
246 UserQueryResult userQueryResult;
247 try
248 {
249 userQueryResult = dbWrapper.findUser(username);
250 Vector<UserTermInfo> terms = userQueryResult.getUserTerms();
251
252 if (terms.size() == 0)
253 {
254 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_REQUESTED_USER_NOT_FOUND));
255 return result;
256 }
257
258 UserTermInfo userInfo = terms.get(0);
259 Element userInfoList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
260 result.appendChild(userInfoList);
261
262 Element usernameField = GSXML.createParameter(this.doc, "username", userInfo.username);
263 Element passwordField = GSXML.createParameter(this.doc, "password", userInfo.password);
264 Element groupsField = GSXML.createParameter(this.doc, "groups", userInfo.groups);
265 Element accountStatusField = GSXML.createParameter(this.doc, "accountstatus", userInfo.accountstatus);
266 Element commentField = GSXML.createParameter(this.doc, "comment", userInfo.comment);
267
268 userInfoList.appendChild(usernameField);
269 userInfoList.appendChild(passwordField);
270 userInfoList.appendChild(groupsField);
271 userInfoList.appendChild(accountStatusField);
272 userInfoList.appendChild(commentField);
273 }
274 catch (SQLException ex)
275 {
276 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_SQL_EXCEPTION));
277 ex.printStackTrace();
278 }
279
280 return result;
281 }
282
283 protected Element processAuthentication(Element request)
284 {
285 checkAdminUserExists();
286
287 // Create a new (empty) result message
288 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
289 result.setAttribute(GSXML.FROM_ATT, AUTHENTICATION_SERVICE);
290 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
291
292 // Create an Authentication node put into the result
293 Element authenNode = this.doc.createElement(GSXML.AUTHEN_NODE_ELEM);
294 result.appendChild(authenNode);
295 result.appendChild(getCollectList(this.site_home + File.separatorChar + "collect"));
296
297 // Create a service node added into the Authentication node
298 Element serviceNode = this.doc.createElement(GSXML.SERVICE_ELEM);
299 authenNode.appendChild(serviceNode);
300
301 // Get the parameters of the request
302 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
303 if (param_list == null)
304 {
305 serviceNode.setAttribute("operation", LOGIN);
306 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_REQUEST_HAS_NO_PARAM_LIST));
307 return result; // Return the empty result
308 }
309 HashMap paramMap = GSXML.extractParams(param_list, false);
310 String op = (String) paramMap.get("authpage");
311 serviceNode.setAttribute("operation", op);
312
313 String username = null;
314 String groups = null;
315
316 Element userInformation = (Element) GSXML.getChildByTagName(request, GSXML.USER_INFORMATION_ELEM);
317 if (userInformation == null && _userOpList.contains(op))
318 {
319 serviceNode.setAttribute("operation", LOGIN);
320 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_NOT_LOGGED_IN));
321 return result;
322 }
323
324 if (userInformation != null)
325 {
326 username = userInformation.getAttribute(GSXML.USERNAME_ATT);
327 groups = userInformation.getAttribute(GSXML.GROUPS_ATT);
328 }
329
330 if (username == null && _userOpList.contains(op))
331 {
332 serviceNode.setAttribute("operation", LOGIN);
333 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_NOT_LOGGED_IN));
334 return result;
335 }
336
337 if (_adminOpList.contains(op) && (groups == null || !groups.matches(".*\\badministrator\\b.*")))
338 {
339 serviceNode.setAttribute("operation", LOGIN);
340 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_ADMIN_NOT_LOGGED_IN));
341 return result;
342 }
343
344 if (op.equals(LIST_USERS))
345 {
346 int error = addUserInformationToNode(null, serviceNode);
347 if (error != NO_ERROR)
348 {
349 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
350 }
351 }
352 else if (op.equals(PERFORM_ADD))
353 {
354 String newUsername = (String) paramMap.get("username");
355 String newPassword = (String) paramMap.get("password");
356 String newGroups = (String) paramMap.get("groups");
357 String newStatus = (String) paramMap.get("status");
358 String newComment = (String) paramMap.get("comment");
359 String newEmail = (String) paramMap.get("email");
360
361 //Check the given user name
362 int error;
363 if ((error = checkUsername(newUsername)) != NO_ERROR)
364 {
365 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
366 return result;
367 }
368
369 //Check the given password
370 if ((error = checkPassword(newPassword)) != NO_ERROR)
371 {
372 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
373 return result;
374 }
375
376 newPassword = hashPassword(newPassword);
377
378 error = addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
379 if (error != NO_ERROR)
380 {
381 serviceNode.setAttribute("operation", ADD_USER);
382 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
383 }
384 else
385 {
386 addUserInformationToNode(null, serviceNode);
387 serviceNode.setAttribute("operation", LIST_USERS);
388 }
389 }
390 else if (op.equals(PERFORM_REGISTER))
391 {
392 String newUsername = (String) paramMap.get("username");
393 String newPassword = (String) paramMap.get("password");
394 String newEmail = (String) paramMap.get("email");
395
396 //Check the given user name
397 int error;
398 if ((error = checkUsername(newUsername)) != NO_ERROR)
399 {
400 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
401 return result;
402 }
403
404 //Check the given password
405 if ((error = checkPassword(newPassword)) != NO_ERROR)
406 {
407 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
408 return result;
409 }
410
411 newPassword = hashPassword(newPassword);
412
413 if(_recaptchaPrivateKey != null)
414 {
415 ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
416 reCaptcha.setPrivateKey(_recaptchaPrivateKey);
417
418 String challenge = (String) paramMap.get("recaptcha_challenge_field");
419 String uResponse = (String) paramMap.get("recaptcha_response_field");
420
421 if (challenge == null || uResponse == null)
422 {
423 serviceNode.setAttribute("operation", REGISTER);
424 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_CAPTCHA_MISSING));
425 return result;
426 }
427
428 ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(request.getAttribute("remoteAddress"), challenge, uResponse);
429
430 if (!reCaptchaResponse.isValid())
431 {
432 serviceNode.setAttribute("operation", REGISTER);
433 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_CAPTCHA_DOES_NOT_MATCH));
434 return result;
435 }
436 }
437
438 error = addUser(newUsername, newPassword, "", "true", "", newEmail);
439 if (error != NO_ERROR)
440 {
441 serviceNode.setAttribute("operation", REGISTER);
442 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
443 }
444 }
445 else if (op.equals(PERFORM_EDIT))
446 {
447 String previousUsername = (String) paramMap.get("prevUsername");
448 String newUsername = (String) paramMap.get("newUsername");
449 String newPassword = (String) paramMap.get("password");
450 String newGroups = (String) paramMap.get("groups");
451 String newStatus = (String) paramMap.get("status");
452 String newComment = (String) paramMap.get("comment");
453 String newEmail = (String) paramMap.get("email");
454
455 //Check the given user name
456 int error;
457 if ((error = checkUsername(newUsername)) != NO_ERROR)
458 {
459 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
460 return result;
461 }
462
463 if (newPassword == null)
464 {
465 newPassword = retrieveDataForUser(previousUsername, "password");
466 }
467 else
468 {
469 //Check the given password
470 if ((error = checkPassword(newPassword)) != NO_ERROR)
471 {
472 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
473 return result;
474 }
475
476 newPassword = hashPassword(newPassword);
477 }
478
479 error = removeUser(previousUsername);
480 if (error != NO_ERROR)
481 {
482 if (error == ERROR_USERNAME_NOT_SPECIFIED)
483 {
484 addUserInformationToNode(null, serviceNode);
485 serviceNode.setAttribute("operation", LIST_USERS);
486 }
487 else
488 {
489 serviceNode.setAttribute("operation", EDIT_USER);
490 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
491 }
492 return result;
493 }
494
495 error = addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
496 if (error != NO_ERROR)
497 {
498 serviceNode.setAttribute("operation", EDIT_USER);
499 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
500 }
501 else
502 {
503 addUserInformationToNode(null, serviceNode);
504 serviceNode.setAttribute("operation", LIST_USERS);
505 }
506 }
507 else if (op.equals(PERFORM_ACCOUNT_EDIT))
508 {
509 String previousUsername = (String) paramMap.get("prevUsername");
510 String newUsername = (String) paramMap.get("newUsername");
511 String oldPassword = (String) paramMap.get("oldPassword");
512 String newPassword = (String) paramMap.get("newPassword");
513 String newEmail = (String) paramMap.get("newEmail");
514
515 //Make sure the user name does not already exist
516 if (!previousUsername.equals(newUsername) && checkUserExists(newUsername))
517 {
518 addUserInformationToNode(previousUsername, serviceNode);
519 serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
520 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_USER_ALREADY_EXISTS));
521 return result;
522 }
523
524 String prevPassword = retrieveDataForUser(previousUsername, "password");
525
526 if (newPassword != null)
527 {
528 oldPassword = hashPassword(oldPassword);
529
530 if (oldPassword == null || !oldPassword.equals(prevPassword))
531 {
532 addUserInformationToNode(previousUsername, serviceNode);
533 serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
534 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_INCORRECT_PASSWORD));
535 return result;
536 }
537
538 //Check the given password
539 int error;
540 if ((error = checkPassword(newPassword)) != NO_ERROR)
541 {
542 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
543 return result;
544 }
545
546 newPassword = hashPassword(newPassword);
547 }
548 else
549 {
550 newPassword = prevPassword;
551 }
552
553 //Check the given user name
554 int error;
555 if ((error = checkUsername(newUsername)) != NO_ERROR)
556 {
557 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
558 return result;
559 }
560
561 String prevGroups = retrieveDataForUser(previousUsername, "groups");
562 String prevStatus = retrieveDataForUser(previousUsername, "status");
563 String prevComment = retrieveDataForUser(previousUsername, "comment");
564
565 error = removeUser(previousUsername);
566 if (error != NO_ERROR)
567 {
568 if (error == ERROR_USERNAME_NOT_SPECIFIED)
569 {
570 addUserInformationToNode(null, serviceNode);
571 serviceNode.setAttribute("operation", LIST_USERS);
572 }
573 else
574 {
575 addUserInformationToNode(previousUsername, serviceNode);
576 serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
577 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
578 }
579 return result;
580 }
581
582 error = addUser(newUsername, newPassword, prevGroups, prevStatus, prevComment, newEmail);
583 if (error != NO_ERROR)
584 {
585 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
586 }
587
588 addUserInformationToNode(null, serviceNode);
589 serviceNode.setAttribute("operation", LIST_USERS);
590 }
591 else if (op.equals(EDIT_USER))
592 {
593 String editUsername = (String) paramMap.get("username");
594 int error = addUserInformationToNode(editUsername, serviceNode);
595 if (error != NO_ERROR)
596 {
597 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
598 }
599 }
600 else if (op.equals(ACCOUNT_SETTINGS))
601 {
602 String editUsername = (String) paramMap.get("username");
603
604 if (editUsername == null)
605 {
606 serviceNode.setAttribute("operation", "");
607 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_USERNAME_NOT_SPECIFIED));
608 return result;
609 }
610
611 if (!editUsername.equals(username))
612 {
613 serviceNode.setAttribute("operation", LOGIN);
614 GSXML.addError(this.doc, result, _errorMessageMap.get(ERROR_NOT_AUTHORISED));
615 return result;
616 }
617 int error = addUserInformationToNode(editUsername, serviceNode);
618 if (error != NO_ERROR)
619 {
620 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
621 }
622 }
623 else if (op.equals(PERFORM_RESET_PASSWORD))
624 {
625 String passwordResetUser = (String) paramMap.get("username");
626
627 String newPassword = UUID.randomUUID().toString();
628 newPassword = newPassword.substring(0, newPassword.indexOf("-"));
629
630 String email = retrieveDataForUser(passwordResetUser, "email");
631 String from = "[email protected]";
632 String host = request.getAttribute("remoteAddress");
633
634 //TODO: FINISH THIS
635 }
636 else if (op.equals(REGISTER))
637 {
638 if(_recaptchaPublicKey != null && _recaptchaPrivateKey != null)
639 {
640 Element recaptchaElem = this.doc.createElement("recaptcha");
641 recaptchaElem.setAttribute("publicKey", _recaptchaPublicKey);
642 recaptchaElem.setAttribute("privateKey", _recaptchaPrivateKey);
643 result.appendChild(recaptchaElem);
644 }
645 }
646 else if (op.equals(PERFORM_DELETE_USER))
647 {
648 String usernameToDelete = (String) paramMap.get("username");
649 int error = removeUser(usernameToDelete);
650 if (error != NO_ERROR)
651 {
652 GSXML.addError(this.doc, result, _errorMessageMap.get(error));
653 }
654 addUserInformationToNode(null, serviceNode);
655 serviceNode.setAttribute("operation", LIST_USERS);
656 }
657
658 return result;
659 }
660
661 public int checkUsernameAndPassword(String username, String password)
662 {
663 int uResult = checkUsername(username);
664 int pResult = checkPassword(password);
665
666 return (uResult != NO_ERROR ? uResult : (pResult != NO_ERROR ? pResult : NO_ERROR));
667 }
668
669 public int checkUsername(String username)
670 {
671 //Check the given user name
672 if ((username == null) || (username.length() < 2) || (username.length() > 30) || (!(Pattern.matches("[a-zA-Z0-9//_//.]+", username))))
673 {
674 return ERROR_INVALID_USERNAME;
675 }
676 return NO_ERROR;
677 }
678
679 public int checkPassword(String password)
680 {
681 //Check the given password
682 if ((password == null) || (password.length() < 3) || (password.length() > 8) || (!(Pattern.matches("[\\p{ASCII}]+", password))))
683 {
684 return ERROR_INVALID_PASSWORD;
685 }
686 return NO_ERROR;
687 }
688
689 public static String hashPassword(String password)
690 {
691 String hashedPassword = null;
692 try
693 {
694 MessageDigest digest = MessageDigest.getInstance("SHA-1");
695 digest.reset();
696 hashedPassword = new String(digest.digest(password.getBytes("UTF-8")));
697 }
698 catch (Exception ex)
699 {
700 ex.printStackTrace();
701 }
702 return hashedPassword;
703 }
704
705 private void checkAdminUserExists()
706 {
707 if (_derbyWrapper == null)
708 {
709 openDatabase();
710 }
711
712 UserQueryResult userQueryResult = _derbyWrapper.findUser(null, null);
713 closeDatabase();
714
715 if (userQueryResult != null)
716 {
717 Vector userInfo = userQueryResult.users;
718
719 boolean adminFound = false;
720 for (int i = 0; i < userQueryResult.getSize(); i++)
721 {
722 if (((UserTermInfo) userInfo.get(i)).groups != null && ((UserTermInfo) userInfo.get(i)).groups.matches(".*\\badministrator\\b.*"))
723 {
724 adminFound = true;
725 }
726 }
727
728 if (!adminFound)
729 {
730 addUser("admin", "admin", "administrator", "true", "Change the password for this account as soon as possible", "");
731 }
732 }
733
734 closeDatabase();
735 }
736
737 private boolean openDatabase()
738 {
739 _derbyWrapper = new DerbyWrapper();
740
741 // 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
742 String usersDB_dir = this.site_home + File.separatorChar + "etc" + File.separatorChar + "usersDB";
743 File usersDB_file = new File(usersDB_dir);
744 if (!usersDB_file.exists())
745 {
746 String etc_dir = this.site_home + File.separatorChar + "etc";
747 File etc_file = new File(etc_dir);
748 if (!etc_file.exists())
749 {
750 boolean success = etc_file.mkdir();
751 if (!success)
752 {
753 logger.error("Couldn't create the etc dir under " + this.site_home + ".");
754 return false;
755 }
756 }
757 _derbyWrapper.connectDatabase(usersDB_dir, true);
758 _derbyWrapper.createDatabase();
759 }
760 else
761 {
762 _derbyWrapper.connectDatabase(usersDB_dir, false);
763 }
764 return true;
765 }
766
767 private void closeDatabase()
768 {
769 if (_derbyWrapper != null)
770 {
771 _derbyWrapper.closeDatabase();
772 _derbyWrapper = null;
773 }
774 }
775
776 private int addUserInformationToNode(String username, Element serviceNode)
777 {
778 if (_derbyWrapper == null)
779 {
780 openDatabase();
781 }
782
783 UserQueryResult userQueryResult = _derbyWrapper.findUser(username, null);
784 closeDatabase();
785
786 if (userQueryResult != null)
787 {
788 Element user_node = getUserNode(userQueryResult);
789 serviceNode.appendChild(user_node);
790 closeDatabase();
791 return NO_ERROR;
792 }
793
794 closeDatabase();
795 return ERROR_COULD_NOT_GET_USER_INFO;
796 }
797
798 private int removeUser(String username)
799 {
800 if (username == null)
801 {
802 return ERROR_USERNAME_NOT_SPECIFIED;
803 }
804
805 if (_derbyWrapper == null)
806 {
807 openDatabase();
808 }
809
810 boolean success = _derbyWrapper.deleteUser(username);
811 closeDatabase();
812
813 if (success)
814 {
815 return NO_ERROR;
816 }
817
818 return ERROR_REMOVING_USER;
819 }
820
821 private int addUser(String newUsername, String newPassword, String newGroups, String newStatus, String newComment, String newEmail)
822 {
823 if (_derbyWrapper == null)
824 {
825 openDatabase();
826 }
827
828 newGroups = newGroups.replaceAll(" ", "");
829
830 //Check if the user already exists
831 UserQueryResult userQueryResult = _derbyWrapper.findUser(newUsername, null);
832 if (userQueryResult != null)
833 {
834 closeDatabase();
835 return ERROR_USER_ALREADY_EXISTS;
836 }
837 else
838 {
839 System.err.println("ADDING " + newUsername + " " + newPassword);
840 boolean success = _derbyWrapper.addUser(newUsername, newPassword, newGroups, newStatus, newComment, newEmail);
841 if (!success)
842 {
843 closeDatabase();
844 return ERROR_ADDING_USER;
845 }
846 }
847 closeDatabase();
848 return NO_ERROR;
849 }
850
851 private boolean checkUserExists(String username)
852 {
853 if (_derbyWrapper == null)
854 {
855 openDatabase();
856 }
857
858 try
859 {
860 UserQueryResult result = _derbyWrapper.findUser(username);
861
862 if (result != null)
863 {
864 return true;
865 }
866 else
867 {
868 return false;
869 }
870
871 }
872 catch (Exception ex)
873 {
874 return false;
875 }
876 finally
877 {
878 closeDatabase();
879 }
880 }
881
882 private String retrieveDataForUser(String username, String dataType)
883 {
884 if (_derbyWrapper == null)
885 {
886 openDatabase();
887 }
888
889 String password = null;
890
891 try
892 {
893 UserQueryResult result = _derbyWrapper.findUser(username);
894 Vector userInfo = result.users;
895
896 for (int i = 0; i < result.getSize(); i++)
897 {
898 if (dataType.equals("password"))
899 {
900 return ((UserTermInfo) userInfo.get(i)).password;
901 }
902 else if (dataType.equals("groups"))
903 {
904 return ((UserTermInfo) userInfo.get(i)).groups;
905 }
906 else if (dataType.equals("status"))
907 {
908 return ((UserTermInfo) userInfo.get(i)).accountstatus;
909 }
910 else if (dataType.equals("comment"))
911 {
912 return ((UserTermInfo) userInfo.get(i)).comment;
913 }
914 else if (dataType.equals("email"))
915 {
916 return ((UserTermInfo) userInfo.get(i)).email;
917 }
918 }
919 }
920 catch (Exception ex)
921 {
922 ex.printStackTrace();
923 }
924
925 closeDatabase();
926 return password;
927 }
928
929 private Element getUserNode(UserQueryResult userQueryResult)
930 {
931 Element user_list_node = this.doc.createElement(GSXML.USER_NODE_ELEM + "List");
932
933 Vector userInfo = userQueryResult.users;
934
935 for (int i = 0; i < userQueryResult.getSize(); i++)
936 {
937 Element user_node = this.doc.createElement(GSXML.USER_NODE_ELEM);
938 String username = ((UserTermInfo) userInfo.get(i)).username;
939 String groups = ((UserTermInfo) userInfo.get(i)).groups;
940 String accountstatus = ((UserTermInfo) userInfo.get(i)).accountstatus;
941 String comment = ((UserTermInfo) userInfo.get(i)).comment;
942 String email = ((UserTermInfo) userInfo.get(i)).email;
943 user_node.setAttribute("username", username);
944 user_node.setAttribute("groups", groups);
945 user_node.setAttribute("status", accountstatus);
946 user_node.setAttribute("comment", comment);
947 user_node.setAttribute("email", email);
948
949 user_list_node.appendChild(user_node);
950 }
951 return user_list_node;
952 }
953
954 private Element getCollectList(String collect)
955 {
956 Element collect_list_node = this.doc.createElement(GSXML.COLLECTION_ELEM + "List");
957 File[] collect_dir = (new File(collect)).listFiles();
958 if (collect_dir != null && collect_dir.length > 0)
959 {
960 for (int i = 0; i < collect_dir.length; i++)
961 {
962 if (collect_dir[i].isDirectory() && (!collect_dir[i].getName().startsWith(".svn")))
963 {
964 Element collect_node = this.doc.createElement(GSXML.COLLECTION_ELEM);
965 collect_node.setAttribute("name", collect_dir[i].getName());
966 collect_list_node.appendChild(collect_node);
967 }
968 }
969 }
970 return collect_list_node;
971 }
972}
Note: See TracBrowser for help on using the repository browser.