#!/usr/bin/python2
# Title:
# Login.py
#
# CVS/RCS $Header$
#
# Description:
# Web authentication module
#
# Copyright:
# Eric S. Johansson (esj@harvee.org)
# BSD License: see LICENSE or http://www.opensource.org/licenses/bsd-license.php
#
# Requires:

import sys
from albatross import SimpleApp
from albatross.cgiapp import Request
import os
import syslog
import time
import hmac, sha



# Login authentication.

# from: "dos and don'ts of client authentication on the Web" http://cookies.lcs.mit.edu
#
# cookie recipe from section 4.1

# use model:
# if there is no "albatross_authentication" field available in
# context.locals, then present a login screen.  On return of the login
# screen, there should be two variables (username, password)
# containing the credentials of the user.  The information is checked
# against the system password file (or optionally some other schema)
# and if it passes, turned into a "cookie" for authentication.

class login_authentication:
    def __init__(self, key, duration = 600):
        """initialize the login_vindication instance.  Key is the
    secret key not shared with or visible from any application.
    Duration is the time in seconds the login authentication value is
    valid for. The default value is 10 minutes"""
        self.key = key
        self.duration = duration
        
    def new(self, data=None, duration = None):
        """ creates a new authentication cookie.  Allows for optional
        additional data field for authentication specific information
        and an optional change in duration from the default one.  If
        there is a user supply data field, it should not contain any &
        characters as that is what we use for a delimiter and I'm too
        lazy to write a smart parser."""

        usable_data = data
        if data  == None:
            usable_data="None"
            
        raw_cookie = "exp="+str(time.time()+self.duration)+"&data="+usable_data
            
        mac_cookie = hmac.new(self.key, raw_cookie, sha).hexdigest()
        cooked_cookie = raw_cookie+"&digest="+mac_cookie

        return cooked_cookie
        
    def validate(self, token):
        """validate the given token and make sure it's all
        hunky-dory"""

        # split apart the token into individual cookie elements then
        # reconstruct and compare.  Also check to make sure token
        # isn't past expiration date

        (expiration, data, mac_value) = token.split("&",3)
        (junk, expiration_time) = expiration.split("=")
        
        mac_cookie = "digest="+hmac.new(self.key, expiration+"&"+data,sha).hexdigest()
        
        return mac_cookie == mac_value and time.time() < float(expiration_time)
            

    def check_authentication(self, context, login_html, application_html):
        #temporary holding
        return


test = login_authentication("simple key")
cookie = test.new()
print cookie
print test.validate(cookie)
