Skip to content

Commit

Permalink
Bugs: new users default policy; org creation
Browse files Browse the repository at this point in the history
 - Add default policy to new users
 - Bump django-tutelary dependency for better queryset filtering
 - Avoid using "default" as a policy name in tests
 - Make creator of organization an org admin
 - DRY tox and setup dependency configuration
 - Fix up policy creation in functional tests
  • Loading branch information
Ian Ross committed Apr 22, 2016
1 parent bb51bf2 commit 7956a82
Show file tree
Hide file tree
Showing 30 changed files with 185 additions and 178 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include requirements/*.txt
21 changes: 21 additions & 0 deletions cadasta/accounts/models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from datetime import datetime, timezone, timedelta
from django.conf import settings
from django.db import models
from django.dispatch import receiver
from django.utils.translation import ugettext as _
from django.contrib.auth.models import AbstractUser
from tutelary.models import Policy
from tutelary.decorators import permissioned_model

from .manager import UserManager


PERMISSIONS_DIR = settings.BASE_DIR + '/permissions/'


def now_plus_48_hours():
return datetime.now(tz=timezone.utc) + timedelta(hours=48)

Expand All @@ -30,3 +36,18 @@ class TutelaryMeta:
('user.update',
{'error_message':
_("You don't have permission to update user details")})]


@receiver(models.signals.post_save, sender=User)
def assign_default_policy(sender, instance, **kwargs):
try:
policy = Policy.objects.get(name='default')
except Policy.DoesNotExist:
policy = Policy.objects.create(
name='default',
body=open(PERMISSIONS_DIR + 'default.json').read()
)
assigned_policies = instance.assigned_policies()
if policy not in assigned_policies:
assigned_policies.insert(0, policy)
instance.assign_policies(*assigned_policies)
18 changes: 6 additions & 12 deletions cadasta/accounts/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,8 @@ def test_signup_with_existing_email(self):

class ProfileFormTest(TestCase):
def test_update_user(self):
user = UserFactory.create(**{
'username': 'imagine71',
'email': '[email protected]'
})
user = UserFactory.create(username='imagine71',
email='[email protected]')
data = {
'username': 'imagine71',
'email': '[email protected]',
Expand All @@ -80,10 +78,8 @@ def test_update_user(self):

def test_update_user_with_existing_username(self):
UserFactory.create(username='existing')
user = UserFactory.create(**{
'username': 'imagine71',
'email': '[email protected]'
})
user = UserFactory.create(username='imagine71',
email='[email protected]')
data = {
'username': 'existing',
'email': '[email protected]',
Expand All @@ -95,10 +91,8 @@ def test_update_user_with_existing_username(self):

def test_update_user_with_existing_email(self):
UserFactory.create(email='[email protected]')
user = UserFactory.create(**{
'username': 'imagine71',
'email': '[email protected]'
})
user = UserFactory.create(username='imagine71',
email='[email protected]')
data = {
'username': 'imagine71',
'email': '[email protected]',
Expand Down
12 changes: 4 additions & 8 deletions cadasta/accounts/tests/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ def test_create_with_existing_email(self):
"""Serialiser should be invalid when another user with the same email
address is already registered."""

UserFactory.create(**{
'email': '[email protected]',
})
UserFactory.create(email='[email protected]')

data = {
'username': 'imagine71',
Expand Down Expand Up @@ -137,11 +135,9 @@ def test_unverified_account(self):
"""Serializer should raise EmailNotVerifiedError exeception when the
user has not verified their email address within 48 hours"""

UserFactory.create(**{
'username': 'sgt_pepper',
'password': 'iloveyoko79',
'verify_email_by': datetime.now()
})
UserFactory.create(username='sgt_pepper',
password='iloveyoko79',
verify_email_by=datetime.now())

with pytest.raises(EmailNotVerifiedError):
AccountLoginSerializer().validate(attrs={
Expand Down
8 changes: 3 additions & 5 deletions cadasta/accounts/tests/test_views_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,9 @@ def test_user_signs_up_with_invalid(self):

class AccountLoginTest(TestCase):
def setUp(self):
self.user = UserFactory.create(**{
'username': 'imagine71',
'email': '[email protected]',
'password': 'iloveyoko79'
})
self.user = UserFactory.create(username='imagine71',
email='[email protected]',
password='iloveyoko79')

def _post(self, data, status=None, token=None):
url = '/v1/account/login/'
Expand Down
5 changes: 4 additions & 1 deletion cadasta/core/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ def add_test_users_and_roles(self):
pols = {}
for pol in ['default', 'superuser', 'org-admin', 'org-member',
'project-manager', 'data-collector', 'project-user']:
pols[pol] = PolicyFactory.create(name=pol, file=pol + '.json')
try:
pols[pol] = Policy.objects.get(name=pol)
except Policy.DoesNotExist:
pols[pol] = PolicyFactory.create(name=pol, file=pol + '.json')

roles = {}
roles['superuser'] = RoleFactory.create(
Expand Down
3 changes: 2 additions & 1 deletion cadasta/organization/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def save(self, *args, **kwargs):
if create:
OrganizationRole.objects.create(
organization=instance,
user=self.user
user=self.user,
admin=True
)

return instance
Expand Down
6 changes: 6 additions & 0 deletions cadasta/organization/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ class TutelaryMeta:
def __str__(self):
return "<Organization: {name}>".format(name=self.name)

def __repr__(self):
return str(self)


class OrganizationRole(RandomIDModel):
organization = models.ForeignKey(Organization)
Expand Down Expand Up @@ -201,6 +204,9 @@ class TutelaryMeta:
def __str__(self):
return "<Project: {name}>".format(name=self.name)

def __repr__(self):
return str(self)

def save(self, *args, **kwargs):
if ((self.country is None or self.country == '') and
self.extent is not None):
Expand Down
3 changes: 2 additions & 1 deletion cadasta/organization/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ def create(self, *args, **kwargs):

OrganizationRole.objects.create(
organization=org,
user=self.context['request'].user
user=self.context['request'].user,
admin=True
)

return org
Expand Down
2 changes: 1 addition & 1 deletion cadasta/organization/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def test_add_organization_with_contact(self):
assert org.contacts == [{'name': 'Ringo Starr', 'tel': '555-5555'}]

def test_update_organization(self):
org = OrganizationFactory.create(**{'slug': 'some-org'})
org = OrganizationFactory.create(slug='some-org')

data = {
'name': 'Org',
Expand Down
2 changes: 1 addition & 1 deletion cadasta/organization/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_remove_admin_role(self):

def test_delete_project_roles(self):
ProjectFactory.create_batch(2, add_users=[self.user],
**{'organization': self.org})
organization=self.org)
ProjectFactory.create_batch(2, add_users=[self.user])
assert ProjectRole.objects.filter(user=self.user).count() == 4

Expand Down
2 changes: 1 addition & 1 deletion cadasta/organization/tests/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def test_list_to_representation(self):
def test_set_roles_for_existing_user(self):
user = UserFactory.create()
org = OrganizationFactory.create(add_users=[user])
project = ProjectFactory.create(**{'organization': org})
project = ProjectFactory.create(organization=org)
data = {'username': user.username, 'role': 'DC'}
serializer = serializers.ProjectUserSerializer(
data=data,
Expand Down
42 changes: 24 additions & 18 deletions cadasta/organization/tests/test_views_api_organizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def setUp(self):
]
}
policy = Policy.objects.create(
name='default',
name='test-policy',
body=json.dumps(clauses))
self.user = UserFactory.create()
assign_user_policies(self.user, policy)
Expand Down Expand Up @@ -128,7 +128,7 @@ def setUp(self):
]
}
policy = Policy.objects.create(
name='default',
name='test-policy-1',
body=json.dumps(clauses))
self.user = UserFactory.create()
assign_user_policies(self.user, policy)
Expand All @@ -140,12 +140,13 @@ def setUp(self):
]
}
policy = Policy.objects.create(
name='default',
name='test-policy-2',
body=json.dumps(clauses))
self.unauth_user = UserFactory.create()
assign_user_policies(self.unauth_user, policy)

def _post(self, data, user=None, status=None, count=None):
def _post(self, data, user=None, status=None, count=None,
check_admin=False):
if user is None:
user = self.user
url = '/v1/organizations/'
Expand All @@ -157,11 +158,16 @@ def _post(self, data, user=None, status=None, count=None):
assert response.status_code == status
if count is not None:
assert Organization.objects.count() == count
if check_admin:
org = Organization.objects.get(pk=content['id'])
assert OrganizationRole.objects.get(
organization=org, user=user
).admin
return content

def test_create_valid_organization(self):
data = {'name': 'Org Name', 'description': 'Org description'}
self._post(data, status=201, count=1)
self._post(data, status=201, count=1, check_admin=True)

def test_create_invalid_organization(self):
data = {'description': 'Org description'}
Expand All @@ -185,7 +191,7 @@ def setUp(self):
]
}
policy = Policy.objects.create(
name='default',
name='test-policy-1',
body=json.dumps(clauses))
self.user = UserFactory.create()
assign_user_policies(self.user, policy)
Expand All @@ -197,7 +203,7 @@ def setUp(self):
]
}
policy = Policy.objects.create(
name='default',
name='test-policy-2',
body=json.dumps(clauses))
self.unauth_user = UserFactory.create()
assign_user_policies(self.unauth_user, policy)
Expand Down Expand Up @@ -227,13 +233,13 @@ def _patch(self, slug, data, user=None, status=None):
return content

def test_get_organization(self):
org = OrganizationFactory.create(**{'slug': 'org'})
org = OrganizationFactory.create(slug='org')
content = self._get(org.slug, status=200)
assert content['id'] == org.id
assert 'users' in content

def test_get_organization_with_unauthorized_user(self):
org = OrganizationFactory.create(**{'slug': 'org'})
org = OrganizationFactory.create(slug='org')
content = self._get(org.slug, user=AnonymousUser(), status=403)
assert content['detail'] == PermissionDenied.default_detail

Expand All @@ -242,50 +248,50 @@ def test_get_organization_that_does_not_exist(self):
assert content['detail'] == "Organization not found."

def test_valid_update(self):
org = OrganizationFactory.create(**{'slug': 'org'})
org = OrganizationFactory.create(slug='org')
data = {'name': 'Org Name'}
self._patch(org.slug, data, status=200)
org.refresh_from_db()
assert org.name == data.get('name')

def test_update_with_unauthorized_user(self):
org = OrganizationFactory.create(**{'name': 'Org name', 'slug': 'org'})
org = OrganizationFactory.create(name='Org name', slug='org')
data = {'name': 'Org Name'}
self._patch(org.slug, data, user=AnonymousUser(), status=403)
org.refresh_from_db()
assert org.name == 'Org name'

def test_invalid_update(self):
org = OrganizationFactory.create(**{'name': 'Org name', 'slug': 'org'})
org = OrganizationFactory.create(name='Org name', slug='org')
data = {'name': ''}
content = self._patch(org.slug, data, status=400)
org.refresh_from_db()
assert org.name == 'Org name'
assert content['name'][0] == 'This field may not be blank.'

def test_archive(self):
org = OrganizationFactory.create(**{'name': 'Org name', 'slug': 'org'})
org = OrganizationFactory.create(name='Org name', slug='org')
data = {'archived': True}
self._patch(org.slug, data, status=200)
org.refresh_from_db()
assert org.archived

def test_archive_with_unauthorized_user(self):
org = OrganizationFactory.create(**{'slug': 'org'})
org = OrganizationFactory.create(slug='org')
data = {'archived': True}
self._patch(org.slug, data, user=self.unauth_user, status=403)
org.refresh_from_db()
assert not org.archived

def test_unarchive(self):
org = OrganizationFactory.create(**{'slug': 'org', 'archived': True})
org = OrganizationFactory.create(slug='org', archived=True)
data = {'archived': False}
self._patch(org.slug, data, status=200)
org.refresh_from_db()
assert not org.archived

def test_unarchive_unauthorized_user(self):
org = OrganizationFactory.create(**{'slug': 'org', 'archived': True})
org = OrganizationFactory.create(slug='org', archived=True)
data = {'archived': False}
self._patch(org.slug, data, user=self.unauth_user, status=403)
org.refresh_from_db()
Expand All @@ -303,7 +309,7 @@ def setUp(self):
]
}
policy = Policy.objects.create(
name='default',
name='test-policy',
body=json.dumps(clauses))
self.user = UserFactory.create()
assign_user_policies(self.user, policy)
Expand Down Expand Up @@ -391,7 +397,7 @@ def setUp(self):
]
}
policy = Policy.objects.create(
name='default',
name='test-policy',
body=json.dumps(clauses))
self.user = UserFactory.create()
assign_user_policies(self.user, policy)
Expand Down
Loading

0 comments on commit 7956a82

Please sign in to comment.