entropy check code in web2py.js, thanks Niphlod

This commit is contained in:
mdipierro
2012-09-23 14:07:50 -05:00
parent 4d6598c645
commit 69a2e76c3c
6 changed files with 142 additions and 135 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.0.9 (2012-09-22 11:19:10) stable
Version 2.0.9 (2012-09-23 14:07:45) stable
+43 -13
View File
@@ -39,7 +39,7 @@ function web2py_ajax_init(target) {
function web2py_event_handlers() {
var doc = jQuery(document)
doc.on('click', '.flash', function(e){jQuery(this).fadeOut('slow'); e.preventDefault();});
doc.on('click', '.flash', function(e){var t=jQuery(this); if(t.css('top')=='0px') t.slideUp('slow'); else t.fadeOut(); e.preventDefault();});
doc.on('keyup', 'input.integer', function(){this.value=this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g,'').reverse();});
doc.on('keyup', 'input.double, input.decimal', function(){this.value=this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g,'').reverse();});
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
@@ -55,7 +55,7 @@ function web2py_event_handlers() {
jQuery(function() {
var flash = jQuery('.flash');
flash.hide();
if(flash.html()) flash.slideDown();
if(flash.html()) flash.append('<span style="float:right;">&times;</span>').slideDown();
web2py_ajax_init(document);
web2py_event_handlers();
});
@@ -67,20 +67,20 @@ function web2py_trap_form(action,target) {
form.submit(function(e){
jQuery('.flash').hide().html('');
web2py_ajax_page('post',action,form.serialize(),target);
e.preventDefault();
e.preventDefault();
});
});
}
function web2py_trap_link(target) {
jQuery('#'+target+' a.w2p_trap').each(function(i){
var link=jQuery(this);
link.click(function(e) {
jQuery('.flash').hide().html('');
web2py_ajax_page('get',link.attr('href'),[],target);
e.preventDefault();
});
});
var link=jQuery(this);
link.click(function(e) {
jQuery('.flash').hide().html('');
web2py_ajax_page('get',link.attr('href'),[],target);
e.preventDefault();
});
});
}
function web2py_ajax_page(method, action, data, target) {
@@ -101,9 +101,9 @@ function web2py_ajax_page(method, action, data, target) {
web2py_trap_link(target);
web2py_ajax_init('#'+target);
if(command)
eval(decodeURIComponent(command));
eval(decodeURIComponent(command));
if(flash)
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
}
});
}
@@ -151,7 +151,7 @@ function web2py_component(action, target, timeout, times){
}
} else {
// run once (no timeout specified)
element.reload_counter = Infinity;
element.reload_counter = Infinity;
web2py_ajax_page('get', action, null, target);
} }); }
@@ -165,3 +165,33 @@ function web2py_comet(url,onmessage,onopen,onclose) {
} else return false; // not supported
}
function web2py_calc_entropy(mystring) {
//calculate a simple entropy for a given string
var csets = new Array(
'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
'0123456789abcdefghijklmnopqrstuvwxyz');
var score = 0, other = {}, seen = {}, lastset = null, mystringlist = mystring.split('');
for (var i=0;i<mystringlist.length;i++) { // classify this character
var c = mystringlist[i], inset=5;
for(var j = 0; j<csets.length; j++)
if (csets[j].indexOf(c) != -1) {inset = j; break;}
//calculate effect of character on alphabet size
if(!(inset in seen)) {seen[inset] = 1;score += csets[inset].length;}
else if (!(c in other)) {score += 1;other[c] = 1;}
if (inset != lastset) {score += 1;lastset = inset;}
}
var entropy = mystring.length*Math.log(score)/0.6931471805599453;
return Math.round(entropy*100)/100
}
function web2py_validate_entropy(myfield, req_entropy) {
var validator = function () {
var v = (web2py_calc_entropy(myfield.val())||0)/req_entropy;
var color ='#'+Math.round(((v<1)?1.0-v:0)*15).toString(16)+Math.round(((v<1)?v:0)*15).toString(16)+Math.round(((v<1)?0:1)*15).toString(16);
myfield.css('background-color',color);
}
if(myfield.attr('entropy_check')!=true) myfield.on('keyup', validator).on('keydown', validator).attr('entropy_check',true);
}
+43 -13
View File
@@ -39,7 +39,7 @@ function web2py_ajax_init(target) {
function web2py_event_handlers() {
var doc = jQuery(document)
doc.on('click', '.flash', function(e){jQuery(this).fadeOut('slow'); e.preventDefault();});
doc.on('click', '.flash', function(e){var t=jQuery(this); if(t.css('top')=='0px') t.slideUp('slow'); else t.fadeOut(); e.preventDefault();});
doc.on('keyup', 'input.integer', function(){this.value=this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g,'').reverse();});
doc.on('keyup', 'input.double, input.decimal', function(){this.value=this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g,'').reverse();});
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
@@ -55,7 +55,7 @@ function web2py_event_handlers() {
jQuery(function() {
var flash = jQuery('.flash');
flash.hide();
if(flash.html()) flash.slideDown();
if(flash.html()) flash.append('<span style="float:right;">&times;</span>').slideDown();
web2py_ajax_init(document);
web2py_event_handlers();
});
@@ -67,20 +67,20 @@ function web2py_trap_form(action,target) {
form.submit(function(e){
jQuery('.flash').hide().html('');
web2py_ajax_page('post',action,form.serialize(),target);
e.preventDefault();
e.preventDefault();
});
});
}
function web2py_trap_link(target) {
jQuery('#'+target+' a.w2p_trap').each(function(i){
var link=jQuery(this);
link.click(function(e) {
jQuery('.flash').hide().html('');
web2py_ajax_page('get',link.attr('href'),[],target);
e.preventDefault();
});
});
var link=jQuery(this);
link.click(function(e) {
jQuery('.flash').hide().html('');
web2py_ajax_page('get',link.attr('href'),[],target);
e.preventDefault();
});
});
}
function web2py_ajax_page(method, action, data, target) {
@@ -101,9 +101,9 @@ function web2py_ajax_page(method, action, data, target) {
web2py_trap_link(target);
web2py_ajax_init('#'+target);
if(command)
eval(decodeURIComponent(command));
eval(decodeURIComponent(command));
if(flash)
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
}
});
}
@@ -151,7 +151,7 @@ function web2py_component(action, target, timeout, times){
}
} else {
// run once (no timeout specified)
element.reload_counter = Infinity;
element.reload_counter = Infinity;
web2py_ajax_page('get', action, null, target);
} }); }
@@ -165,3 +165,33 @@ function web2py_comet(url,onmessage,onopen,onclose) {
} else return false; // not supported
}
function web2py_calc_entropy(mystring) {
//calculate a simple entropy for a given string
var csets = new Array(
'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
'0123456789abcdefghijklmnopqrstuvwxyz');
var score = 0, other = {}, seen = {}, lastset = null, mystringlist = mystring.split('');
for (var i=0;i<mystringlist.length;i++) { // classify this character
var c = mystringlist[i], inset=5;
for(var j = 0; j<csets.length; j++)
if (csets[j].indexOf(c) != -1) {inset = j; break;}
//calculate effect of character on alphabet size
if(!(inset in seen)) {seen[inset] = 1;score += csets[inset].length;}
else if (!(c in other)) {score += 1;other[c] = 1;}
if (inset != lastset) {score += 1;lastset = inset;}
}
var entropy = mystring.length*Math.log(score)/0.6931471805599453;
return Math.round(entropy*100)/100
}
function web2py_validate_entropy(myfield, req_entropy) {
var validator = function () {
var v = (web2py_calc_entropy(myfield.val())||0)/req_entropy;
var color ='#'+Math.round(((v<1)?1.0-v:0)*15).toString(16)+Math.round(((v<1)?v:0)*15).toString(16)+Math.round(((v<1)?0:1)*15).toString(16);
myfield.css('background-color',color);
}
if(myfield.attr('entropy_check')!=true) myfield.on('keyup', validator).on('keydown', validator).attr('entropy_check',true);
}
+41 -11
View File
@@ -67,20 +67,20 @@ function web2py_trap_form(action,target) {
form.submit(function(e){
jQuery('.flash').hide().html('');
web2py_ajax_page('post',action,form.serialize(),target);
e.preventDefault();
e.preventDefault();
});
});
}
function web2py_trap_link(target) {
jQuery('#'+target+' a.w2p_trap').each(function(i){
var link=jQuery(this);
link.click(function(e) {
jQuery('.flash').hide().html('');
web2py_ajax_page('get',link.attr('href'),[],target);
e.preventDefault();
});
});
var link=jQuery(this);
link.click(function(e) {
jQuery('.flash').hide().html('');
web2py_ajax_page('get',link.attr('href'),[],target);
e.preventDefault();
});
});
}
function web2py_ajax_page(method, action, data, target) {
@@ -101,9 +101,9 @@ function web2py_ajax_page(method, action, data, target) {
web2py_trap_link(target);
web2py_ajax_init('#'+target);
if(command)
eval(decodeURIComponent(command));
eval(decodeURIComponent(command));
if(flash)
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
}
});
}
@@ -151,7 +151,7 @@ function web2py_component(action, target, timeout, times){
}
} else {
// run once (no timeout specified)
element.reload_counter = Infinity;
element.reload_counter = Infinity;
web2py_ajax_page('get', action, null, target);
} }); }
@@ -165,3 +165,33 @@ function web2py_comet(url,onmessage,onopen,onclose) {
} else return false; // not supported
}
function web2py_calc_entropy(mystring) {
//calculate a simple entropy for a given string
var csets = new Array(
'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
'0123456789abcdefghijklmnopqrstuvwxyz');
var score = 0, other = {}, seen = {}, lastset = null, mystringlist = mystring.split('');
for (var i=0;i<mystringlist.length;i++) { // classify this character
var c = mystringlist[i], inset=5;
for(var j = 0; j<csets.length; j++)
if (csets[j].indexOf(c) != -1) {inset = j; break;}
//calculate effect of character on alphabet size
if(!(inset in seen)) {seen[inset] = 1;score += csets[inset].length;}
else if (!(c in other)) {score += 1;other[c] = 1;}
if (inset != lastset) {score += 1;lastset = inset;}
}
var entropy = mystring.length*Math.log(score)/0.6931471805599453;
return Math.round(entropy*100)/100
}
function web2py_validate_entropy(myfield, req_entropy) {
var validator = function () {
var v = (web2py_calc_entropy(myfield.val())||0)/req_entropy;
var color ='#'+Math.round(((v<1)?1.0-v:0)*15).toString(16)+Math.round(((v<1)?v:0)*15).toString(16)+Math.round(((v<1)?0:1)*15).toString(16);
myfield.css('background-color',color);
}
if(myfield.attr('entropy_check')!=true) myfield.on('keyup', validator).on('keydown', validator).attr('entropy_check',true);
}
+2 -89
View File
@@ -15,96 +15,9 @@ pass
</div>
<script language="javascript"><!--
jQuery("#web2py_user_form input:visible:enabled:first").focus();
function calc_entropy(mystring) {
/*" calculate a simple entropy for a given string "*/
var lowerset = 'abcdefghijklmnopqrstuvwxyz';
var upperset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var numberset = '0123456789';
var sym1set = '!@#$%^&*()';
var sym2set = '~`-_=+[]{}\\|;:\'",.<>?/';
var otherset = '0123456789abcdefghijklmnopqrstuvwxyz' /*anything else*/
var alphabet = 0;
var other = {};
var seen = {};
var lastset = null;
var mystringlist = mystring.split('');
for (var i=0;i<mystringlist.length;i++) {
var c = mystringlist[i];
//console.log('we are at char', c);
/* classify this character*/
var inset = otherset;
while (1) {
/*lowerset*/
if (lowerset.indexOf(c) != -1) {
inset = lowerset;
break
};
/*upperset*/
if (upperset.indexOf(c) != -1) {
inset = upperset;
break
};
/*numberset*/
if (numberset.indexOf(c) != -1) {
inset = numberset;
break
};
/*sym1set*/
if (sym1set.indexOf(c) != -1) {
inset = sym1set;
break
};
/*sym2set*/
if (sym2set.indexOf(c) != -1) {
inset = sym2set;
break
} else {break};
}
//console.log('inset detected as', inset, seen);
/*calculate effect of character on alphabet size*/
if (!(inset in seen)) {
//console.log('credit for a new character set');
seen[inset] = 1;
alphabet += inset.length; /*credit for a new character set*/
}
else if (!(c in other)) {
//console.log('credit for unique characters');
alphabet += 1;
other[c] = 1;
}
if (inset != lastset) {
//console.log('credit for set transitions');
alphabet += 1; /*credit for set transitions*/
lastset = inset;
}
}
var entropy = mystring.length / 1.0 * Math.log(alphabet) / 0.6931471805599453; /*math.log(2)*/
return Math.round(entropy*100)/100
}
function validate_entropy(myfield, midrange) {
var k = 256.0/midrange;
var validator = function () {
var value = calc_entropy(myfield.val());
var color;
if(value<30) {
var c = Math.floor(value*k).toString(16);
color = '#ff'+((c.length==1)?'0':''+c)+'00';
} else {
var c = Math.floor(Math.max(0,255-(value-midrange)*k)).toString(16);
color = '#'+((c.length==1)?'0':'')+c+'ff00';
}
myfield.css('background-color',color);
}
myfield.on('keyup', validator);
myfield.on('keydown', validator);
}
{{if request.args(0)=='register':}}
validate_entropy(jQuery('#auth_user_password'),50);
web2py_validate_entropy(jQuery('#auth_user_password'),100);
{{elif request.args(0)=='change_password':}}
validate_entropy(jQuery('#no_table_new_password'),50);
web2py_validate_entropy(jQuery('#no_table_new_password'),100);
{{pass}}
//--></script>
+12 -8
View File
@@ -28,7 +28,7 @@ from dal import DAL, Field, Table, Row, CALLABLETYPES, smart_query, \
from storage import Storage
from utils import md5_hash
from validators import IS_EMPTY_OR, IS_NOT_EMPTY, IS_LIST_OF, IS_DATE, \
IS_DATETIME, IS_INT_IN_RANGE, IS_FLOAT_IN_RANGE
IS_DATETIME, IS_INT_IN_RANGE, IS_FLOAT_IN_RANGE, IS_STRONG
import datetime
import urllib
@@ -442,14 +442,23 @@ class PasswordWidget(FormWidget):
see also: :meth:`FormWidget.widget`
"""
# detect if attached a IS_STRONG with entropy
default=dict(
_type='password',
_value=(value and cls.DEFAULT_PASSWORD_DISPLAY) or '',
)
attr = cls._attributes(field, default, **attributes)
output = CAT(INPUT(**attr))
return INPUT(**attr)
# deal with entropy check!
requires = field.requires
if not isinstance(requires,(list,tuple)): requires = [requires]
is_strong = [r for r in requires if isinstance(r, IS_STRONG)]
if is_strong:
output.append(SCRIPT("web2py_validate_entropy(jQuery('#%s'),%s);" \
% (attr['_id'],is_strong[0].entropy)))
# end entropy check
return output
class UploadWidget(FormWidget):
@@ -2713,8 +2722,3 @@ class ExporterXML(ExportClass):
out.write('</row>\n')
out.write('</rows>')
return str(out.getvalue())