import os
import urlparse

import lasso

from quixote import get_request, get_response, redirect, get_field, get_publisher
from quixote.http_request import parse_header
from quixote.directory import Directory
from quixote import get_user, get_session, get_session_manager

from users import User
import misc
import template

from liberty import SOAPException, soap_call


class RootDirectory(Directory):
    _q_exports = ['login', 'singleSignOnArtifact',
            ('metadata.xml', 'metadata'), 'public_key']

    def _q_index(self):
        raise errors.AccessError()

    def login(self):
        return self.perform_login()

    def perform_login(self, idp = None):
        server = misc.get_lasso_server(protocol = 'saml2')
        if not server:
            return template.error_page(_('SAML 2.0 support not yet configured.'))
        login = lasso.Login(server)
        login.initAuthnRequest(idp, lasso.HTTP_METHOD_REDIRECT)
        login.request.nameIDPolicy.format = lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT
        login.request.nameIDPolicy.allowCreate = True
        login.request.forceAuthn = False
        login.request.isPassive = False
        # login.request.consent = /* XXX */
        login.buildAuthnRequestMsg()
        return redirect(login.msgUrl)
        

    def singleSignOnArtifact(self):
        server = misc.get_lasso_server(protocol = 'saml2')
        if not server:
            return template.error_page(_('SAML 2.0 support not yet configured.'))
        login = lasso.Login(server)
        request = get_request()
        login.initRequest(request.get_query(), lasso.HTTP_METHOD_ARTIFACT_GET)
        login.buildRequestMsg()
        try:
            soap_answer = soap_call(login.msgUrl, login.msgBody)
        except SOAPException:
            return template.error_page(_("Failure to communicate with identity provider"))

        login.processResponseMsg(soap_answer)

        login.acceptSso()
        session = get_session()
        if login.isSessionDirty:
            if login.session:
                session.lasso_session_dump = login.session.dump()
            else:
                session.lasso_session_dump = None
        user = self.lookup_user(session, login)
        if user:
            session.set_user(user.id)
        else:
            session.set_user('anonymous-%s' % login.nameIdentifier.content)
            session.lasso_anonymous_identity_dump = login.identity.dump()

        response = get_response()
        if session.after_url:
            after_url = session.after_url
            session.after_url = None
            return redirect(after_url)
        response.set_status(303)
        response.headers['location'] = urlparse.urljoin(request.get_url(), str('..'))
        response.content_type = 'text/plain'
        return "Your browser should redirect you"

    def lookup_user(self, session, login):
        ni = login.nameIdentifier.content
        session.name_identifier = ni
        nis = list(User.select(lambda x: ni in x.name_identifiers))
        if nis:
            user = nis[0]
        else:
            return None

        user.lasso_dump = login.identity.dump()
        user.store()
        return user


    def metadata(self):
        response = get_response()
        response.set_content_type('text/xml', 'utf-8')
        metadata = unicode(open(misc.get_abs_path(
                        misc.cfg['sp']['saml2_metadata'])).read(), 'utf-8')
        return metadata

    def public_key(self):
        response = get_response()
        response.set_content_type('application/octet-stream')
        publickey = file(misc.get_abs_path(misc.cfg['sp']['publickey'])).read()
        return publickey



