1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/XSLForms/Resources/OpenIDInitiation.py Sun Feb 03 20:04:44 2008 +0000
1.3 @@ -0,0 +1,210 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +OpenID initiation resources for XSLForms applications. These resources use
1.8 +"root" attributes on transaction objects, and therefore should be defined within
1.9 +the appropriate resources in site maps.
1.10 +
1.11 +Copyright (C) 2006, 2007, 2008 Paul Boddie <paul@boddie.org.uk>
1.12 +
1.13 +This program is free software; you can redistribute it and/or modify it under
1.14 +the terms of the GNU Lesser General Public License as published by the Free
1.15 +Software Foundation; either version 3 of the License, or (at your option) any
1.16 +later version.
1.17 +
1.18 +This program is distributed in the hope that it will be useful, but WITHOUT
1.19 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.20 +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
1.21 +details.
1.22 +
1.23 +You should have received a copy of the GNU Lesser General Public License along
1.24 +with this program. If not, see <http://www.gnu.org/licenses/>.
1.25 +"""
1.26 +
1.27 +from WebStack.Generic import ContentType, EndOfResponse
1.28 +from WebStack.Resources.OpenIDInitiation import OpenIDInitiationUtils
1.29 +from XSLForms.Resources.WebResources import XSLFormsResource
1.30 +
1.31 +class OpenIDInitiationResource(XSLFormsResource, OpenIDInitiationUtils):
1.32 +
1.33 + """
1.34 + An initiation screen resource which should be modified or subclassed to
1.35 + define the following attributes:
1.36 +
1.37 + * resource_dir
1.38 + * template_resources - including an "initiation" entry for the initiation
1.39 + screen and a "success" entry for a screen
1.40 + indicating successful redirection to a provider
1.41 + (used when redirects are not in use)
1.42 + * document_resources - including a "translations" entry
1.43 +
1.44 + The latter attribute is optional.
1.45 +
1.46 + The initiation template must define an "initiation" action, and provide a
1.47 + document structure where the identity credentials can be found through this
1.48 + class's 'path_to_identity_element' attribute (which can be overridden or
1.49 + modified). Such a structure would be as follows for the default
1.50 + configuration:
1.51 +
1.52 + <initiation identity="..."/>
1.53 +
1.54 + The success template must provide a document structure where the location of
1.55 + the application can be found through this class's 'path_to_success_element'
1.56 + attribute (which can be overridden or modified). Such a structure would be
1.57 + as follows for the default configuration:
1.58 +
1.59 + <success mode="..." return_to="..." claimed_id="..." identity="..."/>
1.60 + """
1.61 +
1.62 + path_to_initiation_element = "/initiation"
1.63 + path_to_success_element = "/success"
1.64 +
1.65 + def __init__(self, openid_mode=None, use_redirect=1):
1.66 +
1.67 + """
1.68 + Initialise the resource.
1.69 +
1.70 + The optional 'openid_mode' parameter may be set to "checkid_immediate"
1.71 + or "checkid_setup" (the default).
1.72 +
1.73 + If the optional 'use_redirect' flag is set to a false value (which is
1.74 + not the default), a confirmation screen is given instead of immediately
1.75 + redirecting the user to the OpenID provider.
1.76 +
1.77 + To get the root of the application, this resource needs an attribute on
1.78 + the transaction called "root".
1.79 + """
1.80 +
1.81 + OpenIDInitiationUtils.__init__(self, openid_mode, use_redirect)
1.82 +
1.83 + def select_activity(self, trans, form):
1.84 + form.set_activity("initiation")
1.85 +
1.86 + def respond_to_input(self, trans, form):
1.87 + parameters = form.get_parameters()
1.88 +
1.89 + if parameters.has_key("app"):
1.90 + app = parameters["app"]
1.91 + else:
1.92 + app = trans.get_fields_from_path().get("app", [""])[0]
1.93 +
1.94 + if parameters.has_key("initiate"):
1.95 + self.check_identity(trans, form, app)
1.96 + # The above method does not return.
1.97 +
1.98 + # Otherwise, show the initiation form.
1.99 +
1.100 + self.show_initiation(trans, form, app)
1.101 +
1.102 + # Methods called by the OpenID logic.
1.103 +
1.104 + def check_identity(self, trans, form, app):
1.105 +
1.106 + """
1.107 + Check the identity found through 'trans' and 'fields', using 'app' and
1.108 + discovered information about the identity to redirect to the provider.
1.109 + """
1.110 +
1.111 + doc = form.get_document()
1.112 + parameters = form.get_parameters()
1.113 +
1.114 + initelem = doc.xpath(self.path_to_initiation_element)[0]
1.115 + identity = initelem.getAttribute("identity") or parameters.get("identity", [""])[0]
1.116 + claimed_identifier, provider, local_identifier = self.get_provider_url(trans, identity)
1.117 +
1.118 + if provider is not None:
1.119 + self.redirect_to_provider(trans, form, app, claimed_identifier, provider, local_identifier)
1.120 +
1.121 + def redirect_to_provider(self, trans, form, app, claimed_identifier, provider, local_identifier):
1.122 +
1.123 + """
1.124 + Redirect the client using 'trans', 'form' and the given 'app',
1.125 + 'claimed_identifier', 'provider' and 'local_identifier' details.
1.126 +
1.127 + See:
1.128 + http://openid.net/specs/openid-authentication-2_0-12.html#rfc.section.5.2
1.129 + http://openid.net/specs/openid-authentication-2_0-12.html#rfc.section.9
1.130 + """
1.131 +
1.132 + url = self.get_redirect_url(trans, app, claimed_identifier, provider, local_identifier)
1.133 +
1.134 + # Show the success page anyway.
1.135 + # Offer a POST-based form for redirection.
1.136 +
1.137 + self.show_success(trans, form, provider, app, claimed_identifier, local_identifier)
1.138 +
1.139 + # Redirect to the OpenID provider URL.
1.140 +
1.141 + if self.use_redirect:
1.142 + trans.redirect(url)
1.143 + else:
1.144 + raise WebStack.Generic.EndOfResponse
1.145 +
1.146 + def show_initiation(self, trans, form, app):
1.147 +
1.148 + """
1.149 + Writes a initiation screen using the transaction 'trans' and 'form',
1.150 + including details of the 'app' which the client was attempting to
1.151 + access.
1.152 + """
1.153 +
1.154 + doc = form.get_document()
1.155 + parameters = form.get_parameters()
1.156 +
1.157 + initelem = doc.xpath(self.path_to_initiation_element)[0]
1.158 + identity = initelem.getAttribute("identity") or parameters.get("identity", [""])[0]
1.159 + app = initelem.getAttribute("app") or parameters.get("app", [""])[0]
1.160 +
1.161 + initelem = doc.xpath(self.path_to_initiation_element)[0]
1.162 + initelem.setAttribute("identity", identity)
1.163 + initelem.setAttribute("app", app)
1.164 +
1.165 + def show_success(self, trans, form, provider, app, claimed_identifier, local_identifier):
1.166 +
1.167 + """
1.168 + Writes a success screen using the transaction 'trans' and 'form',
1.169 + including details of the OpenID 'provider', the 'app' URL,
1.170 + 'claimed_identifier' and 'local_identifier'.
1.171 + """
1.172 +
1.173 + # Switch to the success activity.
1.174 +
1.175 + form.set_activity("success")
1.176 + doc = form.new_instance("success")
1.177 + successelem = doc.xpath(self.path_to_success_element)[0]
1.178 + successelem.setAttribute("provider", provider)
1.179 + successelem.setAttribute("ns", self.openid_ns)
1.180 + successelem.setAttribute("mode", self.openid_mode)
1.181 + successelem.setAttribute("return_to", app)
1.182 + successelem.setAttribute("claimed_id", claimed_identifier)
1.183 + successelem.setAttribute("identity", local_identifier)
1.184 +
1.185 + form.set_document(doc)
1.186 +
1.187 + # Output preparation.
1.188 +
1.189 + def create_output(self, trans, form):
1.190 + attributes = trans.get_attributes()
1.191 +
1.192 + stylesheet_parameters = {}
1.193 + references = {}
1.194 +
1.195 + # Set up translations.
1.196 +
1.197 + if self.document_resources.has_key("translations"):
1.198 + translations_xml = self.prepare_document("translations")
1.199 +
1.200 + try:
1.201 + language = trans.get_content_languages()[0]
1.202 + except IndexError:
1.203 + language = "en"
1.204 +
1.205 + stylesheet_parameters["locale"] = language
1.206 + references["translations"] = translations_xml
1.207 +
1.208 + # Complete the response.
1.209 +
1.210 + stylesheet_parameters["root"] = attributes["root"]
1.211 + XSLFormsResource.create_output(self, trans, form, stylesheet_parameters=stylesheet_parameters, references=references)
1.212 +
1.213 +# vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/XSLForms/Resources/OpenIDLogin.py Sun Feb 03 00:13:42 2008 +0000
2.2 +++ b/XSLForms/Resources/OpenIDLogin.py Sun Feb 03 20:04:44 2008 +0000
2.3 @@ -1,7 +1,7 @@
2.4 #!/usr/bin/env python
2.5
2.6 """
2.7 -OpenID Login resources for XSLForms applications. These resources use "root"
2.8 +OpenID login resources for XSLForms applications. These resources use "root"
2.9 attributes on transaction objects, and therefore should be defined within the
2.10 appropriate resources in site maps.
2.11
2.12 @@ -22,11 +22,9 @@
2.13 """
2.14
2.15 from WebStack.Generic import ContentType, EndOfResponse
2.16 -from WebStack.Resources.OpenIDLogin import OpenIDLoginUtils
2.17 +from WebStack.Resources.OpenIDLogin import OpenIDLoginUtils, Authenticator
2.18 from XSLForms.Resources.WebResources import XSLFormsResource
2.19
2.20 -import WebStack.Resources.OpenIDRedirect # LoginRedirectResource
2.21 -
2.22 class OpenIDLoginResource(XSLFormsResource, OpenIDLoginUtils):
2.23
2.24 """
2.25 @@ -76,9 +74,7 @@
2.26 the transaction called "root".
2.27 """
2.28
2.29 - OpenIDLoginUtils.__init__(self, associations, use_redirect)
2.30 - self.app_url = app_url
2.31 - self.authenticator = authenticator
2.32 + OpenIDLoginUtils.__init__(self, app_url, authenticator, associations, use_redirect)
2.33
2.34 def select_activity(self, trans, form):
2.35 form.set_activity("login")
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/XSLForms/Resources/OpenIDRedirect.py Sun Feb 03 20:04:44 2008 +0000
3.3 @@ -0,0 +1,59 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +"""
3.7 +OpenID redirection resources for XSLForms applications. These resources use
3.8 +"root" attributes on transaction objects, and therefore should be defined within
3.9 +the appropriate resources in site maps.
3.10 +
3.11 +Copyright (C) 2006, 2007, 2008 Paul Boddie <paul@boddie.org.uk>
3.12 +
3.13 +This program is free software; you can redistribute it and/or modify it under
3.14 +the terms of the GNU Lesser General Public License as published by the Free
3.15 +Software Foundation; either version 3 of the License, or (at your option) any
3.16 +later version.
3.17 +
3.18 +This program is distributed in the hope that it will be useful, but WITHOUT
3.19 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.20 +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
3.21 +details.
3.22 +
3.23 +You should have received a copy of the GNU Lesser General Public License along
3.24 +with this program. If not, see <http://www.gnu.org/licenses/>.
3.25 +"""
3.26 +
3.27 +import WebStack.Resources.OpenIDRedirect # OpenIDRedirectResource
3.28 +
3.29 +OpenIDRedirectAuthenticator = WebStack.Resources.OpenIDRedirect.OpenIDRedirectAuthenticator
3.30 +
3.31 +class OpenIDRedirectResource(WebStack.Resources.OpenIDRedirect.OpenIDRedirectResource):
3.32 +
3.33 + "A redirect resource which uses dynamic knowledge about the URL space."
3.34 +
3.35 + def __init__(self, host, path_to_login, *args, **kw):
3.36 +
3.37 + """
3.38 + Initialise the resource with the 'host', 'path_to_login' (the path from
3.39 + the root of the application to the login screen), and other
3.40 + LoginRedirectResource details.
3.41 +
3.42 + To get the root of the application, this resource needs an attribute on
3.43 + the transaction called "root".
3.44 +
3.45 + Examples of 'path_to_login' with "root" attribute and result:
3.46 +
3.47 + "login", "/" -> "/login"
3.48 + "login", "/app/" -> "/app/login"
3.49 + "app/login", "/" -> "/app/login"
3.50 + """
3.51 +
3.52 + self.host = host
3.53 + self.path_to_login = path_to_login
3.54 + WebStack.Resources.OpenIDRedirect.OpenIDRedirectResource.__init__(self, *args, **kw)
3.55 +
3.56 + def get_app_url(self, trans):
3.57 + return self.host
3.58 +
3.59 + def get_login_url(self, trans):
3.60 + return self.host + trans.get_attributes()["root"] + self.path_to_login
3.61 +
3.62 +# vim: tabstop=4 expandtab shiftwidth=4