From 4862200328845270c17c6c066e74493474e5c5c5 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 29 2015 09:27:26 +0000 Subject: [PATCH 1/6] Adjust flask_fas_openid to request the SSH key from FAS if asked to --- diff --git a/pagure/flask_fas_openid.py b/pagure/flask_fas_openid.py index 65646ae..dbe9d6c 100644 --- a/pagure/flask_fas_openid.py +++ b/pagure/flask_fas_openid.py @@ -34,7 +34,7 @@ import flask from openid.consumer import consumer from openid.fetchers import setDefaultFetcher, Urllib2Fetcher -from openid.extensions import pape, sreg +from openid.extensions import pape, sreg, ax from openid_cla import cla from openid_teams import teams @@ -130,6 +130,7 @@ class FAS(object): # pragma: no cover sreg_resp = sreg.SRegResponse.fromSuccessResponse(info) teams_resp = teams.TeamsResponse.fromSuccessResponse(info) cla_resp = cla.CLAResponse.fromSuccessResponse(info) + ssh_resp = ax.FetchResponse.fromSuccessResponse(info) user = {'fullname': '', 'username': '', 'email': '', 'timezone': '', 'cla_done': False, 'groups': []} if not sreg_resp: @@ -145,6 +146,9 @@ class FAS(object): # pragma: no cover if teams_resp: # The groups do not contain the cla_ groups user['groups'] = frozenset(teams_resp.teams) + if ssh_resp: + user['ssh_key'] = '\n'.join( + ssh_resp.get('http://fedoauth.org/openid/schema/SSH/key')) flask.session['FLASK_FAS_OPENID_USER'] = user flask.session.modified = True if self.postlogin_func is not None: @@ -175,7 +179,7 @@ class FAS(object): # pragma: no cover flask.g.fas_session_id = 0 # pylint: disable=R0913 - def login(self, return_url=None, cancel_url=None, groups=None): + def login(self, return_url=None, cancel_url=None, groups=None, ssh=False): """Tries to log in a user. Sets the user information on :attr:`flask.g.fas_user`. @@ -189,6 +193,8 @@ class FAS(object): # pragma: no cover :kwarg return_url: The URL to forward the user to after login :kwarg groups: A string or a list of group the user should belong to to be authentified. + :kwarg ssh: A boolean to specify if you want to retrieve the user's + public SSH key or not. :returns: True if the user was succesfully authenticated. :raises: Might raise an redirect to the OpenID endpoint """ @@ -219,6 +225,12 @@ class FAS(object): # pragma: no cover request.addExtension(teams.TeamsRequest(requested=groups)) request.addExtension(cla.CLARequest( requested=[cla.CLA_URI_FEDORA_DONE])) + if ssh is True: + req = ax.FetchRequest() + req.add(ax.AttrInfo( + type_uri='http://fedoauth.org/openid/schema/SSH/key', + count='unlimited')) + request.addExtension(req) trust_root = self.normalize_url(flask.request.url_root) return_to = trust_root + '_flask_fas_openid_handler/' From c4c400ec66e0f06a01a6cb4720a1faf1fab917b4 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 29 2015 09:28:17 +0000 Subject: [PATCH 2/6] Fix a typo --- diff --git a/pagure/__init__.py b/pagure/__init__.py index ddd978b..eb97c26 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -252,7 +252,7 @@ work. flask.url_for('auth_login', next=flask.request.url)) elif auth_method == 'fas' and not flask.g.fas_user.cla_done: flask.flash('You must sign the FPCA (Fedora Project Contributor ' - 'Agreement to use pagure', 'errors') + 'Agreement) to use pagure', 'errors') return flask.redirect(flask.url_for('.index')) return function(*args, **kwargs) return decorated_function From f686d0760886f2c3f6614a130465ff8a3a35f0bc Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 29 2015 09:28:28 +0000 Subject: [PATCH 3/6] Ask for the SSH key --- diff --git a/pagure/__init__.py b/pagure/__init__.py index eb97c26..bb97770 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -340,7 +340,7 @@ def auth_login(): # pragma: no cover admins = set(admins) if APP.config.get('PAGURE_AUTH', None) == 'fas': - return FAS.login(return_url=return_point, groups=admins) + return FAS.login(return_url=return_point, groups=admins, ssh=True) elif APP.config.get('PAGURE_AUTH', None) == 'local': form = pagure.login_forms.LoginForm() return flask.render_template( From b69b5ca89f9d3a0b773b15ad32834ea273fcefe2 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 29 2015 09:28:41 +0000 Subject: [PATCH 4/6] Forward the ssh key retrieved and set it up if there not one in place already --- diff --git a/pagure/__init__.py b/pagure/__init__.py index bb97770..b7052ab 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -287,11 +287,13 @@ def set_session(): def set_user(return_url): ''' After login method. ''' try: + pagure.lib.set_up_user( session=SESSION, username=flask.g.fas_user.username, fullname=flask.g.fas_user.fullname, default_email=flask.g.fas_user.email, + ssh_key=flask.g.fas_user.get('ssh_key') ) SESSION.commit() except SQLAlchemyError, err: diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index 64a6b3f..64d229c 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -1757,7 +1757,8 @@ def get_pull_request_flag_by_uid(session, flag_uid): return query.first() -def set_up_user(session, username, fullname, default_email, emails=None): +def set_up_user(session, username, fullname, default_email, + emails=None, ssh_key=None): ''' Set up a new user into the database or update its information. ''' user = search_user(session, username=username) if not user: @@ -1782,6 +1783,9 @@ def set_up_user(session, username, fullname, default_email, emails=None): for email in emails: add_email_to_user(session, user, email) + if ssh_key and not user.public_ssh_key: + user.public_ssh_key = ssh_key + return user From 8d79f534260f25297ee17fe7fecbce4df4903018 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 29 2015 15:37:50 +0000 Subject: [PATCH 5/6] Rename ssh_resp to ax_resp --- diff --git a/pagure/flask_fas_openid.py b/pagure/flask_fas_openid.py index dbe9d6c..e4b4219 100644 --- a/pagure/flask_fas_openid.py +++ b/pagure/flask_fas_openid.py @@ -130,7 +130,7 @@ class FAS(object): # pragma: no cover sreg_resp = sreg.SRegResponse.fromSuccessResponse(info) teams_resp = teams.TeamsResponse.fromSuccessResponse(info) cla_resp = cla.CLAResponse.fromSuccessResponse(info) - ssh_resp = ax.FetchResponse.fromSuccessResponse(info) + ax_resp = ax.FetchResponse.fromSuccessResponse(info) user = {'fullname': '', 'username': '', 'email': '', 'timezone': '', 'cla_done': False, 'groups': []} if not sreg_resp: @@ -146,9 +146,9 @@ class FAS(object): # pragma: no cover if teams_resp: # The groups do not contain the cla_ groups user['groups'] = frozenset(teams_resp.teams) - if ssh_resp: + if ax_resp: user['ssh_key'] = '\n'.join( - ssh_resp.get('http://fedoauth.org/openid/schema/SSH/key')) + ax_resp.get('http://fedoauth.org/openid/schema/SSH/key')) flask.session['FLASK_FAS_OPENID_USER'] = user flask.session.modified = True if self.postlogin_func is not None: From ca160e778fb7348ca55700f58531c1377f25ddb7 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jul 29 2015 15:45:47 +0000 Subject: [PATCH 6/6] Be more careful with the data retrieved - Ensure we got something back ('\n'.join(None) doesn't work) - Ensure that something is a list or a tuple (otherwise '\n'.join() won't work either - Ensure all the element of the list have something - Ensure there is something left at the end --- diff --git a/pagure/flask_fas_openid.py b/pagure/flask_fas_openid.py index e4b4219..7defe60 100644 --- a/pagure/flask_fas_openid.py +++ b/pagure/flask_fas_openid.py @@ -147,8 +147,17 @@ class FAS(object): # pragma: no cover # The groups do not contain the cla_ groups user['groups'] = frozenset(teams_resp.teams) if ax_resp: - user['ssh_key'] = '\n'.join( - ax_resp.get('http://fedoauth.org/openid/schema/SSH/key')) + ssh_keys = ax_resp.get( + 'http://fedoauth.org/openid/schema/SSH/key') + if isinstance(ssh_keys, (list, tuple)): + ssh_keys = '\n'.join( + ssh_key + for ssh_key in ssh_keys + if ssh_key.strip() + ) + if ssh_keys: + user['ssh_key'] = ssh_keys + flask.session['FLASK_FAS_OPENID_USER'] = user flask.session.modified = True if self.postlogin_func is not None: