1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/XSLForms/Resources/Login.py Fri Jun 01 23:17:37 2007 +0000
1.3 @@ -0,0 +1,153 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +Login resources for XSLForms applications. These resources use "root" attributes
1.8 +on transaction objects, and therefore should be defined within the appropriate
1.9 +resources in site maps.
1.10 +
1.11 +Copyright (C) 2006, 2007 Paul Boddie <paul@boddie.org.uk>
1.12 +
1.13 +This software is free software; you can redistribute it and/or
1.14 +modify it under the terms of the GNU General Public License as
1.15 +published by the Free Software Foundation; either version 2 of
1.16 +the License, or (at your option) any later version.
1.17 +
1.18 +This software is distributed in the hope that it will be useful,
1.19 +but WITHOUT ANY WARRANTY; without even the implied warranty of
1.20 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.21 +GNU General Public License for more details.
1.22 +
1.23 +You should have received a copy of the GNU General Public
1.24 +License along with this library; see the file LICENCE.txt
1.25 +If not, write to the Free Software Foundation, Inc.,
1.26 +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1.27 +"""
1.28 +
1.29 +from WebStack.Generic import ContentType, EndOfResponse
1.30 +import XSLForms.Resources.WebResources
1.31 +
1.32 +import WebStack.Resources.LoginRedirect # LoginRedirectResource
1.33 +import WebStack.Resources.Login # get_target
1.34 +
1.35 +class LoginResource(XSLForms.Resources.WebResources.XSLFormsResource):
1.36 +
1.37 + """
1.38 + A login screen resource which should be modified or subclassed to define the
1.39 + following attributes:
1.40 +
1.41 + * resource_dir
1.42 + * template_resources - including a "login" entry for the login screen
1.43 + * document_resources - including a "translations" entry
1.44 +
1.45 + The latter attribute is optional.
1.46 +
1.47 + The login template must define a "login" action, and provide a document
1.48 + structure where the login credentials can be found through this class's
1.49 + 'path_to_login_element' attribute (which can be overridden or modified).
1.50 + Such a structure would be as follows for the default configuration:
1.51 +
1.52 + <login username="..." password="..."/>
1.53 + """
1.54 +
1.55 + path_to_login_element = "/login"
1.56 +
1.57 + def __init__(self, authenticator):
1.58 +
1.59 + """
1.60 + Initialise the resource with an 'authenticator'.
1.61 +
1.62 + To get the root of the application, this resource needs an attribute on
1.63 + the transaction called "root".
1.64 + """
1.65 +
1.66 + self.authenticator = authenticator
1.67 +
1.68 + def respond_to_form(self, trans, form):
1.69 +
1.70 + """
1.71 + Respond to a request having the given transaction 'trans' and the given
1.72 + 'form' information.
1.73 + """
1.74 +
1.75 + parameters = form.get_parameters()
1.76 + documents = form.get_documents()
1.77 + attributes = trans.get_attributes()
1.78 +
1.79 + # Ensure the presence of a document.
1.80 +
1.81 + if documents.has_key("login"):
1.82 + login = documents["login"]
1.83 + else:
1.84 + login = form.new_instance("login")
1.85 +
1.86 + # Test for login.
1.87 +
1.88 + if parameters.has_key("login"):
1.89 + logelem = login.xpath(self.path_to_login_element)[0]
1.90 + username = logelem.getAttribute("username")
1.91 + password = logelem.getAttribute("password")
1.92 +
1.93 + if self.authenticator.authenticate(trans, username, password):
1.94 + app, path, qs = WebStack.Resources.Login.get_target(trans)
1.95 + trans.redirect(app + trans.encode_path(path) + qs)
1.96 + else:
1.97 + error = login.createElement("error")
1.98 + logelem.appendChild(error)
1.99 + error.setAttribute("message", "Username or password not valid")
1.100 +
1.101 + # Start the response.
1.102 +
1.103 + trans.set_content_type(ContentType("application/xhtml+xml"))
1.104 + references = {}
1.105 +
1.106 + # Set up translations.
1.107 +
1.108 + if self.document_resources.has_key("translations"):
1.109 + translations_xml = self.prepare_document("translations")
1.110 +
1.111 + try:
1.112 + language = trans.get_content_languages()[0]
1.113 + except IndexError:
1.114 + language = "en"
1.115 +
1.116 + stylesheet_parameters = {"locale" : language}
1.117 + references["translations"] = translations_xml
1.118 +
1.119 + # Complete the response.
1.120 +
1.121 + trans_xsl = self.prepare_output("login")
1.122 + stylesheet_parameters["root"] = attributes["root"]
1.123 + self.send_output(trans, [trans_xsl], login, stylesheet_parameters, references=references)
1.124 +
1.125 +class LoginRedirectResource(WebStack.Resources.LoginRedirect.LoginRedirectResource):
1.126 +
1.127 + "A redirect resource which uses dynamic knowledge about the URL space."
1.128 +
1.129 + def __init__(self, host, path_to_login, *args, **kw):
1.130 +
1.131 + """
1.132 + Initialise the resource with the 'host', 'path_to_login' (the path from
1.133 + the root of the application to the login screen), and other
1.134 + LoginRedirectResource details.
1.135 +
1.136 + To get the root of the application, this resource needs an attribute on
1.137 + the transaction called "root".
1.138 +
1.139 + Examples of 'path_to_login' with "root" attribute and result:
1.140 +
1.141 + "login", "/" -> "/login"
1.142 + "login", "/app/" -> "/app/login"
1.143 + "app/login", "/" -> "/app/login"
1.144 + """
1.145 +
1.146 + self.host = host
1.147 + self.path_to_login = path_to_login
1.148 + WebStack.Resources.LoginRedirect.LoginRedirectResource.__init__(self, *args, **kw)
1.149 +
1.150 + def get_app_url(self, trans):
1.151 + return self.host
1.152 +
1.153 + def get_login_url(self, trans):
1.154 + return self.host + trans.get_attributes()["root"] + path_to_login
1.155 +
1.156 +# vim: tabstop=4 expandtab shiftwidth=4