pyazo core: switch to Django login views

parent 47c8f686
{% extends "_admin/base.html" %}
{% load i18n %}
{% load pyazo %}
{% block content %}
<div class="row">
<div class="col-md-3">
<div class="card">
<div class="card-header">
{% trans "Users" %}
</div>
<div class="card-block">
<div class="card-text">
<h1 class="text-center">{{ user_count }}</h1>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card">
<div class="card-header">
{% trans "Version" %}
</div>
<div class="card-block">
<div class="card-text">
<h1 class="text-center">{% setting 'VERSION_HASH' %}</h1>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% extends 'core/generic_form_login.html' %}
......@@ -2,6 +2,19 @@
{% csrf_token %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<div class="alert-items">
<div class="alert-item">
<div class="alert-icon-wrapper">
<clr-icon class="alert-icon" shape="exclamation-circle"></clr-icon>
</div>
<span class="alert-text">
</span>
</div>
</div>
</div>
{% endfor %}
{% if field.field.widget|fieldtype == 'CheckboxInput' %}
<div class="checkbox">
<input type="checkbox" id="id_{{ field.name }}" name="{{ field.name }}">
......@@ -19,3 +32,10 @@
{{ field }}
{% endif %}
{% endfor %}
{% if form.errors %}
{% for error in form.non_field_errors %}
<div class="error active">
{{ error|escape }}
</div>
{% endfor %}
{% endif %}
{% extends "core/skel.html" %}
{% load i18n %}
{% load static %}
{% load socialaccount %}
{% block header %}
<title>{% trans 'login - pyazo' %}</title>
{% endblock %}
{% block body %}
<div class="login-wrapper">
<form class="login" method="POST">
<label class="title">
<img src="{% static 'img/icon.png' %}" alt="" style="width: 48px; height: 48px;">
{% trans 'pyazo' %}
</label>
<label class="subtitle">
{{ title }}
</label>
<div class="login-group">
{% if not external_only %}
{% include 'blocks/block_form_login.html' with form=form %}
{% block messages %}
{% if messages %}
{% for msg in messages %}
<div class="error {{ msg.level_tag }} active">
{{ msg.message|safe }}
</div>
{% endfor %}
{% endif %}
{% for field in form %}
{% if field.errors %}
{% for error in field.errors %}
<div class="error active">
{{ field.label }}: {{ error|escape }}
</div>
{% endfor %}
{% endif %}
{% endfor %}
{% endblock %}
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% endif %}
<button type="submit" class="btn btn-primary">{% trans 'Login' %}</button>
{% endif %}
{% if extra_links %}
{% for link, name in extra_links.items %}
<a href="{% url link %}" class="signup">{% trans name %}</a>
{% endfor %}
{% endif %}
{% get_providers as socialaccount_providers %}
{% if socialaccount_providers %}
{% for provider in socialaccount_providers %}
<a href="{% provider_login_url provider.id process='login' %}" class="btn btn-primary">{% trans "Login with" %} {{ provider.name }}</a>
{% endfor %}
{% endif %}
</div>
</form>
</div>
{% endblock %}
......@@ -70,7 +70,7 @@
<form action="" method="POST">
{% include 'blocks/block_form.html' with form=forms.collection %}
<input class="btn btn-primary" type="submit" value="{% trans 'Assign' %}">
<a href="{% url 'admin:pyazo_collection_add' %}" class="btn">{% trans 'Create new...' %}</a>
<a href="{% url 'admin:pyazo_core_collection_add' %}" class="btn">{% trans 'Create new...' %}</a>
{% if upload.collection %}
<a href="{% url 'index' %}?collection={{ upload.collection.name }}" class="btn">{% trans 'Show collection' %}</a>
{% endif %}
......@@ -81,7 +81,7 @@
<div class="col-sm-12">
<h3>{% trans 'Statistics' %}</h3>
<hr>
<h1>{% trans 'Views: ' %}{{ upload.uploadview_set.count }}</h1>
<h1>{% trans 'Views: ' %}{{ upload.ObjectView_set.count }}</h1>
{% if not upload.user or upload.user == request.user or request.user.is_superuser %}
<table class="table">
<thead>
......@@ -156,4 +156,4 @@ $('iframe').on('load', function () {
.append($("<style type='text/css'>body{color: #E9ECEF;}</style>"));
});
</script>
{% endblock %}
\ No newline at end of file
{% endblock %}
"""test pyazo's account views"""
from django.contrib.auth.models import User
from django.shortcuts import reverse
from django.test import TestCase
from pyazo.core.tests.utils import test_auth
class AccountViewTests(TestCase):
"""Test views in views/accounts.py"""
def setUp(self):
super().setUp()
self.invalid_data = {}
self.invalid_creds = {
'username': 'test',
'password': 'test23',
'remember': False
}
self.valid_data = {
'username': 'test',
'password': 'test',
'remember': False
}
User.objects.create_user(username='test', password='test')
self.url = reverse('accounts-login')
def test_login_get(self):
"""Test login view"""
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
def test_login_auth(self):
"""Test login view while being authenticated"""
self.client.login(**test_auth())
response = self.client.get(self.url)
self.assertEqual(response.status_code, 302)
def test_login_post_valid(self):
"""Test valid login"""
response = self.client.post(self.url, self.valid_data)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse('index'))
def test_login_post_next(self):
"""Test valid login + next param"""
response = self.client.post(self.url+'?next=/test', self.valid_data)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, '/test')
def test_login_post_invalid_form(self):
"""Test invalid login (inalid form data)"""
response = self.client.post(self.url, self.invalid_data)
self.assertEqual(response.status_code, 200)
def test_login_post_invalid_creds(self):
"""Test invalid login (inalid creds data)"""
response = self.client.post(self.url, self.invalid_creds)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, self.url)
def test_logout(self):
"""Test logout view"""
self.client.login(**self.valid_data)
response = self.client.get(reverse('accounts-logout'))
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse('index'))
"""pyazo URL Configuration"""
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls import url
from django.contrib import admin
from django.urls import path
from django.contrib.auth import views
from django.urls import include, path
from django.views.generic.base import RedirectView
from pyazo.core.views import accounts, core, download, upload, view
from pyazo.core.views import core, download, upload, view
admin.site.index_title = 'Pyazo Admin'
admin.site.site_title = 'pyazo'
urlpatterns = [
url(r'^$', RedirectView.as_view(url='overview/')),
url(r'^overview/$', core.IndexView.as_view(), name='index'),
url(r'^admin/', admin.site.urls),
url(r'^accounts/allauth/', include('allauth.urls')),
url(r'^accounts/login/$', accounts.login, name='accounts-login'),
url(r'^accounts/logout/$', accounts.logout, name='accounts-logout'),
url(r'^download/win/$', download.client_windows, name='download_client_windows'),
url(r'^download/sharex/$', download.sxcu, name='download-sxcu'),
url(r'^download/macos/$', download.client_macos, name='download_client_macos'),
path('', RedirectView.as_view(url='overview/')),
path('overview/', core.IndexView.as_view(), name='index'),
path('admin/', admin.site.urls),
path('accounts/allauth/', include('allauth.urls')),
path('accounts/login/', views.LoginView.as_view(), name='accounts-login'),
path('accounts/logout/', views.LogoutView.as_view(), name='accounts-logout'),
path('download/win/', download.client_windows, name='download_client_windows'),
path('download/sharex/', download.sxcu, name='download-sxcu'),
path('download/macos/', download.client_macos, name='download_client_macos'),
# Legacy upload URL
url(r'^gyazo\.php$', upload.LegacyUploadView.as_view(), name='upload'),
url(r'^upload/$', upload.LegacyUploadView.as_view(), name='upload'),
url(r'^upload/browser/$', upload.BrowserUploadView.as_view(), name='upload_browser'),
path('gyazo.php', upload.LegacyObjectView.as_view(), name='upload'),
path('upload/', upload.LegacyObjectView.as_view(), name='upload'),
path('upload/browser/', upload.BrowserObjectView.as_view(), name='upload_browser'),
url(r'^upload/(?P<file_hash>\w{128})/view/$',
upload.UploadView.as_view(), name='upload_view'),
upload.ObjectView.as_view(), name='upload_view'),
url(r'^upload/(?P<file_hash>\w{128})/claim/$',
upload.ClaimUploadView.as_view(), name='upload_claim'),
upload.ClaimObjectView.as_view(), name='upload_claim'),
url(r'^upload/(?P<file_hash>\w{128})/delete/$',
upload.DeleteUploadView.as_view(), name='upload_delete'),
upload.DeleteObjectView.as_view(), name='upload_delete'),
# All view URLs are handeled by the same Function, but we need different names
# so the default can be changed in the settings
url(r'^(?P<file_hash>\w{16})(\..{1,5})?$',
view.UploadViewFile.as_view(), name='view_sha512_short'),
view.ObjectViewFile.as_view(), name='view_sha512_short'),
url(r'^(?P<file_hash>\w{32})(\..{1,5})?$',
view.UploadViewFile.as_view(), name='view_md5'),
view.ObjectViewFile.as_view(), name='view_md5'),
url(r'^(?P<file_hash>\w{64})(\..{1,5})?$',
view.UploadViewFile.as_view(), name='view_sha256'),
view.ObjectViewFile.as_view(), name='view_sha256'),
url(r'^(?P<file_hash>\w{128})(\..{1,5})?$',
view.UploadViewFile.as_view(), name='view_sha512'),
view.ObjectViewFile.as_view(), name='view_sha512'),
]
if settings.DEBUG:
......
"""pyazo Core Account Views"""
import logging
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import authenticate
from django.contrib.auth import login as django_login
from django.contrib.auth import logout as django_logout
from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils.translation import ugettext as _
from pyazo.core.decorators import anonymous_required
from pyazo.core.forms.account import LoginForm
LOGGER = logging.getLogger(__name__)
@anonymous_required
def login(req):
"""View to handle Browser Logins Requests"""
if req.method == 'POST':
form = LoginForm(req.POST)
if form.is_valid():
user = authenticate(
username=form.cleaned_data.get('username'),
password=form.cleaned_data.get('password'))
if user is not None:
django_login(req, user)
# Set updated password in user profile for PAM
if not form.cleaned_data.get('remember'):
req.session.set_expiry(0) # Expires when browser is closed
messages.success(req, _("Successfully logged in!"))
LOGGER.info("Successfully logged in %s", form.cleaned_data.get('username'))
# Check if there is a next GET parameter and redirect to that
if 'next' in req.GET:
return redirect(req.GET.get('next'))
# Otherwise just index
return redirect(reverse('index'))
# Check if the user's account is pending
# and inform that, they need to check their usernames
# users = User.objects.filter(username=form.cleaned_data.get('username'))
messages.error(req, _("Invalid Login"))
LOGGER.info("Failed to log in %s", form.cleaned_data.get('username'))
return redirect(reverse('accounts-login'))
LOGGER.info("Form invalid")
else:
form = LoginForm()
return render(req, 'account/login.html', {
'form': form,
'title': _("SSO - Login"),
'primary_action': _("Login"),
'external_only': settings.EXTERNAL_AUTH_ONLY,
})
def logout(request):
"""Logout"""
django_logout(request)
messages.success(request, _("Successfully logged out!"))
return redirect(reverse('index'))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment