---
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