1.1 --- a/WebStack/Resources/OpenIDInitiation.py Tue Nov 13 23:15:50 2007 +0000
1.2 +++ b/WebStack/Resources/OpenIDInitiation.py Tue Nov 13 23:16:42 2007 +0000
1.3 @@ -105,6 +105,7 @@
1.4 self.show_success(trans, url)
1.5
1.6 # Redirect to the OpenID provider URL.
1.7 + # NOTE: Offer a POST-based form for redirection.
1.8
1.9 if self.use_redirect:
1.10 trans.redirect(url)
2.1 --- a/WebStack/Resources/OpenIDLogin.py Tue Nov 13 23:15:50 2007 +0000
2.2 +++ b/WebStack/Resources/OpenIDLogin.py Tue Nov 13 23:16:42 2007 +0000
2.3 @@ -84,6 +84,8 @@
2.4 password = fields_body.get("password", [""])[0]
2.5 app = fields_body.get("app", [""])[0]
2.6
2.7 + # NOTE: Permit flexibility in the credentials.
2.8 +
2.9 if self.authenticator.authenticate(trans, (local_id, username), password):
2.10 self._redirect(trans, claimed_id, local_id, username, app)
2.11 # The above method does not return.
2.12 @@ -106,6 +108,8 @@
2.13 self.show_verification(trans, valid)
2.14 # The above method does not return.
2.15
2.16 + # NOTE: Permit association requests here.
2.17 +
2.18 # Otherwise, show the login form.
2.19
2.20 fields_path = trans.get_fields_from_path(self.urlencoding)
2.21 @@ -164,6 +168,7 @@
2.22 url += "&%s=%s" % (name, trans.encode_path(value[0], self.urlencoding))
2.23
2.24 # Show the success page anyway.
2.25 + # NOTE: Offer a POST-based form for redirection.
2.26
2.27 self.show_success(trans, url)
2.28 if self.use_redirect:
3.1 --- a/WebStack/Resources/OpenIDRedirect.py Tue Nov 13 23:15:50 2007 +0000
3.2 +++ b/WebStack/Resources/OpenIDRedirect.py Tue Nov 13 23:16:42 2007 +0000
3.3 @@ -21,11 +21,37 @@
3.4 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
3.5 """
3.6
3.7 +from WebStack.Resources.LoginRedirect import LoginRedirectResource
3.8 from WebStack.Helpers.Auth import Verifier, check_openid_signature
3.9 import WebStack.Generic
3.10 import datetime
3.11 import urllib
3.12
3.13 +class OpenIDRedirectResource(LoginRedirectResource):
3.14 +
3.15 + "A resource redirecting to an OpenID initiation page."
3.16 +
3.17 + openid_ns = "http://specs.openid.net/auth/2.0"
3.18 +
3.19 + def respond(self, trans):
3.20 +
3.21 + "Respond using the given transaction 'trans'."
3.22 +
3.23 + fields_path = trans.get_fields_from_path(self.path_encoding)
3.24 +
3.25 + # If requested, attempt to verify OpenID assertions.
3.26 + # http://openid.net/specs/openid-authentication-2_0-12.html#rfc.section.11
3.27 +
3.28 + if fields_path.get("openid.ns", [None])[0] == self.openid_ns and \
3.29 + fields_path.get("openid.mode", [None])[0] == "id_res":
3.30 +
3.31 + if self.authenticator.authenticate(trans, verify=1):
3.32 + trans.redirect(fields_path["openid.return_to"][0])
3.33 +
3.34 + # Otherwise, handle the usual parameters and request details.
3.35 +
3.36 + LoginRedirectResource.respond(self, trans)
3.37 +
3.38 class OpenIDRedirectAuthenticator(Verifier):
3.39
3.40 """
3.41 @@ -52,56 +78,54 @@
3.42 self.replay_limit = replay_limit or self.replay_limit
3.43 self.urlencoding = urlencoding or self.encoding
3.44
3.45 - def authenticate(self, trans):
3.46 + def authenticate(self, trans, verify=0):
3.47
3.48 """
3.49 Authenticate the originator of 'trans', updating the object if
3.50 successful and returning a true value if successful, or a false value
3.51 otherwise.
3.52 +
3.53 + If the optional 'verify' parameter is specified as a true value, perform
3.54 + verification on any
3.55 """
3.56
3.57 - # First, try to authenticate with an application cookie.
3.58 -
3.59 - valid = Verifier.authenticate(self, trans)
3.60 + # If requested, attempt to verify OpenID assertions.
3.61
3.62 - # Without a valid login, attempt to verify OpenID assertions.
3.63 - # http://openid.net/specs/openid-authentication-2_0-12.html#rfc.section.11
3.64 -
3.65 - if not valid:
3.66 + if verify:
3.67 fields_path = trans.get_fields_from_path(self.urlencoding)
3.68
3.69 - if fields_path.get("openid.ns", [None])[0] == self.openid_ns and \
3.70 - fields_path.get("openid.mode", [None])[0] == "id_res":
3.71 -
3.72 - # NOTE: Could expose all errors.
3.73 + # NOTE: Could expose all errors.
3.74
3.75 - try:
3.76 -
3.77 - if self.test_url(fields_path) and \
3.78 - self.test_signature(fields_path) and \
3.79 - self.test_replay(fields_path):
3.80 + try:
3.81 + # Test the details of the assertion.
3.82
3.83 - self.set_token(trans, fields_path["openid.identity"][0])
3.84 + if self.test_url(fields_path) and \
3.85 + self.test_signature(fields_path) and \
3.86 + self.test_replay(fields_path):
3.87
3.88 - # NOTE: Should return true and let the redirector do this.
3.89 - trans.redirect(fields_path["openid.return_to"][0])
3.90 - #return 1
3.91 + self.set_token(trans, fields_path["openid.identity"][0])
3.92 + return 1
3.93
3.94 - # Incomplete assertion.
3.95 + # Incomplete assertion.
3.96
3.97 - except (KeyError, ValueError):
3.98 - raise
3.99 + except (KeyError, ValueError):
3.100 + raise
3.101
3.102 # Assertion failed or was incomplete.
3.103
3.104 return 0
3.105
3.106 - # Update the transaction with the user details.
3.107 + # Otherwise, try to authenticate with an application cookie.
3.108 +
3.109 + else:
3.110 + valid = Verifier.authenticate(self, trans)
3.111
3.112 - if valid:
3.113 - username, token = self.get_username_and_token(trans)
3.114 - trans.set_user(username)
3.115 - return valid
3.116 + # Update the transaction with the user details.
3.117 +
3.118 + if valid:
3.119 + username, token = self.get_username_and_token(trans)
3.120 + trans.set_user(username)
3.121 + return valid
3.122
3.123 def test_url(self, fields_path):
3.124