from collections import defaultdict
from django.db import models
from django.db.models import F, Q
-from core.models import PlCoreBase,Site, DashboardView
+from core.models import PlCoreBase,Site, DashboardView, DiffModelMixIn
from core.models.site import Deployment
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from timezones.fields import TimeZoneField
from django.core.mail import EmailMultiAlternatives
from core.middleware import get_request
import model_policy
+from django.core.exceptions import PermissionDenied
+
+# ------ from plcorebase.py ------
+try:
+ # This is a no-op if observer_disabled is set to 1 in the config file
+ from observer import *
+except:
+ print >> sys.stderr, "import of observer failed! printing traceback and disabling observer:"
+ import traceback
+ traceback.print_exc()
+
+ # guard against something failing
+ def notify_observer(*args, **kwargs):
+ pass
+# ------ ------
# Create your models here.
class UserManager(BaseUserManager):
return user
class DeletedUserManager(UserManager):
- def get_query_set(self):
+ def get_queryset(self):
return super(UserManager, self).get_query_set().filter(deleted=True)
-class User(AbstractBaseUser):
+ # deprecated in django 1.7 in favor of get_queryset()
+ def get_query_set(self):
+ return self.get_queryset()
+
+class User(AbstractBaseUser, DiffModelMixIn):
class Meta:
app_label = "core"
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['firstname', 'lastname']
+ PI_FORBIDDEN_FIELDS = ["is_admin", "site", "is_staff"]
+ USER_FORBIDDEN_FIELDS = ["is_admin", "is_active", "site", "is_staff", "is_readonly"]
+
+ def __init__(self, *args, **kwargs):
+ super(User, self).__init__(*args, **kwargs)
+ self._initial = self._dict # for DiffModelMixIn
+
def isReadOnlyUser(self):
return self.is_readonly
def delete(self, *args, **kwds):
# so we have something to give the observer
purge = kwds.get('purge',False)
+ if purge:
+ del kwds['purge']
try:
purge = purge or observer_disabled
except NameError:
self.username = self.email
super(User, self).save(*args, **kwds)
+ self._initial = self._dict
+
def send_temporary_password(self):
password = User.objects.make_random_password()
self.set_password(password)\r
msg.attach_alternative(html_content, "text/html")\r
msg.send()
+ def can_update(self, user):
+ from core.models import SitePrivilege
+ _cant_update_fieldName = None
+ if user.is_readonly:
+ return False
+ if user.is_admin:
+ return True
+ # site pis can update
+ site_privs = SitePrivilege.objects.filter(user=user, site=self.site)
+ for site_priv in site_privs:
+ if site_priv.role.role == 'pi':
+ for fieldName in self.diff.keys():
+ if fieldName in self.PI_FORBIDDEN_FIELDS:
+ _cant_update_fieldName = fieldName
+ return False
+ return True
+ if (user.id == self.id):
+ for fieldName in self.diff.keys():
+ if fieldName in self.USER_FORBIDDEN_FIELDS:
+ _cant_update_fieldName = fieldName
+ return False
+ return True
+
+ return False
+
@staticmethod
def select_by_user(user):
if user.is_admin:
qs = User.objects.filter(Q(site__in=sites) | Q(id__in=user_ids))
return qs
+ def save_by_user(self, user, *args, **kwds):
+ if not self.can_update(user):
+ if getattr(self, "_cant_update_fieldName", None) is not None:
+ raise PermissionDenied("You do not have permission to update field %s on object %s" % (self._cant_update_fieldName, self.__class__.__name__))
+ else:
+ raise PermissionDenied("You do not have permission to update %s objects" % self.__class__.__name__)
+
+ self.save(*args, **kwds)
+
+ def delete_by_user(self, user, *args, **kwds):
+ if not self.can_update(user):
+ raise PermissionDenied("You do not have permission to delete %s objects" % self.__class__.__name__)
+ self.delete(*args, **kwds)
+
class UserDashboardView(PlCoreBase):
user = models.ForeignKey(User, related_name="dashboardViews")
dashboardView = models.ForeignKey(DashboardView, related_name="dashboardViews")