Got admin user login working

This commit is contained in:
Tris 2020-09-14 13:34:53 +10:00
parent 65d5c9631c
commit d1698a958c
12 changed files with 145 additions and 12 deletions

View File

@ -0,0 +1,25 @@
# Generated by Django 3.1.1 on 2020-09-13 23:43
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('interface', '0016_auto_20200910_2025'),
]
operations = [
migrations.AddField(
model_name='ensemble',
name='admins',
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='submission',
name='instrument',
field=models.CharField(max_length=100, verbose_name='Instrument / Voice'),
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 3.1.1 on 2020-09-14 00:09
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('interface', '0017_auto_20200914_0943'),
]
operations = [
migrations.AddField(
model_name='resource',
name='visible',
field=models.BooleanField(default=True),
),
migrations.AlterField(
model_name='ensemble',
name='admins',
field=models.ManyToManyField(related_name='ensembles', to=settings.AUTH_USER_MODEL),
),
]

View File

@ -28,6 +28,7 @@ class Ensemble(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=9, default=generate_code)
passphrase = models.CharField(max_length=100)
admins = models.ManyToManyField('auth.User', related_name='ensembles')
def active_projects(self):
return self.projects.filter(active=True)
@ -62,6 +63,7 @@ class Resource(models.Model):
description = models.TextField(blank=True)
key = models.CharField(max_length=255, blank=True)
media_type = models.CharField(max_length=10, choices=MEDIA_TYPES, default='*')
visible = models.BooleanField(default=True)
def key_template(self):
return "{}/${{filename}}".format(slugify(self.name))

View File

@ -29,12 +29,9 @@
Ensembles</span></a>
</li>
{% endif %}
{% if request.is_admin %}
<li class="nav-item">
<a class="nav-link" href=""><i class="fas fa-question"></i> <span class="">About</span></a>
</li>
{% if request.user.is_authenticated %}
<li class="nav-item">
<a href="/admin"><i class="fas fa-key"></i></a>
<a href="{% url 'manage' %}"><i class="fas fa-user-lock"></i></a>
</li>
{% endif %}
</ul>

View File

@ -0,0 +1,20 @@
{% extends "base.html" %}
{% block content %}
<div class="narrow">
<h3>Manage {{ ensemble.name }}</h3>
<p>
Joining code for participants:<br/>
<a href="{{ ensemble_url }}">{{ ensemble_url }}</a>
</p>
<p>
Sorry, not much you can do here yet.
<ul>
<li>Should be able to create new projects.</li>
</ul>
<br/>
Logged in as {{ request.user }} [<a href="{% url 'logout' %}">Logout</a>]
</p>
</div>
{% endblock %}

View File

@ -11,7 +11,7 @@
<tr>
<td>{{ submission.date|timesince }} ago</td>
<td>{{ submission.name }} ({{ submission.instrument }})</td>
{% if request.user.is_authenticated %}
{% if request.is_admin %}
<td>
<a href="{% url 'submission_detail' project=project.pk pk=submission.pk %}"><i class="fas fa-info-circle"></i></a>
&nbsp;

View File

@ -1,6 +1,9 @@
{% extends "base.html" %}
{% block content %}
{% if not request.user.is_authenticated %}
<a href="{% url 'login' %}" style="float: right"><i class="fa fa-key"></i></a>
{% endif %}
<div style="display: flex">
{% if current %}
<div>

View File

@ -14,7 +14,7 @@
<i class="fas fa-download"></i> Download
</a>
{% endif %}
{% if request.user.is_authenticated %}
{% if request.is_admin %}
<a href="{% url 'resource_upload' project=project.pk pk=resource.pk %}">
<i class="fas fa-upload"></i> Upload
</a>
@ -28,7 +28,7 @@
{% endwith %}
{% endfor %}
</div>
{% if request.user.is_authenticated %}
{% if request.is_admin %}
<div class="admin-actions">
<a href="{% url 'resource_create' project=project.pk %}"><i class="fas fa-plus-circle"></i> Add new</a>
</div>

View File

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% block content %}
<form method="POST" class="vertical">
{% csrf_token %}
{{ form }}
<div class="form-actions">
<button type="submit">Login</button>
</div>
</form>
{% endblock %}

View File

@ -1,10 +1,16 @@
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
path('', views.EnsembleDetailView.as_view(), name='ensemble_detail'),
path('login', auth_views.LoginView.as_view(), name='login'),
path('logout', views.logout, name='logout'),
path('register', views.register, name="register"),
path('manage', views.ManageView.as_view(), name="manage"),
path('', views.EnsembleDetailView.as_view(), name='ensemble_detail'),
path('projects/<int:pk>', views.ProjectDetailView.as_view(), name="project_detail"),
path('projects/<int:project>/page/<int:pk>', views.WikiView.as_view(), name="wiki"),

View File

@ -6,6 +6,7 @@ from django.views.generic.edit import CreateView
from django.views.generic.base import ContextMixin
from django.http import HttpResponseRedirect
from django.core.exceptions import SuspiciousOperation
from django.contrib import auth
from markdown2 import markdown
from datetime import datetime
@ -19,14 +20,26 @@ import logging
logger = logging.getLogger(__name__)
class EnsembleMixin(object):
admin_required = False
def dispatch(self, request, *args, **kwargs):
request.ensemble_id = request.session.get('ensemble')
request.is_admin = request.user.is_superuser
if not request.ensemble_id:
return redirect('register')
if not request.is_admin and request.user.is_authenticated:
try:
request.user.ensembles.get(pk=request.ensemble_id)
request.is_admin = True
except models.Ensemble.DoesNotExist:
pass
if self.admin_required and not request.is_admin:
return redirect('login')
return super().dispatch(request, *args, **kwargs)
class ProjectMixin(EnsembleMixin):
@ -134,6 +147,24 @@ def register(request):
return render(request, 'interface/register.html', {'form': form, 'current': current})
def on_login(sender, **kwargs):
request = kwargs['request']
registered = request.session.get('registered', {})
for e in kwargs['user'].ensembles.all():
if not e.code in registered:
registered[e.code] = e.pk
request.session['registered'] = registered
auth.signals.user_logged_in.connect(on_login)
def logout(request):
ensemble = request.session.get('ensemble')
registered = request.session.get('registered', {})
auth.logout(request)
request.session['ensemble'] = ensemble
request.session['registered'] = registered
return redirect('/')
class EnsembleDetailView(EnsembleMixin, DetailView):
def dispatch(self, request, *args, **kwargs):
@ -188,7 +219,7 @@ class SubmissionDetailView(ProjectMixin, S3CompleteMixin, DetailView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
if self.request.is_admin:
context['download'] = self.object.presigned_url()
return context
@ -219,7 +250,7 @@ class ResourceCreateView(ProjectMixin, CreateView):
def form_valid(self, form):
if not self.request.user.is_authenticated:
if not self.request.is_admin:
raise SuspiciousOperation("Must be logged in to create resources")
self.object = form.save(commit=False)
@ -250,3 +281,16 @@ class ResourceCompleteView(S3CompleteMixin, SingleObjectMixin, RedirectView):
class ResourceListView(ProjectMixin, ListView):
model = models.Resource
def get_queryset(self):
return super().get_queryset().filter(visible=True)
class ManageView(EnsembleMixin, TemplateView):
template_name = 'interface/manage.html'
admin_required = True
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['ensemble'] = models.Ensemble.objects.get(pk=self.request.ensemble_id)
context['ensemble_url'] = self.request.build_absolute_uri('/?code={0}'.format(context['ensemble'].ensemble_code()))
return context

View File

@ -99,7 +99,7 @@ AUTH_PASSWORD_VALIDATORS = [
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LOGIN_REDIRECT_URL = "/"
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/