XSLTools

XSLForms/Resources/Login.py

593:3298a294f6f9
2007-06-10 paulb [project @ 2007-06-10 22:48:40 by paulb] Added support for success pages, necessary for mod_python.
     1 #!/usr/bin/env python     2      3 """     4 Login resources for XSLForms applications. These resources use "root" attributes     5 on transaction objects, and therefore should be defined within the appropriate     6 resources in site maps.     7      8 Copyright (C) 2006, 2007 Paul Boddie <paul@boddie.org.uk>     9     10 This software is free software; you can redistribute it and/or    11 modify it under the terms of the GNU General Public License as    12 published by the Free Software Foundation; either version 2 of    13 the License, or (at your option) any later version.    14     15 This software is distributed in the hope that it will be useful,    16 but WITHOUT ANY WARRANTY; without even the implied warranty of    17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    18 GNU General Public License for more details.    19     20 You should have received a copy of the GNU General Public    21 License along with this library; see the file LICENCE.txt    22 If not, write to the Free Software Foundation, Inc.,    23 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA    24 """    25     26 from WebStack.Generic import ContentType, EndOfResponse    27 import XSLForms.Resources.WebResources    28     29 import WebStack.Resources.LoginRedirect # LoginRedirectResource    30 import WebStack.Resources.Login # get_target    31     32 class LoginResource(XSLForms.Resources.WebResources.XSLFormsResource):    33     34     """    35     A login screen resource which should be modified or subclassed to define the    36     following attributes:    37     38       * resource_dir    39       * template_resources - including a "login" entry for the login screen and    40                              a "success" entry for a screen indicating a    41                              successful login (used when redirects are not in    42                              use)    43       * document_resources - including a "translations" entry    44     45     The latter attribute is optional.    46     47     The login template must define a "login" action, and provide a document    48     structure where the login credentials can be found through this class's    49     'path_to_login_element' attribute (which can be overridden or modified).    50     Such a structure would be as follows for the default configuration:    51     52     <login username="..." password="..."/>    53     54     The success template must provide a document structure where the location of    55     the application can be found through this class's 'path_to_success_element'    56     attribute (which can be overridden or modified). Such a structure would be    57     as follows for the default configuration:    58     59     <success location="..."/>    60     """    61     62     path_to_login_element = "/login"    63     path_to_success_element = "/success"    64     65     def __init__(self, authenticator, use_redirect=1):    66     67         """    68         Initialise the resource with an 'authenticator'. If the optional    69         'use_redirect' parameter is specified and set to a false value (unlike    70         the default),     71     72         To get the root of the application, this resource needs an attribute on    73         the transaction called "root".    74         """    75     76         self.authenticator = authenticator    77         self.use_redirect = use_redirect    78     79     def respond_to_form(self, trans, form):    80     81         """    82         Respond to a request having the given transaction 'trans' and the given    83         'form' information.    84         """    85     86         parameters = form.get_parameters()    87         documents = form.get_documents()    88         attributes = trans.get_attributes()    89     90         # Ensure the presence of a document.    91     92         if documents.has_key("login"):    93             doc = documents["login"]    94         else:    95             doc = form.new_instance("login")    96     97         template_name = "login"    98     99         # NOTE: Consider initialisation of both the login and success documents.   100    101         # Test for login.   102    103         if parameters.has_key("login"):   104             logelem = doc.xpath(self.path_to_login_element)[0]   105             username = logelem.getAttribute("username")   106             password = logelem.getAttribute("password")   107    108             if self.authenticator.authenticate(trans, username, password):   109                 app, path, qs = WebStack.Resources.Login.get_target(trans)   110    111                 # Either redirect or switch to the success template.   112    113                 if self.use_redirect:   114                     trans.redirect(app + trans.encode_path(path) + qs)   115                 else:   116                     template_name = "success"   117                     doc = form.new_instance("success")   118                     successelem = doc.xpath(self.path_to_success_element)[0]   119                     successelem.setAttribute("location", app + trans.encode_path(path) + qs)   120             else:   121                 error = doc.createElement("error")   122                 logelem.appendChild(error)   123                 error.setAttribute("message", "Username or password not valid")   124    125         # Start the response.   126    127         trans.set_content_type(ContentType("application/xhtml+xml"))   128         stylesheet_parameters = {}   129         references = {}   130    131         # Set up translations.   132    133         if self.document_resources.has_key("translations"):   134             translations_xml = self.prepare_document("translations")   135    136             try:   137                 language = trans.get_content_languages()[0]   138             except IndexError:   139                 language = "en"   140    141             stylesheet_parameters["locale"] = language   142             references["translations"] = translations_xml   143    144         # Complete the response.   145    146         trans_xsl = self.prepare_output(template_name)   147         stylesheet_parameters["root"] = attributes["root"]   148         self.send_output(trans, [trans_xsl], doc, stylesheet_parameters, references=references)   149    150 class LoginRedirectResource(WebStack.Resources.LoginRedirect.LoginRedirectResource):   151    152     "A redirect resource which uses dynamic knowledge about the URL space."   153    154     def __init__(self, host, path_to_login, *args, **kw):   155    156         """   157         Initialise the resource with the 'host', 'path_to_login' (the path from   158         the root of the application to the login screen), and other   159         LoginRedirectResource details.   160    161         To get the root of the application, this resource needs an attribute on   162         the transaction called "root".   163    164         Examples of 'path_to_login' with "root" attribute and result:   165    166         "login", "/" -> "/login"   167         "login", "/app/" -> "/app/login"   168         "app/login", "/" -> "/app/login"   169         """   170    171         self.host = host   172         self.path_to_login = path_to_login   173         WebStack.Resources.LoginRedirect.LoginRedirectResource.__init__(self, *args, **kw)   174    175     def get_app_url(self, trans):   176         return self.host   177    178     def get_login_url(self, trans):   179         return self.host + trans.get_attributes()["root"] + self.path_to_login   180    181 # vim: tabstop=4 expandtab shiftwidth=4