1 64 65 package com.jcorporate.expresso.services.validation; 66 67 import com.jcorporate.expresso.core.db.DBException; 68 import com.jcorporate.expresso.core.dbobj.SecuredDBObject; 69 import com.jcorporate.expresso.core.job.Job; 70 import com.jcorporate.expresso.core.job.ServerException; 71 import com.jcorporate.expresso.core.misc.ConfigManager; 72 import com.jcorporate.expresso.core.misc.CookieBase64; 73 import com.jcorporate.expresso.core.misc.DateTime; 74 import com.jcorporate.expresso.core.misc.EMailSender; 75 import com.jcorporate.expresso.core.misc.StringUtil; 76 import com.jcorporate.expresso.core.security.CryptoManager; 77 import com.jcorporate.expresso.core.security.User; 78 import com.jcorporate.expresso.kernel.exception.ChainedException; 79 import com.jcorporate.expresso.kernel.util.ClassLocator; 80 import com.jcorporate.expresso.kernel.util.FastStringBuffer; 81 import com.jcorporate.expresso.services.dbobj.JobQueue; 82 import com.jcorporate.expresso.services.dbobj.JobQueueParam; 83 import com.jcorporate.expresso.services.dbobj.Setup; 84 import com.jcorporate.expresso.services.dbobj.ValidationQueue; 85 import com.jcorporate.expresso.services.dbobj.ValidationQueueParam; 86 import org.apache.log4j.Logger; 87 88 import java.io.Serializable ; 89 import java.util.Calendar ; 90 import java.util.Date ; 91 import java.util.Enumeration ; 92 import java.util.Hashtable ; 93 import java.util.Iterator ; 94 import java.util.List ; 95 import java.util.StringTokenizer ; 96 import java.util.Vector ; 97 98 99 114 public class ValidationEntry implements Serializable { 115 118 public static final String PRM_VALIDATOR = "$$$Validator"; 119 120 123 public static final String PRM_EXPIRES_AFTER = "$$$ExpiresAfter"; 124 125 128 public static final String PRM_VAL_TITLE = "$$$ValTitle"; 129 130 133 public static final String PRM_VAL_DESC = "$$$ValDesc"; 134 135 138 public static final String PRM_VAL_SERVER = "$$$ValDServer"; 139 140 143 public static final String PRM_VAL_PORT = "$$$ValPort"; 144 145 148 public static final String PRM_VAL_CTX = "$$$ValContext"; 149 150 153 public static final String NEW = "N"; 154 155 158 public static final String WAITING = "W"; 159 160 163 public static final String AVAILABLE = "A"; 164 165 168 public static final String VALIDATED = "V"; 169 170 173 public static final String EXPIRED = "E"; 174 175 178 public static final String SESSION_KEY = "expresso.services.validation.ValidationEntry"; 179 180 183 private static Logger log = Logger.getLogger(ValidationEntry.class); 184 185 188 protected JobQueue jq = null; 189 190 193 protected JobQueueParam jqp = null; 194 195 198 protected String dataContext = "default"; 199 200 203 protected String expiresAfter = "120:0:0"; 205 208 protected String jobClassName = com.jcorporate.expresso.services.job.ValidationJob.class.getName(); 209 210 213 protected String jobNumber = null; 214 215 218 protected String valContextPath = null; 219 220 223 protected String valDesc = "Validation Job"; 224 225 228 protected String valPort = null; 229 230 233 protected String valServer = null; 234 235 238 protected String valTitle = "Validation Job"; 239 240 243 protected String valType = "default"; 244 245 248 protected String validationClassName = null; 249 250 253 protected ValidationQueue vq = null; 254 255 258 protected int paramNum = 0; 259 260 271 public ValidationEntry(String newDbName) throws AuthValidationException { 272 super(); 273 274 if ((newDbName == null) || (newDbName.equals(""))) { 276 newDbName = "default"; 277 } 278 279 dataContext = newDbName; 280 281 try { 282 int uid = User.getAdminId(newDbName); 283 284 jq = new JobQueue(); 286 jq.setDataContext(dataContext); 287 jq.setField(JobQueue.FLD_UID, uid); 288 jq.setField(JobQueue.FLD_JOBCODE, jobClassName); 289 jq.setField(JobQueue.FLD_STATUS_CODE, "N"); 290 jq.add(); 291 292 jobNumber = jq.getField("JobNumber"); 294 295 jqp = new JobQueueParam(); 297 jqp.setDataContext(dataContext); 298 } catch (DBException dbe) { 299 throw new AuthValidationException("Database error creating job or parameters", 300 dbe); 301 } 302 303 if (log.isDebugEnabled()) { 304 log.debug("New entry started with job number " + jobNumber); 305 } 306 } 307 308 318 public ValidationEntry(String dbName, String id) 319 throws AuthValidationException { 320 super(); 321 322 try { 323 vq = new ValidationQueue(SecuredDBObject.SYSTEM_ACCOUNT); 325 vq.setDataContext(dbName); 326 vq.setField(ValidationQueue.FLD_ID, id); 327 328 if (!vq.find()) { 329 throw new AuthValidationException("Validation queue id \"" + 330 id + "\" not found in db \"" + dbName + "\""); 331 } 332 } catch (DBException dbe) { 333 throw new AuthValidationException("DB error", dbe); 334 } 335 } 336 337 348 public ValidationEntry(String context, List paramsVector, JobQueue jq) 349 throws AuthValidationException { 350 super(); 351 352 String id = null; 353 354 try { 355 String expiresAfter = jq.getParamValue(ValidationEntry.PRM_EXPIRES_AFTER); 358 Calendar now = Calendar.getInstance(); 359 StringTokenizer stk = new StringTokenizer (expiresAfter, ":"); 360 int hr = Integer.parseInt((String ) stk.nextElement()); 361 int mn = Integer.parseInt((String ) stk.nextElement()); 362 int sc = Integer.parseInt((String ) stk.nextElement()); 363 now.add(Calendar.HOUR, hr); 364 now.add(Calendar.MINUTE, mn); 365 now.add(Calendar.SECOND, sc); 366 367 valServer = jq.getParamValue(ValidationEntry.PRM_VAL_SERVER); 369 valPort = jq.getParamValue(ValidationEntry.PRM_VAL_PORT); 370 valContextPath = jq.getParamValue(ValidationEntry.PRM_VAL_CTX); 371 372 vq = new ValidationQueue(); 374 vq.setDataContext(context); 375 vq.setField(ValidationQueue.FLD_STATUS_CODE, "N"); vq.setField(ValidationQueue.FLD_EXPIRES_AT, 377 DateTime.getDateTimeForDB(now.getTime(), context)); 378 vq.setField(ValidationQueue.FLD_VAL_CODE, createValidationCode()); vq.setField(ValidationQueue.FLD_VAL_HANDLER, 380 jq.getParamValue(ValidationEntry.PRM_VALIDATOR)); 381 vq.setField(ValidationQueue.FLD_PROCESSED_BY, "1"); 382 vq.add(); 383 384 id = vq.getField(ValidationQueue.FLD_ID); 386 387 int paramNum = 0; 389 ValidationQueueParam vqp = new ValidationQueueParam(); 390 vqp.setDataContext(context); 391 392 for (Iterator i = paramsVector.iterator(); i.hasNext();) { 393 JobQueueParam jqp = (JobQueueParam) i.next(); 394 String key = jqp.getField("ParamCode"); 395 String val = jqp.getField("ParamValue"); 396 vqp.clear(); 397 vqp.setField(ValidationQueueParam.FLD_QUEUE_ID, id); 398 vqp.setField(ValidationQueueParam.FLD_PARAM_NUM, Integer.toString(++paramNum)); 399 vqp.setField(ValidationQueueParam.FLD_PARAM_CODE, key); 400 vqp.setField(ValidationQueueParam.FLD_PARAM_VAL, val); 401 vqp.add(); 402 } 403 404 vq.setField(ValidationQueue.FLD_STATUS_CODE, "A"); 406 vq.update(); 407 } catch (DBException dbe) { 408 throw new AuthValidationException("Database error storing validation entry", 409 dbe); 410 } 411 } 412 413 418 private ValidationEntry() throws AuthValidationException { 419 throw new AuthValidationException("Please do not use the default constructor"); 420 } 421 422 425 public void setContextPath(String path) { 426 valContextPath = path; 427 } 428 429 435 public void setDesc(String desc) { 436 valDesc = desc; 437 } 438 439 445 public Date getExpiresAt() throws AuthValidationException { 446 if (vq == null) { 447 throw new AuthValidationException("Use loadQueueEntry(...) method first"); 448 } 449 450 try { 451 Date ex = vq.getFieldDate(ValidationQueue.FLD_EXPIRES_AT); 452 453 return ex; 454 } catch (DBException dbe) { 455 throw new AuthValidationException("DB error", dbe); 456 } 457 } 458 459 468 public void setJobClassName(String name) throws AuthValidationException { 469 try { 470 Job.instantiate(name); 471 } catch (ServerException se) { 472 throw new AuthValidationException("Class \"" + name + 473 "\" is not an Expresso Job", se); 474 } 475 476 jobClassName = name; 477 } 478 479 486 public Hashtable getParams() throws AuthValidationException { 487 if (vq == null) { 488 throw new AuthValidationException("Use loadQueueEntry(...) method first"); 489 } 490 491 Hashtable params = new Hashtable (8); 492 493 try { 494 String id = vq.getField(ValidationQueue.FLD_ID); 495 ValidationQueueParam vqp = new ValidationQueueParam(); 496 vqp.setField(ValidationQueueParam.FLD_QUEUE_ID, id); 497 vqp.setDataContext(dataContext); 498 499 for (Iterator i = vqp.searchAndRetrieveList().iterator(); 500 i.hasNext();) { 501 ValidationQueueParam oneParam = (ValidationQueueParam) i.next(); 502 params.put(oneParam.getField(ValidationQueueParam.FLD_PARAM_CODE), 503 oneParam.getField(ValidationQueueParam.FLD_PARAM_VAL)); 504 } 505 } catch (DBException dbe) { 506 throw new AuthValidationException("DB error", dbe); 507 } 508 509 return params; 510 } 511 512 515 public void setPort(String port) { 516 valPort = port; 517 } 518 519 522 public void setServer(String server) { 523 valServer = server; 524 } 525 526 534 public void setStatus(String newStatus) throws AuthValidationException { 535 if (vq == null) { 536 throw new AuthValidationException("Use loadQueueEntry(...) method first"); 537 } 538 539 try { 540 vq.setField(ValidationQueue.FLD_STATUS_CODE, newStatus); 541 vq.update(); 542 } catch (DBException dbe) { 543 throw new AuthValidationException("DB error", dbe); 544 } 545 } 546 547 554 public String getStatus() throws AuthValidationException { 555 if (vq == null) { 556 throw new AuthValidationException("Use loadQueueEntry(...) method first"); 557 } 558 559 try { 560 String status = vq.getField(ValidationQueue.FLD_STATUS_CODE); 561 562 return status; 563 } catch (DBException dbe) { 564 throw new AuthValidationException("DB error", dbe); 565 } 566 } 567 568 574 public void setTitle(String title) { 575 valTitle = title; 576 } 577 578 588 public void setValidationHandler(String className) 589 throws AuthValidationException { 590 StringUtil.assertNotBlank(className, 591 "ValidationHandler class name " + " may not be blank or null here"); 592 593 try { 594 Class c = ClassLocator.loadClass(className); 595 c.newInstance(); 596 } catch (ClassNotFoundException cn) { 597 throw new AuthValidationException("ValidationHandler object '" + 598 className + "' not found", cn); 599 } catch (InstantiationException ie) { 600 throw new AuthValidationException("ValidationHandler object '" + 601 className + "' cannot be instantiated", ie); 602 } catch (IllegalAccessException iae) { 603 throw new AuthValidationException("Illegal access loading " + 604 "ValidationHandler object '" + className + "'", iae); 605 } 606 607 validationClassName = className; 608 } 609 610 611 620 public void setValidationHandler(Class clazz) throws AuthValidationException { 621 try { 622 clazz.newInstance(); 623 } catch (IllegalAccessException ex) { 624 throw new AuthValidationException("Illegal access loading " + 625 "ValidationHandler object '" + clazz.getName() + "'", ex); 626 } catch (InstantiationException ex) { 627 throw new AuthValidationException("ValidationHandler object '" + 628 clazz.getName() + "' cannot be instantiated", ex); 629 } 630 631 validationClassName = clazz.getName(); 632 } 633 634 635 642 public void addParam(String name, String value) 643 throws AuthValidationException { 644 try { 645 646 jqp.clear(); 647 jqp.setField("JobNumber", jobNumber); 648 paramNum++; 649 jqp.setField("ParamNumber", Integer.toString(paramNum)); 650 jqp.setField("ParamCode", name); 651 jqp.setField("ParamValue", value); 652 jqp.add(); 653 } catch (DBException dbe) { 654 throw new AuthValidationException("Database error adding job parameter", 655 dbe); 656 } 657 658 if (log.isDebugEnabled()) { 659 log.debug("Job id= " + jobNumber + ": Adding param name=" + name + 660 " value=" + value); 661 } 662 } 663 664 672 public boolean codeMatches(String code) throws AuthValidationException { 673 try { 674 String storedCode = vq.getField(ValidationQueue.FLD_VAL_CODE); 675 676 if (storedCode.equals(code)) { 677 return true; 678 } else { 679 return false; 680 } 681 } catch (DBException dbe) { 682 throw new AuthValidationException("DB error", dbe); 683 } 684 } 685 686 692 public void delete() throws AuthValidationException { 693 if (vq == null) { 694 throw new AuthValidationException("Use loadQueueEntry(...) method first"); 695 } 696 697 try { 698 vq.delete(true); 699 vq = null; 700 } catch (DBException dbe) { 701 throw new AuthValidationException("DB error", dbe); 702 } 703 } 704 705 714 public void expiresAfter(int hr, int min, int sec) { 715 FastStringBuffer fsb = FastStringBuffer.getInstance(); 716 717 try { 718 fsb.append(hr); 719 fsb.append(":"); 720 fsb.append(min); 721 fsb.append(":"); 722 fsb.append(sec); 723 724 expiresAfter = fsb.toString(); 726 } finally { 727 fsb.release(); 728 fsb = null; 729 } 730 } 731 732 739 public ValidationHandler instantiateHandler() 740 throws AuthValidationException { 741 ValidationHandler vh = null; 742 String className = null; 743 744 try { 745 className = vq.getField(ValidationQueue.FLD_VAL_HANDLER); 746 } catch (DBException dbe) { 747 throw new AuthValidationException("DB error", dbe); 748 } 749 750 StringUtil.assertNotBlank(className, 751 "ValidationHandler class name " + " may not be blank or null here"); 752 753 try { 754 Class c = ClassLocator.loadClass(className); 755 vh = (ValidationHandler) c.newInstance(); 756 } catch (ClassNotFoundException cn) { 757 throw new AuthValidationException("ValidationHandler object '" + 758 className + "' not found", cn); 759 } catch (InstantiationException ie) { 760 throw new AuthValidationException("ValidationHandler object '" + 761 className + "' cannot be instantiated", ie); 762 } catch (IllegalAccessException iae) { 763 throw new AuthValidationException("llegal access loading " + 764 "ValidationHandler object '" + className + "'", iae); 765 } 766 767 return vh; 768 } 769 770 780 public static void notifyByEmail(String dbName, String from, 781 Vector addresses, String subject, String content) 782 throws AuthValidationException { 783 EMailSender ems = new EMailSender(); 784 ems.setFromAddress(from); 785 ems.setDBName(dbName); 786 787 for (Enumeration e = addresses.elements(); e.hasMoreElements();) { 788 String oneAddr = (String ) e.nextElement(); 789 790 try { 791 ems.send(oneAddr, subject, content); 792 } catch (Exception exc) { 793 throw new AuthValidationException("Email error sending to \"" + 794 oneAddr + "\"", exc); 795 } 796 } 797 } 798 799 805 public void submit() throws AuthValidationException { 806 try { 807 if ((valServer == null) || valServer.equals("")) { 808 valServer = Setup.getValue(dataContext, "HTTPServ"); 809 } 810 811 if ((valPort == null) || valPort.equals("")) { 812 valPort = Setup.getValue(dataContext, "ServletPort"); 813 } 814 815 if ((valContextPath == null) || valContextPath.equals("")) { 816 valContextPath = Setup.getValue(dataContext, "ContextPath"); 817 } 818 819 addParam(PRM_VALIDATOR, validationClassName); 820 addParam(PRM_EXPIRES_AFTER, expiresAfter); 821 addParam(PRM_VAL_TITLE, valTitle); 822 addParam(PRM_VAL_DESC, valDesc); 823 addParam(PRM_VAL_SERVER, valServer); 824 addParam(PRM_VAL_PORT, valPort); 825 addParam(PRM_VAL_CTX, valContextPath); 826 jq.setField(JobQueue.FLD_STATUS_CODE, AVAILABLE); 827 jq.update(); 828 } catch (DBException dbe) { 829 throw new AuthValidationException("Database error updating job status to active", 830 dbe); 831 } 832 } 833 834 844 public String validationURL() throws AuthValidationException { 845 FastStringBuffer authURL = FastStringBuffer.getInstance(); 846 String returnValue = null; 847 848 try { 849 try { 850 String db = vq.getDataContext(); 851 if (valPort.equals(ConfigManager.getConfig().getSslPort())) { 852 authURL.append("https://"); 853 } else { 854 authURL.append("http://"); 855 } 856 authURL.append(valServer); 857 authURL.append(":" + valPort); 858 authURL.append(valContextPath); 859 authURL.append("/Validate.do?"); 860 authURL.append("ctx=" + db); 861 authURL.append("&id=" + vq.getField(ValidationQueue.FLD_ID)); 862 authURL.append("&code=" + vq.getField(ValidationQueue.FLD_VAL_CODE)); 863 } catch (DBException dbe) { 864 throw new AuthValidationException("DB error", dbe); 865 } 866 867 returnValue = authURL.toString(); 868 } finally { 869 authURL.release(); 870 } 871 872 return returnValue; 873 } 874 875 883 protected static String createValidationCode() { 884 final int length = 256 / 8; 886 byte[] possibleNumbers; 887 888 try { 889 possibleNumbers = CryptoManager.getInstance().getRandomGenerator() 890 .getRandomBytes(length); 891 } catch (ChainedException e) { 892 possibleNumbers = new byte[length]; 893 894 Logger.getLogger("com.jcorporate.expresso.core.security.").error("Create Validation Code", 897 e); 898 899 for (int i = 0; i < length; i++) { 900 possibleNumbers[i] = (byte) (Math.random() * 256); 901 } 902 } 903 904 return CookieBase64.encodeNoPadding(possibleNumbers); 905 } 906 } 907 | Popular Tags |