"""THE PLAN

Aim is to do stack various layers together:

    1. Authentication
    2. Authorization
    3. Dispatching to applications

For the time being we will focus on the first using dummy stand-ins for
authentication function etc


OK: so the basics work but:

    1. we need to sort out reverse proxying (for example trac is broken)
    2. need to do sessions
    3. need to write proper stack

Setup is:

    Authentication: defaults to pass through but catches 403 and converts to
    401s as necessary

    Authorization: this is where we plugin in our url stuff at least 

    Url Dispatching: 
"""
import wsgiref.simple_server
import paste.auth.multi
import paste.auth.basic
import paste.proxy
import paste.urlmap


# Stubs
# =====

# proxy middleware
# issues: 
#  File "/opt/dports/lib/python2.4/site-packages/Paste-0.9.7-py2.4.egg/paste/proxy.py", line 105, in __call__
#    start_response(status, headers_out)
#  File "/opt/dports/lib/python2.4/site-packages/wsgiref-0.1.2-py2.4.egg/wsgiref/handlers.py", line 186, in start_response
#AssertionError: Hop-by-hop headers not allowed
#local.kforge.net - - [09/Oct/2006 19:06:18] "GET /svn/ HTTP/1.1" 500 59
#
# see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1:
# The following HTTP/1.1 headers are hop-by-hop headers:
#
#      - Connection
#      - Keep-Alive
#      - Proxy-Authenticate
#      - Proxy-Authorization
#      - TE
#      - Trailers
#      - Transfer-Encoding
#      - Upgrade


local_kforge = 'http://project.local.kforge.net/warandpeace/svn/'
kforge_trac = 'http://project.local.kforge.net/warandpeace/trac'
# local_kforge = 'http://local.okfn.org/'
# local_kforge = 'http://www.thefactz.org/'
proxy_app_svn = paste.proxy.make_proxy(global_conf = {}, address=local_kforge,
        allowed_request_methods='')
proxy_app_trac = paste.proxy.make_proxy(global_conf = {}, address=kforge_trac,
        allowed_request_methods='')


realm = 'wsgitest'
svn_offset = '/svnmount/'
trac_offset = '/tracmount/'

def dummyauth(environ, username, password):
    # dummy version at present
    return username == password

#def simple_app(environ, start_response):
#    urlpath = environ['PATH_INFO']
#    if urlpath.startswith('/svnmount'):
#        # return wsgiref.simple_server.demo_app(environ, start_response)
#        # TODO: modify environ PATH_INFO to take account of offset
#        return proxy_app(environ, start_response)
#    else:
#        return wsgiref.simple_server.demo_app(environ, start_response)

simple_app = paste.urlmap.URLMap()
simple_app['/'] = wsgiref.simple_server.demo_app
simple_app[svn_offset] = proxy_app_svn
simple_app[trac_offset] = proxy_app_trac


# add authentication
multi = paste.auth.multi.MultiHandler(simple_app)

# todo add predicate test so that we use cookie by default ...
# multi.add_predicate('cookie', checker)
multi.add_method('basic', paste.auth.basic.middleware, realm, dummyauth)
multi.set_default('basic')

import paste.auth.cookie
import paste.auth.form
# multi.add_method('form', paste.auth.form.middleware, dummyauth)
# multi.set_default('form')
# multi = paste.auth.cookie.AuthCookieHandler(multi)

import twill
from twill import commands as web
from StringIO import StringIO
class TestStuff:

    def setup_method(self, name=''):
        # create a publisher obj
        wsgi_app = multi

        # install the app at localhost:8080 for wsgi_intercept
        twill.add_wsgi_intercept('localhost', 8080, lambda : wsgi_app)

        # while we're at it, stop twill from running off at the mouth...
        self.outp = StringIO()
        twill.set_output(self.outp)

        self.siteurl = 'http://localhost:8080/'

    def teardown_method(self, name=''):
        # remove intercept.
        twill.remove_wsgi_intercept('localhost', 8080)

    def test_auth_required(self):
        # script = "find 'Hello World'"
        # twill.execute_string(script, initial_url='http://localhost:8080/')
        web.go(self.siteurl)
        web.code(401)

    def test_auth_ok(self):
        # script = "find 'Hello World'"
        # twill.execute_string(script, initial_url='http://localhost:8080/')
        web.add_auth(realm, self.siteurl, 'rgrp', 'rgrp')
        web.go(self.siteurl)
        web.code(200)

    def test_proxy(self):
        desturl = self.siteurl + svn_offset[1:] + '/' # strip off leading '/'
        print desturl
        web.add_auth(realm, self.siteurl, 'rgrp', 'rgrp')
        web.go(desturl)
        web.code(200)
        page = web.show()
        print page
        web.find('Revision 0')

    def test_proxy_2(self):
        desturl = self.siteurl + trac_offset[1:] + '/'
        print desturl
        web.add_auth(realm, self.siteurl, 'rgrp', 'rgrp')
        web.go(desturl)
        web.code(200)
        page = web.show()
        print page
        web.find('Trac')


if __name__ == '__main__': 
    httpd = wsgiref.simple_server.make_server('', 8080, multi)
    print "Serving HTTP on port 8080..."
    httpd.serve_forever()

    # import paste.httpserver
    # paste.httpserver.serve(multi)
