# HG changeset patch # User Matt Johnston # Date 1391697916 -28800 # Node ID d68af9e84485e2054948d70787dc4564e743e40b # Parent 4a51e2bf689b6d2da3f05ae3263dea85e9ed35b6 working diff -r 4a51e2bf689b -r d68af9e84485 web/config.py --- a/web/config.py Thu Feb 06 20:35:43 2014 +0800 +++ b/web/config.py Thu Feb 06 22:45:16 2014 +0800 @@ -44,6 +44,9 @@ # determine by zooming in an image viewer GRAPH_LEFT_MARGIN = 63 +# 1 hour +CSRF_TIMEOUT = 3600 + try: from localconfig import * except ImportError: diff -r 4a51e2bf689b -r d68af9e84485 web/log.py --- a/web/log.py Thu Feb 06 20:35:43 2014 +0800 +++ b/web/log.py Thu Feb 06 22:45:16 2014 +0800 @@ -285,3 +285,7 @@ r.append(n) return json.dumps(r, sort_keys=True, indent=4) + + +def get_csrf_blob(user_ident): + return "aaa" diff -r 4a51e2bf689b -r d68af9e84485 web/secure.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/secure.py Thu Feb 06 22:45:16 2014 +0800 @@ -0,0 +1,65 @@ +import os +import time +import fcntl +import hmac +import binascii +import sys + +import config + +__all__ = ["get_csrf_blob", "check_csrf_blob", "setup_csrf"] + +def get_user_hash(): + return "aaa" + +def setup_csrf(): + NONCE_SIZE=16 + global _csrf_fd, _csrf_key + _csrf_fd = open('%s/csrf.dat' % config.DATA_PATH, 'r+') + + try: + fcntl.lockf(_csrf_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + os.fchmod(_csrf_fd.fileno(), 0600) + _csrf_fd.write("%d-%s" % (os.getpid(), binascii.hexlify(os.urandom(NONCE_SIZE)))) + _csrf_fd.flush() + _csrf_fd.seek(0) + except IOError: + pass + fcntl.lockf(_csrf_fd, fcntl.LOCK_SH) + _csrf_key = _csrf_fd.read() + # keep the lock open until we go away + + +def get_csrf_blob(): + expiry = int(config.CSRF_TIMEOUT + time.time()) + content = '%s-%s' % (get_user_hash(), expiry) + mac = hmac.new(_csrf_key, content).hexdigest() + return "%s-%s" % (content, mac) + +def check_csrf_blob(blob): + toks = blob.split('-') + if len(toks) != 3: + return False + + user, expiry, mac = toks + if user != get_user_hash(): + return False + + try: + exp = int(expiry) + except ValueError: + return False + + if exp < 1000000000: + return False + + if exp > time.time(): + return False + + check_content = "%s-%s" % (user, expiry) + check_mac = hmac.new(_csrf_key, content).hexdigest() + if mac == check_mac: + return True + + return False + diff -r 4a51e2bf689b -r d68af9e84485 web/templog.py --- a/web/templog.py Thu Feb 06 20:35:43 2014 +0800 +++ b/web/templog.py Thu Feb 06 22:45:16 2014 +0800 @@ -9,12 +9,15 @@ import urllib import sys import os +import traceback +import fcntl import bottle from bottle import route, request, response import config import log +import secure DATE_FORMAT = '%Y%m%d-%H.%M' ZOOM_SCALE = 2.0 @@ -47,7 +50,9 @@ @route('/set') def set(): - return bottle.template('set', inline_data = log.get_params()) + return bottle.template('set', + inline_data = log.get_params(), + csrf_blob = secure.get_csrf_blob()) @route('/set_current.json') def set_fresh(): @@ -100,7 +105,8 @@ @route('/env') def env(): response.set_header('Content-Type', 'text/plain') - return '\n'.join(("%s %s" % k) for k in request.environ.items()) + return '\n'.join(traceback.format_stack()) + #return '\n'.join(("%s %s" % k) for k in request.environ.items()) #return str(request.environ) #yield "\n" #var_lookup = environ['mod_ssl.var_lookup'] @@ -108,8 +114,18 @@ @bottle.get('/') def javascripts(filename): + response.set_header('Cache-Control', "public, max-age=1296000") return bottle.static_file(filename, root='static') +@route('/setparams', method='post') +def update(): + post_json = json.loads(request.forms.data) + + csrf_blob = post_json['csrf_blob'] + + return str(post_json['params']) + +secure.setup_csrf() def main(): #bottle.debug(True) diff -r 4a51e2bf689b -r d68af9e84485 web/views/set.tpl --- a/web/views/set.tpl Thu Feb 06 20:35:43 2014 +0800 +++ b/web/views/set.tpl Thu Feb 06 22:45:16 2014 +0800 @@ -46,6 +46,11 @@ text-align: center; } +#savebox { + align: center; + width: 100%; +} + .onbutton { background-color: #cdf; } @@ -64,17 +69,6 @@ Set templog - - -
-
- -
-
- - - - + + +
+
+ +
+ + +
+
+
+ + + +