#!/usr/bin/env python
# cgistate_cryptcookies.py -- Preserving CGI state with encrypted cookies

import sys, os
sys.path.append(os.environ['SCRIPT_FILENAME'])

import cgitb; cgitb.enable(logdir='/tmp/cgitb', format='text')
from cryptcookie import CryptCookie, ModifiedCookieError

SERVER_KEY = 'oj2kj6/vboU872lj'    # must be 16 bytes

def state_fetch():
    try:
        c = CryptCookie(SERVER_KEY)
        c.load(os.environ['HTTP_COOKIE'])
        state = int(c['state'].value)
    except KeyError:
        state = 1                  # No cookie yet, start with 1
    except ValueError:
        state = -1000              # There was no integer in the cookie
    except ModifiedCookieError:
        state = -2000              # Someone tampered with the cookie
    except:
        state = -3000              # Some other error occured
    finally:
        return state

def state_update(state):
    state = state + 1
    return state

def state_store(state):
    c = CryptCookie(SERVER_KEY)
    c['state'] = state
    c['state']['expires'] = 3600  # forget state in 3600 seconds = 1 hour
    c['state']['path'] = '/'      # cookie valid for the whole domain
    return c.output()

result_http = []
result_http.append("Content-type: text/html")

result_html = []
result_html.append('<html><head><title>Counter 4</title></head></body><p>')

# Fetch old counter value from client
oldstate = state_fetch()
result_html.append('Old Counter: %d<br />' % (oldstate,))

# Compute new counter value
newstate = state_update(oldstate)
result_html.append('New Counter: %d<br />' % (newstate,))

# Send new counter value to client
result_http.append(state_store(newstate))

# Send feedback
result_html.append('Call me <a href="%s">again</a><br />' %
                   os.environ.get('SCRIPT_NAME', 'not_a_cgi'))

result_html.append('</p></body></html>')

print '\n'.join(result_http)
print
print '\n'.join(result_html)
