"""This is a cookie authentication implementation for Aspen.
"""
import datetime

from aspen import auth
from aspen.utils import to_rfc822, utcnow


MINUTE = datetime.timedelta(seconds=60)
HOUR = 60 * MINUTE
DAY  = 24 * HOUR
WEEK = 7 * DAY


TIMEOUT = 2 * HOUR


# Public config knobs
# ===================
# Feel free to set these in, e.g., configure-aspen.py

NAME = "auth"
DOMAIN = None
PATH = "/"
HTTPONLY = "Yes, please."


# Hooks
# =====

def inbound_early(request):
    """Authenticate from a cookie.
    """
    if 'user' not in request.context:
        token = None
        if NAME in request.headers.cookie:
            token = request.headers.cookie[NAME].value
            token = token.decode('US-ASCII')
        request.context['user'] = auth.User(token)


def outbound_late(response):
    """Set outbound auth cookie.
    """
    if 'user' not in response.request.context:
        # XXX When does this happen? When auth.inbound_early hasn't run, eh?
        raise

    user = response.request.context['user']
    if not isinstance(user, auth.User):
        raise Exception("If you define 'user' in a simplate it has to be an "
                        "instance of an aspen.auth.User.")

    if NAME not in response.request.headers.cookie:
        # no cookie in the request, don't set one on response
        return
    elif user.ANON:
        # user is anonymous, instruct browser to delete any auth cookie
        cookie_value = ''
        cookie_expires = auth.THE_PAST
    else:
        # user is authenticated, keep it rolling for them
        cookie_value = user.token
        cookie_expires = utcnow() + TIMEOUT


    # Configure outgoing cookie.
    # ==========================

    response.headers.cookie[NAME] = cookie_value  # creates a cookie object?
    cookie = response.headers.cookie[NAME]          # loads a cookie object?

    cookie['expires'] = to_rfc822(cookie_expires)

    if DOMAIN is not None:
        # Browser default is the domain of the resource requested.
        # Aspen default is the browser default.
        cookie['domain'] = DOMAIN

    if PATH is not None:
        # XXX What's the browser default? Probably /? Or current dir?
        # Aspen default is "/".
        cookie['path'] = PATH

    if HTTPONLY is not None:
        # Browser default is to allow access from JavaScript.
        # Aspen default is to prevent access from JavaScript.
        cookie['httponly'] = HTTPONLY

@@ -140,16 +140,51 @@
  utcnow%0A
+from aspen.website import THE_PAST%0A
 %0A%0AMINUTE
@@ -1503,21 +1503,16 @@
 pires = 
-auth.
 THE_PAST
@@ -1639,16 +1639,26 @@
 pires = 
+to_rfc822(
 utcnow()
@@ -1667,16 +1667,17 @@
  TIMEOUT
+)
 %0A%0A%0A    #
@@ -1917,26 +1917,16 @@
 res'%5D = 
-to_rfc822(
 cookie_e
@@ -1931,17 +1931,16 @@
 _expires
-)
 %0A%0A    if

Fix bugs in expires part of cookie auth