diff -crB src.orig/webfaf/config.py src/webfaf/config.py *** src.orig/webfaf/config.py 2021-02-11 11:31:10.000000000 +0200 --- src/webfaf/config.py 2021-02-11 11:43:27.000000000 +0200 *************** *** 10,15 **** --- 10,16 ---- class Config(object): + SAML_CONFIG_DIR = '/etc/faf/saml' DEBUG = False TESTING = False SECRET_KEY = 'NOT_A_RANDOM_STRING' diff -crB src.orig/webfaf/login.py src/webfaf/login.py *** src.orig/webfaf/login.py 2021-02-11 11:31:10.000000000 +0200 --- src/webfaf/login.py 2021-02-11 11:44:30.000000000 +0200 *************** *** 1,56 **** import flask from openid_teams import teams from werkzeug.wrappers import Response from pyfaf.storage.user import User from webfaf.webfaf_main import db, oid, app from webfaf.utils import fed_raw_name ! login = flask.Blueprint("login", __name__) ! @login.route("/login/", methods=["GET"]) ! @oid.loginhandler ! def do_login() -> Response: ! if flask.g.user is not None: ! return flask.redirect(oid.get_next_url()) ! ! teams_req = teams.TeamsRequest(app.config["OPENID_PRIVILEGED_TEAMS"]) ! return oid.try_login("https://id.fedoraproject.org/", ! ask_for=["email"], extensions=[teams_req]) ! ! ! @oid.after_login ! def create_or_login(resp) -> Response: ! flask.session["openid"] = resp.identity_url ! username = fed_raw_name(resp.identity_url) privileged = False ! # "lp" is the namespace for openid-teams ! if "lp" in resp.extensions and any(group in app.config["OPENID_PRIVILEGED_TEAMS"] ! for group in resp.extensions["lp"].teams): privileged = True user = db.session.query(User).filter(User.username == username).first() if not user: # create ! user = User(username=username, mail=resp.email, privileged=privileged) else: ! user.mail = resp.email user.privileged = privileged db.session.add(user) db.session.commit() flask.flash(u"Welcome, {0}".format(user.username)) flask.g.user = user ! if flask.request.url_root == oid.get_next_url(): ! return flask.redirect(flask.url_for("summary.index")) ! return flask.redirect(oid.get_next_url()) @login.route("/logout/") def do_logout() -> Response: ! flask.session.pop("openid", None) flask.flash(u"You were signed out") ! return flask.redirect(oid.get_next_url()) --- 1,113 ---- import flask from openid_teams import teams from werkzeug.wrappers import Response + from urllib.parse import urlparse, urljoin from pyfaf.storage.user import User from webfaf.webfaf_main import db, oid, app from webfaf.utils import fed_raw_name + from onelogin.saml2.auth import OneLogin_Saml2_Auth ! login = flask.Blueprint('login', __name__) ! def init_saml_auth(req): ! saml_config_dir = app.config['SAML_CONFIG_DIR'] ! return OneLogin_Saml2_Auth(req, custom_base_path=saml_config_dir) ! ! ! def prepare_flask_request(req): ! parsed_url = urlparse(req.url) ! return { ! 'https': 'on' if req.scheme == 'https' else 'off', ! 'http_host': req.host, ! 'server_port': parsed_url.port, ! 'script_name': req.script_root + req.path, ! 'get_data': req.args.copy(), ! 'post_data': req.form.copy(), ! 'query_string': req.query_string ! } ! ! ! @login.route('/login/', methods=('GET',)) ! def do_login(): ! """SSO authentication entry-point.""" ! req = prepare_flask_request(flask.request) ! comeback_url = urljoin(flask.request.host_url, '/faf/summary') ! return_to = flask.request.args.get('return_to') ! if return_to: ! comeback_url += '?return_to={0}'.format(return_to) ! auth = init_saml_auth(req) ! return flask.redirect(auth.login(comeback_url)) ! ! ! @login.route('/acs/', methods=('POST',)) ! def acs(): ! req = prepare_flask_request(flask.request) ! auth = init_saml_auth(req) ! auth.process_response() ! errors = auth.get_errors() ! if errors: ! return flask.helpers.make_response('Error: {0}'.format(', '.join(errors)), 500) ! elif not auth.is_authenticated(): ! return flask.helpers.make_response('Error: authentication failed', 401) ! user_attrs = auth.get_attributes() privileged = False ! is_admin = False ! if any(group in user_attrs['groups'] for group in ('alma_retrace_admin', 'admins')): privileged = True + is_admin = True + email = user_attrs['email'][0] + username = email.split('@')[0] user = db.session.query(User).filter(User.username == username).first() if not user: # create ! user = User(username=username, mail=email, privileged=privileged, admin=is_admin) else: ! user.mail = email user.privileged = privileged + user.admin = is_admin db.session.add(user) db.session.commit() flask.flash(u"Welcome, {0}".format(user.username)) flask.g.user = user + flask.session['username'] = username ! return flask.redirect(flask.request.form['RelayState']) ! ! @login.route('/metadata/', methods=('GET',)) ! def metadata(): ! """ ! Returns the Build System IDP provider metadata. ! ! Returns ! ------- ! flask.wrappers.Response ! IDP provider metadata response. ! ! See Also ! -------- ! https://en.wikipedia.org/wiki/SAML_Metadata#Identity_Provider_Metadata ! """ ! req = prepare_flask_request(flask.request) ! auth = init_saml_auth(req) ! settings = auth.get_settings() ! metadata = settings.get_sp_metadata() ! errors = settings.validate_metadata(metadata) ! if errors: ! rsp = flask.make_response(', '.join(errors), 500) ! else: ! rsp = flask.make_response(metadata, 200) ! rsp.headers['Content-Type'] = 'text/xml' ! return rsp @login.route("/logout/") def do_logout() -> Response: ! flask.session.pop("username", None) flask.flash(u"You were signed out") ! return flask.redirect(flask.url_for("summary.index")) ! diff -crB src.orig/webfaf/templates/base.html src/webfaf/templates/base.html *** src.orig/webfaf/templates/base.html 2021-02-11 11:31:12.000000000 +0200 --- src/webfaf/templates/base.html 2021-02-11 13:09:20.000000000 +0200 *************** *** 71,77 **** {% if config['OPENID_ENABLED'] %}