Skip to content

Commit d53f81e

Browse files
authored
Disable User petition with setting (#237)
* feat - Add filtering on new DISABLE_USER_PETITION setting * test - Test users can't access user petition - Test users can still access org petition * test - check no error message * misc - Document DISABLE_USER_PETITION setting * feat - Disable petition transfer from org to user
1 parent d8d635e commit d53f81e

File tree

5 files changed

+136
-5
lines changed

5 files changed

+136
-5
lines changed

doc/configuration.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,5 @@ Those are things you can configure to customize your Pytition instance:
5050

5151
.. autodata:: pytition.settings.base.SITE_NAME
5252
.. autodata:: pytition.settings.base.FOOTER_TEMPLATE
53+
.. autodata:: pytition.settings.base.DISABLE_USER_PETITION
5354
.. autodata:: pytition.settings.base.RESTRICT_ORG_CREATION

pytition/petition/tests/tests_PetitionCreationWizard.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from django.test import TestCase
1+
from django.test import TestCase, override_settings
22
from django.urls import reverse
33
from django.contrib.auth import get_user_model
4+
from django.contrib.messages import get_messages
45

56
from petition.models import Organization, Petition, PytitionUser, Permission
67

@@ -75,3 +76,20 @@ def test_call_page2_ok(self):
7576
org = Organization.objects.get(name='Les Amis de la Terre')
7677
response = self.client.get(reverse("user_petition_wizard"))
7778
self.assertEqual(response.status_code, 200)
79+
80+
@override_settings(DISABLE_USER_PETITION=True)
81+
def test_user_petition_disabled(self):
82+
self.login("julia")
83+
response = self.client.get(reverse("user_petition_wizard"))
84+
self.assertRedirects(response, reverse("user_dashboard"))
85+
response = self.client.get(reverse("user_petition_wizard"), follow=True)
86+
self.assertEqual(response.status_code, 200)
87+
self.assertContains(response, "Users are not allowed to create their own petitions.")
88+
89+
@override_settings(DISABLE_USER_PETITION=True)
90+
def test_org_petition_still_working(self):
91+
self.login("julia")
92+
org = Organization.objects.get(name='Les Amis de la Terre')
93+
response = self.client.get(reverse("org_petition_wizard", args=[org.slugname]))
94+
self.assertEqual(response.status_code, 200)
95+
self.assertNotContains(response, "Users are not allowed to create their own petitions.")
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from django.test import TestCase, override_settings
2+
from django.urls import reverse
3+
from django.contrib.auth import get_user_model
4+
from django.contrib.messages import get_messages
5+
6+
from petition.models import Organization, Petition, PytitionUser, Permission
7+
8+
9+
users = ['julia', 'john', 'max', 'sarah']
10+
orgs = ['RAP', 'Greenpeace', 'Attac', 'Les Amis de la Terre']
11+
12+
org_members = {
13+
'RAP': ['julia'],
14+
'Les Amis de la Terre': ['julia', 'max'],
15+
'Attac': ['john'],
16+
}
17+
18+
19+
class PetitionCreateWizardViewTest(TestCase):
20+
"""Test PetitionCreateWizard view"""
21+
@classmethod
22+
def setUpTestData(cls):
23+
User = get_user_model()
24+
for org in orgs:
25+
o = Organization.objects.create(name=org)
26+
o.save()
27+
for user in users:
28+
u = User.objects.create_user(user, password=user)
29+
u.first_name = user
30+
u.last_name = user + "Last"
31+
u.save()
32+
for orgname in org_members:
33+
org = Organization.objects.get(name=orgname)
34+
for username in org_members[orgname]:
35+
user = PytitionUser.objects.get(user__username=username)
36+
org.members.add(user)
37+
permission = Permission.objects.get(organization=org, user=user)
38+
permission.can_modify_permissions=True
39+
permission.save()
40+
41+
# give julia can_modify_petitions permission on "Les Amis de la Terre" organization
42+
user = PytitionUser.objects.get(user__username='julia')
43+
org = Organization.objects.get(name="Les Amis de la Terre")
44+
perm = Permission.objects.get(organization=org, user=user)
45+
perm.can_modify_petitions = True
46+
perm.save()
47+
48+
def login(self, name, password=None):
49+
self.client.login(username=name, password=password if password else name)
50+
self.pu = PytitionUser.objects.get(user__username=name)
51+
return self.pu
52+
53+
def logout(self):
54+
self.client.logout()
55+
56+
def test_model_transfer_method(self):
57+
org = Organization.objects.get(name="Les Amis de la Terre")
58+
user = PytitionUser.objects.get(user__username="julia")
59+
60+
user_petition = Petition.objects.create(title="Petition 1", user=user)
61+
self.assertEqual(user_petition.user, user)
62+
self.assertEqual(user_petition.org, None)
63+
64+
user_petition.transfer_to(org=org)
65+
self.assertEqual(user_petition.user, None)
66+
self.assertEqual(user_petition.org, org)
67+
68+
user_petition.transfer_to(user=user)
69+
self.assertEqual(user_petition.user, user)
70+
self.assertEqual(user_petition.org, None)
71+
72+
with self.assertRaises(ValueError):
73+
user_petition.transfer_to()
74+
user_petition.transfer_to(org=org, user=user)
75+
76+
def test_transfer_view(self):
77+
self.login("julia")
78+
org = Organization.objects.get(name="Les Amis de la Terre")
79+
user = PytitionUser.objects.get(user__username="julia")
80+
user_petition = Petition.objects.create(title="Petition 1", user=user)
81+
url = reverse("transfer_petition", args=[user_petition.id])
82+
83+
response = self.client.post(url, data={"new_owner_type": "org", "new_owner_name": org.slugname}, follow=True)
84+
self.assertEqual(response.status_code, 200)
85+
user_petition = Petition.objects.get(id=user_petition.id)
86+
self.assertEqual(user_petition.org, org)
87+
88+
response = self.client.post(url, data={"new_owner_type": "user", "new_owner_name": user.user.username}, follow=True)
89+
self.assertEqual(response.status_code, 200)
90+
user_petition = Petition.objects.get(id=user_petition.id)
91+
self.assertEqual(user_petition.user, user)
92+
93+
with override_settings(DISABLE_USER_PETITION=True):
94+
user_petition = Petition.objects.create(title="Petition 1", org=org)
95+
response = self.client.post(url, data={"new_owner_type": "user", "new_owner_name": user.user.username}, follow=True)
96+
self.assertContains(response, "Users are not allowed to transfer petitions to organizations on this instance.")
97+
user_petition = Petition.objects.get(id=user_petition.id)
98+
self.assertIsNone(user_petition.user)
99+

pytition/petition/views.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,12 @@ def org_set_user_perms(request, orgslugname, user_name):
902902
# PATH : subroutes of /wizard
903903
@method_decorator(login_required, name='dispatch')
904904
class PetitionCreationWizard(SessionWizardView):
905+
def dispatch(self, request, *args, **kwargs):
906+
if settings.DISABLE_USER_PETITION and "orgslugname" not in self.kwargs:
907+
messages.error(request, _("Users are not allowed to create their own petitions."))
908+
return redirect("user_dashboard")
909+
return super().dispatch(request, *args, **kwargs)
910+
905911
def get_template_names(self):
906912
return [WizardTemplates[self.steps.current]]
907913

@@ -1614,6 +1620,9 @@ def transfer_petition(request, petition_id):
16141620
except:
16151621
notFound = True
16161622
if owner_type == "user":
1623+
if settings.DISABLE_USER_PETITION:
1624+
messages.error(request, _("Users are not allowed to transfer petitions to organizations on this instance."))
1625+
return redirect("user_dashboard")
16171626
try:
16181627
user = PytitionUser.objects.get(user__username=new_owner_name)
16191628
except:

pytition/pytition/settings/base.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,12 @@
104104
MAIL_EXTERNAL_CRON_SET = False
105105

106106
# number of seconds to wait before sending emails. This will be usefull only if USE_MAIL_QUEUE=True and uwsgi is used
107-
UWSGI_WAIT_FOR_MAIL_SEND_IN_S=10
107+
UWSGI_WAIT_FOR_MAIL_SEND_IN_S = 10
108108
# number of seconds to wait before retrying emails. This will be usefull only if USE_MAIL_QUEUE=True and uwsgi is used
109-
UWSGI_WAIT_FOR_RETRY_IN_S=1 * 60
109+
UWSGI_WAIT_FOR_RETRY_IN_S = 1 * 60
110110
# number of seconds to wait before purging emails. This will be usefull only if USE_MAIL_QUEUE=True and uwsgi is used
111-
UWSGI_WAIT_FOR_PURGE_IN_S=1 * 24 * 60 * 60
112-
UWSGI_NB_DAYS_TO_KEEP=3
111+
UWSGI_WAIT_FOR_PURGE_IN_S = 1 * 24 * 60 * 60
112+
UWSGI_NB_DAYS_TO_KEEP = 3
113113

114114
# Password validation
115115
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
@@ -256,6 +256,10 @@
256256
FILE_UPLOAD_PERMISSIONS = 0o640
257257
FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o750
258258

259+
260+
#:| If set to True, users won't be able to create petitions in their name, but only for an organization
261+
DISABLE_USER_PETITION = False
262+
259263
#:| If set to True, regular users won't be able to create new organizations.
260264
#:| Only superusers will be allowed to
261265
RESTRICT_ORG_CREATION = False

0 commit comments

Comments
 (0)