#!/usr/bin/env python
'''
$Id$

SessionCookieCrumbler
'''

__rcs_id__  = '$Id$'
__version__ = '$Revision$'[11:-2]

import os.path
from App.Common import package_home
from AccessControl import ClassSecurityInfo, Permissions
from Globals import DTMLFile, InitializeClass
from App.Common import package_home
from OFS.DTMLMethod import addDTMLMethod
from ZPublisher import BeforeTraverse

from Products.CookieCrumbler.CookieCrumbler import CookieCrumbler

ModifyCookieCrumblers = 'Modify Cookie Crumblers'

# NOTE: to disable cookie auth, set the request var disable_cookie_login__

class SessionCookieCrumbler(CookieCrumbler):
    ''' A CookieCrumbler that stores authentication credentials on
        the server in the SESSION rather than transmitting than on
        the client in a cookie.
    '''
    meta_type = 'Session Cookie Crumbler'
    security = ClassSecurityInfo()

    security.declarePrivate('getCookieMethod')
    def getCookieMethod(self, name='setAuthCookie', default=None):
        ''' No overrides '''
        return getattr(self, name)

    security.declarePrivate('setAuthCookie')
    def setAuthCookie(self, resp, cookie_name, cookie_value):
        self.REQUEST.SESSION[(cookie_name, self.getCookiePath())] = cookie_value

    security.declarePrivate('expireAuthCookie')
    def expireAuthCookie(self, resp, cookie_name):
        try:
            del self.REQUEST.SESSION[(cookie_name, self.getCookiePath())]
        except KeyError:
            pass

    security.declarePrivate('modifyRequest')
    def modifyRequest(self, req, resp):
        key = (self.auth_cookie, self.getCookiePath())
        creds = req.SESSION.get(key,None)
        if creds:
            req[self.auth_cookie] = creds
        rV = CookieCrumbler.modifyRequest(self, req, resp)
        return rV

    # Installation and removal of traversal hooks.
    def manage_beforeDelete(self, item, container):
        if item is self:
            handle = self.meta_type + '/' + self.getId()
            BeforeTraverse.unregisterBeforeTraverse(container, handle)

    def manage_afterAdd(self, item, container):
        if item is self:
            handle = self.meta_type + '/' + self.getId()
            container = container.this()
            nc = BeforeTraverse.NameCaller(self.getId())
            BeforeTraverse.registerBeforeTraverse(container, nc, handle)

    security.declarePublic('logout')
    def logout(self):
        ' log the user out '
        # clear the user's SESSION of all fun stuff too
        self.REQUEST.SESSION.invalidate()
        # now log 'em out
        return CookieCrumbler.logout(self)


InitializeClass(SessionCookieCrumbler)

manage_addSessionCCForm = DTMLFile(
    os.path.join('www','addSessionCC'), globals()
    )

def manage_addSessionCC(self, id, create_forms=0, REQUEST=None):
    ''' Create a Session Cookie Crumbler '''
    ob = SessionCookieCrumbler()
    ob.id = id
    self._setObject(id, ob)
    if create_forms:
        here = package_home(globals())
        for fn in ('login_form', 'logged_in', 'logged_out'):
            filename = os.path.join(
                here, os.pardir, 'CookieCrumbler', fn + '.dtml'
                )
            f = open(filename, 'rt')
            try: data = f.read()
            finally: f.close()
            addDTMLMethod(self, fn, file=data)
    if REQUEST is not None:
        return self.manage_main(self, REQUEST)
 
def initialize(context):
    ''' Register the SessionCookieCrumbler class '''
    context.registerClass(
        SessionCookieCrumbler,
        constructors = (manage_addSessionCCForm, manage_addSessionCC),
        icon='../CookieCrumbler/cookie.gif'
        )
