Changeset - 4fa0f8343c20
[Not reviewed]
0 2 0
Brett Smith (brett) - 4 years ago 2016-12-02 20:07:35
brett@sfconservancy.org
supporter: Use proper float formatting for parameter validation.
2 files changed with 46 insertions and 18 deletions:
0 comments (0 inline, 0 general)
www/conservancy/__init__.py
Show inline comments
...
 
@@ -4,24 +4,45 @@ from django.conf import settings
 
from django.shortcuts import render_to_response
 
from django.template import RequestContext
 

	
 
HASH_ENCODING = 'utf-8'
 
class ParameterValidator(object):
 
    def __init__(self, given_hash_or_params, params_hash_key=None):
 
        if params_hash_key is None:
 
            self.given_hash = given_hash_or_params
 
        else:
 
            self.given_hash = given_hash_or_params.get(params_hash_key)
 
        seed = getattr(settings, 'CONSERVANCY_SECRET_KEY', '')
 
        self.hasher = hashlib.sha256(seed)
 
        if isinstance(self.given_hash, basestring):
 
            self.hash_type = type(self.given_hash)
 
        else:
 
            self.hash_type = type(self.hasher.hexdigest())
 
        self.valid = None
 
        if not (self.given_hash and seed):
 
            self.fail()
 

	
 
    def __enter__(self):
 
        self.valid = self.valid and None
 
        return self
 

	
 
    def __exit__(self, exc_type, exc_value, exc_tb):
 
        if exc_type is None:
 
            self.check()
 
        else:
 
            self.fail()
 

	
 
    def validate(self, data):
 
        self.valid = self.valid and None
 
        self.hasher.update(data)
 

	
 
    def check(self):
 
        if self.valid or (self.valid is None):
 
            self.valid = self.hash_type(self.hasher.hexdigest()) == self.given_hash
 
        return self.valid
 

	
 
    def fail(self):
 
        self.valid = False
 

	
 

	
 
def render_template_with_context(request, template_path, context_dict):
 
    return render_to_response(template_path, context_dict,
 
                              context_instance=RequestContext(request))
 

	
 
def param_if_valid(params, param_name, hash_param_name, default=None):
 
    try:
 
        seed = settings.CONSERVANCY_SECRET_KEY
 
        param_value = params[param_name]
 
        param_bytes = param_value.encode(HASH_ENCODING)
 
        given_hash = params[hash_param_name]
 
    except (AttributeError, KeyError, UnicodeEncodeError):
 
        return default
 
    good_hash = hashlib.sha256()
 
    good_hash.update(seed)
 
    good_hash.update(param_bytes)
 
    if given_hash == unicode(good_hash.hexdigest()):
 
        return param_value
 
    else:
 
        return default
www/conservancy/apps/supporter/views.py
Show inline comments
 
import conservancy
 

	
 
def index(request):
 
    partial_amount = conservancy.param_if_valid(request.GET, 'upgrade', 'upgrade_id', 0)
 
    with conservancy.ParameterValidator(request.GET, 'upgrade_id') as validator:
 
        try:
 
            amount_param = float(request.GET['upgrade'])
 
        except (KeyError, ValueError):
 
            validator.fail()
 
        else:
 
            validator.validate('{.2f}'.format(amount_param))
 
    partial_amount = amount_param if validator.valid else 0
 
    context = {
 
        'partial_amount': partial_amount,
 
        'minimum_amount': 120 - partial_amount,
0 comments (0 inline, 0 general)