diff --git a/newsletter/admin.py b/newsletter/admin.py
index 20157f36..69cb634d 100644
--- a/newsletter/admin.py
+++ b/newsletter/admin.py
@@ -1,12 +1,7 @@
from __future__ import unicode_literals
-
-import logging
-logger = logging.getLogger(__name__)
-
import six
from django.db import models
-
from django.conf import settings
from django.conf.urls import url
@@ -50,6 +45,9 @@
from .settings import newsletter_settings
+import logging
+logger = logging.getLogger(__name__)
+
# Contsruct URL's for icons
ICON_URLS = {
'yes': '%snewsletter/admin/img/icon-yes.gif' % settings.STATIC_URL,
@@ -65,7 +63,19 @@ class NewsletterAdmin(admin.ModelAdmin):
)
prepopulated_fields = {'slug': ('title',)}
+ # filter queryset by user group
+ def get_queryset(self, request):
+ qs = super(NewsletterAdmin, self).get_queryset(request)
+ if request.user.is_superuser:
+ return qs
+ newsqs = qs.filter(
+ groups__name__in=request.user.groups.values_list('name', flat=True)
+ )
+ nogroupsqs = qs.filter(groups__isnull=True)
+ return newsqs | nogroupsqs
+
""" List extensions """
+
def _admin_url(self, obj, model, text):
url = reverse('admin:%s_%s_changelist' %
(model._meta.app_label, model._meta.model_name),
@@ -89,6 +99,7 @@ def admin_submissions(self, obj):
class NewsletterAdminLinkMixin(object):
+
def admin_newsletter(self, obj):
opts = Newsletter._meta
newsletter = obj.newsletter
@@ -111,7 +122,42 @@ class SubmissionAdmin(NewsletterAdminLinkMixin, ExtendibleModelAdminMixin,
save_as = True
filter_horizontal = ('subscriptions',)
+ """ restrict access by newsletter groups """
+
+ def get_form(self, request, *args, **kwargs):
+ form = super(SubmissionAdmin, self).get_form(request, *args, **kwargs)
+ form.current_user = request.user
+ return form
+
+ def formfield_for_foreignkey(self, db_field, request, **kwargs):
+ if db_field.name == "message" and not request.user.is_superuser:
+ newsqs = Newsletter.objects.filter(
+ groups__name__in=request.user.groups.values_list(
+ 'name', flat=True)
+ )
+ nogroupsqs = Newsletter.objects.filter(groups__isnull=True)
+
+ kwargs["queryset"] = Message.objects.filter(
+ newsletter__in=(newsqs | nogroupsqs))
+ return super(SubmissionAdmin, self).formfield_for_foreignkey(
+ db_field, request, **kwargs)
+
+ # filter queryset by user group
+
+ def get_queryset(self, request):
+ qs = super(SubmissionAdmin, self).get_queryset(request)
+ if request.user.is_superuser:
+ return qs
+ newsqs = Newsletter.objects.filter(
+ groups__name__in=request.user.groups.values_list('name', flat=True)
+ )
+ nogroupsqs = Newsletter.objects.filter(groups__isnull=True)
+ listMessages = Message.objects.filter(
+ newsletter__in=(newsqs | nogroupsqs))
+ return qs.filter(message__in=listMessages)
+
""" List extensions """
+
def admin_message(self, obj):
return format_html('{}', obj.id, obj.message.title)
admin_message.short_description = _('submission')
@@ -162,6 +208,7 @@ def admin_status_text(self, obj):
admin_status_text.short_description = _('Status')
""" Views """
+
def submit(self, request, object_id):
submission = self._getobj(request, object_id)
@@ -181,6 +228,7 @@ def submit(self, request, object_id):
return HttpResponseRedirect(changelist_url)
""" URLs """
+
def get_urls(self):
urls = super(SubmissionAdmin, self).get_urls()
@@ -247,7 +295,32 @@ class MessageAdmin(NewsletterAdminLinkMixin, ExtendibleModelAdminMixin,
inlines = [ArticleInline, ]
+ # show only newsletter for user's groups
+ def formfield_for_foreignkey(self, db_field, request, **kwargs):
+ if db_field.name == "newsletter" and not request.user.is_superuser:
+ newsqs = Newsletter.objects.filter(
+ groups__name__in=request.user.groups.values_list(
+ 'name', flat=True)
+ )
+ nogroupsqs = Newsletter.objects.filter(groups__isnull=True)
+ kwargs["queryset"] = newsqs | nogroupsqs
+ return super(MessageAdmin, self).formfield_for_foreignkey(
+ db_field, request, **kwargs)
+
+ # filter queryset by user group
+ def get_queryset(self, request):
+ qs = super(MessageAdmin, self).get_queryset(request)
+ if request.user.is_superuser:
+ return qs
+ newsqs = Newsletter.objects.filter(
+ groups__name__in=request.user.groups.values_list('name', flat=True)
+ )
+ nogroupsqs = Newsletter.objects.filter(groups__isnull=True)
+
+ return qs.filter(newsletter__in=(newsqs | nogroupsqs))
+
""" List extensions """
+
def admin_title(self, obj):
return format_html('{}', obj.id, obj.title)
admin_title.short_description = _('message')
@@ -259,6 +332,7 @@ def admin_preview(self, obj):
admin_preview.short_description = ''
""" Views """
+
def preview(self, request, object_id):
return render(
request,
@@ -320,6 +394,7 @@ def subscribers_json(self, request, object_id):
return HttpResponse(json, content_type='application/json')
""" URLs """
+
def get_urls(self):
urls = super(MessageAdmin, self).get_urls()
@@ -366,7 +441,33 @@ class SubscriptionAdmin(NewsletterAdminLinkMixin, ExtendibleModelAdminMixin,
actions = ['make_subscribed', 'make_unsubscribed']
exclude = ['unsubscribed']
+ """ restrict access by newsletter groups """
+
+ def formfield_for_foreignkey(self, db_field, request, **kwargs):
+ if db_field.name == "newsletter" and not request.user.is_superuser:
+ newsqs = Newsletter.objects.filter(
+ groups__name__in=request.user.groups.values_list(
+ 'name', flat=True)
+ )
+ nogroupsqs = Newsletter.objects.filter(groups__isnull=True)
+ kwargs["queryset"] = newsqs | nogroupsqs
+ return super(SubscriptionAdmin, self).formfield_for_foreignkey(
+ db_field, request, **kwargs)
+
+ # filter queryset by user group
+ def get_queryset(self, request):
+ qs = super(SubscriptionAdmin, self).get_queryset(request)
+ if request.user.is_superuser:
+ return qs
+ newsqs = Newsletter.objects.filter(
+ groups__name__in=request.user.groups.values_list('name', flat=True)
+ )
+ nogroupsqs = Newsletter.objects.filter(groups__isnull=True)
+
+ return qs.filter(newsletter__in=(newsqs | nogroupsqs))
+
""" List extensions """
+
def admin_status(self, obj):
img_tag = ''
alt_txt = self.admin_status_text(obj)
@@ -403,6 +504,7 @@ def admin_unsubscribe_date(self, obj):
admin_unsubscribe_date.short_description = _("unsubscribe date")
""" Actions """
+
def make_subscribed(self, request, queryset):
rows_updated = queryset.update(subscribed=True)
self.message_user(
@@ -428,6 +530,7 @@ def make_unsubscribed(self, request, queryset):
make_unsubscribed.short_description = _("Unsubscribe selected users")
""" Views """
+
def subscribers_import(self, request):
if not request.user.has_perm('newsletter.add_subscription'):
raise PermissionDenied()
@@ -501,6 +604,7 @@ def subscribers_import_confirm(self, request):
)
""" URLs """
+
def get_urls(self):
urls = super(SubscriptionAdmin, self).get_urls()
@@ -516,13 +620,14 @@ def get_urls(self):
# only used in this part of the admin. For now, leave them here.
if HAS_CBV_JSCAT:
my_urls.append(url(r'^jsi18n/$',
- JavaScriptCatalog.as_view(packages=('newsletter',)),
- name='newsletter_js18n'))
+ JavaScriptCatalog.as_view(
+ packages=('newsletter',)),
+ name='newsletter_js18n'))
else:
my_urls.append(url(r'^jsi18n/$',
- javascript_catalog,
- {'packages': ('newsletter',)},
- name='newsletter_js18n'))
+ javascript_catalog,
+ {'packages': ('newsletter',)},
+ name='newsletter_js18n'))
return my_urls + urls
diff --git a/newsletter/admin_forms.py b/newsletter/admin_forms.py
index 59aa0c1c..c7967ffb 100644
--- a/newsletter/admin_forms.py
+++ b/newsletter/admin_forms.py
@@ -148,6 +148,17 @@ class Meta:
model = Submission
fields = '__all__'
+ def __init__(self, *args, **kwargs):
+ super(SubmissionAdminForm, self).__init__(*args, **kwargs)
+ if not self.current_user.is_superuser:
+ newsqs = Newsletter.objects.filter(
+ groups__name__in=self.current_user.groups.values_list(
+ 'name', flat=True)
+ )
+ nogroupsqs = Newsletter.objects.filter(groups__isnull=True)
+ self.fields['subscriptions'].queryset = Subscription.objects.filter(
+ newsletter__in=(newsqs | nogroupsqs))
+
def clean_publish(self):
"""
Make sure only one submission can be published for each message.
diff --git a/newsletter/migrations/0005_newsletter_groups.py b/newsletter/migrations/0005_newsletter_groups.py
new file mode 100644
index 00000000..e2304cd9
--- /dev/null
+++ b/newsletter/migrations/0005_newsletter_groups.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.16 on 2018-11-23 13:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('auth', '0008_alter_user_username_max_length'),
+ ('newsletter', '0004_auto_20180407_1043'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='newsletter',
+ name='groups',
+ field=models.ManyToManyField(blank=True, related_name='groups', to='auth.Group', verbose_name='Groups'),
+ ),
+ ]
diff --git a/newsletter/models.py b/newsletter/models.py
index 9d2a7cd4..b8d2396b 100644
--- a/newsletter/models.py
+++ b/newsletter/models.py
@@ -3,6 +3,7 @@
import django
from django.conf import settings
+from django.contrib.auth.models import Group
from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager
from django.core.mail import EmailMultiAlternatives
@@ -53,6 +54,11 @@ class Newsletter(models.Model):
help_text=_('Whether or not to send HTML versions of e-mails.')
)
+ groups = models.ManyToManyField(
+ Group, related_name='groups', verbose_name=_('Groups'),
+ blank=True
+ )
+
objects = models.Manager()
# Automatically filter the current site