[PATCH] Update flask_fas_openid to latest upstream version

Pierre-Yves Chibon pingou at pingoured.fr
Fri Sep 27 10:14:13 UTC 2013


---

We have seen some issues when trying to login on stg in our apps.

This commit update a hotfix of flask_fas_openid to use the latest version from
upstream git.

I know we are not in freeze, but I still would like to get a couple of +1 before
pushing it to make sure we are on the same page.


Thanks,
Pierre

 .../hotfix/files/python-fedora/flask_fas_openid.py |   51 ++++++++++++++-----
 1 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/modules-staging/hotfix/files/python-fedora/flask_fas_openid.py b/modules-staging/hotfix/files/python-fedora/flask_fas_openid.py
index 8810230..b951fb5 100644
--- a/modules-staging/hotfix/files/python-fedora/flask_fas_openid.py
+++ b/modules-staging/hotfix/files/python-fedora/flask_fas_openid.py
@@ -39,10 +39,10 @@ import openid
 from openid.consumer import consumer
 from openid.fetchers import setDefaultFetcher, Urllib2Fetcher
 from openid.extensions import pape, sreg
+from openid_cla import cla
+from openid_teams import teams
 
 from fedora import __version__
-import fedora._openid_extensions.openid_teams as teams
-import fedora._openid_extensions.openid_cla as cla
 
 class FAS(object):
 
@@ -68,8 +68,9 @@ class FAS(object):
     def _handle_openid_request(self):
         return_url = flask.session['FLASK_FAS_OPENID_RETURN_URL']
         cancel_url = flask.session['FLASK_FAS_OPENID_CANCEL_URL']
+        base_url = self.normalize_url(flask.request.base_url)
         oidconsumer = consumer.Consumer(flask.session, None)
-        info = oidconsumer.complete(flask.request.values, flask.request.base_url)
+        info = oidconsumer.complete(flask.request.values, base_url)
         display_identifier = info.getDisplayIdentifier()
 
         if info.status == consumer.FAILURE and display_identifier:
@@ -83,14 +84,18 @@ class FAS(object):
             pape_resp = pape.Response.fromSuccessResponse(info)
             teams_resp = teams.TeamsResponse.fromSuccessResponse(info)
             cla_resp = cla.CLAResponse.fromSuccessResponse(info)
-            user = dict()
+            user = {'fullname': '', 'username': '', 'email': '', 'timezone': '', 'cla_done': False, 'groups': []}
+            if not sreg_resp:
+                # If we have no basic info, be gone with them!
+                return flask.redirect(cancel_url)
             user['username'] = sreg_resp.get('nickname')
             user['fullname'] = sreg_resp.get('fullname')
             user['email'] = sreg_resp.get('email')
             user['timezone'] = sreg_resp.get('timezone')
-            #user['locale'] = sreg_resp.get('LOCALE')
-            user['cla_done'] = cla.CLA_URI_FEDORA_DONE in cla_resp.clas
-            user['groups'] = teams_resp.teams   # The groups do not contain the cla_ groups
+            if cla_resp:
+                user['cla_done'] = cla.CLA_URI_FEDORA_DONE in cla_resp.clas
+            if teams_resp:
+                user['groups'] = frozenset(teams_resp.teams) # The groups do not contain the cla_ groups
             flask.session['FLASK_FAS_OPENID_USER'] = user
             flask.session.modified = True
             return flask.redirect(return_url)
@@ -112,21 +117,26 @@ class FAS(object):
             flask.g.fas_user = Bunch.fromDict(user)
         flask.g.fas_session_id = 0
 
-    def login(self, username=None, password=None, return_url=None, cancel_url=None):
+    def login(self, username=None, password=None, return_url=None,
+              cancel_url=None, groups=['_FAS_ALL_GROUPS_']):
         """Tries to log in a user.
 
         Sets the user information on :attr:`flask.g.fas_user`.
         Will set 0 to :attr:`flask.g.fas_session_id, for compatibility
         with flask_fas.
 
-        :arg username: Not used, but accepted for compatibility with the flask_fas module
-        :arg password: Not used, but accepted for compatibility with the flask_fas module
+        :arg username: Not used, but accepted for compatibility with the
+           flask_fas module
+        :arg password: Not used, but accepted for compatibility with the
+           flask_fas module
         :arg return_url: The URL to forward the user to after login
+        :arg groups: A string or a list of group the user should belong to
+           to be authentified.
         :returns: True if the user was succesfully authenticated.
         :raises: Might raise an redirect to the OpenID endpoint
         """
         if return_url is None:
-            if 'next' in flask.request.args.values:
+            if 'next' in flask.request.args.values():
                 return_url = flask.request.args.values['next']
             else:
                 return_url = flask.request.url
@@ -139,12 +149,18 @@ class FAS(object):
         if request is None:
             # Also very strange, as this means the discovered OpenID endpoint is no OpenID endpoint
             return 'no-request'
+
+        if isinstance(groups, basestring):
+           groups = [groups]
+
         request.addExtension(sreg.SRegRequest(required=['nickname', 'fullname', 'email', 'timezone']))
         request.addExtension(pape.Request([]))
-        request.addExtension(teams.TeamsRequest(requested=['_FAS_ALL_GROUPS_'])) # Magic value which requests all groups from FAS-OpenID >= 0.2.0
+        request.addExtension(teams.TeamsRequest(requested=groups))
         request.addExtension(cla.CLARequest(requested=[cla.CLA_URI_FEDORA_DONE]))
-        trust_root = flask.request.url_root
-        return_to = flask.request.url_root + '_flask_fas_openid_handler/'
+
+        trust_root = self.normalize_url(flask.request.url_root)
+        return_to = trust_root + '_flask_fas_openid_handler/'
+
         flask.session['FLASK_FAS_OPENID_RETURN_URL'] = return_url
         flask.session['FLASK_FAS_OPENID_CANCEL_URL'] = cancel_url
         if request.shouldSendRedirect():
@@ -161,6 +177,13 @@ class FAS(object):
         flask.g.fas_user = None
         flask.session.modified = True
 
+    def normalize_url(self, url):
+        ''' Replace the scheme prefix of a url with our preferred scheme.
+        '''
+        scheme = self.app.config['PREFERRED_URL_SCHEME']
+        scheme_index = url.index('://')
+        return scheme + url[scheme_index:]
+
 
 # This is a decorator we can use with any HTTP method (except login, obviously)
 # to require a login.
-- 
1.7.2.1



More information about the infrastructure mailing list