Revision: 1004
Author: jmncarvalho
Date: Sat Nov 19 05:10:12 2011
Log: Adds automatic email confirmation. Adds form validation on client
side with query. Includes jcaptcha to avoid automatic form submissions.
http://code.google.com/p/mhk/source/detail?r=1004
Added:
/trunk/idb/etc/template/new/query_export.vm
/trunk/idb/etc/template/new/validateuser_success.vm
/trunk/idb/lib/commons-collections-3.2.1.jar
/trunk/idb/lib/jcaptcha-all-1.0-RC3.jar
/trunk/idb/lib/mail-1.4.2.jar
/trunk/idb/lib/owasp-captcha.jar
/trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoValidateUser.java
/trunk/idb/web/scripts/jquery.validate.js
/trunk/idb/web/scripts/timelink.validator.js
Modified:
/trunk/.classpath
/trunk/.settings/org.eclipse.core.resources.prefs
/trunk/idb/.upload_information
/trunk/idb/build.number
/trunk/idb/build_joao_mac.xml
/trunk/idb/etc/template/new/advanced_search_show.vm
/trunk/idb/etc/template/new/header.vm
/trunk/idb/etc/template/new/login.vm
/trunk/idb/etc/template/new/signup.vm
/trunk/idb/etc/template/new/signup_missingfields.vm
/trunk/idb/etc/template/new/signup_success.vm
/trunk/idb/etc/web.xml
/trunk/idb/pt/uc/cisuc/jrc/mhk/rch/DBSystem.java
/trunk/idb/pt/uc/cisuc/jrc/mhk/rch/DBUser.java
/trunk/idb/pt/uc/cisuc/jrc/mhk/resources/MHKStrings.properties
/trunk/idb/pt/uc/cisuc/jrc/mhk/resources/MHKStrings_pt.properties
/trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/CentralServlet.java
/trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoInsertUser.java
/trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoLogin.java
/trunk/idb/web/stylesheets/main.css
=======================================
--- /dev/null
+++ /trunk/idb/etc/template/new/query_export.vm Sat Nov 19 05:10:12 2011
@@ -0,0 +1,17 @@
+#set($database=$db.getDBUtils())##
+#set($query=$req.getParameter("query"))##
+#set($export_type= "csv")##
+#set($res = $req.setCharacterEncoding("ISO-8859-1"))##
+$resp.setHeader("Content-Disposition", "attachment;
charset=ISO-8859-1;fileName=export-${dbname}-${export_type}.csv")##
+#set($lb = "")##
+#set($sep = ",")##
+#set($results=$database.search($req.getParameter("query")))##
+#set($cols=$results.get(0).COLUMNS)
+#set($i=0)##
+#foreach($col in
$cols)#if($i>0)${sep}#end#if($col.startsWith("_"))$mhks.get($col)#else${col}#end#set($i=$i+1)#end
##print column names
+${lb}
+#foreach($row in $results)
+#set($i=0)##
+#foreach($col in
$cols)#if($i>0)${sep}#end#if($col.startsWith("_"))$mhkcs.get(${row.get($col)})#else#if($col.equals("latitude")|
|
$col.equals("longitude"))$database.stringFormat("%5.8f","$row.get($col)")#else${row.get($col)}#end#end#set($i=$i+1)#end
## print line values
+${lb}
+#end
=======================================
--- /dev/null
+++ /trunk/idb/etc/template/new/validateuser_success.vm Sat Nov 19 05:10:12
2011
@@ -0,0 +1,53 @@
+##
+## This file is part of the Time Link project hosted at
+##
http://code.google.com/p/mhk/
+##
+## Copyright (c) 2010, iClio Lda (
http://www.iclio.pt)
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
modification, are
+## permitted provided that the following conditions are met:
+##
+## 1. Redistributions of source code must retain the above copyright
notice, this list of
+## conditions and the following disclaimer.
+##
+## 2. Redistributions in binary form must reproduce the above copyright
notice, this list
+## of conditions and the following disclaimer in the documentation
and/or other materials
+## provided with the distribution.
+##
+## 3. Neither the name of the iClio nor the names of its contributors
may be used to endorse
+## or promote products derived from this software without specific
prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS
OR IMPLIED
+## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND
+## FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
COPYRIGHT HOLDERS OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR
+## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR
+## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON
+## ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING
+## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF
+## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+##
+#set ( $title = $mhks.get("success"))
+
+#parse("new/head.vm")
+
+<META HTTP-EQUIV=REFRESH
CONTENT="3;URL=${uri}?action=login.vm&validatesuccess=1&username=$req.getParameter("username")"/>
+
+</head>
+
+<body>
+
+#parse("new/header.vm")
+
+<div id="main">
+<div id="center_dialog">
+ <h3 class="success">$mhks.get("email.validated")</h3>
+ <p>$mhks.get('
go.back.to') <a
href="${uri}?action=login.vm&validatesuccess=1&username=$req.getParameter("username")">Login</a>
+ <p><i>$mhks.get('redirection')</i>
+</div>
+</div>
+
+#parse("new/footer.vm")
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/idb/lib/commons-collections-3.2.1.jar Sat Nov 19 05:10:12 2011
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/idb/lib/jcaptcha-all-1.0-RC3.jar Sat Nov 19 05:10:12 2011
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/idb/lib/mail-1.4.2.jar Sat Nov 19 05:10:12 2011
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/idb/lib/owasp-captcha.jar Sat Nov 19 05:10:12 2011
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoValidateUser.java Sat Nov 19
05:10:12 2011
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the Time Link project hosted at
+ *
http://code.google.com/p/mhk/
+ *
+ * Copyright © 2011, iClio Lda (
http://www.iclio.pt)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
notice, this list
+ * of conditions and the following disclaimer in the documentation
and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the iClio nor the names of its contributors
may be used to endorse
+ * or promote products derived from this software without specific
prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS
OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ package pt.uc.cisuc.jrc.mhk.servlet;
+
+import java.io.File;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.Message.RecipientType;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.log4j.Logger;
+import org.apache.velocity.context.Context;
+import org.owasp.validator.html.AntiSamy;
+import org.owasp.validator.html.CleanResults;
+import org.owasp.validator.html.Policy;
+
+import pt.uc.cisuc.jrc.mhk.rch.DBSystem;
+import pt.uc.cisuc.jrc.mhk.rch.DBUser;
+
+public class DoValidateUser extends Command {
+
+ Logger log = Logger.getLogger("idb.pt.uc.cisuc.jrc.mhk.rch.DBSystem");
+
+ public DoValidateUser(ServletContext con, HttpServletRequest req,
+ HttpServletResponse resp) {
+ super(con, req, resp);
+ }
+
+ public String exec(Context ctx) {
+ String code = request.getParameter("code");
+ String username = request.getParameter("username");
+
+ DBSystem db = (DBSystem) ctx.get("db");
+ DBUser dbuser = new DBUser(db);
+ boolean validated = false;
+ try {
+ validated = dbuser.validate(code, username);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ if(validated) {
+ //ctx.put("validatesuccess", "yes");
+ //request.setAttribute("validatesuccess", "1");
+ return "validateuser_success.vm";
+ } else
+ return "login.vm";
+ }
+}
=======================================
--- /dev/null
+++ /trunk/idb/web/scripts/jquery.validate.js Sat Nov 19 05:10:12 2011
@@ -0,0 +1,1188 @@
+/**
+ * jQuery Validation Plugin 1.9.0
+ *
+ *
http://bassistance.de/jquery-plugins/jquery-plugin-validation/
+ *
http://docs.jquery.com/Plugins/Validation
+ *
+ * Copyright (c) 2006 - 2011 Jörn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *
http://www.opensource.org/licenses/mit-license.php
+ *
http://www.gnu.org/licenses/gpl.html
+ */
+
+(function($) {
+
+$.extend($.fn, {
+ //
http://docs.jquery.com/Plugins/Validation/validate
+ validate: function( options ) {
+
+ // if nothing is selected, return nothing; can't chain anyway
+ if (!this.length) {
+ options && options.debug && window.console && console.warn( "nothing
selected, can't validate, returning nothing" );
+ return;
+ }
+
+ // check if a validator for this form was already created
+ var validator = $.data(this[0], 'validator');
+ if ( validator ) {
+ return validator;
+ }
+
+ // Add novalidate tag if HTML5.
+ this.attr('novalidate', 'novalidate');
+
+ validator = new $.validator( options, this[0] );
+ $.data(this[0], 'validator', validator);
+
+ if ( validator.settings.onsubmit ) {
+
+ var inputsAndButtons = this.find("input, button");
+
+ // allow suppresing validation by adding a cancel class to the submit
button
+ inputsAndButtons.filter(".cancel").click(function () {
+ validator.cancelSubmit = true;
+ });
+
+ // when a submitHandler is used, capture the submitting button
+ if (validator.settings.submitHandler) {
+ inputsAndButtons.filter(":submit").click(function () {
+ validator.submitButton = this;
+ });
+ }
+
+ // validate the form on submit
+ this.submit( function( event ) {
+ if ( validator.settings.debug )
+ // prevent form submit to be able to see console output
+ event.preventDefault();
+
+ function handle() {
+ if ( validator.settings.submitHandler ) {
+ if (validator.submitButton) {
+ // insert a hidden input as a replacement for the missing submit
button
+ var hidden = $("<input type='hidden'/>").attr("name",
validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
+ }
+ validator.settings.submitHandler.call( validator,
validator.currentForm );
+ if (validator.submitButton) {
+ // and clean up afterwards; thanks to no-block-scope, hidden can be
referenced
+ hidden.remove();
+ }
+ return false;
+ }
+ return true;
+ }
+
+ // prevent submit for invalid forms or custom submit handlers
+ if ( validator.cancelSubmit ) {
+ validator.cancelSubmit = false;
+ return handle();
+ }
+ if ( validator.form() ) {
+ if ( validator.pendingRequest ) {
+ validator.formSubmitted = true;
+ return false;
+ }
+ return handle();
+ } else {
+ validator.focusInvalid();
+ return false;
+ }
+ });
+ }
+
+ return validator;
+ },
+ //
http://docs.jquery.com/Plugins/Validation/valid
+ valid: function() {
+ if ( $(this[0]).is('form')) {
+ return this.validate().form();
+ } else {
+ var valid = true;
+ var validator = $(this[0].form).validate();
+ this.each(function() {
+ valid &= validator.element(this);
+ });
+ return valid;
+ }
+ },
+ // attributes: space seperated list of attributes to retrieve and remove
+ removeAttrs: function(attributes) {
+ var result = {},
+ $element = this;
+ $.each(attributes.split(/\s/), function(index, value) {
+ result[value] = $element.attr(value);
+ $element.removeAttr(value);
+ });
+ return result;
+ },
+ //
http://docs.jquery.com/Plugins/Validation/rules
+ rules: function(command, argument) {
+ var element = this[0];
+
+ if (command) {
+ var settings = $.data(element.form, 'validator').settings;
+ var staticRules = settings.rules;
+ var existingRules = $.validator.staticRules(element);
+ switch(command) {
+ case "add":
+ $.extend(existingRules, $.validator.normalizeRule(argument));
+ staticRules[
element.name] = existingRules;
+ if (argument.messages)
+ settings.messages[
element.name] = $.extend(
settings.messages[
element.name], argument.messages );
+ break;
+ case "remove":
+ if (!argument) {
+ delete staticRules[
element.name];
+ return existingRules;
+ }
+ var filtered = {};
+ $.each(argument.split(/\s/), function(index, method) {
+ filtered[method] = existingRules[method];
+ delete existingRules[method];
+ });
+ return filtered;
+ }
+ }
+
+ var data = $.validator.normalizeRules(
+ $.extend(
+ {},
+ $.validator.metadataRules(element),
+ $.validator.classRules(element),
+ $.validator.attributeRules(element),
+ $.validator.staticRules(element)
+ ), element);
+
+ // make sure required is at front
+ if (data.required) {
+ var param = data.required;
+ delete data.required;
+ data = $.extend({required: param}, data);
+ }
+
+ return data;
+ }
+});
+
+// Custom selectors
+$.extend($.expr[":"], {
+ //
http://docs.jquery.com/Plugins/Validation/blank
+ blank: function(a) {return !$.trim("" + a.value);},
+ //
http://docs.jquery.com/Plugins/Validation/filled
+ filled: function(a) {return !!$.trim("" + a.value);},
+ //
http://docs.jquery.com/Plugins/Validation/unchecked
+ unchecked: function(a) {return !a.checked;}
+});
+
+// constructor for validator
+$.validator = function( options, form ) {
+ this.settings = $.extend( true, {}, $.validator.defaults, options );
+ this.currentForm = form;
+ this.init();
+};
+
+$.validator.format = function(source, params) {
+ if ( arguments.length == 1 )
+ return function() {
+ var args = $.makeArray(arguments);
+ args.unshift(source);
+ return $.validator.format.apply( this, args );
+ };
+ if ( arguments.length > 2 && params.constructor != Array ) {
+ params = $.makeArray(arguments).slice(1);
+ }
+ if ( params.constructor != Array ) {
+ params = [ params ];
+ }
+ $.each(params, function(i, n) {
+ source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
+ });
+ return source;
+};
+
+$.extend($.validator, {
+
+ defaults: {
+ messages: {},
+ groups: {},
+ rules: {},
+ errorClass: "error",
+ validClass: "valid",
+ errorElement: "label",
+ focusInvalid: true,
+ errorContainer: $( [] ),
+ errorLabelContainer: $( [] ),
+ onsubmit: true,
+ ignore: ":hidden",
+ ignoreTitle: false,
+ onfocusin: function(element, event) {
+ this.lastActive = element;
+
+ // hide error label and remove error class on focus if enabled
+ if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
+ this.settings.unhighlight && this.settings.unhighlight.call( this,
element, this.settings.errorClass, this.settings.validClass );
+ this.addWrapper(this.errorsFor(element)).hide();
+ }
+ },
+ onfocusout: function(element, event) {
+ if ( !this.checkable(element) && (
element.name in this.submitted |
| !this.optional(element)) ) {
+ this.element(element);
+ }
+ },
+ onkeyup: function(element, event) {
+ if (
element.name in this.submitted || element == this.lastElement ) {
+ this.element(element);
+ }
+ },
+ onclick: function(element, event) {
+ // click on selects, radiobuttons and checkboxes
+ if (
element.name in this.submitted )
+ this.element(element);
+ // or option elements, check parent select in that case
+ else if (
element.parentNode.name in this.submitted)
+ this.element(element.parentNode);
+ },
+ highlight: function(element, errorClass, validClass) {
+ if (element.type === 'radio') {
+
this.findByName(
element.name).addClass(errorClass).removeClass(validClass);
+ } else {
+ $(element).addClass(errorClass).removeClass(validClass);
+ }
+ },
+ unhighlight: function(element, errorClass, validClass) {
+ if (element.type === 'radio') {
+
this.findByName(
element.name).removeClass(errorClass).addClass(validClass);
+ } else {
+ $(element).removeClass(errorClass).addClass(validClass);
+ }
+ }
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
+ setDefaults: function(settings) {
+ $.extend( $.validator.defaults, settings );
+ },
+
+ messages: {
+ required: "This field is required.",
+ remote: "Please fix this field.",
+ email: "Please enter a valid email address.",
+ url: "Please enter a valid URL.",
+ date: "Please enter a valid date.",
+ dateISO: "Please enter a valid date (ISO).",
+ number: "Please enter a valid number.",
+ digits: "Please enter only digits.",
+ creditcard: "Please enter a valid credit card number.",
+ equalTo: "Please enter the same value again.",
+ accept: "Please enter a value with a valid extension.",
+ maxlength: $.validator.format("Please enter no more than {0}
characters."),
+ minlength: $.validator.format("Please enter at least {0} characters."),
+ rangelength: $.validator.format("Please enter a value between {0} and
{1} characters long."),
+ range: $.validator.format("Please enter a value between {0} and {1}."),
+ max: $.validator.format("Please enter a value less than or equal to
{0}."),
+ min: $.validator.format("Please enter a value greater than or equal to
{0}.")
+ },
+
+ autoCreateRanges: false,
+
+ prototype: {
+
+ init: function() {
+ this.labelContainer = $(this.settings.errorLabelContainer);
+ this.errorContext = this.labelContainer.length && this.labelContainer |
| $(this.currentForm);
+ this.containers = $(this.settings.errorContainer).add(
this.settings.errorLabelContainer );
+ this.submitted = {};
+ this.valueCache = {};
+ this.pendingRequest = 0;
+ this.pending = {};
+ this.invalid = {};
+ this.reset();
+
+ var groups = (this.groups = {});
+ $.each(this.settings.groups, function(key, value) {
+ $.each(value.split(/\s/), function(index, name) {
+ groups[name] = key;
+ });
+ });
+ var rules = this.settings.rules;
+ $.each(rules, function(key, value) {
+ rules[key] = $.validator.normalizeRule(value);
+ });
+
+ function delegate(event) {
+ var validator = $.data(this[0].form, "validator"),
+ eventType = "on" + event.type.replace(/^validate/, "");
+ validator.settings[eventType] &&
validator.settings[eventType].call(validator, this[0], event);
+ }
+ $(this.currentForm)
+ .validateDelegate("[type='text'], [type='password'],
[type='file'], select, textarea, " +
+ "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
+ "[type='email'], [type='datetime'], [type='date'], [type='month'], "
+
+ "[type='week'], [type='time'], [type='datetime-local'], " +
+ "[type='range'], [type='color'] ",
+ "focusin focusout keyup", delegate)
+ .validateDelegate("[type='radio'], [type='checkbox'], select,
option", "click", delegate);
+
+ if (this.settings.invalidHandler)
+ $(this.currentForm).bind("invalid-form.validate",
this.settings.invalidHandler);
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Validator/form
+ form: function() {
+ this.checkForm();
+ $.extend(this.submitted, this.errorMap);
+ this.invalid = $.extend({}, this.errorMap);
+ if (!this.valid())
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
+ this.showErrors();
+ return this.valid();
+ },
+
+ checkForm: function() {
+ this.prepareForm();
+ for ( var i = 0, elements = (this.currentElements = this.elements());
elements[i]; i++ ) {
+ this.check( elements[i] );
+ }
+ return this.valid();
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Validator/element
+ element: function( element ) {
+ element = this.validationTargetFor( this.clean( element ) );
+ this.lastElement = element;
+ this.prepareElement( element );
+ this.currentElements = $(element);
+ var result = this.check( element );
+ if ( result ) {
+ delete this.invalid[
element.name];
+ } else {
+ this.invalid[
element.name] = true;
+ }
+ if ( !this.numberOfInvalids() ) {
+ // Hide error containers on last error
+ this.toHide = this.toHide.add( this.containers );
+ }
+ this.showErrors();
+ return result;
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Validator/showErrors
+ showErrors: function(errors) {
+ if(errors) {
+ // add items to error list and map
+ $.extend( this.errorMap, errors );
+ this.errorList = [];
+ for ( var name in errors ) {
+ this.errorList.push({
+ message: errors[name],
+ element: this.findByName(name)[0]
+ });
+ }
+ // remove items from success list
+ this.successList = $.grep( this.successList, function(element) {
+ return !(
element.name in errors);
+ });
+ }
+ this.settings.showErrors
+ ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
+ : this.defaultShowErrors();
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Validator/resetForm
+ resetForm: function() {
+ if ( $.fn.resetForm )
+ $( this.currentForm ).resetForm();
+ this.submitted = {};
+ this.lastElement = null;
+ this.prepareForm();
+ this.hideErrors();
+ this.elements().removeClass( this.settings.errorClass );
+ },
+
+ numberOfInvalids: function() {
+ return this.objectLength(this.invalid);
+ },
+
+ objectLength: function( obj ) {
+ var count = 0;
+ for ( var i in obj )
+ count++;
+ return count;
+ },
+
+ hideErrors: function() {
+ this.addWrapper( this.toHide ).hide();
+ },
+
+ valid: function() {
+ return this.size() == 0;
+ },
+
+ size: function() {
+ return this.errorList.length;
+ },
+
+ focusInvalid: function() {
+ if( this.settings.focusInvalid ) {
+ try {
+ $(this.findLastActive() || this.errorList.length &&
this.errorList[0].element || [])
+ .filter(":visible")
+ .focus()
+ // manually trigger focusin event; without it, focusin handler isn't
called, findLastActive won't have anything to find
+ .trigger("focusin");
+ } catch(e) {
+ // ignore IE throwing errors when focusing hidden elements
+ }
+ }
+ },
+
+ findLastActive: function() {
+ var lastActive = this.lastActive;
+ return lastActive && $.grep(this.errorList, function(n) {
+ return
n.element.name == lastActive.name;
+ }).length == 1 && lastActive;
+ },
+
+ elements: function() {
+ var validator = this,
+ rulesCache = {};
+
+ // select all valid inputs inside the form (no submit or reset buttons)
+ return $(this.currentForm)
+ .find("input, select, textarea")
+ .not(":submit, :reset, :image, [disabled]")
+ .not( this.settings.ignore )
+ .filter(function() {
+ !
this.name && validator.settings.debug && window.console &&
console.error( "%o has no name assigned", this);
+
+ // select only the first element for each name, and only those with
rules specified
+ if (
this.name in rulesCache |
| !validator.objectLength($(this).rules()) )
+ return false;
+
+ rulesCache[
this.name] = true;
+ return true;
+ });
+ },
+
+ clean: function( selector ) {
+ return $( selector )[0];
+ },
+
+ errors: function() {
+ return $( this.settings.errorElement + "." + this.settings.errorClass,
this.errorContext );
+ },
+
+ reset: function() {
+ this.successList = [];
+ this.errorList = [];
+ this.errorMap = {};
+ this.toShow = $([]);
+ this.toHide = $([]);
+ this.currentElements = $([]);
+ },
+
+ prepareForm: function() {
+ this.reset();
+ this.toHide = this.errors().add( this.containers );
+ },
+
+ prepareElement: function( element ) {
+ this.reset();
+ this.toHide = this.errorsFor(element);
+ },
+
+ check: function( element ) {
+ element = this.validationTargetFor( this.clean( element ) );
+
+ var rules = $(element).rules();
+ var dependencyMismatch = false;
+ for (var method in rules ) {
+ var rule = { method: method, parameters: rules[method] };
+ try {
+ var result = $.validator.methods[method].call( this,
element.value.replace(/\r/g, ""), element, rule.parameters );
+
+ // if a method indicates that the field is optional and therefore
valid,
+ // don't mark it as valid when there are no other rules
+ if ( result == "dependency-mismatch" ) {
+ dependencyMismatch = true;
+ continue;
+ }
+ dependencyMismatch = false;
+
+ if ( result == "pending" ) {
+ this.toHide = this.toHide.not( this.errorsFor(element) );
+ return;
+ }
+
+ if( !result ) {
+ this.formatAndAdd( element, rule );
+ return false;
+ }
+ } catch(e) {
+ this.settings.debug && window.console && console.log("exception
occured when checking element " +
element.id
+ + ", check the '" + rule.method + "' method", e);
+ throw e;
+ }
+ }
+ if (dependencyMismatch)
+ return;
+ if ( this.objectLength(rules) )
+ this.successList.push(element);
+ return true;
+ },
+
+ // return the custom message for the given element and validation method
+ // specified in the element's "messages" metadata
+ customMetaMessage: function(element, method) {
+ if (!$.metadata)
+ return;
+
+ var meta = this.settings.meta
+ ? $(element).metadata()[this.settings.meta]
+ : $(element).metadata();
+
+ return meta && meta.messages && meta.messages[method];
+ },
+
+ // return the custom message for the given element name and validation
method
+ customMessage: function( name, method ) {
+ var m = this.settings.messages[name];
+ return m && (m.constructor == String
+ ? m
+ : m[method]);
+ },
+
+ // return the first defined argument, allowing empty strings
+ findDefined: function() {
+ for(var i = 0; i < arguments.length; i++) {
+ if (arguments[i] !== undefined)
+ return arguments[i];
+ }
+ return undefined;
+ },
+
+ defaultMessage: function( element, method) {
+ return this.findDefined(
+ this.customMessage(
element.name, method ),
+ this.customMetaMessage( element, method ),
+ // title is never undefined, so handle empty string as undefined
+ !this.settings.ignoreTitle && element.title || undefined,
+ $.validator.messages[method],
+ "<strong>Warning: No message defined for " +
element.name + "</strong>"
+ );
+ },
+
+ formatAndAdd: function( element, rule ) {
+ var message = this.defaultMessage( element, rule.method ),
+ theregex = /\$?\{(\d+)\}/g;
+ if ( typeof message == "function" ) {
+ message = message.call(this, rule.parameters, element);
+ } else if (theregex.test(message)) {
+ message = jQuery.format(message.replace(theregex, '{$1}'),
rule.parameters);
+ }
+ this.errorList.push({
+ message: message,
+ element: element
+ });
+
+ this.errorMap[
element.name] = message;
+ this.submitted[
element.name] = message;
+ },
+
+ addWrapper: function(toToggle) {
+ if ( this.settings.wrapper )
+ toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
+ return toToggle;
+ },
+
+ defaultShowErrors: function() {
+ for ( var i = 0; this.errorList[i]; i++ ) {
+ var error = this.errorList[i];
+ this.settings.highlight && this.settings.highlight.call( this,
error.element, this.settings.errorClass, this.settings.validClass );
+ this.showLabel( error.element, error.message );
+ }
+ if( this.errorList.length ) {
+ this.toShow = this.toShow.add( this.containers );
+ }
+ if (this.settings.success) {
+ for ( var i = 0; this.successList[i]; i++ ) {
+ this.showLabel( this.successList[i] );
+ }
+ }
+ if (this.settings.unhighlight) {
+ for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
+ this.settings.unhighlight.call( this, elements[i],
this.settings.errorClass, this.settings.validClass );
+ }
+ }
+ this.toHide = this.toHide.not( this.toShow );
+ this.hideErrors();
+ this.addWrapper( this.toShow ).show();
+ },
+
+ validElements: function() {
+ return this.currentElements.not(this.invalidElements());
+ },
+
+ invalidElements: function() {
+ return $(this.errorList).map(function() {
+ return this.element;
+ });
+ },
+
+ showLabel: function(element, message) {
+ var label = this.errorsFor( element );
+ if ( label.length ) {
+ // refresh error/success class
+ label.removeClass( this.settings.validClass ).addClass(
this.settings.errorClass );
+
+ // check if we have a generated label, replace the message then
+ label.attr("generated") && label.html(message);
+ } else {
+ // create label
+ label = $("<" + this.settings.errorElement + "/>")
+ .attr({"for": this.idOrName(element), generated: true})
+ .addClass(this.settings.errorClass)
+ .html(message || "");
+ if ( this.settings.wrapper ) {
+ // make sure the element is visible, even in IE
+ // actually showing the wrapped element is handled elsewhere
+ label = label.hide().show().wrap("<" + this.settings.wrapper
+ "/>").parent();
+ }
+ if ( !this.labelContainer.append(label).length )
+ this.settings.errorPlacement
+ ? this.settings.errorPlacement(label, $(element) )
+ : label.insertAfter(element);
+ }
+ if ( !message && this.settings.success ) {
+ label.text("");
+ typeof this.settings.success == "string"
+ ? label.addClass( this.settings.success )
+ : this.settings.success( label );
+ }
+ this.toShow = this.toShow.add(label);
+ },
+
+ errorsFor: function(element) {
+ var name = this.idOrName(element);
+ return this.errors().filter(function() {
+ return $(this).attr('for') == name;
+ });
+ },
+
+ idOrName: function(element) {
+ return this.groups[
element.name] || (this.checkable(element) ?
element.name :
element.id ||
element.name);
+ },
+
+ validationTargetFor: function(element) {
+ // if radio/checkbox, validate first element in group instead
+ if (this.checkable(element)) {
+ element = this.findByName(
element.name ).not(this.settings.ignore)[0];
+ }
+ return element;
+ },
+
+ checkable: function( element ) {
+ return /radio|checkbox/i.test(element.type);
+ },
+
+ findByName: function( name ) {
+ // select by name and filter by form for performance over
form.find("[name=...]")
+ var form = this.currentForm;
+ return $(document.getElementsByName(name)).map(function(index, element)
{
+ return element.form == form &&
element.name == name && element ||
null;
+ });
+ },
+
+ getLength: function(value, element) {
+ switch( element.nodeName.toLowerCase() ) {
+ case 'select':
+ return $("option:selected", element).length;
+ case 'input':
+ if( this.checkable( element) )
+ return this.findByName(
element.name).filter(':checked').length;
+ }
+ return value.length;
+ },
+
+ depend: function(param, element) {
+ return this.dependTypes[typeof param]
+ ? this.dependTypes[typeof param](param, element)
+ : true;
+ },
+
+ dependTypes: {
+ "boolean": function(param, element) {
+ return param;
+ },
+ "string": function(param, element) {
+ return !!$(param, element.form).length;
+ },
+ "function": function(param, element) {
+ return param(element);
+ }
+ },
+
+ optional: function(element) {
+ return !$.validator.methods.required.call(this, $.trim(element.value),
element) && "dependency-mismatch";
+ },
+
+ startRequest: function(element) {
+ if (!this.pending[
element.name]) {
+ this.pendingRequest++;
+ this.pending[
element.name] = true;
+ }
+ },
+
+ stopRequest: function(element, valid) {
+ this.pendingRequest--;
+ // sometimes synchronization fails, make sure pendingRequest is never <
0
+ if (this.pendingRequest < 0)
+ this.pendingRequest = 0;
+ delete this.pending[
element.name];
+ if ( valid && this.pendingRequest == 0 && this.formSubmitted &&
this.form() ) {
+ $(this.currentForm).submit();
+ this.formSubmitted = false;
+ } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
+ this.formSubmitted = false;
+ }
+ },
+
+ previousValue: function(element) {
+ return $.data(element, "previousValue") ||
$.data(element, "previousValue", {
+ old: null,
+ valid: true,
+ message: this.defaultMessage( element, "remote" )
+ });
+ }
+
+ },
+
+ classRuleSettings: {
+ required: {required: true},
+ email: {email: true},
+ url: {url: true},
+ date: {date: true},
+ dateISO: {dateISO: true},
+ dateDE: {dateDE: true},
+ number: {number: true},
+ numberDE: {numberDE: true},
+ digits: {digits: true},
+ creditcard: {creditcard: true}
+ },
+
+ addClassRules: function(className, rules) {
+ className.constructor == String ?
+ this.classRuleSettings[className] = rules :
+ $.extend(this.classRuleSettings, className);
+ },
+
+ classRules: function(element) {
+ var rules = {};
+ var classes = $(element).attr('class');
+ classes && $.each(classes.split(' '), function() {
+ if (this in $.validator.classRuleSettings) {
+ $.extend(rules, $.validator.classRuleSettings[this]);
+ }
+ });
+ return rules;
+ },
+
+ attributeRules: function(element) {
+ var rules = {};
+ var $element = $(element);
+
+ for (var method in $.validator.methods) {
+ var value;
+ // If .prop exists (jQuery >= 1.6), use it to get true/false for
required
+ if (method === 'required' && typeof $.fn.prop === 'function') {
+ value = $element.prop(method);
+ } else {
+ value = $element.attr(method);
+ }
+ if (value) {
+ rules[method] = value;
+ } else if ($element[0].getAttribute("type") === method) {
+ rules[method] = true;
+ }
+ }
+
+ // maxlength may be returned as -1,
2147483647 (IE) and 524288 (safari)
for text inputs
+ if (rules.maxlength && /-1|
2147483647|524288/.test(rules.maxlength)) {
+ delete rules.maxlength;
+ }
+
+ return rules;
+ },
+
+ metadataRules: function(element) {
+ if (!$.metadata) return {};
+
+ var meta = $.data(element.form, 'validator').settings.meta;
+ return meta ?
+ $(element).metadata()[meta] :
+ $(element).metadata();
+ },
+
+ staticRules: function(element) {
+ var rules = {};
+ var validator = $.data(element.form, 'validator');
+ if (validator.settings.rules) {
+ rules =
$.validator.normalizeRule(validator.settings.rules[
element.name]) || {};
+ }
+ return rules;
+ },
+
+ normalizeRules: function(rules, element) {
+ // handle dependency check
+ $.each(rules, function(prop, val) {
+ // ignore rule when param is explicitly false, eg. required:false
+ if (val === false) {
+ delete rules[prop];
+ return;
+ }
+ if (val.param || val.depends) {
+ var keepRule = true;
+ switch (typeof val.depends) {
+ case "string":
+ keepRule = !!$(val.depends, element.form).length;
+ break;
+ case "function":
+ keepRule = val.depends.call(element, element);
+ break;
+ }
+ if (keepRule) {
+ rules[prop] = val.param !== undefined ? val.param : true;
+ } else {
+ delete rules[prop];
+ }
+ }
+ });
+
+ // evaluate parameters
+ $.each(rules, function(rule, parameter) {
+ rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
+ });
+
+ // clean number parameters
+ $.each(['minlength', 'maxlength', 'min', 'max'], function() {
+ if (rules[this]) {
+ rules[this] = Number(rules[this]);
+ }
+ });
+ $.each(['rangelength', 'range'], function() {
+ if (rules[this]) {
+ rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
+ }
+ });
+
+ if ($.validator.autoCreateRanges) {
+ // auto-create ranges
+ if (rules.min && rules.max) {
+ rules.range = [rules.min, rules.max];
+ delete rules.min;
+ delete rules.max;
+ }
+ if (rules.minlength && rules.maxlength) {
+ rules.rangelength = [rules.minlength, rules.maxlength];
+ delete rules.minlength;
+ delete rules.maxlength;
+ }
+ }
+
+ // To support custom messages in metadata ignore rule methods
titled "messages"
+ if (rules.messages) {
+ delete rules.messages;
+ }
+
+ return rules;
+ },
+
+ // Converts a simple string to a {string: true} rule, e.g., "required" to
{required:true}
+ normalizeRule: function(data) {
+ if( typeof data == "string" ) {
+ var transformed = {};
+ $.each(data.split(/\s/), function() {
+ transformed[this] = true;
+ });
+ data = transformed;
+ }
+ return data;
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Validator/addMethod
+ addMethod: function(name, method, message) {
+ $.validator.methods[name] = method;
+ $.validator.messages[name] = message != undefined ? message :
$.validator.messages[name];
+ if (method.length < 3) {
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
+ }
+ },
+
+ methods: {
+
+ //
http://docs.jquery.com/Plugins/Validation/Methods/required
+ required: function(value, element, param) {
+ // check if dependency is met
+ if ( !this.depend(param, element) )
+ return "dependency-mismatch";
+ switch( element.nodeName.toLowerCase() ) {
+ case 'select':
+ // could be an array for select-multiple or a string, both are fine
this way
+ var val = $(element).val();
+ return val && val.length > 0;
+ case 'input':
+ if ( this.checkable(element) )
+ return this.getLength(value, element) > 0;
+ default:
+ return $.trim(value).length > 0;
+ }
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Methods/remote
+ remote: function(value, element, param) {
+ if ( this.optional(element) )
+ return "dependency-mismatch";
+
+ var previous = this.previousValue(element);
+ if (!this.settings.messages[
element.name] )
+ this.settings.messages[
element.name] = {};
+ previous.originalMessage = this.settings.messages[
element.name].remote;
+ this.settings.messages[
element.name].remote = previous.message;
+
+ param = typeof param == "string" && {url:param} || param;
+
+ if ( this.pending[
element.name] ) {
+ return "pending";
+ }
+ if ( previous.old === value ) {
+ return previous.valid;
+ }
+
+ previous.old = value;
+ var validator = this;
+ this.startRequest(element);
+ var data = {};
+ data[
element.name] = value;
+ $.ajax($.extend(true, {
+ url: param,
+ mode: "abort",
+ port: "validate" +
element.name,
+ dataType: "json",
+ data: data,
+ success: function(response) {
+ validator.settings.messages[
element.name].remote =
previous.originalMessage;
+ var valid = response === true;
+ if ( valid ) {
+ var submitted = validator.formSubmitted;
+ validator.prepareElement(element);
+ validator.formSubmitted = submitted;
+ validator.successList.push(element);
+ validator.showErrors();
+ } else {
+ var errors = {};
+ var message = response || validator.defaultMessage(
element, "remote" );
+ errors[
element.name] = previous.message = $.isFunction(message) ?
message(value) : message;
+ validator.showErrors(errors);
+ }
+ previous.valid = valid;
+ validator.stopRequest(element, valid);
+ }
+ }, param));
+ return "pending";
+ },
+
+ //
http://docs.jquery.com/Plugins/Validation/Methods/minlength
+ minlength: function(value, element, param) {
+ return this.optional(element) || this.getLength($.trim(value), element)
>= param;
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/idb/web/scripts/timelink.validator.js Sat Nov 19 05:10:12 2011
@@ -0,0 +1,99 @@
+//$.validator.setDefaults({
+// submitHandler: function() { return true; }
+//});
+
+$().ready(function() {
+ jQuery.validator.addMethod("noSpace", function(value, element) {
+ return value.indexOf(" ") < 0 && value != "";
+ }, "No space please and don't leave it empty");
+
+ $.validator.addMethod('letters', function(value) {
+ return value.match(/^[- a-z]+$/);
+ });
+
+ // validate signup form on keyup and submit
+ $("#signupForm").validate({
+ rules: {
+ firstname: {
+ required: true,
+ minlength: 1
+ },
+ lastname: {
+ required: true,
+ minlength: 1
+ },
+ username: {
+ required: true,
+ minlength: 5,
+ noSpace: true,
+ letters : true
+ },
+ password: {
+ required: true,
+ minlength: 5
+ },
+ confirm_password: {
+ required: true,
+ minlength: 5,
+ equalTo: "#password"
+ },
+ email: {
+ required: true,
+ email: true
+ },
+ jcaptcha: {
+ required: true
+ },
+ topic: {
+ required: "#newsletter:checked",
+ minlength: 2
+ },
+ terms: "required"
+ },
+ messages: {
+ firstname: "Por favor, indique o seu primeiro nome",
+ lastname: "Por favor, indique o seu último nome",
+ username: {
+ required: "Por favor, indique um nome de utilizador",
+ minlength: "O seu nome de utilizador deve conter no mínimo 5
caracteres, sem acentos e sem espaços",
+ noSpace: "O seu nome de utilizador não deve conter espaços ou outros
caracteres especiais",
+ letters : "O seu nome de utilizador não deve conter espaços,
maiúsculas ou outros caracteres especiais"
+ },
+ password: {
+ required: "Por favor, indique uma senha de acesso",
+ minlength: "A sua senha de acesso deverá conter no mínimo 5 caracteres"
+ },
+ confirm_password: {
+ required: "Por favor, indique uma senha de acesso",
+ minlength: "A sua senha de acesso deverá conter no mínimo 5
caracteres",
+ equalTo: "As senhas indicadas não coincidem."
+ },
+ jcaptcha: {
+ required: "Por favor, preencha com os caracteres da imagem"
+ },
+ email: "Por favor, indique um endereço de email válido",
+ terms: "Por favor, aceite os nossos termos de acesso"
+ }
+ });
+
+ // propose username by combining first- and lastname
+ //$("#username").focus(function() {
+ // var firstname = $("#firstname").val();
+ // var lastname = $("#lastname").val();
+ // if(firstname && lastname && !this.value) {
+ // this.value = firstname + "" + lastname;
+ // }
+ //});
+
+ //code to hide topic selection, disable for demo
+ var newsletter = $("#newsletter");
+ // newsletter topics are optional, hide at first
+ var inital =
newsletter.is(":checked");
+ var topics =
$("#newsletter_topics")[inital ? "removeClass" : "addClass"]("gray");
+ var topicInputs = topics.find("input").attr("disabled", !inital);
+ // show when newsletter is checked
+ newsletter.click(function() {
+ topics[this.checked ? "removeClass" : "addClass"]("gray");
+ topicInputs.attr("disabled", !this.checked);
+ });
+});
=======================================
--- /trunk/.classpath Tue Jan 11 04:07:31 2011
+++ /trunk/.classpath Sat Nov 19 05:10:12 2011
@@ -24,6 +24,15 @@
<classpathentry kind="lib" path="idb/lib/velocity-dep-1.4.jar"/>
<classpathentry kind="lib" path="idb/lib/xercesImpl.jar"/>
<classpathentry kind="lib" path="idb/lib/xml-apis.jar"/>
+ <classpathentry kind="lib" path="idb/lib/mail-1.4.2.jar"/>
+ <classpathentry kind="lib" path="idb/lib/simplecaptcha-1.2-jdk1.5.jar"/>
+ <classpathentry kind="lib" path="idb/lib/commons-collections-3.2.1.jar"/>
+ <classpathentry kind="lib" path="idb/lib/commons-logging-1.1.1.jar"/>
+ <classpathentry kind="lib" path="idb/lib/jcaptcha-1.0-all.jar"/>
+ <classpathentry kind="lib" path="idb/lib/jcaptcha-api-1.0.jar"/>
+ <classpathentry kind="lib"
path="idb/lib/jcaptcha-integration-simple-servlet-2.0-alpha-1-SNAPSHOT.jar"/>
+ <classpathentry kind="lib" path="idb/lib/jcaptcha-all-1.0-RC3.jar"/>
+ <classpathentry kind="lib" path="idb/lib/owasp-captcha.jar"/>
<classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
=======================================
--- /trunk/.settings/org.eclipse.core.resources.prefs Fri Sep 17 02:28:32
2010
+++ /trunk/.settings/org.eclipse.core.resources.prefs Sat Nov 19 05:10:12
2011
@@ -1,4 +1,9 @@
-#Fri Sep 17 09:55:57 WEST 2010
+#Sat Nov 19 12:27:53 WET 2011
eclipse.preferences.version=1
encoding//idb/etc/template/new/login.vm=UTF8
+encoding//idb/etc/template/new/signup.vm=ISO-8859-1
+encoding//idb/etc/template/new/signup_missingfields.vm=ISO-8859-1
encoding//idb/pt/uc/cisuc/jrc/mhk/rch/DBClass.java=UTF-8
+encoding//idb/pt/uc/cisuc/jrc/mhk/servlet/DoInsertUser.java=UTF-8
+encoding//idb/web/scripts/timelink.validator.js=ISO-8859-1
+encoding//idb/web/scripts/validate.js=ISO-8859-1
=======================================
--- /trunk/idb/.upload_information Fri Aug 5 10:46:40 2011
+++ /trunk/idb/.upload_information Sat Nov 19 05:10:12 2011
@@ -1,6 +1,6 @@
-#Fri, 05 Aug 2011 15:04:24 +0100
+#Sat, 19 Nov 2011 13:03:45 +0000
#Wed Jul 20 15:48:09 WEST 2011
-build.number=499
+build.number=815
upload.number=89
09=
-prepare.time=05/08/2011 03\:04
+prepare.time=19/11/2011 01\:03
=======================================
--- /trunk/idb/build.number Fri Aug 5 10:46:40 2011
+++ /trunk/idb/build.number Sat Nov 19 05:10:12 2011
@@ -1,4 +1,4 @@
#Build Number for ANT. Do not edit!
-#Fri Aug 05 15:04:24 WEST 2011
-build.number=500
+#Sat Nov 19 13:03:45 WET 2011
+build.number=816
33=
=======================================
--- /trunk/idb/build_joao_mac.xml Fri Aug 5 10:46:40 2011
+++ /trunk/idb/build_joao_mac.xml Sat Nov 19 05:10:12 2011
@@ -130,14 +130,14 @@
<target name="compile" depends="prepare">
<javac srcdir="." destdir="${deploy.home}/WEB-INF/classes"
target="1.5" source="1.5"
-
classpath="${deploy.home}/WEB-INF/lib/baf.jar:${deploy.home}/WEB-INF/lib/jdom.jar:${deploy.home}/WEB-INF/lib/log4j-1.2.15.jar:${deploy.home}/WEB-INF/lib/dom4j-1.5-beta-2.jar:${deploy.home}/WEB-INF/classes:${deploy.home}/WEB-INF/lib/lucene-1.4-final.jar:${deploy.home}/WEB-INF/lib/xerces.jar:${deploy.home}/WEB-INF/lib/velocity-dep-1.4.jar:${servlet.jar}:${junit.jar}:${deploy.home}/WEB-INF/lib/commons-fileupload-1.0.jar:${deploy.home}/WEB-INF/lib/antisamy-bin.1.3.jar:${deploy.home}/WEB-INF/lib/nekohtml.jar:${deploy.home}/WEB-INF/lib/gedcom.jar:${deploy.home}/WEB-INF/lib/gedcom4j.jar"
+
classpath="${deploy.home}/WEB-INF/lib/baf.jar:${deploy.home}/WEB-INF/lib/jdom.jar:${deploy.home}/WEB-INF/lib/log4j-1.2.15.jar:${deploy.home}/WEB-INF/lib/dom4j-1.5-beta-2.jar:${deploy.home}/WEB-INF/classes:${deploy.home}/WEB-INF/lib/lucene-1.4-final.jar:${deploy.home}/WEB-INF/lib/xerces.jar:${deploy.home}/WEB-INF/lib/velocity-dep-1.4.jar:${servlet.jar}:${junit.jar}:${deploy.home}/WEB-INF/lib/commons-fileupload-1.0.jar:${deploy.home}/WEB-INF/lib/antisamy-bin.1.3.jar:${deploy.home}/WEB-INF/lib/nekohtml.jar:${deploy.home}/WEB-INF/lib/gedcom.jar:${deploy.home}/WEB-INF/lib/gedcom4j.jar:${deploy.home}/WEB-INF/lib/mail-1.4.2.jar:${deploy.home}/WEB-INF/lib/jcaptcha-all-1.0-RC3.jar:${deploy.home}/WEB-INF/lib/commons-collections-3.2.1.jar:${deploy.home}/WEB-INF/lib/owasp-captcha.jar"
debug="on" optimize="off" deprecation="off"/>
</target>
<target name="javadoc" depends="prepare">
<javadoc sourcepath="." packagenames="pt.*"
-
classpath="${deploy.home}/WEB-INF/lib/baf.jar:${deploy.home}/WEB-INF/lib/jdom.jar:${deploy.home}/WEB-INF/lib/log4j-1.2.15.jar:${deploy.home}/WEB-INF/lib/dom4j-1.5-beta-2.jar:${deploy.home}/WEB-INF/classes:${deploy.home}/WEB-INF/lib/lucene-1.4-final.jar:${deploy.home}/WEB-INF/lib/xerces.jar:${deploy.home}/WEB-INF/lib/velocity-dep-1.4.jar:${servlet.jar}:${junit.jar}:${deploy.home}/WEB-INF/lib/commons-fileupload-1.0.jar"
+
classpath="${deploy.home}/WEB-INF/lib/baf.jar:${deploy.home}/WEB-INF/lib/jdom.jar:${deploy.home}/WEB-INF/lib/log4j-1.2.15.jar:${deploy.home}/WEB-INF/lib/dom4j-1.5-beta-2.jar:${deploy.home}/WEB-INF/classes:${deploy.home}/WEB-INF/lib/lucene-1.4-final.jar:${deploy.home}/WEB-INF/lib/xerces.jar:${deploy.home}/WEB-INF/lib/velocity-dep-1.4.jar:${servlet.jar}:${junit.jar}:${deploy.home}/WEB-INF/lib/commons-fileupload-1.0.jar:${deploy.home}/WEB-INF/lib/jcaptcha-all-1.0-RC3.jar:${deploy.home}/WEB-INF/lib/commons-collections-3.2.1.jar:${deploy.home}/WEB-INF/lib/owasp-captcha.jar"
destdir="${javadoc.home}"/>
</target>
=======================================
--- /trunk/idb/etc/template/new/advanced_search_show.vm Fri Oct 23 10:18:37
2009
+++ /trunk/idb/etc/template/new/advanced_search_show.vm Sat Nov 19 05:10:12
2011
@@ -41,7 +41,7 @@
## Attributes query
#set($attribute_sql="SELECT ")
-#set($attribute_sql="$attribute_sql a.entity,a.the_date")
+#set($attribute_sql="$attribute_sql a.entity,a.the_date, a.obs")
#set($attribute_sql="$attribute_sql ,a.the_type as atype,a.the_value as
avalue")
#if($searchAttr2.equals("")) #else
#set($attribute_sql="$attribute_sql ,b.the_type as btype,b.the_value as
bvalue") #end
#if($searchAttr3.equals("")) #else
#set($attribute_sql="$attribute_sql ,c.the_type as ctype,c.the_value as
cvalue") #end
=======================================
--- /trunk/idb/etc/template/new/header.vm Tue Jul 13 08:37:20 2010
+++ /trunk/idb/etc/template/new/header.vm Sat Nov 19 05:10:12 2011
@@ -45,7 +45,8 @@
<div id="nav">
<ul>
#if($level)
- <li><A
HREF=$resp.encodeURL("${uri}?action=login.vm")>$mhks.get("login")</a></li>
+ ##<li><A
HREF=$resp.encodeURL("${uri}?action=login.vm")>$mhks.get("login")</a></li>
+ <li><A HREF="${uri}?action=login.vm">$mhks.get("login")</a></li>
#end
#if($level)
<li><A
HREF=$resp.encodeURL("${uri}?dbname=$!dbname&action=exec&script=search.vm")
title='$mhks.get("searchDatabase")'>$mhks.get("search")</a></li>
=======================================
--- /trunk/idb/etc/template/new/login.vm Fri Sep 17 02:28:32 2010
+++ /trunk/idb/etc/template/new/login.vm Sat Nov 19 05:10:12 2011
@@ -28,12 +28,18 @@
<body>
#parse("new/header.vm")
<div id="main">
-
+
####
## Login page changes if online or offline. First online version.
####
#if($online.equals("yes"))
<div class="wrapper">
+
+ #if($validatesuccess)
+ <div id="center_dialog">
+ <h2 class="success"
style="color:green;"><b>$req.getParameter("username")</b>,
<small>$mhks.get("email.validated2")</small></h2>
+ </div>
+ #end
<div class="left_box">
<h3 class="separator">$mhks.get("welcome")</h3>
=======================================
--- /trunk/idb/etc/template/new/signup.vm Mon Mar 8 13:46:37 2010
+++ /trunk/idb/etc/template/new/signup.vm Sat Nov 19 05:10:12 2011
@@ -2,11 +2,27 @@
## This template handles the user registration
## The user data is sent by email
##
+$resp.setContentType("text/html; charset=iso-8859-1")
#set ( $title = "Pedido de registo de conta de utilizador")
#parse("new/head.vm")
+##<link rel="stylesheet" href="${baseaddr}/stylesheets/validate_style.css"
type="text/css" media="screen" />
+
+<script type="text/javascript"
src="${baseaddr}/scripts/jquery.validate.js" charset="iso-8859-1"></script>
+<script type="text/javascript"
src="${baseaddr}/scripts/timelink.validator.js"
charset="iso-8859-1"></script>
+
+<style type="text/css">
+#signupForm label.error {
+ margin-left: 0px;
+ width: auto;
+ float:right;
+}
+
+</style>
+
+
</head>
<body>
@@ -17,36 +33,41 @@
<h3 class="separator">Pedido de registo de conta de utilizador</h3>
<div id="center_dialog">
-
- <form method="POST" action="${baseaddr}/servlet/do">
-
+
+ <form method="POST" id="signupForm" action="${baseaddr}/servlet/do">
+
<INPUT TYPE="HIDDEN" NAME="action" value="insertuser">
-
-
+
<table class="register">
<tr>
- <td align="right">Primeiro(s) Nome(s) *</td><td><input type="text"
name="firstname" size="30"></td>
+ <td align="right">Primeiro(s) Nome(s) *</td><td><input type="text"
name="firstname" id="firstname" size="30"></td>
</tr>
<tr>
- <td align="right">Último(s) Nome(s) *</td><td><input type="text"
name="lastname" size="30"></td>
+ <td align="right">Último(s) Nome(s) *</td><td><input type="text"
name="lastname" id="lastname" size="30"></td>
</tr>
<tr>
- <td align="right">Correio Electrónico *</td><td><input type="text"
name="email" size="30"></td>
+ <td align="right">Nome de Utilizador * <p
style="color:red;padding:0px;margin:0px"> Não utilize espaços, acentos ou
outros caracteres especiais</td><td><input type="text" name="username"
id="username" size="30"></td>
</tr>
<tr>
- <td align="right">Nome de Utilizador * <br> Não utilize espaços, acentos
ou outros caracteres especiais</td><td><input type="text" name="username"
size="30"></td>
+ <td align="right">Correio Electrónico *</td><td><input type="text"
name="email" id="email" size="30"></td>
</tr>
<tr>
- <td align="right">Senha de Acesso*</td><td><input type="text"
name="password" size="30"></td>
+ <td align="right">Senha de Acesso*</td><td><input type="password"
id="password" name="password" size="30"></td>
</tr>
<tr>
- <td colspan="2"><p><input type="checkbox" name="terms" value="1"> Aceito
os <A HREF="${baseaddr}/servlet/do?action=terms_conditions.vm">Termos e
Condições</a> *</td>
+ <td align="right">Confirme a senha de acesso*</td><td><input
type="password" id="confirm_password" name="confirm_password"
size="30"></td>
+ </tr>
+ <tr>
+ <td colspan="2"><p><input type="checkbox" name="terms" id="terms"
value="1"> Aceito os <A
HREF="${baseaddr}/servlet/do?action=terms_conditions.vm">Termos e
Condições</a> *</td>
</tr>
<tr>
<td colspan="2"><p><input type="checkbox" name="notify" value="1">Podem
enviar-me mensagens sobre novas funcionalidades.</td>
</tr>
<tr>
- <td align="right"></td><td> <INPUT class="button" title="" TYPE="SUBMIT"
name="insertuser" VALUE='Registar-me'/>
+ <td colspan="2" style="top;"><p>Por favor, introduza os seguintes
caracteres. <br><img src="/mhk/servlet/jcaptcha" /> <input type="text"
id="jcaptcha" name="jcaptcha" value="" /></td>
+ </tr>
+ <tr>
+ <td align="right"></td><td> <input class="button" title="" TYPE="SUBMIT"
name="insertuser" VALUE='Registar-me'/>
</td>
</tr>
</table>
@@ -57,5 +78,7 @@
</div>
#parse("new/footer.vm")
+
+## <script type="text/javascript"
src="${baseaddr}/scripts/jquery.validate.js" charset="utf-8"></script>
</body>
</html>
=======================================
--- /trunk/idb/etc/template/new/signup_missingfields.vm Mon Mar 8 13:46:37
2010
+++ /trunk/idb/etc/template/new/signup_missingfields.vm Sat Nov 19 05:10:12
2011
@@ -17,7 +17,14 @@
<div id="center_dialog">
-<p>Não preencheu correctamente todos os campos. Os campos marcados com
asterisco (*) são de preenchimento obrigatório. Por favor tente de novo.
+#if($req.getSession().getAttribute("error").equals("captcha"))
+<p>Não preencheu correctamente a expressão de controlo.
+<center><A
HREF="$resp.encodeURL("${uri}?action=signup.vm")">$mhks.get("welcome.register.again")</a></center>
+#else
+<p>Não preencheu correctamente todos os campos. Os campos marcados com
asterisco (*) são de preenchimento obrigatório. Por favor tente de novo:
+<center><A
HREF="$resp.encodeURL("${uri}?action=signup.vm")">$mhks.get("welcome.register.here")</a></center>
+
+#end
</div>
=======================================
--- /trunk/idb/etc/template/new/signup_success.vm Thu Mar 19 04:30:31 2009
+++ /trunk/idb/etc/template/new/signup_success.vm Sat Nov 19 05:10:12 2011
@@ -18,7 +18,10 @@
<div id="center_dialog">
<p><b>O seu pedido de registo foi efectuado com sucesso. </b>
-<p>Por favor aguarde uma mensagem de confirmação no seu
endereço de correio electrónico. A criação de
um acesso não é imediata e pode demorar alguns dias.
+<p>Por favor aguarde uma mensagem de confirmação no seu
endereço de correio electrónico.
+<p>Em caso de dificuldades agradecemos o contacto para
mhk.ti...@gmail.com.
+
+##A criação de um acesso não é imediata e pode
demorar alguns dias.
</div>
=======================================
--- /trunk/idb/etc/web.xml Tue Oct 13 07:04:02 2009
+++ /trunk/idb/etc/web.xml Sat Nov 19 05:10:12 2011
@@ -12,7 +12,7 @@
-->
<load-on-startup>1</load-on-startup>
</servlet>
-
+
<!-- Definition of urlrewrite in order to allow url mapping-->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
@@ -26,6 +26,15 @@
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
+
+ <servlet>
+ <servlet-name>jcaptcha</servlet-name>
+
<servlet-class>org.owasp.captcha.SimpleCaptchaServlet</servlet-class>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>jcaptcha</servlet-name>
+ <url-pattern>/servlet/jcaptcha</url-pattern>
+ </servlet-mapping>
<servlet-mapping>
<servlet-name>do</servlet-name>
=======================================
--- /trunk/idb/pt/uc/cisuc/jrc/mhk/rch/DBSystem.java Thu Jan 6 14:18:46
2011
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/rch/DBSystem.java Sat Nov 19 05:10:12
2011
@@ -2518,7 +2518,10 @@
public String format(String message, ArrayList arguments) {
return MessageFormat.format(message, arguments.toArray());
}
-
+
+ public String stringFormat(String message, String number) {
+ return String.format(message, Double.valueOf(number));
+ }
/**
* Do a search and return the result as a Vector of Hashtables
with each Hashtable representing a row of results.
=======================================
--- /trunk/idb/pt/uc/cisuc/jrc/mhk/rch/DBUser.java Thu Jan 6 14:18:46 2011
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/rch/DBUser.java Sat Nov 19 05:10:12 2011
@@ -5,6 +5,8 @@
import java.text.ParseException;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Random;
+import java.util.UUID;
import java.util.Vector;
import java.io.IOException;
@@ -17,7 +19,9 @@
private DBSystem dbsystem = null;
Logger log = Logger.getLogger("pt.uc.cisuc.jrc.mhk.rch.DBUser");
-
+
+ private String username = null;
+
public DBUser(DBSystem db) {
this.dbsystem = db;
}
@@ -63,19 +67,21 @@
public boolean insertUser(String firstname, String lastname, String
email,
String username,String password,String notify,String terms)
throws SQLException, Exception {
-
+ this.username = username;
+
Connection conn = this.dbsystem.getUsersConn();
/*
* Add user to database
*/
String sql = "INSERT INTO users (username, password, firstname," +
- "lastname, email, notify, registered) VALUES (?,?,?,?,?,?,NOW())";
+ "lastname, email, notify, code, registered) VALUES
(?,?,?,?,?,?,?,NOW())";
PreparedStatement ps = conn.prepareStatement(sql);
if (notify == null)
notify = "0";
+ UUID randomId = UUID.randomUUID();
try {
ps.setString(1, username);
ps.setString(2, password);
@@ -83,7 +89,8 @@
ps.setString(4, lastname);
ps.setString(5, email);
ps.setString(6, notify);
-
+ ps.setString(7, String.valueOf(randomId));
+
ps.executeUpdate();
ps.close();
conn.commit();
@@ -91,7 +98,7 @@
log.info("[DBuser] ----------------------> user inserted");
// Save properties to text file
- this.SaveTextFile();
+ //this.SaveTextFile();
} catch (SQLException e) {
ps.close();
@@ -102,6 +109,68 @@
}
return true;
}
+
+ public String getUniqueID() {
+ String code = null;
+
+ Connection conn = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+
+ conn = this.dbsystem.getUsersConn();
+
+ try {
+ //Select data
+ stmt = conn.createStatement();
+ String sql = "SELECT code FROM users WHERE username='"+username+"'";
+ rs = stmt.executeQuery(sql);
+
+ while(rs.next()){
+ code = rs.getString("code");
+ }
+ } catch (SQLException e) {
+
+ } finally{
+ dbsystem.closeConn();
+ }
+
+ return code;
+ }
+
+ public boolean validate(String code, String username) throws SQLException
{
+
log.info("Validating " + username + " with code " + code);
+
+ this.username = username;
+
+ if(this.getUniqueID().equalsIgnoreCase(code)) {
+ PreparedStatement p;
+
+ String sqlText = "UPDATE users set active='1' WHERE
username='"+username+"'";
+
+ Connection conn = this.dbsystem.getUsersConn();
+ p = conn.prepareStatement(sqlText);
+
+ try {
+
+ p.executeUpdate();
+ p.close();
+ conn.commit();
+
+ } catch (SQLException e) {
+ p.close();
+
+ conn.rollback();
+ throw(e);
+
+ } finally{
+ dbsystem.closeConn(conn);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
/*
* Insert User comments on database
=======================================
--- /trunk/idb/pt/uc/cisuc/jrc/mhk/resources/MHKStrings.properties Wed Jul
20 13:22:49 2011
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/resources/MHKStrings.properties Sat Nov
19 05:10:12 2011
Binary file, no diff available.
=======================================
--- /trunk/idb/pt/uc/cisuc/jrc/mhk/resources/MHKStrings_pt.properties Wed
Jul 20 13:22:49 2011
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/resources/MHKStrings_pt.properties Sat
Nov 19 05:10:12 2011
Binary file, no diff available.
=======================================
--- /trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/CentralServlet.java Wed Jul 20
13:22:49 2011
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/CentralServlet.java Sat Nov 19
05:10:12 2011
@@ -1247,6 +1247,9 @@
} else if (name.equalsIgnoreCase("insertuser") && level > 2) {
c = new DoInsertUser(appcontext, req, resp);
template = c.exec(context);
+ } else if (name.equalsIgnoreCase("validateuser") && level > 2) {
+ c = new DoValidateUser(appcontext, req, resp);
+ template = c.exec(context);
} else if (name.equalsIgnoreCase("geoentity") && level > 2) {
c = new DoGeoentity(appcontext, req, resp);
template = c.exec(context);
=======================================
--- /trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoInsertUser.java Mon Nov 29
10:12:47 2010
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoInsertUser.java Sat Nov 19
05:10:12 2011
@@ -1,80 +1,183 @@
package pt.uc.cisuc.jrc.mhk.servlet;
-
-import org.apache.velocity.context.Context;
-import pt.uc.cisuc.jrc.mhk.rch.DBSystem;
-import pt.uc.cisuc.jrc.mhk.rch.DBUser;
-import pt.uc.cisuc.jrc.mhk.servlet.Command;
-
+import java.io.File;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+
+import javax.mail.Message.RecipientType;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.io.*;
-
-import org.owasp.validator.html.*;
-import org.cyberneko.html.parsers.DOMParser;
import org.apache.log4j.Logger;
-
+import org.apache.velocity.context.Context;
+import org.owasp.validator.html.AntiSamy;
+import org.owasp.validator.html.CleanResults;
+import org.owasp.validator.html.Policy;
+
+import pt.uc.cisuc.jrc.mhk.rch.DBSystem;
+import pt.uc.cisuc.jrc.mhk.rch.DBUser;
+
+import com.octo.captcha.service.CaptchaServiceException;
public class DoInsertUser extends Command {
-Logger log = Logger.getLogger("idb.pt.uc.cisuc.jrc.mhk.rch.DBSystem");
-
-public DoInsertUser ( ServletContext con, HttpServletRequest req,
HttpServletResponse resp ){
- super(con, req, resp );
-}
-
-public String exec(Context ctx) {
-
- DBSystem db = (DBSystem) ctx.get("db");
- String contextName = context.getRealPath("/");
- File tomcatDir = new File(contextName);
- File f = new File(tomcatDir + "/WEB-INF/lib/antisamy-slashdot-1.3.xml");
-
- String firstname = request.getParameter("firstname");
- String lastname = request.getParameter("lastname");
- String email = request.getParameter("email");
- String username = request.getParameter("username");
- String password = request.getParameter("password");
- String notify = request.getParameter("notify");
- String terms = request.getParameter("terms");
-
- try {
- AntiSamy as = new AntiSamy();
-
- CleanResults firstnamecr = as.scan(firstname, Policy.getInstance(f));
- CleanResults lastnamecr = as.scan(lastname, Policy.getInstance(f));
- CleanResults emailcr = as.scan(email, Policy.getInstance(f));
- CleanResults usernamecr = as.scan(username, Policy.getInstance(f));
- CleanResults passwordcr = as.scan(password, Policy.getInstance(f));
-
- DBUser dbuser = new DBUser(db);
-
- if (firstname.equals("") || lastname.equals("") || username.equals("")
- || password.equals("") || email.equals("") || terms.equals("") ) {
- return "signup_missingfields.vm";
- } else {
- dbuser.insertUser(firstnamecr.getCleanHTML(),
lastnamecr.getCleanHTML(),emailcr.getCleanHTML(),usernamecr.getCleanHTML(),passwordcr.getCleanHTML(),notify,terms);
-
//dbuser.insertUser(id,entity_id,database,titlecr.getCleanHTML(),textcr.getCleanHTML());
- }
-
- } catch (Exception e) {
- String errormessage = e.getMessage();
- StringTokenizer st = new StringTokenizer(errormessage);
- while (st.hasMoreTokens()) {
- if (st.nextToken().equals("Duplicate")){
- return "signup_userexists.vm";
- } else {
- System.out.println("[DoInsertUser] error while processing
user "+e.getMessage());
- return "signup_missingfields.vm";
- }
-
- }
-
- }
- return "signup_success.vm";
-}
-
-}
+ Logger log = Logger.getLogger("idb.pt.uc.cisuc.jrc.mhk.rch.DBSystem");
+
+ public DoInsertUser(ServletContext con, HttpServletRequest req,
+ HttpServletResponse resp) {
+ super(con, req, resp);
+ }
+
+ public String exec(Context ctx) {
+ String userCaptchaResponse = request.getParameter("jcaptcha");
+ String sessId = request.getSession().getId();
+
+ boolean passedCaptchaTest = validateCaptcha( sessId, userCaptchaResponse
);
+
+ DBSystem db = (DBSystem) ctx.get("db");
+ String contextName = context.getRealPath("/");
+ File tomcatDir = new File(contextName);
+ File f = new File(tomcatDir + "/WEB-INF/lib/antisamy-slashdot-1.3.xml");
+
+ String firstname = request.getParameter("firstname");
+ String lastname = request.getParameter("lastname");
+ String email = request.getParameter("email");
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+ String notify = request.getParameter("notify");
+ String terms = request.getParameter("terms");
+
+ try {
+ AntiSamy as = new AntiSamy();
+
+ CleanResults firstnamecr = as
+ .scan(firstname, Policy.getInstance(f));
+ CleanResults lastnamecr = as.scan(lastname, Policy.getInstance(f));
+ CleanResults emailcr = as.scan(email, Policy.getInstance(f));
+ CleanResults usernamecr = as.scan(username, Policy.getInstance(f));
+ CleanResults passwordcr = as.scan(password, Policy.getInstance(f));
+
+ DBUser dbuser = new DBUser(db);
+
+ if (firstname.equals("") || lastname.equals("")
+ || username.equals("") || password.equals("")
+ || email.equals("") || terms.equals("")) {
+ return "signup_missingfields.vm";
+ } else {
+ // check captcha
+ if(passedCaptchaTest){
+ // proceed!
+ }else{
+ request.getSession().setAttribute("error", "captcha");
+ return "signup_missingfields.vm";
+ }
+
+ dbuser.insertUser(firstnamecr.getCleanHTML(),
+ lastnamecr.getCleanHTML(), emailcr.getCleanHTML(),
+ usernamecr.getCleanHTML(), passwordcr.getCleanHTML(),
+ notify, terms);
+ //
dbuser.insertUser(id,entity_id,database,titlecr.getCleanHTML(),textcr.getCleanHTML());
+
+ // get generated string from database
+ // and send email message with link
+ sendEmailMessage(context, dbuser.getUniqueID(), username,
emailcr.getCleanHTML());
+ }
+
+ } catch (Exception e) {
+ String errormessage = e.getMessage();
+ StringTokenizer st = new StringTokenizer(errormessage);
+ while (st.hasMoreTokens()) {
+ if (st.nextToken().equals("Duplicate")) {
+ return "signup_userexists.vm";
+ } else {
+ System.out
+ .println("[DoInsertUser] error while processing user "
+ + e.getMessage());
+ return "signup_missingfields.vm";
+ }
+
+ }
+
+ }
+ return "signup_success.vm";
+ }
+
+ private void sendEmailMessage(ServletContext ctx, String value, String
username, String emailTo) {
+
log.info("Sending email message for user " + emailTo);
+
+ String to = emailTo;
+ String host = (String) ctx.getAttribute("mhk.mail.smtp.host");
+ String from = (String) ctx.getAttribute("mhk.mail.smtp.user");
+ String pass = (String) ctx.getAttribute("mhk.mail.smtp.password");
+ String port = (String) ctx.getAttribute("mhk.mail.smtp.port");
+
+ Properties props = new Properties();
+ props.put("mail.smtp.host", host);
+ props.put("mail.smtp.port", port);
+
+ props.put("mail.smtp.starttls.enable", "true");
+ props.put("mail.smtp.user", from);
+ props.put("mail.smtp.password", pass);
+ props.put("mail.smtp.auth", "true");
+
+ Session mailSession = Session.getDefaultInstance(props);
+ //Message simpleMessage = new MimeMessage(mailSession);
+ MimeMessage simpleMessage = new MimeMessage(mailSession);
+
+ InternetAddress fromAddress = null;
+ InternetAddress toAddress = null;
+ try {
+ fromAddress = new InternetAddress(from);
+ toAddress = new InternetAddress(to);
+ } catch (AddressException e) {
+ e.printStackTrace();
+ }
+
+ ResourceBundle mhkStrings =
ResourceBundle.getBundle("pt.uc.cisuc.jrc.mhk.resources.MHKStrings",
request.getLocale());
+
+ String confirmUrl
= "
http://timelink.fl.uc.pt/mhk/servlet/do?action=validateuser&username=" +
username + "&code=" + value +"";
+ String messageText = mhkStrings.getString("email.line1");
+ messageText = messageText + "<p><a
href='"+confirmUrl+"'>"+confirmUrl+"</a>";
+ messageText = messageText + mhkStrings.getString("email.line3");
+
+ try {
+ //simpleMessage.setHeader("Content-Type","text/html");
+ //simpleMessage.setFrom(fromAddress);
+ //simpleMessage.setRecipient(RecipientType.TO, toAddress);
+ //simpleMessage.setSubject("Bem-vindo(a) ao Time Link");
+ //simpleMessage.setText(messageText);
+
+ simpleMessage.setFrom(fromAddress);
+ simpleMessage.addRecipient(RecipientType.TO, toAddress);
+ simpleMessage.setSubject(mhkStrings.getString("email.subject"));
+ simpleMessage.setContent("<html><body>" + messageText
+"</body></html>", "text/html");
+
+ Transport transport = mailSession.getTransport("smtp");
+ transport.connect(host, from, pass);
+ transport.sendMessage(simpleMessage,
simpleMessage.getAllRecipients());
+ transport.close();
+
+ } catch (MessagingException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private boolean validateCaptcha(String captchaId, String inputChars)
+ {
+ boolean bValidated = false;
+ try
+ {
+ bValidated =
org.owasp.captcha.MyCaptchaService.getInstance().validateResponseForID(
captchaId, inputChars );
+ }
+ catch( CaptchaServiceException cse )
+ {}
+ return bValidated;
+ }
+}
=======================================
--- /trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoLogin.java Thu Jan 6 14:18:46
2011
+++ /trunk/idb/pt/uc/cisuc/jrc/mhk/servlet/DoLogin.java Sat Nov 19 05:10:12
2011
@@ -23,6 +23,9 @@
"password". If it does stores "username" in session attribute "userID".
Custom velocity templates can be defined on the login form and passed
trough "template" parameter .
+Also tries to get user and password from mhk_users database. If
dbuser.shouldLogin() returns true
+user properties will be loaded from users database instead.
+
*/
public class DoLogin extends Command {
@@ -150,7 +153,7 @@
} else {
return "error_page.vm";
}
- }
+ }
if (!password.equals(pwd)) {
ctx.put("error","system.bad.password");
=======================================
--- /trunk/idb/web/stylesheets/main.css Thu Dec 9 11:46:12 2010
+++ /trunk/idb/web/stylesheets/main.css Sat Nov 19 05:10:12 2011
@@ -22,6 +22,13 @@
body p {
font: 12px/24px "Helvetica", Sans-Serif;
}
+
+#signupform .error {
+ padding: 3px;
+ color: #fff;
+ font: 1em serif;
+ background: #FF0000;
+}
#wrap {
background:#fff;
@@ -490,6 +497,7 @@
border: 0px solid #ccc;
background: #fff;
}
+
.error {
padding: 3px;
color: #fff;