Add a new dev login page for logging in without a password on the dev VM.

(imported from commit ac8f2504771c9907b7e92dc91cec5f7220ce951b)
This commit is contained in:
David Roe 2015-08-18 17:58:20 -07:00 committed by Tim Abbott
parent ef50e74873
commit 46e224997e
7 changed files with 104 additions and 7 deletions

View File

@ -693,6 +693,17 @@ a.bottom-signup-button {
margin-bottom: 50px;
}
.login-page-subheader {
font-weight: 300;
font-size: 24px;
display: block;
margin: auto;
width: 300px;
text-align: center;
margin-top: -30px;
margin-bottom: 50px;
}
.feature-page-header,
.api-page-header,
.apps-page-header,
@ -761,6 +772,18 @@ a.bottom-signup-button {
margin-bottom: 15px;
}
.btn-direct {
margin-top: 0px;
margin-bottom: 0px;
padding: 8px;
color: #fff;
font-size: 18px;
background-color: #428bca;
border-color: #357ebd;
border-radius: 5px;
min-width: 300px;
}
.feature-page-header {
width: auto;
}
@ -792,6 +815,11 @@ a.bottom-signup-button {
margin-bottom: 2px;
}
.login-form .direct-label {
margin-top: 50px;
margin-bottom: 6px;
}
.login-form #id_username,
.login-form #id_password {
width: 100%;

View File

@ -23,7 +23,14 @@ autofocus('#id_username');
<div class="app login-page">
<div class="app-main login-page-container">
{% if dev_auth_enabled %}
<h3 class="login-page-header">Zulip Dev Login</h3>
{% if not password_auth_enabled %}
<h4 class="login-page-subheader">Choose a user:</h4>
{% endif %}
{% else %}
<h3 class="login-page-header">You look familiar.</h3>
{% endif %}
{% if only_sso %}
{% comment %}SSO users don't have a password.{% endcomment %}
@ -54,6 +61,7 @@ autofocus('#id_username');
</div>
{% endif %}
{% if password_auth_enabled or desktop_sso_dispatch %}
<form name="login_form" id="login_form" method="post" class="login-form"
{% if desktop_sso_dispatch %}
{# desktop_sso_dispatch is only set when this template is invoked by zilencer.views #}
@ -89,8 +97,25 @@ autofocus('#id_username');
</div>
</div>
</form>
{% endif %}
{% if dev_auth_enabled %}
<form name="direct_login_form" id="direct_login_form" method="post" class="login-form"
action="{% url 'zerver.views.dev_direct_login' %}">
{% csrf_token %}
<div class="control-group">
{% if password_auth_enabled %}
<label for="direct_email" class="direct-label">or Choose a user:</label>
{% endif %}
<div class="controls">
{% for user_email in direct_users %}
<p><input type="submit" name="direct_email" class="btn-direct" value="{{ user_email }}" /></p>
{% endfor %}
</div>
</div>
</form>
{% endif %}
{% if not desktop_sso_dispatch %}
{% if google_auth_enabled %}
<div class="login-google">
or <a href="{% url 'zerver.views.start_google_oauth2' %}" class="login-google-button zocial google">Sign in with Google</a>
</div>

View File

@ -2,7 +2,7 @@ from __future__ import absolute_import
from django.conf import settings
import ujson
from zproject.backends import password_auth_enabled
from zproject.backends import password_auth_enabled, dev_auth_enabled, google_auth_enabled
def add_settings(request):
if hasattr(request.user, "realm"):
@ -16,7 +16,6 @@ def add_settings(request):
# to the template
'not_enterprise': not settings.ENTERPRISE,
'zulip_admin': settings.ZULIP_ADMINISTRATOR,
'password_auth_enabled': is_pw_auth_enabled,
'login_url': settings.HOME_NOT_LOGGED_IN,
'only_sso': settings.ONLY_SSO,
'external_api_path': settings.EXTERNAL_API_PATH,
@ -25,6 +24,9 @@ def add_settings(request):
'api_site_required': settings.EXTERNAL_API_PATH != "api.zulip.com",
'email_integration_enabled': settings.EMAIL_GATEWAY_BOT != "",
'email_gateway_example': settings.EMAIL_GATEWAY_EXAMPLE,
'password_auth_enabled': is_pw_auth_enabled,
'dev_auth_enabled': dev_auth_enabled(),
'google_auth_enabled': google_auth_enabled(),
}
def add_metrics(request):

View File

@ -71,7 +71,7 @@ from zerver.lib.response import json_success, json_error, json_response
from zerver.lib.unminify import SourceMap
from zerver.lib.queue import queue_json_publish
from zerver.lib.utils import statsd, generate_random_token, statsd_key
from zproject.backends import password_auth_enabled
from zproject.backends import password_auth_enabled, dev_auth_enabled
from confirmation.models import Confirmation
@ -784,9 +784,12 @@ def finish_google_oauth2(request):
return login_or_register_remote_user(request, email_address, user_profile, full_name)
def login_page(request, **kwargs):
extra_context = kwargs.pop('extra_context',{})
if dev_auth_enabled():
extra_context['direct_users'] = sorted([u.email for u in UserProfile.objects.filter(is_bot=False, is_active=True)])
template_response = django_login_page(
request, authentication_form=OurAuthenticationForm, **kwargs)
request, authentication_form=OurAuthenticationForm,
extra_context=extra_context, **kwargs)
try:
template_response.context_data['email'] = request.GET['email']
except KeyError:
@ -794,6 +797,18 @@ def login_page(request, **kwargs):
return template_response
def dev_direct_login(request, **kwargs):
# This function allows logging in without a password and should only be called in development environments.
# It may be called if the DevAuthBackend is included in settings.AUTHENTICATION_BACKENDS
if (not dev_auth_enabled()) or settings.DEPLOYED:
# This check is probably not required, since authenticate would fail without an enabled DevAuthBackend.
raise Exception('Direct login not supported.')
email = request.POST['direct_email']
user_profile = authenticate(username=email)
login(request, user_profile)
return HttpResponseRedirect("%s%s" % (settings.EXTERNAL_URI_SCHEME,
request.get_host()))
@authenticated_json_post_view
@has_request_variables
def json_bulk_invite_users(request, user_profile,

View File

@ -16,7 +16,7 @@ from oauth2client.crypt import AppIdentityError
def password_auth_enabled(realm):
if realm.domain == 'employees.customer16.invalid':
return False
elif realm.domain == 'zulip.com' and not settings.TEST_SUITE:
elif realm.domain == 'zulip.com' and settings.DEPLOYED:
# the dropbox realm is SSO only, but the unit tests still need to be
# able to login
return False
@ -26,6 +26,18 @@ def password_auth_enabled(realm):
return True
return False
def dev_auth_enabled():
for backend in django.contrib.auth.get_backends():
if isinstance(backend, DevAuthBackend):
return True
return False
def google_auth_enabled():
for backend in django.contrib.auth.get_backends():
if isinstance(backend, GoogleMobileOauth2Backend):
return True
return False
class ZulipAuthMixin(object):
def get_user(self, user_profile_id):
""" Get a UserProfile object from the user_profile_id. """
@ -162,3 +174,13 @@ class ZulipLDAPUserPopulator(ZulipLDAPAuthBackend):
def authenticate(self, username, password):
return None
class DevAuthBackend(ZulipAuthMixin):
# Allow logging in as any user without a password.
# This is used for convenience when developing Zulip.
def authenticate(self, username):
try:
return get_user_profile_by_email(username)
except UserProfile.DoesNotExist:
return None

View File

@ -174,6 +174,10 @@ EMAIL_GATEWAY_BOT = "emailgateway@zulip.com"
SSO_APPEND_DOMAIN = None
## WARNING: DO NOT ENABLE DevAuthBackend UNLESS YOU WANT
## ANYONE TO BE ABLE TO LOG IN AS ANY USER.
# AUTHENTICATION_BACKENDS = ('zproject.backends.DevAuthBackend',)
AUTHENTICATION_BACKENDS = ('zproject.backends.EmailAuthBackend',
'zproject.backends.GoogleMobileOauth2Backend',
'zproject.backends.GoogleBackend')

View File

@ -26,6 +26,7 @@ urlpatterns = patterns('',
url(r'^accounts/login/jwt/$', 'zerver.views.remote_user_jwt', name='login-jwt'),
url(r'^accounts/login/google/$', 'zerver.views.start_google_oauth2'),
url(r'^accounts/login/google/done/$', 'zerver.views.finish_google_oauth2'),
url(r'^accounts/login/local/$', 'zerver.views.dev_direct_login'),
# We have two entries for accounts/login to allow reverses on the Django
# view we're wrapping to continue to function.
url(r'^accounts/login/', 'zerver.views.login_page', {'template_name': 'zerver/login.html'}),