From 0a511e4f8a9fefc7ac8a6e4af61dc45a8045d6ba Mon Sep 17 00:00:00 2001 From: Arik Fraimovich Date: Sun, 2 Mar 2014 21:54:50 +0200 Subject: [PATCH] Ability to disable openid or password login --- rd_ui/app/login.html | 4 ++++ redash/authentication.py | 16 +++++++--------- redash/controllers.py | 9 +++++++-- redash/settings.py | 8 ++++++++ tests/test_controllers.py | 11 +++++++++++ 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/rd_ui/app/login.html b/rd_ui/app/login.html index 3a96ffc07..a5271f9d4 100644 --- a/rd_ui/app/login.html +++ b/rd_ui/app/login.html @@ -56,6 +56,8 @@ + {% if show_google_openid %} +

or @@ -66,6 +68,8 @@ Google
+ + {% endif %} diff --git a/redash/authentication.py b/redash/authentication.py index 98ec9db29..238683d7a 100644 --- a/redash/authentication.py +++ b/redash/authentication.py @@ -23,9 +23,6 @@ def sign(key, path, expires): class HMACAuthentication(object): - def __init__(self, auth): - self.auth = auth - @staticmethod def api_key_authentication(): signature = request.args.get('signature') @@ -92,14 +89,15 @@ def load_user(user_id): def setup_authentication(app): - openid_auth = GoogleAuth(app, url_prefix="/google_auth") - # If we don't have a list of external users, we can use Google's federated login, which limits - # the domain with which you can sign in. - if not settings.ALLOWED_EXTERNAL_USERS and settings.GOOGLE_APPS_DOMAIN: - openid_auth._OPENID_ENDPOINT = "https://www.google.com/a/%s/o8/ud?be=o8" % settings.GOOGLE_APPS_DOMAIN + if settings.GOOGLE_OPENID_ENABLED: + openid_auth = GoogleAuth(app, url_prefix="/google_auth") + # If we don't have a list of external users, we can use Google's federated login, which limits + # the domain with which you can sign in. + if not settings.ALLOWED_EXTERNAL_USERS and settings.GOOGLE_APPS_DOMAIN: + openid_auth._OPENID_ENDPOINT = "https://www.google.com/a/%s/o8/ud?be=o8" % settings.GOOGLE_APPS_DOMAIN login_manager.init_app(app) app.wsgi_app = ProxyFix(app.wsgi_app) app.secret_key = settings.COOKIE_SECRET - return HMACAuthentication(openid_auth) + return HMACAuthentication() diff --git a/redash/controllers.py b/redash/controllers.py index b93835a8e..74ceebb40 100644 --- a/redash/controllers.py +++ b/redash/controllers.py @@ -12,7 +12,7 @@ import cStringIO import datetime from flask import render_template, send_from_directory, make_response, request, jsonify, redirect, \ - session + session, url_for from flask.ext.restful import Resource, abort from flask_login import current_user, login_user, logout_user @@ -55,6 +55,10 @@ def login(): if current_user.is_authenticated(): return redirect(request.args.get('next') or '/') + if not settings.PASSWORD_LOGIN_ENABLED: + blueprint = app.extensions['googleauth'].blueprint + return redirect(url_for("%s.login" % blueprint.name, next=request.args.get('next'))) + if request.method == 'POST': user = models.User.select().where(models.User.email == request.form['username']).first() if user and user.verify_password(request.form['password']): @@ -65,7 +69,8 @@ def login(): return render_template("login.html", analytics=settings.ANALYTICS, next=request.args.get('next'), - username=request.form.get('username', '')) + username=request.form.get('username', ''), + show_google_openid=settings.GOOGLE_OPENID_ENABLED) @app.route('/logout') diff --git a/redash/settings.py b/redash/settings.py index 90c5b45e1..adb1b882a 100644 --- a/redash/settings.py +++ b/redash/settings.py @@ -1,3 +1,4 @@ +import json import os import urlparse @@ -32,6 +33,11 @@ def array_from_string(str): return array + +def parse_boolean(str): + return json.loads(str.lower()) + + REDIS_URL = os.environ.get('REDASH_REDIS_URL', "redis://localhost:6379") # "pg", "graphite" or "mysql" @@ -48,6 +54,8 @@ DATABASE_CONFIG = parse_db_url(os.environ.get("REDASH_DATABASE_URL", "postgresql # Google Apps domain to allow access from; any user with email in this Google Apps will be allowed # access GOOGLE_APPS_DOMAIN = os.environ.get("REDASH_GOOGLE_APPS_DOMAIN", "") +GOOGLE_OPENID_ENABLED = parse_boolean(os.environ.get("REDASH_GOOGLE_OPENID_ENABLED", "true")) +PASSWORD_LOGIN_ENABLED = parse_boolean(os.environ.get("REDASH_PASSWORD_LOGIN_ENABLED", "false")) # Email addresses of admin users (comma separated) ADMINS = array_from_string(os.environ.get("REDASH_ADMINS", '')) ALLOWED_EXTERNAL_USERS = array_from_string(os.environ.get("REDASH_ALLOWED_EXTERNAL_USERS", '')) diff --git a/tests/test_controllers.py b/tests/test_controllers.py index 19d9cdb4f..d370c2d6f 100644 --- a/tests/test_controllers.py +++ b/tests/test_controllers.py @@ -2,6 +2,7 @@ from contextlib import contextmanager import json import time from unittest import TestCase +from flask import url_for from flask.ext.login import current_user from mock import patch from tests import BaseTestCase @@ -337,6 +338,16 @@ class CsvQueryResultAPITest(BaseTestCase, AuthenticationTestMixin): class TestLogin(BaseTestCase): + def setUp(self): + settings.PASSWORD_LOGIN_ENABLED = True + super(TestLogin, self).setUp() + + def test_redirects_to_google_login_if_password_disabled(self): + with app.test_client() as c, patch.object(settings, 'PASSWORD_LOGIN_ENABLED', False): + rv = c.get('/login') + self.assertEquals(rv.status_code, 302) + self.assertTrue(rv.location.endswith(url_for('GoogleAuth.login'))) + def test_get_login_form(self): with app.test_client() as c: rv = c.get('/login')