def login() -> Union[str, Response]:
    """User login page."""
    if current_user.get_id():
        next_url = request.args.get("next", default="/")

        if is_safe_url(next_url, app.config["ALLOWED_HOSTS"]) is False:
            return abort(400)

        return redirect(next_url)

    # if demo, login as first user
    if app.config.get("DEMO"):

        session.pop("_flashes", None)

        user = User.query.first()

        if user:
            login_user(user, remember=True)
        else:
            flash("Something broke!")

        next_url = request.args.get("next", default="/")

        if is_safe_url(next_url, app.config["ALLOWED_HOSTS"]) is False:
            return abort(400)

        return redirect(next_url)

    if request.method == "POST" and app.config["AUTH_METHOD"] in ["LDAP", "DEV"]:
        user = request.form.get("user", "")
        password = request.form.get("password", "")

        if app.config["AUTH_METHOD"] == "LDAP":  # pragma: no cover
            ldap = LDAP(app)  # type: ignore[no-untyped-call]
            ldap_details = ldap.bind_user(user, password)  # type: ignore[no-untyped-call]

            if ldap_details is None or password == "":  # noqa: S105
                executor.submit(log_login, request.form["user"], 3)

                flash("Invalid login, please try again!")
                return render_template("pages/login.html.j2", title="Login")

            # require specific user group
            # fmt: off
            if "REQUIRED_GROUPS" in app.config and not set(
                app.config["REQUIRED_GROUPS"]
            ).issubset(
                set(ldap.get_user_groups(user=user.lower()))  # type: ignore[no-untyped-call]
            ):
                executor.submit(log_login, request.form["user"], 3)

                flash(
                    "You must be part of the %s group(s) to use this site."
                    % app.config["REQUIRED_GROUPS"]
                )
                return render_template("pages/login.html.j2", title="Login")
            # fmt: on
            executor.submit(log_login, request.form["user"], 1)

            user = User.query.filter(
                (User.account_name == user.lower()) | (User.email == user.lower())
            ).first()

            # if user isn't existing, create
            if not user:
                user = User()  # type: ignore[call-arg]

            # update user attributes
            user.account_name = (
                ldap_details.get(app.config["LDAP_ATTR_MAP"]["account_name"])[0]
                .decode("utf-8")
                .lower()
            )
            user.email = (
                ldap_details.get(app.config["LDAP_ATTR_MAP"]["email"])[0]
                .decode("utf-8")
                .lower()
            )
            user.full_name = ldap_details.get(app.config["LDAP_ATTR_MAP"]["full_name"])[
                0
            ].decode("utf-8")
            user.first_name = ldap_details.get(
                app.config["LDAP_ATTR_MAP"]["first_name"]
            )[0].decode("utf-8")

            db.session.add(user)
            db.session.commit()

            login_user(user, remember=True)

            next_url = request.args.get("next", default="/")

            if is_safe_url(next_url, app.config["ALLOWED_HOSTS"]) is False:
                return abort(400)

            return redirect(next_url)

        if app.config["AUTH_METHOD"] == "DEV":  # pragma: no cover
            user = User.query.filter(
                (User.account_name == user.lower()) | (User.email == user.lower())
            ).first()

            if user:
                login_user(user, remember=True)
            else:
                flash("Invalid login, please try again!")

            next_url = request.args.get("next", default="/")

            if is_safe_url(next_url, app.config["ALLOWED_HOSTS"]) is False:
                return abort(400)

            return redirect(next_url)

        # if login methods fail, add flash message
        flash("Invalid login, please try again!")

    # saml does not have a login page but redirects to idp
    if app.config["AUTH_METHOD"] == "SAML":  # pragma: no cover
        saml = SAML(app)
        saml_client = saml.saml_client_for()
        # pylint: disable=W0612
        reqid, info = saml_client.prepare_for_authenticate()

        redirect_url = ""
        # Select the IdP URL to send the AuthN request to
        for key, value in info["headers"]:
            if key == "Location":
                redirect_url = value

        # add next url to request to be appropriatly redirected
        # after a successful login
        next_url = request.args.get("next", "/")
        if is_safe_url(next_url, app.config["ALLOWED_HOSTS"]):
            redirect_url += "&RelayState=" + next_url

        return redirect(redirect_url)

    return render_template("pages/login.html.j2", title="Login")
def idp_initiated() -> Response:
    """Get response from IDP."""
    try:
        saml = SAML(app)
        saml_client = saml.saml_client_for()
        authn_response = saml_client.parse_authn_request_response(
            request.form["SAMLResponse"], entity.BINDING_HTTP_POST)

        identity = authn_response.get_identity()

        if "REQUIRED_GROUPS" in app.config and not set(
                app.config["REQUIRED_GROUPS"]).issubset(
                    set(identity.get(app.config["SAML_ATTR_MAP"]["groups"]))):

            session.pop("_flashes", None)

            # user is not authorized.
            flash("You must be part of the %s group(s) to use this site." %
                  app.config["REQUIRED_GROUPS"])
            return redirect(app.config["NOT_AUTHORIZED_URL"])

        logging.warning(identity)

        if identity:
            account_name = identity.get(
                app.config["SAML_ATTR_MAP"]["account_name"])[0].lower()

            email = identity.get(
                app.config["SAML_ATTR_MAP"]["email"])[0].lower()

            user = User.query.filter((User.account_name == account_name)
                                     | (User.email == email)).first()

            # if user isn't existing, create
            if not user:
                user = User()

            # update user attributes
            user.account_name = account_name
            user.email = email

            user.full_name = "%s %s" % (
                identity.get(app.config["SAML_ATTR_MAP"]["first_name"])[0],
                identity.get(app.config["SAML_ATTR_MAP"]["last_name"])[0],
            )

            user.first_name = identity.get(
                app.config["SAML_ATTR_MAP"]["first_name"])[0]

            db.session.add(user)
            db.session.commit()

            login_user(user, remember=True)

            next_url = (request.args.get("next")
                        or request.args.get("RelayState")
                        or request.form.get("RelayState")
                        or app.config["LOGIN_REDIRECT_URL"])

            if not is_safe_url(next_url, app.config["ALLOWED_HOSTS"]):
                return abort(400)

            session.pop("_flashes", None)
            return redirect(next_url)
        return redirect(app.congif["LOGIN_VIEW"])

    except SignatureError as e:
        flash(str(e))
        return redirect(app.congif["SAML_ATTR_MAP"])