- {% if show_google_openid or show_saml_login or show_remote_user_login or show_ldap_login %}
+ {% if show_google_openid or show_microsoft_openid or show_saml_login or show_remote_user_login or show_ldap_login %}
To create your account, please choose a password or login with your SSO provider.
{% else %}
To create your account, please choose a password.
@@ -28,6 +28,13 @@
{% endif %}
+ {% if show_microsoft_openid %}
+
+
+ Login with Office365
+
+ {% endif %}
+
{% if show_saml_login %}
SAML Login
{% endif %}
@@ -40,7 +47,7 @@
LDAP/SSO Login
{% endif %}
- {% if show_google_openid or show_saml_login or show_remote_user_login or show_ldap_login %}
+ {% if show_google_openid or show_microsoft_openid or show_saml_login or show_remote_user_login or show_ldap_login %}
{% endif %}
diff --git a/redash/templates/login.html b/redash/templates/login.html
index 71bc8b4aec..7c9f6218b0 100644
--- a/redash/templates/login.html
+++ b/redash/templates/login.html
@@ -20,6 +20,13 @@
{% endif %}
+ {% if show_microsoft_openid %}
+
+
+ Login with Office365
+
+ {% endif %}
+
{% if show_saml_login %}
SAML Login
{% endif %}
@@ -33,7 +40,7 @@
{% endif %}
{% if show_password_login %}
- {% if show_google_openid or show_saml_login or show_remote_user_login or show_ldap_login %}
+ {% if show_google_openid or show_microsoft_openid or show_saml_login or show_remote_user_login or show_ldap_login %}
{% endif %}
diff --git a/tests/handlers/test_settings.py b/tests/handlers/test_settings.py
index 6c9e33b9a9..b9872549c3 100644
--- a/tests/handlers/test_settings.py
+++ b/tests/handlers/test_settings.py
@@ -47,3 +47,23 @@ def test_get_returns_google_appas_domains(self):
rv = self.make_request("get", "/api/settings/organization", user=admin)
self.assertEqual(rv.json["settings"]["auth_google_apps_domains"], domains)
+
+ def test_updates_microsoft_apps_domains(self):
+ admin = self.factory.create_admin()
+ domains = ["example.com"]
+ rv = self.make_request(
+ "post",
+ "/api/settings/organization",
+ data={"auth_microsoft_apps_domains": domains},
+ user=admin,
+ )
+ updated_org = Organization.get_by_slug(self.factory.org.slug)
+ self.assertEqual(updated_org.microsoft_apps_domains, domains)
+
+ def test_get_returns_microsoft_appas_domains(self):
+ admin = self.factory.create_admin()
+ domains = ["example.com"]
+ admin.org.settings[Organization.SETTING_MICROSOFT_APPS_DOMAINS] = domains
+
+ rv = self.make_request("get", "/api/settings/organization", user=admin)
+ self.assertEqual(rv.json["settings"]["auth_microsoft_apps_domains"], domains)
\ No newline at end of file
diff --git a/tests/test_authentication.py b/tests/test_authentication.py
index 91be52ea76..9004a84995 100644
--- a/tests/test_authentication.py
+++ b/tests/test_authentication.py
@@ -11,7 +11,9 @@
hmac_load_user_from_request,
sign,
)
-from redash.authentication.google_oauth import create_and_login_user, verify_profile
+from redash.authentication import create_and_login_user
+from redash.authentication.google_oauth import verify_profile as google_verify_profile
+from redash.authentication.microsoft_oauth import verify_profile as microsoft_verify_profile
from redash.utils import utcnow
from sqlalchemy.orm.exc import NoResultFound
from tests import BaseTestCase
@@ -201,33 +203,54 @@ def test_updates_user_name(self):
class TestVerifyProfile(BaseTestCase):
def test_no_domain_allowed_for_org(self):
profile = dict(email="arik@example.com")
- self.assertFalse(verify_profile(self.factory.org, profile))
+ self.assertFalse(google_verify_profile(self.factory.org, profile))
+ self.assertFalse(microsoft_verify_profile(self.factory.org, profile))
def test_domain_not_in_org_domains_list(self):
profile = dict(email="arik@example.com")
self.factory.org.settings[models.Organization.SETTING_GOOGLE_APPS_DOMAINS] = [
"example.org"
]
- self.assertFalse(verify_profile(self.factory.org, profile))
+ self.assertFalse(google_verify_profile(self.factory.org, profile))
+ self.factory.org.settings[models.Organization.SETTING_MICROSOFT_APPS_DOMAINS] = [
+ "example.org"
+ ]
+ self.assertFalse(microsoft_verify_profile(self.factory.org, profile))
+
def test_domain_in_org_domains_list(self):
profile = dict(email="arik@example.com")
self.factory.org.settings[models.Organization.SETTING_GOOGLE_APPS_DOMAINS] = [
"example.com"
]
- self.assertTrue(verify_profile(self.factory.org, profile))
+ self.assertTrue(google_verify_profile(self.factory.org, profile))
self.factory.org.settings[models.Organization.SETTING_GOOGLE_APPS_DOMAINS] = [
"example.org",
"example.com",
]
- self.assertTrue(verify_profile(self.factory.org, profile))
+ self.assertTrue(google_verify_profile(self.factory.org, profile))
+
+ self.factory.org.settings[models.Organization.SETTING_MICROSOFT_APPS_DOMAINS] = [
+ "example.com"
+ ]
+ self.assertTrue(microsoft_verify_profile(self.factory.org, profile))
+
+ self.factory.org.settings[models.Organization.SETTING_MICROSOFT_APPS_DOMAINS] = [
+ "example.org",
+ "example.com",
+ ]
+ self.assertTrue(microsoft_verify_profile(self.factory.org, profile))
+
def test_org_in_public_mode_accepts_any_domain(self):
profile = dict(email="arik@example.com")
self.factory.org.settings[models.Organization.SETTING_IS_PUBLIC] = True
self.factory.org.settings[models.Organization.SETTING_GOOGLE_APPS_DOMAINS] = []
- self.assertTrue(verify_profile(self.factory.org, profile))
+ self.assertTrue(google_verify_profile(self.factory.org, profile))
+ self.factory.org.settings[models.Organization.SETTING_MICROSOFT_APPS_DOMAINS] = []
+ self.assertTrue(microsoft_verify_profile(self.factory.org, profile))
+
def test_user_not_in_domain_but_account_exists(self):
profile = dict(email="arik@example.com")
@@ -235,7 +258,11 @@ def test_user_not_in_domain_but_account_exists(self):
self.factory.org.settings[models.Organization.SETTING_GOOGLE_APPS_DOMAINS] = [
"example.org"
]
- self.assertTrue(verify_profile(self.factory.org, profile))
+ self.assertTrue(google_verify_profile(self.factory.org, profile))
+ self.factory.org.settings[models.Organization.SETTING_MICROSOFT_APPS_DOMAINS] = [
+ "example.org"
+ ]
+ self.assertTrue(microsoft_verify_profile(self.factory.org, profile))
class TestGetLoginUrl(BaseTestCase):
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 537c83d03d..ddc4fd4414 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -360,6 +360,33 @@ def test_show_google_apps_domains(self):
"""
self.assertMultiLineEqual(result.output, textwrap.dedent(output).lstrip())
+ def test_set_microsoft_apps_domains(self):
+ domains = ["example.org", "example.com"]
+ runner = CliRunner()
+ result = runner.invoke(
+ manager, ["org", "set_microsoft_apps_domains", ",".join(domains)]
+ )
+ self.assertFalse(result.exception)
+ self.assertEqual(result.exit_code, 0)
+ db.session.add(self.factory.org)
+ self.assertEqual(self.factory.org.microsoft_apps_domains, domains)
+
+ def test_show_microsoft_apps_domains(self):
+ self.factory.org.settings[Organization.SETTING_MICROSOFT_APPS_DOMAINS] = [
+ "example.org",
+ "example.com",
+ ]
+ db.session.add(self.factory.org)
+ db.session.commit()
+ runner = CliRunner()
+ result = runner.invoke(manager, ["org", "show_microsoft_apps_domains"])
+ self.assertFalse(result.exception)
+ self.assertEqual(result.exit_code, 0)
+ output = """
+ Current list of Microsoft Apps domains: example.org, example.com
+ """
+ self.assertMultiLineEqual(result.output, textwrap.dedent(output).lstrip())
+
def test_list(self):
self.factory.create_org(name="test", slug="test_org")
self.factory.create_org(name="Borg", slug="B_org")