Merge ssh://github.com/web2py/web2py

This commit is contained in:
Michele Comitini
2013-07-17 16:49:43 +02:00
5 changed files with 54 additions and 27 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.6.0-development+timestamp.2013.07.16.13.14.21 Version 2.6.0-development+timestamp.2013.07.17.07.36.50
+26 -9
View File
@@ -40,15 +40,32 @@
:copyright: (c) Copyright 2011 by Armin Ronacher. :copyright: (c) Copyright 2011 by Armin Ronacher.
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
import hmac #import hmac
import hashlib #import hashlib
try:
# Use PyCrypto (if available).
from Crypto.Hash import HMAC as hmac, SHA as sha1
except ImportError:
# PyCrypto not available. Use the Python standard library.
import hmac
try:
from hashlib import sha1
except ImportError:
# hashlib not available. Use the old sha module.
import sha as sha1
from struct import Struct from struct import Struct
from operator import xor from operator import xor
from itertools import izip, starmap from itertools import izip, starmap
from collections import deque
_pack_int = Struct('>I').pack _pack_int = Struct('>I').pack
try:
from Crypto.Util.strxor import strxor
except ImportError:
def strxor(a, b):
return ''.join(chr(xor(ord(x), ord(y))) for x,y in izip(a, b))
def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None): def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Like :func:`pbkdf2_bin` but returns a hex encoded string.""" """Like :func:`pbkdf2_bin` but returns a hex encoded string."""
@@ -61,20 +78,20 @@ def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
key of `keylen` bytes. By default SHA-1 is used as hash function, key of `keylen` bytes. By default SHA-1 is used as hash function,
a different hashlib `hashfunc` can be provided. a different hashlib `hashfunc` can be provided.
""" """
hashfunc = hashfunc or hashlib.sha1 hashfunc = hashfunc or sha1
mac = hmac.new(data, None, hashfunc) mac = hmac.new(data, None, hashfunc)
def _pseudorandom(x, mac=mac): def _pseudorandom(x, mac=mac):
h = mac.copy() h = mac.copy()
h.update(x) h.update(x)
return map(ord, h.digest()) return h.digest()
buf = [] buf = deque()
for block in xrange(1, -(-keylen // mac.digest_size) + 1): for block in xrange(1, -(-keylen // mac.digest_size) + 1):
rv = u = _pseudorandom(salt + _pack_int(block)) rv = u = _pseudorandom(salt + _pack_int(block))
for i in xrange(iterations - 1): for i in xrange(iterations - 1):
u = _pseudorandom(''.join(map(chr, u))) u = _pseudorandom(u)
rv = starmap(xor, izip(rv, u)) rv = strxor(rv, u)
buf.extend(rv) buf.extend(rv)
return ''.join(map(chr, buf))[:keylen] return ''.join(buf)[:keylen]
def test(): def test():
+1 -1
View File
@@ -57,7 +57,7 @@ def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1):
# if not relative and not from applications: # if not relative and not from applications:
if hasattr(current, 'request') \ if hasattr(current, 'request') \
and level <= 0 \ and level <= 0 \
and not name.split('.')[0] in INVALID_MODULES \ and not name.partition('.')[0] in INVALID_MODULES \
and isinstance(globals, dict): and isinstance(globals, dict):
import_tb = None import_tb = None
try: try:
+2 -1
View File
@@ -5540,8 +5540,9 @@ class MongoDBAdapter(NoSQLAdapter):
filter = None filter = None
if query: if query:
filter = self.expand(query) filter = self.expand(query)
# do not try to update id fields to avoid backend errors
modify = {'$set': dict((k.name, self.represent(v, k.type)) for modify = {'$set': dict((k.name, self.represent(v, k.type)) for
k, v in fields)} k, v in fields if (not k.name in ("_id", "id")))}
return modify, filter return modify, filter
def update(self, tablename, query, fields, safe=None): def update(self, tablename, query, fields, safe=None):
+24 -15
View File
@@ -24,6 +24,8 @@ import socket
import base64 import base64
import zlib import zlib
_struct_2_long_long = struct.Struct('=QQ')
python_version = sys.version_info[0] python_version = sys.version_info[0]
if python_version == 2: if python_version == 2:
@@ -31,6 +33,15 @@ if python_version == 2:
else: else:
import pickle import pickle
try:
from Crypto.Hash import MD5 as md5, \
SHA as sha1, \
SHA224 as sha224, \
SHA256 as sha256, \
SHA384 as sha384, \
SHA512 as sha512
except ImportError:
from hashlib import md5, sha1, sha224, sha256, sha384, sha512
try: try:
from Crypto.Cipher import AES from Crypto.Cipher import AES
@@ -69,7 +80,7 @@ def compare(a, b):
def md5_hash(text): def md5_hash(text):
""" Generate a md5 hash with the given text """ """ Generate a md5 hash with the given text """
return hashlib.md5(text).hexdigest() return md5.new(text).hexdigest()
def simple_hash(text, key='', salt='', digest_alg='md5'): def simple_hash(text, key='', salt='', digest_alg='md5'):
@@ -102,17 +113,17 @@ def get_digest(value):
return value return value
value = value.lower() value = value.lower()
if value == "md5": if value == "md5":
return hashlib.md5 return md5
elif value == "sha1": elif value == "sha1":
return hashlib.sha1 return sha1
elif value == "sha224": elif value == "sha224":
return hashlib.sha224 return sha224
elif value == "sha256": elif value == "sha256":
return hashlib.sha256 return sha256
elif value == "sha384": elif value == "sha384":
return hashlib.sha384 return sha384
elif value == "sha512": elif value == "sha512":
return hashlib.sha512 return sha512
else: else:
raise ValueError("Invalid digest algorithm: %s" % value) raise ValueError("Invalid digest algorithm: %s" % value)
@@ -212,7 +223,7 @@ This is not specific to web2py; consider deploying on a different operating syst
packed = ''.join(chr(x) for x in ctokens) # python 2 packed = ''.join(chr(x) for x in ctokens) # python 2
else: else:
packed = bytes([]).join(bytes([x]) for x in ctokens) # python 3 packed = bytes([]).join(bytes([x]) for x in ctokens) # python 3
unpacked_ctokens = struct.unpack('=QQ', packed) unpacked_ctokens = _struct_2_long_long.unpack(packed)
return unpacked_ctokens, have_urandom return unpacked_ctokens, have_urandom
UNPACKED_CTOKENS, HAVE_URANDOM = initialize_urandom() UNPACKED_CTOKENS, HAVE_URANDOM = initialize_urandom()
@@ -244,14 +255,12 @@ def web2py_uuid(ctokens=UNPACKED_CTOKENS):
""" """
rand_longs = (random.getrandbits(64), random.getrandbits(64)) rand_longs = (random.getrandbits(64), random.getrandbits(64))
if HAVE_URANDOM: if HAVE_URANDOM:
urand_longs = struct.unpack('=QQ', fast_urandom16()) urand_longs = _struct_2_long_long.unpack(fast_urandom16())
byte_s = struct.pack('=QQ', byte_s = _struct_2_long_long.pack(rand_longs[0] ^ urand_longs[0] ^ ctokens[0],
rand_longs[0] ^ urand_longs[0] ^ ctokens[0], rand_longs[1] ^ urand_longs[1] ^ ctokens[1])
rand_longs[1] ^ urand_longs[1] ^ ctokens[1])
else: else:
byte_s = struct.pack('=QQ', byte_s = _struct_2_long_long.pack(rand_longs[0] ^ ctokens[0],
rand_longs[0] ^ ctokens[0], rand_longs[1] ^ ctokens[1])
rand_longs[1] ^ ctokens[1])
return str(uuid.UUID(bytes=byte_s, version=4)) return str(uuid.UUID(bytes=byte_s, version=4))
REGEX_IPv4 = re.compile('(\d+)\.(\d+)\.(\d+)\.(\d+)') REGEX_IPv4 = re.compile('(\d+)\.(\d+)\.(\d+)\.(\d+)')