Blame pagure/ui/oidc_login.py

Pierre-Yves Chibon b130e5
# -*- coding: utf-8 -*-
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
"""
Pierre-Yves Chibon b130e5
 (c) 2014-2017 - Copyright Red Hat Inc
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
 Authors:
Pierre-Yves Chibon b130e5
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
"""
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Aurélien Bompard dcf6f6
Pierre-Yves Chibon b130e5
import logging
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
import flask
Mary Kate Fain a16918
from flask import Markup
Pierre-Yves Chibon b130e5
import munch
Pierre-Yves Chibon b130e5
from sqlalchemy.exc import SQLAlchemyError
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon 930073
import pagure.lib.query
Pierre-Yves Chibon b130e5
from pagure.config import config as pagure_config
Pierre-Yves Chibon b130e5
from pagure.flask_app import logout
Pierre-Yves Chibon b130e5
from pagure.utils import is_admin
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
from flask_oidc import OpenIDConnect
Pierre-Yves Chibon 9c2953
Pierre-Yves Chibon b130e5
oidc = OpenIDConnect()
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
_log = logging.getLogger(__name__)
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
def fas_user_from_oidc():
Karsten Hopp f96f02
    if "oidc_cached_userdata" in flask.session:
Karsten Hopp f96f02
        flask.g.fas_user = munch.Munch(**flask.session["oidc_cached_userdata"])
Karsten Hopp f96f02
    elif oidc.user_loggedin and "oidc_logintime" in flask.session:
Pierre-Yves Chibon b130e5
        email_key, fulln_key, usern_key, ssh_key, groups_key = [
Pierre-Yves Chibon 9c2953
            pagure_config["OIDC_PAGURE_EMAIL"],
Pierre-Yves Chibon 9c2953
            pagure_config["OIDC_PAGURE_FULLNAME"],
Pierre-Yves Chibon 9c2953
            pagure_config["OIDC_PAGURE_USERNAME"],
Pierre-Yves Chibon 9c2953
            pagure_config["OIDC_PAGURE_SSH_KEY"],
Pierre-Yves Chibon 9c2953
            pagure_config["OIDC_PAGURE_GROUPS"],
Pierre-Yves Chibon b130e5
        ]
Pierre-Yves Chibon b130e5
        info = oidc.user_getinfo(
Pierre-Yves Chibon b130e5
            [email_key, fulln_key, usern_key, ssh_key, groups_key]
Pierre-Yves Chibon b130e5
        )
Pierre-Yves Chibon b130e5
        username = info.get(usern_key)
Pierre-Yves Chibon b130e5
        if not username:
Pierre-Yves Chibon 9c2953
            fb = pagure_config["OIDC_PAGURE_USERNAME_FALLBACK"]
Pierre-Yves Chibon 9c2953
            if fb == "email":
Pierre-Yves Chibon 9c2953
                username = info[email_key].split("@")[0]
Pierre-Yves Chibon 9c2953
            elif fb == "sub":
Pierre-Yves Chibon 9c2953
                username = flask.g.oidc_id_token["sub"]
Pierre-Yves Chibon b130e5
        flask.g.fas_user = munch.Munch(
Pierre-Yves Chibon b130e5
            username=username,
Pierre-Yves Chibon 9c2953
            fullname=info.get(fulln_key, ""),
Pierre-Yves Chibon b130e5
            email=info[email_key],
Pierre-Yves Chibon b130e5
            ssh_key=info.get(ssh_key),
Pierre-Yves Chibon b130e5
            groups=info.get(groups_key, []),
Pierre-Yves Chibon 9c2953
            login_time=flask.session["oidc_logintime"],
Pierre-Yves Chibon b130e5
        )
Karsten Hopp f96f02
        flask.session["oidc_cached_userdata"] = dict(flask.g.fas_user)
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
def set_user():
Pierre-Yves Chibon b130e5
    if flask.g.fas_user.username is None:
Pierre-Yves Chibon b130e5
        flask.flash(
Pierre-Yves Chibon 9c2953
            "It looks like your Identity Provider did not provide an "
Pierre-Yves Chibon 9c2953
            "username we could retrieve, username being needed we cannot "
Pierre-Yves Chibon 9c2953
            "go further.",
Pierre-Yves Chibon 9c2953
            "error",
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon b130e5
        logout()
Pierre-Yves Chibon b130e5
        return
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon 9c2953
    flask.session["_new_user"] = False
Pierre-Yves Chibon 930073
    if not pagure.lib.query.search_user(
Pierre-Yves Chibon 9c2953
        flask.g.session, username=flask.g.fas_user.username
Pierre-Yves Chibon 9c2953
    ):
Pierre-Yves Chibon 9c2953
        flask.session["_new_user"] = True
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
    try:
Pierre-Yves Chibon 930073
        pagure.lib.query.set_up_user(
Pierre-Yves Chibon b130e5
            session=flask.g.session,
Pierre-Yves Chibon b130e5
            username=flask.g.fas_user.username,
Pierre-Yves Chibon b130e5
            fullname=flask.g.fas_user.fullname,
Pierre-Yves Chibon b130e5
            default_email=flask.g.fas_user.email,
Pierre-Yves Chibon 9c2953
            ssh_key=flask.g.fas_user.get("ssh_key"),
Pierre-Yves Chibon 9c2953
            keydir=pagure_config.get("GITOLITE_KEYDIR", None),
Pierre-Yves Chibon b130e5
        )
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
        # If groups are managed outside pagure, set up the user at login
Pierre-Yves Chibon 9c2953
        if not pagure_config.get("ENABLE_GROUP_MNGT", False):
Pierre-Yves Chibon 930073
            user = pagure.lib.query.search_user(
Pierre-Yves Chibon 9c2953
                flask.g.session, username=flask.g.fas_user.username
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon b130e5
            old_groups = set(user.groups)
Pierre-Yves Chibon b130e5
            fas_groups = set(flask.g.fas_user.groups)
Pierre-Yves Chibon b130e5
            # Add the new groups
Pierre-Yves Chibon b130e5
            for group in fas_groups - old_groups:
Pierre-Yves Chibon b130e5
                groupobj = None
Pierre-Yves Chibon b130e5
                if group:
Pierre-Yves Chibon 930073
                    groupobj = pagure.lib.query.search_groups(
Pierre-Yves Chibon 9c2953
                        flask.g.session, group_name=group
Pierre-Yves Chibon 9c2953
                    )
Pierre-Yves Chibon b130e5
                if groupobj:
Pierre-Yves Chibon b130e5
                    try:
Pierre-Yves Chibon 930073
                        pagure.lib.query.add_user_to_group(
Pierre-Yves Chibon b130e5
                            session=flask.g.session,
Pierre-Yves Chibon b130e5
                            username=flask.g.fas_user.username,
Pierre-Yves Chibon b130e5
                            group=groupobj,
Pierre-Yves Chibon b130e5
                            user=flask.g.fas_user.username,
Pierre-Yves Chibon b130e5
                            is_admin=is_admin(),
Pierre-Yves Chibon b130e5
                            from_external=True,
Pierre-Yves Chibon b130e5
                        )
Pierre-Yves Chibon b130e5
                    except pagure.exceptions.PagureException as err:
Pierre-Yves Chibon b130e5
                        _log.error(err)
Pierre-Yves Chibon b130e5
            # Remove the old groups
Pierre-Yves Chibon b130e5
            for group in old_groups - fas_groups:
Pierre-Yves Chibon b130e5
                if group:
Pierre-Yves Chibon b130e5
                    try:
Pierre-Yves Chibon 930073
                        pagure.lib.query.delete_user_of_group(
Pierre-Yves Chibon b130e5
                            session=flask.g.session,
Pierre-Yves Chibon b130e5
                            username=flask.g.fas_user.username,
Pierre-Yves Chibon b130e5
                            groupname=group,
Pierre-Yves Chibon b130e5
                            user=flask.g.fas_user.username,
Pierre-Yves Chibon b130e5
                            is_admin=is_admin(),
Pierre-Yves Chibon b130e5
                            force=True,
Pierre-Yves Chibon b130e5
                            from_external=True,
Pierre-Yves Chibon b130e5
                        )
Pierre-Yves Chibon b130e5
                    except pagure.exceptions.PagureException as err:
Pierre-Yves Chibon b130e5
                        _log.error(err)
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
        flask.g.session.commit()
Pierre-Yves Chibon b130e5
    except SQLAlchemyError as err:
Pierre-Yves Chibon b130e5
        flask.g.session.rollback()
Pierre-Yves Chibon b130e5
        _log.exception(err)
Mary Kate Fain a16918
        message = Markup(
Mary Kate Fain a16918
            "Could not set up you as a user properly,"
Mary Kate Fain a16918
            ' please contact an administrator'
Pierre-Yves Chibon 9c2953
        )
Mary Kate Fain a16918
        flask.flash(message, "error")
Pierre-Yves Chibon b130e5
        # Ensure the user is logged out if we cannot set them up
Pierre-Yves Chibon b130e5
        # correctly
Pierre-Yves Chibon b130e5
        logout()
Slavek Kabrda a17304
Slavek Kabrda a17304
Slavek Kabrda a17304
def oidc_logout():
Slavek Kabrda a17304
    flask.g.fas_user = None
Pierre-Yves Chibon 9c2953
    del flask.session["oidc_logintime"]
Karsten Hopp f96f02
    del flask.session["oidc_cached_userdata"]
Slavek Kabrda a17304
    oidc.logout()