Skip to content

Commit

Permalink
Merge pull request #160 from rapidpro/django_19_pt1
Browse files Browse the repository at this point in the history
Django 1.9 preparation
  • Loading branch information
rowanseymour committed Oct 6, 2016
2 parents 296cecd + 5217f3a commit 8e29057
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 283 deletions.
34 changes: 1 addition & 33 deletions casepro/orgs_ext/__init__.py
Original file line number Diff line number Diff line change
@@ -1,33 +1 @@
from __future__ import absolute_import, unicode_literals

from dash.orgs.models import Org
from django.conf import settings
from django.contrib.auth.models import User
from django.db.models import Q


ORG_CACHE_TTL = 60 * 60 * 24 * 7 # 1 week
ORG_CONFIG_BANNER_TEXT = 'banner_text'


def _org_get_users(org):
queryset = User.objects.filter(is_active=True)
return queryset.filter(Q(org_admins=org) | Q(org_editors=org) | Q(org_viewers=org)).distinct()


def _org_get_banner_text(org):
return org.get_config(ORG_CONFIG_BANNER_TEXT)


def _org_set_banner_text(org, text):
org.set_config(ORG_CONFIG_BANNER_TEXT, text)


def _org_make_absolute_url(org, url):
return settings.SITE_HOST_PATTERN % org.subdomain + url


Org.get_users = _org_get_users
Org.get_banner_text = _org_get_banner_text
Org.set_banner_text = _org_set_banner_text
Org.make_absolute_url = _org_make_absolute_url
from __future__ import unicode_literals
33 changes: 33 additions & 0 deletions casepro/orgs_ext/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from __future__ import unicode_literals

from dash.orgs.models import Org
from django.conf import settings
from django.contrib.auth.models import User
from django.db.models import Q


ORG_CACHE_TTL = 60 * 60 * 24 * 7 # 1 week
ORG_CONFIG_BANNER_TEXT = 'banner_text'


def _org_get_users(org):
queryset = User.objects.filter(is_active=True)
return queryset.filter(Q(org_admins=org) | Q(org_editors=org) | Q(org_viewers=org)).distinct()


def _org_get_banner_text(org):
return org.get_config(ORG_CONFIG_BANNER_TEXT)


def _org_set_banner_text(org, text):
org.set_config(ORG_CONFIG_BANNER_TEXT, text)


def _org_make_absolute_url(org, url):
return settings.SITE_HOST_PATTERN % org.subdomain + url


Org.get_users = _org_get_users
Org.get_banner_text = _org_get_banner_text
Org.set_banner_text = _org_set_banner_text
Org.make_absolute_url = _org_make_absolute_url
194 changes: 1 addition & 193 deletions casepro/profiles/__init__.py
Original file line number Diff line number Diff line change
@@ -1,193 +1 @@
from __future__ import absolute_import, unicode_literals

from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _


# ================================== Monkey patching for the User class ====================================

def _user_clean(user):
# we use email for login
if User.objects.filter(email=user.email).exclude(pk=user.pk).exists():
raise ValidationError(_("Email address already taken."))

user.username = user.email

super(User, user).clean()


def _user_has_profile(user):
from .models import Profile
return Profile.exists_for(user)


def _user_get_full_name(user):
"""
Override regular get_full_name which returns first_name + last_name
"""
return user.profile.full_name if user.has_profile() else " ".join([user.first_name, user.last_name]).strip()


def _user_get_partner(user, org):
"""
Gets the partner org for this user in the given org
"""
return user.partners.filter(org=org, is_active=True).first()


def _user_get_role(user, org):
"""
Gets the role as a character code for this user in the given org
"""
from .models import ROLE_ADMIN, ROLE_MANAGER, ROLE_ANALYST

if user in org.administrators.all():
return ROLE_ADMIN
elif user in org.editors.all():
return ROLE_MANAGER
elif user in org.viewers.all():
return ROLE_ANALYST
else:
return None


def _user_update_role(user, org, role, partner=None):
"""
Updates this user's role in the given org
"""
from .models import ROLE_ADMIN, ROLE_MANAGER, ROLE_ANALYST, PARTNER_ROLES

if partner and partner.org != org: # pragma: no cover
raise ValueError("Can only update partner to partner in same org")

if role in PARTNER_ROLES and not partner:
raise ValueError("Role %s requires a partner org" % role)
elif role not in PARTNER_ROLES and partner:
raise ValueError("Cannot specify a partner for role %s" % role)

remove_from = [p for p in user.partners_primary.filter(org=org) if p != partner]
user.partners_primary.remove(*remove_from)

user.partners.remove(*user.partners.filter(org=org))

if partner:
user.partners.add(partner)

if role == ROLE_ADMIN:
org.administrators.add(user)
org.editors.remove(user)
org.viewers.remove(user)
elif role == ROLE_MANAGER:
org.administrators.remove(user)
org.editors.add(user)
org.viewers.remove(user)
elif role == ROLE_ANALYST:
org.administrators.remove(user)
org.editors.remove(user)
org.viewers.add(user)
else: # pragma: no cover
raise ValueError("Invalid user role: %s" % role)


def _user_remove_from_org(user, org):
# remove user from all org groups
org.administrators.remove(user)
org.editors.remove(user)
org.viewers.remove(user)

# remove primary_contact fk relationship
user.partners_primary.remove(*user.partners_primary.filter(org=org))

# remove user from any partners for this org
user.partners.remove(*user.partners.filter(org=org))

# remove as watcher of any case in this org
for case in user.watched_cases.filter(org=org):
case.unwatch(user)

# remove as watcher of any label in this org
for label in user.watched_labels.filter(org=org):
label.unwatch(user)


def _user_can_administer(user, org):
"""
Whether this user can administer the given org
"""
return user.is_superuser or org.administrators.filter(pk=user.pk).exists()


def _user_can_manage(user, partner):
"""
Whether this user can manage the given partner org
"""
org = partner.org

if user.can_administer(org):
return True

return user.get_partner(org) == partner and org.editors.filter(pk=user.pk).exists()


def _user_can_edit(user, org, other):
"""
Whether or not this user can edit the other user
"""
if user.is_superuser:
return True

other_group = org.get_user_org_group(other)
if not other_group: # other user doesn't belong to this org
return False

if user.can_administer(org):
return True

other_partner = other.get_partner(org)
return other_partner and user.can_manage(other_partner) # manager can edit users in same partner org


def _user_unicode(user):
if user.has_profile():
if user.profile.full_name:
return '%s (%s)' % (user.profile.full_name, user.email)
else:
return user.username # superuser

return user.email or user.username


def _user_as_json(user, full=True, org=None):
if full:
if org and user.has_profile():
partner = user.get_partner(org)
partner_json = partner.as_json(full=False) if partner else None
role_json = user.get_role(org)
else:
role_json = None
partner_json = None

return {
'id': user.pk,
'name': user.get_full_name(),
'email': user.email,
'role': role_json,
'partner': partner_json
}
else:
return {'id': user.pk, 'name': user.get_full_name()}


User.clean = _user_clean
User.has_profile = _user_has_profile
User.get_full_name = _user_get_full_name
User.get_partner = _user_get_partner
User.get_role = _user_get_role
User.update_role = _user_update_role
User.can_administer = _user_can_administer
User.can_manage = _user_can_manage
User.can_edit = _user_can_edit
User.remove_from_org = _user_remove_from_org
User.__unicode__ = _user_unicode
User.as_json = _user_as_json
from __future__ import unicode_literals

0 comments on commit 8e29057

Please sign in to comment.