diff --git a/interface/migrations/0017_auto_20200914_0943.py b/interface/migrations/0017_auto_20200914_0943.py
new file mode 100644
index 0000000..bb2e88a
--- /dev/null
+++ b/interface/migrations/0017_auto_20200914_0943.py
@@ -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'),
+ ),
+ ]
diff --git a/interface/migrations/0018_auto_20200914_1009.py b/interface/migrations/0018_auto_20200914_1009.py
new file mode 100644
index 0000000..cf7a09e
--- /dev/null
+++ b/interface/migrations/0018_auto_20200914_1009.py
@@ -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),
+ ),
+ ]
diff --git a/interface/models.py b/interface/models.py
index cf67033..e2cba05 100644
--- a/interface/models.py
+++ b/interface/models.py
@@ -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))
diff --git a/interface/templates/base.html b/interface/templates/base.html
index 1fe19ea..bff9eb0 100644
--- a/interface/templates/base.html
+++ b/interface/templates/base.html
@@ -29,12 +29,9 @@
Ensembles
{% endif %}
+ {% if request.is_admin %}
- About
-
- {% if request.user.is_authenticated %}
-
-
+
{% endif %}
diff --git a/interface/templates/interface/manage.html b/interface/templates/interface/manage.html
new file mode 100644
index 0000000..011a4ea
--- /dev/null
+++ b/interface/templates/interface/manage.html
@@ -0,0 +1,20 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+
Manage {{ ensemble.name }}
+
+ Joining code for participants:
+ {{ ensemble_url }}
+
+
+ Sorry, not much you can do here yet.
+
+ - Should be able to create new projects.
+
+
+
+ Logged in as {{ request.user }} [
Logout]
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/interface/templates/interface/project_detail.html b/interface/templates/interface/project_detail.html
index 64011bb..f2373db 100644
--- a/interface/templates/interface/project_detail.html
+++ b/interface/templates/interface/project_detail.html
@@ -11,7 +11,7 @@
| {{ submission.date|timesince }} ago |
{{ submission.name }} ({{ submission.instrument }}) |
- {% if request.user.is_authenticated %}
+ {% if request.is_admin %}
diff --git a/interface/templates/interface/register.html b/interface/templates/interface/register.html
index d4dcade..a61fdc3 100644
--- a/interface/templates/interface/register.html
+++ b/interface/templates/interface/register.html
@@ -1,6 +1,9 @@
{% extends "base.html" %}
{% block content %}
+{% if not request.user.is_authenticated %}
+
+{% endif %}
{% if current %}
diff --git a/interface/templates/interface/resource_list.html b/interface/templates/interface/resource_list.html
index 800d023..508c3ee 100644
--- a/interface/templates/interface/resource_list.html
+++ b/interface/templates/interface/resource_list.html
@@ -14,7 +14,7 @@
Download
{% endif %}
- {% if request.user.is_authenticated %}
+ {% if request.is_admin %}
Upload
@@ -28,7 +28,7 @@
{% endwith %}
{% endfor %}
- {% if request.user.is_authenticated %}
+ {% if request.is_admin %}
diff --git a/interface/templates/registration/login.html b/interface/templates/registration/login.html
new file mode 100644
index 0000000..a30ffa0
--- /dev/null
+++ b/interface/templates/registration/login.html
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/interface/urls.py b/interface/urls.py
index b47621a..7203ffe 100644
--- a/interface/urls.py
+++ b/interface/urls.py
@@ -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/ ', views.ProjectDetailView.as_view(), name="project_detail"),
path('projects//page/', views.WikiView.as_view(), name="wiki"),
diff --git a/interface/views.py b/interface/views.py
index d3b1de0..2fc6237 100644
--- a/interface/views.py
+++ b/interface/views.py
@@ -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
\ No newline at end of file
diff --git a/polyphonic/settings_default.py b/polyphonic/settings_default.py
index e96084e..b2b4f8d 100644
--- a/polyphonic/settings_default.py
+++ b/polyphonic/settings_default.py
@@ -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/
|