Add global authentication
This commit adds global authentication to binder to ensure that only valid users are able to use it. This should enable binder to be used in environemts where it's webfrontend is reachable for unauthenticated users as well. For setups where such a global authentication isn't desired it can be disabled by simply removing the LoginRequiredMiddleware from the list of active middlewares.
This commit is contained in:
parent
dc15440a98
commit
7882ee9121
|
@ -0,0 +1,23 @@
|
|||
from django.conf import settings
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
class LoginRequiredMiddleware(object):
|
||||
"""Middleware to redirect to the login page if the user isn't authenticated
|
||||
|
||||
After successful authentication the user is redirected back to the page he
|
||||
initially wanted to access.
|
||||
"""
|
||||
def process_request(self, request):
|
||||
# allow access to the login url
|
||||
if request.path == settings.LOGIN_URL:
|
||||
return
|
||||
# redirect to the login url if the user isn't authenticated
|
||||
if not request.user.is_authenticated():
|
||||
if request.path not in (settings.LOGIN_URL,
|
||||
settings.LOGIN_REDIRECT_URL):
|
||||
return HttpResponseRedirect('%s?%s=%s' % (settings.LOGIN_URL,
|
||||
REDIRECT_FIELD_NAME,
|
||||
request.path))
|
||||
else:
|
||||
return HttpResponseRedirect(settings.LOGIN_URL)
|
|
@ -67,6 +67,7 @@ MIDDLEWARE_CLASSES = (
|
|||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'binder.middlewares.LoginRequiredMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'binder.urls'
|
||||
|
@ -86,3 +87,5 @@ INSTALLED_APPS = (
|
|||
)
|
||||
|
||||
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
|
||||
|
||||
LOGIN_REDIRECT_URL = '/'
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
<li role="presentation" class="active">Actions</li>
|
||||
<li role="presentation"><a href="/">Home</a></li>
|
||||
<li role="presentation"><a href="{% url "server_list" %}">Server List</a></li>
|
||||
{% if user.is_authenticated %}
|
||||
<li role="presentation"><a href="{% url "logout" %}">Logout</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endblock navigation %}
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Binder DNS Admin – Login</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}bootstrap/css/bootstrap.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="page-header text-center">
|
||||
<h1>Binder DNS Admin</h1>
|
||||
</div>
|
||||
|
||||
{% if form.errors %}
|
||||
<div class="row">
|
||||
<div class="col-md-4"></div>
|
||||
<div class="col-md-4 alert alert-danger text-center" role="alert">Wrong username or password! Please try again.</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="{% url 'django.contrib.auth.views.login' %}{% if next %}?next={{ next }}{% endif %}" class="form-horizontal" >
|
||||
{% csrf_token %}
|
||||
<div class="form-group">
|
||||
<label for="{{ form.username.id_for_label }}" class="control-label col-md-5">Username</label>
|
||||
<div class="controls col-md-3">
|
||||
<input type="text" id="{{ form.username.id_for_label }}" name="username" class="form-control" value="{{ form.username.value|default_if_none:"" }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="{{ form.password.id_for_label }}" class="control-label col-md-5">Password</label>
|
||||
<div class="controls col-md-3">
|
||||
<input type="password" id="{{ form.password.id_for_label }}" name="password" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-5"></div>
|
||||
<div class="col-md-3">
|
||||
<button type="submit" class="btn btn-default">Login</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,6 @@
|
|||
from django.test import TestCase
|
||||
from django.test.client import Client
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from binder import models, helpers
|
||||
|
@ -9,6 +10,12 @@ class GetTests(TestCase):
|
|||
""" Unit Tests that exercise HTTP GET. """
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
user = User.objects.create_user('testuser',
|
||||
'testuser@example.com',
|
||||
'testpassword')
|
||||
response = self.client.login(username='testuser',
|
||||
password='testpassword')
|
||||
|
||||
|
||||
def test_GetIndex(self):
|
||||
response = self.client.get(reverse("index"))
|
||||
|
@ -44,6 +51,11 @@ class PostTests(TestCase):
|
|||
models.BindServer(hostname="testserver.test.net",
|
||||
statistics_port=1234).save()
|
||||
|
||||
user = User.objects.create_user('testuser',
|
||||
'testuser@example.com',
|
||||
'testpassword')
|
||||
response = self.client.login(username='testuser',
|
||||
password='testpassword')
|
||||
|
||||
def test_DeleteRecordInitial_Empty(self):
|
||||
""" Ensure the initial deletion form works as expected with no RR list. """
|
||||
|
|
|
@ -6,6 +6,10 @@ admin.autodiscover()
|
|||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
|
||||
url(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login'),
|
||||
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login', name='logout'),
|
||||
|
||||
url(r'^$', 'binder.views.home_index', name="index"),
|
||||
url(r'^server_list/$', 'binder.views.view_server_list', name="server_list"),
|
||||
|
||||
|
|
Loading…
Reference in New Issue