auth.py: Add config_error page for misconfigured github/google auth.

Significantly modified by tabbott to use a better system, pass tests,
and clean up the content.
This commit is contained in:
Vaida Plankyte 2017-08-07 16:38:25 +01:00 committed by Tim Abbott
parent 71b3245905
commit 52046d537a
5 changed files with 149 additions and 0 deletions

View File

@ -0,0 +1,89 @@
{% extends "zerver/portico.html" %}
{% block portico_content %}
<div class="error_page" style="padding-bottom: 60px;">
<div class="container">
<div class="row-fluid">
<img src="/static/images/500art.svg" alt=""/>
<div class="errorbox">
<div class="errorcontent">
<h1 class="lead">Configuration error</h1>
<br/>
{% if google_error %}
<p>
You are using the <b>Google auth backend</b>,
but it is not properly configured. Please
check the following:
</p>
<ul>
<li>
You have created a Google Oauth2 client
and enabled the Google+ API. You can
create OAuth2 apps
at <a href="https://console.developers.google.com">https://console.developers.google.com</a>.
</li>
<li>
You have configured your OAuth2 client to
allow redirects to your server's Google
auth URL:
<code>{{ server_uri }}/accounts/login/google/done/</code>.
</li>
<li>
You have
set <code>GOOGLE_OAUTH2_CLIENT_ID</code>
in <code>{{ settings_path }}</code>
and <code>google_oauth2_client_secret</code>
in <code>{{ secrets_path }}</code>.
</li>
</ul>
{% endif %}
{% if github_error %}
<p>
You are using the <b>GitHub auth backend</b>,
but it is not properly configured. Please
check the following:
</p>
<ul>
<li>
You have added <code>{{ server_uri }}/complete/github/</code>
as the callback URL in the OAuth application in
GitHub. You can create OAuth apps
from <a href="https://github.com/settings/developers">GitHub's
developer site</a>.
</li>
<li>
You have set <code>SOCIAL_AUTH_GITHUB_KEY</code>
in <code>{{ settings_path }}</code>
and <code>social_auth_github_secret</code>
in <code>{{ secrets_path }}</code> with
the values from your OAuth application.
</li>
</ul>
{% endif %}
<p>After making your changes, remember to restart
the Zulip server.</p>
{% if development %}
<p>
For more information, have a look at
the <a href="http://zulip.readthedocs.io/en/latest/settings.html#testing-google-github-authentication">authentication
setup guide</a> for the development environment.
</p>
{% else %}
<p>
For more information, have a look at
our <a href="http://zulip.readthedocs.io/en/latest/prod-authentication-methods.html">authentication
setup guide</a> and the comments in <code>{{ settings_comments_path }}</code>.
</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -89,6 +89,15 @@ def zulip_default_context(request):
if hasattr(request, 'user') and hasattr(request.user, 'is_authenticated'):
user_is_authenticated = request.user.is_authenticated.value
if settings.DEVELOPMENT:
secrets_path = "zproject/dev-secrets.conf"
settings_path = "zproject/dev_settings.py"
settings_comments_path = "zproject/prod_settings_template.py"
else:
secrets_path = "/etc/zulip/zulip-secrets.conf"
settings_path = "/etc/zulip/settings.py"
settings_comments_path = "/etc/zulip/settings.py"
return {
'realms_have_subdomains': settings.REALMS_HAVE_SUBDOMAINS,
'custom_logo_url': settings.CUSTOM_LOGO_URL,
@ -126,6 +135,9 @@ def zulip_default_context(request):
'password_min_quality': settings.PASSWORD_MIN_ZXCVBN_QUALITY,
'zulip_version': ZULIP_VERSION,
'user_is_authenticated': user_is_authenticated,
'settings_path': settings_path,
'secrets_path': secrets_path,
'settings_comments_path': settings_comments_path,
}

View File

@ -166,3 +166,33 @@ class AboutPageTest(ZulipTestCase):
flat_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
expected_result = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
self.assertEqual(split_by(flat_list, 3, None), expected_result)
class ConfigErrorTest(ZulipTestCase):
@override_settings(GOOGLE_OAUTH2_CLIENT_ID=None)
def test_google(self):
# type: () -> None
result = self.client_get("/accounts/login/google/")
self.assertEqual(result.status_code, 302)
self.assertEqual(result.url, '/config-error/google')
result = self.client_get(result.url)
self.assert_in_success_response(["GOOGLE_OAUTH2_CLIENT_ID"], result)
@override_settings(SOCIAL_AUTH_GITHUB_KEY=None)
def test_github(self):
# type: () -> None
result = self.client_get("/accounts/login/social/github")
self.assertEqual(result.status_code, 302)
self.assertEqual(result.url, '/config-error/github')
result = self.client_get(result.url)
self.assert_in_success_response(["SOCIAL_AUTH_GITHUB_KEY"], result)
@override_settings(SOCIAL_AUTH_GITHUB_KEY=None)
@override_settings(DEVELOPMENT=False)
def test_github_production_error(self):
# type: () -> None
"""Test the !DEVELOPMENT code path of config-error."""
result = self.client_get("/accounts/login/social/github")
self.assertEqual(result.status_code, 302)
self.assertEqual(result.url, '/config-error/github')
result = self.client_get(result.url)
self.assert_in_success_response(["/etc/zulip/zulip-secrets.conf"], result)

View File

@ -81,6 +81,10 @@ def redirect_to_subdomain_login_url():
redirect_url = login_url + '?subdomain=1'
return HttpResponseRedirect(redirect_url)
def redirect_to_config_error(error_type):
# type: (str) -> HttpResponseRedirect
return HttpResponseRedirect("/config-error/%s" % (error_type,))
def login_or_register_remote_user(request, remote_username, user_profile, full_name='',
invalid_subdomain=False, mobile_flow_otp=None,
is_signup=False):
@ -210,6 +214,10 @@ def google_oauth2_csrf(request, value):
def start_google_oauth2(request):
# type: (HttpRequest) -> HttpResponse
url = reverse('zerver.views.auth.send_oauth_request_to_google')
if not (settings.GOOGLE_OAUTH2_CLIENT_ID and settings.GOOGLE_OAUTH2_CLIENT_SECRET):
return redirect_to_config_error("google")
is_signup = bool(request.GET.get('is_signup'))
return redirect_to_main_site(request, url, is_signup=is_signup)
@ -238,6 +246,9 @@ def redirect_to_main_site(request, url, is_signup=False):
def start_social_login(request, backend):
# type: (HttpRequest, Text) -> HttpResponse
backend_url = reverse('social:begin', args=[backend])
if (backend == "github") and not (settings.SOCIAL_AUTH_GITHUB_KEY and settings.SOCIAL_AUTH_GITHUB_SECRET):
return redirect_to_config_error("github")
return redirect_to_main_site(request, backend_url)
def start_social_signup(request, backend):

View File

@ -160,6 +160,13 @@ i18n_urls = [
# Terms of service and privacy pages.
url(r'^terms/$', TemplateView.as_view(template_name='zerver/terms.html'), name='terms'),
url(r'^privacy/$', TemplateView.as_view(template_name='zerver/privacy.html'), name='privacy'),
url(r'^config-error/google$', TemplateView.as_view(
template_name='zerver/config_error.html',),
{'google_error': True},),
url(r'^config-error/github$', TemplateView.as_view(
template_name='zerver/config_error.html',),
{'github_error': True},),
]
# Make a copy of i18n_urls so that they appear without prefix for english