Exemplo n.º 1
0
    def test_logins_valid_user(self):
        user = user_factory.create(email='*****@*****.**')

        with patch.object(
                settings, 'GOOGLE_APPS_DOMAIN', 'example.com'), patch(
                    'redash.authentication.login_user') as login_user_mock:
            create_and_login_user(None, user)
            login_user_mock.assert_called_once_with(user, remember=True)
Exemplo n.º 2
0
    def test_ignores_invliad_user(self):
        user = ObjectDict({'email': '*****@*****.**'})

        with patch.object(
                settings, 'GOOGLE_APPS_DOMAIN', 'example.com'), patch(
                    'redash.authentication.login_user') as login_user_mock:
            create_and_login_user(None, user)
            self.assertFalse(login_user_mock.called)
Exemplo n.º 3
0
    def test_creates_vaild_new_user(self):
        openid_user = ObjectDict({'email': '*****@*****.**', 'name': 'Test User'})

        with patch.multiple(settings, GOOGLE_APPS_DOMAIN='example.com'), \
             patch('redash.authentication.login_user') as login_user_mock:

            create_and_login_user(None, openid_user)

            self.assertTrue(login_user_mock.called)
            user = models.User.get(models.User.email == openid_user.email)
Exemplo n.º 4
0
    def test_creates_vaild_new_user(self):
        email = "*****@*****.**"
        name = "Test User"

        with patch("redash.authentication.login_user") as login_user_mock:
            create_and_login_user(self.factory.org, name, email)

            self.assertTrue(login_user_mock.called)
            user = models.User.query.filter(models.User.email == email).one()
            self.assertEqual(user.email, email)
Exemplo n.º 5
0
def idp_initiated(org_slug=None):
    if not current_org.get_setting("auth_saml_enabled"):
        logger.error("SAML Login is not enabled")
        return redirect(url_for('redash.index', org_slug=org_slug))

    saml_client = get_saml_client(current_org)
    try:
        authn_response = saml_client.parse_authn_request_response(
            request.form['SAMLResponse'],
            entity.BINDING_HTTP_POST)
    except Exception:
        logger.error('Failed to parse SAML response', exc_info=True)
        flash('SAML login failed. Please try again later.')
        return redirect(url_for('redash.login', org_slug=org_slug))

    authn_response.get_identity()
    user_info = authn_response.get_subject()
    email = user_info.text
    name = "%s %s" % (authn_response.ava['FirstName'][0], authn_response.ava['LastName'][0])

    # This is what as known as "Just In Time (JIT) provisioning".
    # What that means is that, if a user in a SAML assertion
    # isn't in the user store, we create that user first, then log them in
    user = create_and_login_user(current_org, name, email)
    if user is None:
        return logout_and_redirect_to_index()

    if 'RedashGroups' in authn_response.ava:
        group_names = authn_response.ava.get('RedashGroups')
        user.update_group_assignments(group_names)

    url = url_for('redash.index', org_slug=org_slug)

    return redirect(url)
Exemplo n.º 6
0
def login(org_slug=None):
    unsafe_next_path = request.args.get('next')
    next_path = get_next_path(unsafe_next_path)

    if not settings.REMOTE_USER_LOGIN_ENABLED:
        logger.error("Cannot use remote user for login without being enabled in settings")
        return redirect(url_for('redash.index', next=next_path, org_slug=org_slug))

    email = request.headers.get(settings.REMOTE_USER_HEADER)

    # Some Apache auth configurations will, stupidly, set (null) instead of a
    # falsey value.  Special case that here so it Just Works for more installs.
    # '(null)' should never really be a value that anyone wants to legitimately
    # use as a redash user email.
    if email == '(null)':
        email = None

    if not email:
        logger.error("Cannot use remote user for login when it's not provided in the request (looked in headers['" + settings.REMOTE_USER_HEADER + "'])")
        return redirect(url_for('redash.index', next=next_path, org_slug=org_slug))

    logger.info("Logging in " + email + " via remote user")

    user = create_and_login_user(current_org, email, email)
    if user is None:
        return logout_and_redirect_to_index()

    return redirect(next_path or url_for('redash.index', org_slug=org_slug), code=302)
Exemplo n.º 7
0
def authorized():
    app = xinniuren_remote_app()
    resp = app.authorized_response()
    access_token = resp['access_token']

    if access_token is None:
        logger.warning("Access token missing in call back request.")
        flash("Validation error. Please retry.")
        return redirect(url_for('redash.login'))

    profile = get_user_profile(access_token)
    if profile is None:
        flash("Validation error. Please retry.")
        return redirect(url_for('redash.login'))

    if 'org_slug' in session:
        org = models.Organization.get_by_slug(session.pop('org_slug'))
    else:
        org = current_org

    if not verify_profile(org, profile):
        logger.warning("User tried to login with unauthorized domain name: %s (org: %s)", profile['Email'], org)
        flash("Your Google Apps account ({}) isn't allowed.".format(profile['Email']))
        return redirect(url_for('redash.login', org_slug=org.slug))

    # picture_url = "%s?sz=40" % profile['picture']
    picture_url = "/static/images/avatar.svg"
    user = create_and_login_user(org, profile['UserName'], profile['Email'], picture_url)
    if user is None:
        return logout_and_redirect_to_index()

    unsafe_next_path = request.args.get('state') or url_for("redash.index", org_slug=org.slug)
    next_path = get_next_path(unsafe_next_path)

    return redirect(next_path)
Exemplo n.º 8
0
def login(org_slug=None):
    unsafe_next_path = request.args.get('next')
    next_path = get_next_path(unsafe_next_path)

    if not settings.REMOTE_USER_LOGIN_ENABLED:
        logger.error(
            "Cannot use remote user for login without being enabled in settings"
        )
        return redirect(
            url_for('redash.index', next=next_path, org_slug=org_slug))

    email = request.headers.get(settings.REMOTE_USER_HEADER)

    # Some Apache auth configurations will, stupidly, set (null) instead of a
    # falsey value.  Special case that here so it Just Works for more installs.
    # '(null)' should never really be a value that anyone wants to legitimately
    # use as a redash user email.
    if email == '(null)':
        email = None

    if not email:
        logger.error(
            "Cannot use remote user for login when it's not provided in the request (looked in headers['"
            + settings.REMOTE_USER_HEADER + "'])")
        return redirect(
            url_for('redash.index', next=next_path, org_slug=org_slug))

    logger.info("Logging in " + email + " via remote user")

    user = create_and_login_user(current_org, email, email)
    if user is None:
        return logout_and_redirect_to_index()

    return redirect(next_path or url_for('redash.index', org_slug=org_slug),
                    code=302)
Exemplo n.º 9
0
def idp_initiated(org_slug=None):
    if not current_org.get_setting("auth_saml_enabled"):
        logger.error("SAML Login is not enabled")
        return redirect(url_for('redash.index', org_slug=org_slug))

    saml_client = get_saml_client(current_org)
    try:
        authn_response = saml_client.parse_authn_request_response(
            request.form['SAMLResponse'], entity.BINDING_HTTP_POST)
    except Exception:
        logger.error('Failed to parse SAML response', exc_info=True)
        flash('SAML login failed. Please try again later.')
        return redirect(url_for('redash.login', org_slug=org_slug))

    authn_response.get_identity()
    user_info = authn_response.get_subject()
    email = user_info.text
    name = "%s %s" % (authn_response.ava['FirstName'][0],
                      authn_response.ava['LastName'][0])

    # This is what as known as "Just In Time (JIT) provisioning".
    # What that means is that, if a user in a SAML assertion
    # isn't in the user store, we create that user first, then log them in
    user = create_and_login_user(current_org, name, email)
    if user is None:
        return logout_and_redirect_to_index()

    if 'RedashGroups' in authn_response.ava:
        group_names = authn_response.ava.get('RedashGroups')
        user.update_group_assignments(group_names)

    url = url_for('redash.index', org_slug=org_slug)

    return redirect(url)
Exemplo n.º 10
0
def authorized():
    resp = google_remote_app().authorized_response()
    access_token = resp['access_token']

    if access_token is None:
        logger.warning("Access token missing in call back request.")
        flash("Validation error. Please retry.")
        return redirect(url_for('redash.login'))

    profile = get_user_profile(access_token)
    if profile is None:
        flash("Validation error. Please retry.")
        return redirect(url_for('redash.login'))

    if 'org_slug' in session:
        org = models.Organization.get_by_slug(session.pop('org_slug'))
    else:
        org = current_org

    if not verify_profile(org, profile):
        logger.warning("User tried to login with unauthorized domain name: %s (org: %s)", profile['email'], org)
        flash("Your Google Apps account ({}) isn't allowed.".format(profile['email']))
        return redirect(url_for('redash.login', org_slug=org.slug))

    picture_url = "%s?sz=40" % profile['picture']
    user = create_and_login_user(org, profile['name'], profile['email'], picture_url)
    if user is None:
        return logout_and_redirect_to_index()

    next_path = request.args.get('state') or url_for("redash.index", org_slug=org.slug)

    return redirect(next_path)
Exemplo n.º 11
0
def login(org_slug=None):
    index_url = url_for("redash.index", org_slug=org_slug)
    next_path = request.args.get('next', index_url)

    if not settings.LDAP_LOGIN_ENABLED:
        logger.error("Cannot use LDAP for login without being enabled in settings")
        return redirect(url_for('redash.index', next=next_path))

    if current_user.is_authenticated:
        return redirect(next_path)

    if request.method == 'POST':
        ldap_user = auth_ldap_user(request.form['email'], request.form['password'])

        if ldap_user is not None:
            user = create_and_login_user(
                current_org,
                ldap_user[settings.LDAP_DISPLAY_NAME_KEY][0],
                ldap_user[settings.LDAP_EMAIL_KEY][0]
            )
            if user is None:
                return logout_and_redirect_to_index()

            return redirect(next_path or url_for('redash.index'))
        else:
            flash("Incorrect credentials.")

    return render_template("login.html",
                           org_slug=org_slug,
                           next=next_path,
                           email=request.form.get('email', ''),
                           show_password_login=True,
                           username_prompt=settings.LDAP_CUSTOM_USERNAME_PROMPT,
                           hide_forgot_password=True)
Exemplo n.º 12
0
def login(org_slug=None):
    index_url = url_for("redash.index", org_slug=org_slug)
    next_path = request.args.get('next', index_url)

    if not settings.LDAP_LOGIN_ENABLED:
        logger.error("Cannot use LDAP for login without being enabled in settings")
        return redirect(url_for('redash.index', next=next_path))

    if current_user.is_authenticated:
        return redirect(next_path)

    if request.method == 'POST':
        ldap_user = auth_ldap_user(request.form['email'], request.form['password'])

        if ldap_user is not None:
            user = create_and_login_user(
                current_org,
                ldap_user[settings.LDAP_DISPLAY_NAME_KEY][0],
                ldap_user[settings.LDAP_EMAIL_KEY][0]
            )
            if user is None:
                return logout_and_redirect_to_index()

            return redirect(next_path or url_for('redash.index'))
        else:
            flash("Incorrect credentials.")

    return render_template("login.html",
                           org_slug=org_slug,
                           next=next_path,
                           email=request.form.get('email', ''),
                           show_password_login=True,
                           username_prompt=settings.LDAP_CUSTOM_USERNAME_PROMPT,
                           hide_forgot_password=True)
Exemplo n.º 13
0
def login(org_slug=None):
    next_path = request.args.get('next')

    if not settings.REMOTE_JWT_LOGIN_ENABLED:
        logger.error(
            "Cannot use remote user for login without being enabled in settings"
        )
        return redirect(
            url_for('redash.index', next=next_path, org_slug=org_slug))

    jwttoken = request.headers.get(
        settings.REMOTE_USER_HEADER) or request.cookies.get('jwt')

    # Some Apache auth configurations will, stupidly, set (null) instead of a
    # falsey value.  Special case that here so it Just Works for more installs.
    # '(null)' should never really be a value that anyone wants to legitimately
    # use as a redash user jwt.
    if jwttoken == '(null)':
        jwttoken = None

    if not jwt:
        logger.error(
            "Cannot use remote jwt for login when it's not provided in the request (looked in headers['"
            + settings.REMOTE_USER_HEADER + "'])")
        return redirect(
            url_for('redash.index', next=next_path, org_slug=org_slug))

    try:
        public_key = get_jwt_public_key()
        jwt_decoded = jwt.get_unverified_claims(
            jwttoken) if public_key is '' else jwt.decode(
                jwttoken, public_key)
        email = jwt_decoded.get('email', None)

        if not email:
            logger.error(
                "Cannot use remote jwt for login when it's not provided in the request (looked in headers['"
                + settings.REMOTE_USER_HEADER + "'])")
            return redirect(
                url_for('redash.index', next=next_path, org_slug=org_slug))

        logger.info("Logging in " + email + " via remote jwt")

        user = create_and_login_user(current_org, email, email)
        if user is None:
            return logout_and_redirect_to_index()

        resp = redirect(next_path
                        or url_for('redash.index', org_slug=org_slug),
                        code=302)
        resp.set_cookie('jwt', jwttoken, secure=True, httponly=True)

        return resp
    except jwt.JWTError, jwt.ExpiredSignatureError:
        logger.error(
            "Remote user attempted entry using key with invalid signature")
        logger.info(settings.REMOTE_JWT_EXPIRED_ENDPOINT)
        return redirect(
            url_for('redash.index', next=next_path, org_slug=org_slug))
Exemplo n.º 14
0
def app_profile():
    resp = register_remote_app().get('oauth-2/resource')
    profile = resp.json()

    picture_url = "%s?sz=40" % profile['picture']
    user = create_and_login_user(current_org, profile['name'],
                                 profile['email'], picture_url)
    if user is None:
        return logout_and_redirect_to_index()

    # next_path = request.args.get('state') or url_for("redash.index", org_slug=org.slug)
    next_path = request.args.get('state') or url_for("redash.index")

    return redirect(next_path)
Exemplo n.º 15
0
    def authorized():

        logger.debug("Authorized user inbound")

        resp = oauth.google.authorize_access_token()
        user = resp.get("userinfo")
        if user:
            session["user"] = user

        access_token = resp["access_token"]

        if access_token is None:
            logger.warning("Access token missing in call back request.")
            flash("Validation error. Please retry.")
            return redirect(url_for("redash.login"))

        profile = get_user_profile(access_token)
        if profile is None:
            flash("Validation error. Please retry.")
            return redirect(url_for("redash.login"))

        if "org_slug" in session:
            org = models.Organization.get_by_slug(session.pop("org_slug"))
        else:
            org = current_org

        if not verify_profile(org, profile):
            logger.warning(
                "User tried to login with unauthorized domain name: %s (org: %s)",
                profile["email"],
                org,
            )
            flash("Your Google Apps account ({}) isn't allowed.".format(
                profile["email"]))
            return redirect(url_for("redash.login", org_slug=org.slug))

        picture_url = "%s?sz=40" % profile["picture"]
        user = create_and_login_user(org, profile["name"], profile["email"],
                                     picture_url)
        if user is None:
            return logout_and_redirect_to_index()

        unsafe_next_path = session.get("next_url") or url_for(
            "redash.index", org_slug=org.slug)
        next_path = get_next_path(unsafe_next_path)

        return redirect(next_path)
Exemplo n.º 16
0
def login(org_slug=None):
    next_path = request.args.get('next')

    if not settings.REMOTE_USER_LOGIN_ENABLED:
        logger.error(
            "Cannot use remote user for login without being enabled in settings"
        )
        return redirect(
            url_for('redash.index', next=next_path, org_slug=org_slug))

    email = request.headers.get(settings.REMOTE_USER_HEADER)

    # Some Apache auth configurations will, stupidly, set (null) instead of a
    # falsey value.  Special case that here so it Just Works for more installs.
    # '(null)' should never really be a value that anyone wants to legitimately
    # use as a redash user email.
    if email == '(null)':
        email = None

    if not email:
        logger.error(
            "Cannot use remote user for login when it's not provided in the request (looked in headers['"
            + settings.REMOTE_USER_HEADER + "'])")
        return redirect(
            url_for('redash.index', next=next_path, org_slug=org_slug))

    # Check if there is a header of user groups and if yes
    # check it against a list of allowed user groups from the settings
    if settings.REMOTE_GROUPS_ENABLED:
        remote_groups = settings.set_from_string(
            request.headers.get(settings.REMOTE_GROUPS_HEADER) or '')
        allowed_groups = settings.REMOTE_GROUPS_ALLOWED
        if not allowed_groups.intersection(remote_groups):
            logger.error(
                "User groups provided in the %s header are not "
                "matching the allowed groups.", settings.REMOTE_GROUPS_HEADER)
            return redirect(url_for('redash.index', next=next_path))

    logger.info("Logging in " + email + " via remote user")

    user = create_and_login_user(current_org, email, email)
    if user is None:
        return logout_and_redirect_to_index()

    return redirect(next_path or url_for('redash.index', org_slug=org_slug),
                    code=302)
Exemplo n.º 17
0
def idp_initiated(org_slug=None):
    if not current_org.get_setting("auth_saml_enabled"):
        logger.error("SAML Login is not enabled")
        return redirect(url_for("redash.index", org_slug=org_slug))

    saml_client = get_saml_client(current_org)
    try:
        authn_response = saml_client.parse_authn_request_response(
            request.form["SAMLResponse"], entity.BINDING_HTTP_POST
        )
    except Exception:
        logger.error("Failed to parse SAML response", exc_info=True)
        flash("SAML login failed. Please try again later.")
        return redirect(url_for("redash.login", org_slug=org_slug))

    authn_response.get_identity()
    user_info = authn_response.get_subject()
    email = user_info.text
    # Google SAML auth does not return these FirstName / LastName fields
    try:
        name = "%s %s" % (authn_response.ava['FirstName'][0], authn_response.ava['LastName'][0])
    except Exception as e:
        # logger.exception(e)
        logger.warning("could not fetch FirstName or LastName from SAML response: falling back to email user")
        name = email.split('@')[0]

    # This is what as known as "Just In Time (JIT) provisioning".
    # What that means is that, if a user in a SAML assertion
    # isn't in the user store, we create that user first, then log them in
    user = create_and_login_user(current_org, name, email)
    if user is None:
        return logout_and_redirect_to_index()

    if "RedashGroups" in authn_response.ava:
        group_names = authn_response.ava.get("RedashGroups")
        user.update_group_assignments(group_names)

    url = url_for("redash.index", org_slug=org_slug)

    return redirect(url)
Exemplo n.º 18
0
def authorized():
    code = request.args.get('code')
    if code is None:
        logger.warning("code missing in call back request.")
        flash("Validation error. Please retry.")
        return redirect(url_for("redash.login"))
    profile = get_user_profile(code)
    if profile is None:
        flash("Validation error. Please retry.")
        return redirect(url_for("redash.login"))

    if "org_slug" in session:
        org = models.Organization.get_by_slug(session.pop("org_slug"))
    else:
        org = current_org

    if not verify_profile(org, profile):
        logger.warning(
            "User tried to login with unauthorized domain name: %s (org: %s)",
            profile["email"],
            org,
        )
        flash("Your microsoft Apps account ({}) isn't allowed.".format(
            profile["email"]))
        return redirect(url_for("redash.login", org_slug=org.slug))

    picture_url = profile.get('picture')
    user = create_and_login_user(org, profile["name"], profile["email"],
                                 picture_url)
    if user is None:
        return logout_and_redirect_to_index()

    unsafe_next_path = request.args.get("state") or url_for("redash.index",
                                                            org_slug=org.slug)
    next_path = get_next_path(unsafe_next_path)

    return redirect(next_path)
Exemplo n.º 19
0
def authorized():
    resp = google_remote_app().authorized_response()
    access_token = resp['access_token']

    if access_token is None:
        logger.warning("Access token missing in call back request.")
        flash("Validation error. Please retry.")
        return redirect(url_for('redash.login'))

    profile = get_user_profile(access_token)
    if profile is None:
        flash("Validation error. Please retry.")
        return redirect(url_for('redash.login'))

    if 'org_slug' in session:
        org = models.Organization.get_by_slug(session.pop('org_slug'))
    else:
        org = current_org

    if not verify_profile(org, profile):
        logger.warning(
            "User tried to login with unauthorized domain name: %s (org: %s)",
            profile['email'], org)
        session['relogin'] = '******'
        return redirect(url_for('redash.login', org_slug=org.slug))

    picture_url = "%s?sz=40" % profile['picture']
    user = create_and_login_user(org, profile['name'], profile['email'],
                                 picture_url)
    if user is None:
        return logout_and_redirect_to_index()

    next_path = request.args.get('state') or url_for("redash.index",
                                                     org_slug=org.slug)

    return redirect(next_path)
Exemplo n.º 20
0
    def test_ignores_invliad_user(self):
        user = ObjectDict({'email': '*****@*****.**'})

        with patch.object(settings, 'GOOGLE_APPS_DOMAIN', 'example.com'), patch('redash.authentication.login_user') as login_user_mock:
            create_and_login_user(None, user)
            self.assertFalse(login_user_mock.called)
Exemplo n.º 21
0
    def test_logins_valid_user(self):
        user = user_factory.create(email='*****@*****.**')

        with patch.object(settings, 'GOOGLE_APPS_DOMAIN', 'example.com'), patch('redash.authentication.login_user') as login_user_mock:
            create_and_login_user(None, user)
            login_user_mock.assert_called_once_with(user, remember=True)
Exemplo n.º 22
0
    def test_updates_user_name(self):
        user = self.factory.create_user(email="*****@*****.**")

        with patch("redash.authentication.login_user") as login_user_mock:
            create_and_login_user(self.factory.org, "New Name", user.email)
            login_user_mock.assert_called_once_with(user, remember=True)