added rbac for viewing objects
diff --git a/planetstack/core/admin.py b/planetstack/core/admin.py
index 5281bb1..2dbf2c4 100644
--- a/planetstack/core/admin.py
+++ b/planetstack/core/admin.py
@@ -156,6 +156,9 @@
     model = Reservation
     extra = 0
     suit_classes = 'suit-tab suit-tab-reservations'
+        
+    def queryset(self, request):
+        return Reservation.select_by_user(request.user)
 
 class TagROInline(generic.GenericTabularInline):
     model = Tag
@@ -175,6 +178,10 @@
     model = Tag
     extra = 0
     suit_classes = 'suit-tab suit-tab-tags'
+    fields = ['service', 'name', 'value']
+
+    def queryset(self, request):
+        return Tag.select_by_user(request.user)
 
 class NetworkLookerUpper:
     """ This is a callable that looks up a network name in a sliver and returns
@@ -208,6 +215,9 @@
     readonly_fields = ['ip', 'instance_name']
     suit_classes = 'suit-tab suit-tab-slivers'
 
+    def queryset(self, request):
+        return Sliver.select_by_user(request.user)
+
 # Note this is breaking in the admin.py when trying to use an inline to add a node/image 
 #    def _declared_fieldsets(self):
 #        # Return None so django will call get_fieldsets and we can insert our
@@ -252,6 +262,9 @@
     extra = 0
     suit_classes = 'suit-tab suit-tab-sites'
 
+    def queryset(self, request):
+        return Site.select_by_user(request.user)
+
 class UserROInline(ReadOnlyTabularInline):
     model = User
     fields = ['email', 'firstname', 'lastname']
@@ -264,6 +277,9 @@
     extra = 0
     suit_classes = 'suit-tab suit-tab-users'
 
+    def queryset(self, request):
+        return User.select_by_user(request.user)
+
 class SliceROInline(ReadOnlyTabularInline):
     model = Slice
     suit_classes = 'suit-tab suit-tab-slices'
@@ -275,6 +291,9 @@
     extra = 0
     suit_classes = 'suit-tab suit-tab-slices'
 
+    def queryset(self, request):
+        return Slice.select_by_user(request.user)
+
 class NodeROInline(ReadOnlyTabularInline):
     model = Node
     extra = 0
@@ -285,6 +304,7 @@
     model = Node
     extra = 0
     suit_classes = 'suit-tab suit-tab-nodes'
+    fields = ['name','deployment']
 
 class DeploymentPrivilegeROInline(ReadOnlyTabularInline):
     model = DeploymentPrivilege
@@ -296,6 +316,10 @@
     model = DeploymentPrivilege
     extra = 0
     suit_classes = 'suit-tab suit-tab-deploymentprivileges'
+    fields = ['user','role']
+
+    def queryset(self, request):
+        return DeploymentPrivilege.select_by_user(request.user)
 
 #CLEANUP DOUBLE SitePrivilegeInline
 class SitePrivilegeROInline(ReadOnlyTabularInline):
@@ -308,34 +332,18 @@
     model = SitePrivilege
     extra = 0
     suit_classes = 'suit-tab suit-tab-siteprivileges'
+    fields = ['user','site', 'role']
 
     def formfield_for_foreignkey(self, db_field, request, **kwargs):
         if db_field.name == 'site':
-            if not request.user.is_admin:
-                # only show sites where user is an admin or pi
-                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-                login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
-                sites = Site.objects.filter(login_base__in=login_bases)
-                kwargs['queryset'] = sites
+            kwargs['queryset'] = Site.select_by_user(request.user)
 
         if db_field.name == 'user':
-            if not request.user.is_admin:
-                # only show users from sites where caller has admin or pi role
-                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-                sites = [site_privilege.site for site_privilege in site_privileges]
-                site_privileges = SitePrivilege.objects.filter(site__in=sites)
-                emails = [site_privilege.user.email for site_privilege in site_privileges]
-                users = User.objects.filter(email__in=emails)
-                kwargs['queryset'] = users
+            kwargs['queryset'] = User.select_by_user(request.user)
         return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
-class SitePrivilegeInline(PlStackTabularInline):
-    model = SitePrivilege
-    suit_classes = 'suit-tab suit-tab-siteprivileges'
-    extra = 0
-    fields = ('user', 'site','role')
+    def queryset(self, request):
+        return SitePrivilege.select_by_user(request.user)
 
 class SlicePrivilegeROInline(ReadOnlyTabularInline):
     model = SlicePrivilege
@@ -351,26 +359,15 @@
 
     def formfield_for_foreignkey(self, db_field, request, **kwargs):
         if db_field.name == 'slice':
-            if not request.user.is_admin:
-                # only show slices at sites where caller has admin or pi role
-                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-                sites = [site_privilege.site for site_privilege in site_privileges]
-                slices = Slice.objects.filter(site__in=sites)
-                kwargs['queryset'] = slices 
+           kwargs['queryset'] = Slice.select_by_user(request.user) 
         if db_field.name == 'user':
-            if not request.user.is_admin:
-                # only show users from sites where caller has admin or pi role
-                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-                sites = [site_privilege.site for site_privilege in site_privileges]
-                site_privileges = SitePrivilege.objects.filter(site__in=sites)
-                emails = [site_privilege.user.email for site_privilege in site_privileges]   
-                users = User.objects.filter(email__in=emails) 
-                kwargs['queryset'] = list(users)
+           kwargs['queryset'] = User.select_by_user(request.user) 
 
         return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
+    def queryset(self, request):
+        return SlicePrivilege.select_by_user(request.user)
+
 class SliceNetworkROInline(ReadOnlyTabularInline):
     model = Network.slices.through
     extra = 0
@@ -503,15 +500,8 @@
     search_fields = ['name']
 
     def queryset(self, request):
-        # admins can see all keys. Users can only see sites they belong to.
-        qs = super(SiteAdmin, self).queryset(request)
-        if not request.user.is_admin:
-            valid_sites = [request.user.site.login_base]
-            roles = request.user.get_roles()
-            for tenant_list in roles.values():
-                valid_sites.extend(tenant_list)
-            qs = qs.filter(login_base__in=valid_sites)
-        return qs
+        #print dir(UserInline)
+        return Site.select_by_user(request.user)
 
     def get_formsets(self, request, obj=None):
         for inline in self.get_inline_instances(request, obj):
@@ -579,12 +569,12 @@
         # admins can see all privileges. Users can only see privileges at sites
         # where they have the admin role or pi role.
         qs = super(SitePrivilegeAdmin, self).queryset(request)
-        if not request.user.is_admin:
-            roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-            site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-            login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
-            sites = Site.objects.filter(login_base__in=login_bases)
-            qs = qs.filter(site__in=sites)
+        #if not request.user.is_admin:
+        #    roles = Role.objects.filter(role_type__in=['admin', 'pi'])
+        #    site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
+        #    login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
+        #    sites = Site.objects.filter(login_base__in=login_bases)
+        #    qs = qs.filter(site__in=sites)
         return qs
 
 class SliceForm(forms.ModelForm):
@@ -614,26 +604,13 @@
 
     def formfield_for_foreignkey(self, db_field, request, **kwargs):
         if db_field.name == 'site':
-            if not request.user.is_admin:
-                # only show sites where user is a pi or admin 
-                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-                login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
-                sites = Site.objects.filter(login_base__in=login_bases)
-                kwargs['queryset'] = sites
-
+            kwargs['queryset'] = Site.select_by_user(request.user)
+                
         return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
     def queryset(self, request):
         # admins can see all keys. Users can only see slices they belong to.
-        qs = super(SliceAdmin, self).queryset(request)
-        if not request.user.is_admin:
-            valid_slices = []
-            roles = request.user.get_roles()
-            for tenant_list in roles.values():
-                valid_slices.extend(tenant_list)
-            qs = qs.filter(name__in=valid_slices)
-        return qs
+        return Slice.select_by_user(request.user)
 
     def get_formsets(self, request, obj=None):
         for inline in self.get_inline_instances(request, obj):
@@ -644,12 +621,6 @@
                 inline.model.caller = request.user
             yield inline.get_formset(request, obj)
 
-    def get_queryset(self, request):
-        qs = super(SliceAdmin, self).get_queryset(request)
-        if request.user.is_superuser:
-            return qs
-        # users can only see slices at their site
-        return qs.filter(site=request.user.site)
 
 class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
     fieldsets = [
@@ -662,39 +633,17 @@
 
     def formfield_for_foreignkey(self, db_field, request, **kwargs):
         if db_field.name == 'slice':
-            if not request.user.is_admin:
-                # only show slices at sites where caller has admin or pi role
-                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-                sites = [site_privilege.site for site_privilege in site_privileges]
-                slices = Slice.objects.filter(site__in=sites)
-                kwargs['queryset'] = slices
+            kwargs['queryset'] = Slice.select_by_user(request.user)
         
         if db_field.name == 'user':
-            if not request.user.is_admin:
-                # only show users from sites where caller has admin or pi role
-                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-                sites = [site_privilege.site for site_privilege in site_privileges]
-                site_privileges = SitePrivilege.objects.filter(site__in=sites)
-                emails = [site_privilege.user.email for site_privilege in site_privileges]
-                users = User.objects.filter(email__in=emails)
-                kwargs['queryset'] = users
+            kwargs['queryset'] = User.select_by_user(request.user)
 
         return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
     def queryset(self, request):
         # admins can see all memberships. Users can only see memberships of
         # slices where they have the admin role.
-        qs = super(SlicePrivilegeAdmin, self).queryset(request)
-        if not request.user.is_admin:
-            roles = Role.objects.filter(role_type__in=['admin', 'pi'])
-            site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
-            login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
-            sites = Site.objects.filter(login_base__in=login_bases)
-            slices = Slice.objects.filter(site__in=sites)
-            qs = qs.filter(slice__in=slices)
-        return qs
+        return SlicePrivilege.select_by_user(request.user)
 
     def save_model(self, request, obj, form, change):
         # update openstack connection to use this site/tenant
@@ -783,24 +732,15 @@
 
     def formfield_for_foreignkey(self, db_field, request, **kwargs):
         if db_field.name == 'slice':
-            if not request.user.is_admin:
-                slices = set([sm.slice.name for sm in SlicePrivilege.objects.filter(user=request.user)]) 
-                kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
+            kwargs['queryset'] = Slice.select_by_user(request.user)
 
         return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
     def queryset(self, request):
         # admins can see all slivers. Users can only see slivers of 
         # the slices they belong to.
-        qs = super(SliverAdmin, self).queryset(request)
-        if not request.user.is_admin:
-            tenants = []
-            roles = request.user.get_roles()
-            for tenant_list in roles.values():
-                tenants.extend(tenant_list)
-            valid_slices = Slice.objects.filter(name__in=tenants)
-            qs = qs.filter(slice__in=valid_slices)
-        return qs
+        return Sliver.select_by_user(request.user)
+
 
     def get_formsets(self, request, obj=None):
         # make some fields read only if we are updating an existing record
@@ -815,11 +755,6 @@
             # hide MyInline in the add view
             if obj is None:
                 continue
-            # give inline object access to driver and caller
-            auth = request.session.get('auth', {})
-            auth['tenant'] = obj.name       # meed to connect using slice's tenant
-            inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
-            yield inline.get_formset(request, obj)
 
     #def save_model(self, request, obj, form, change):
     #    # update openstack connection to use this site/tenant
@@ -922,13 +857,7 @@
 
     def formfield_for_foreignkey(self, db_field, request, **kwargs):
         if db_field.name == 'site':
-            if not request.user.is_admin:
-                # show sites where caller is an admin or pi 
-                sites = []
-                for site_privilege in SitePrivilege.objects.filer(user=request.user):
-                    if site_privilege.role.role_type in ['admin', 'pi']:
-                        sites.append(site_privilege.site.login_base)  
-                kwargs['queryset'] = Site.objects.filter(login_base__in(list(sites)))
+            kwargs['queryset'] = Site.select_by_user(request.user)
 
         return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
@@ -966,6 +895,9 @@
         #return "readonly" in groups
         return request.user.isReadOnlyUser()
 
+    def queryset(self, request):
+        return User.select_by_user(request.user)
+
 
 
 class ServiceResourceROInline(ReadOnlyTabularInline):
@@ -1015,6 +947,9 @@
 

         return field
 
+    def queryset(self, request):
+        return ReservedResource.select_by_user(request.user)
+
 class ReservationChangeForm(forms.ModelForm):
     class Meta:
         model = Reservation
@@ -1124,6 +1059,9 @@
         else:
             return []
 
+    def queryset(self, request):
+        return Reservation.select_by_user(request.user)
+
 class NetworkParameterTypeAdmin(PlanetStackBaseAdmin):
     list_display = ("name", )
     user_readonly_fields = ['name']
diff --git a/planetstack/core/models/deployment.py b/planetstack/core/models/deployment.py
index 1e5e6dc..ea77dea 100644
--- a/planetstack/core/models/deployment.py
+++ b/planetstack/core/models/deployment.py
@@ -32,3 +32,27 @@
 
     def __unicode__(self):  return u'%s %s %s' % (self.deployment, self.user, self.role)
 
+
+    def can_update(self, user):
+        if user.is_readonly:
+            return False
+        if user.is_admin:
+            return True
+        dprivs = DeploymentPrivilege.objects.filter(user=user)
+        for dpriv in dprivs:
+            if dpriv.role.role_type == 'admin':
+                return True
+        return False
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(DeploymentPrivilege, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = DeploymentPrivilege.objects.all()
+        else:
+            dpriv_ids = [dp.id for dp in DeploymentPrivilege.objects.filter(user=user)]
+            qs = DeploymentPrivilege.objects.filter(id__in=dpriv_ids)
+        return qs
diff --git a/planetstack/core/models/network.py b/planetstack/core/models/network.py
index 72e7a5f..7b9364c 100644
--- a/planetstack/core/models/network.py
+++ b/planetstack/core/models/network.py
@@ -50,6 +50,22 @@
             self.subnet = find_unused_subnet(existing_subnets=[x.subnet for x in Network.objects.all()])
         super(Network, self).save(*args, **kwds)
 
+    def can_update(self, user):
+        return self.slice.can_update(user)
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.slice.can_update(user):
+            super(Network, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = Network.objects.all()
+        else:
+            slice_ids = [s.id for s in Slice.select_by_user(user)]
+            qs = Network.objects.filter(id__in=slice_ids)
+        return qs
+
 class NetworkSlice(PlCoreBase):
     # This object exists solely so we can implement the permission check when
     # adding slices to networks. It adds no additional fields to the relation.
@@ -70,6 +86,22 @@
 
     def __unicode__(self):  return u'%s-%s' % (self.network.name, self.slice.name)
 
+    def can_update(self, user):
+        return self.slice.can_update(user)
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.slice.can_update(user):
+            super(NetworkSlice, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = NetworkSlice.objects.all()
+        else:
+            slice_ids = [s.id for s in Slice.select_by_user(user)]
+            qs = NetworkSlice.objects.filter(id__in=slice_ids)
+        return qs
+
 class NetworkSliver(PlCoreBase):
     network = models.ForeignKey(Network)
     sliver = models.ForeignKey(Sliver)
@@ -93,6 +125,22 @@
 
     def __unicode__(self):  return u'%s-%s' % (self.network.name, self.sliver.instance_name)
 
+    def can_update(self, user):
+        return self.sliver.can_update(user)
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.sliver.can_update(user):
+            super(NetworkSliver, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = NetworkSliver.objects.all()
+        else:
+            sliver_ids = [s.id for s in NetworkSliver.select_by_user(user)]
+            qs = NetworkSliver.objects.filter(id__in=sliver_ids)
+        return qs
+
 class Router(PlCoreBase):
     name = models.CharField(max_length=32)
     owner = models.ForeignKey(Slice, related_name="routers")
diff --git a/planetstack/core/models/plcorebase.py b/planetstack/core/models/plcorebase.py
index 590e240..9838d7f 100644
--- a/planetstack/core/models/plcorebase.py
+++ b/planetstack/core/models/plcorebase.py
@@ -38,6 +38,13 @@
     def get_field_diff(self, field_name):
         return self.diff.get(field_name, None)
 
+    def can_update(self, user):
+        if user.is_readonly:
+            return False
+        if user.is_admin:
+            return True
+        return False
+
     def delete(self, *args, **kwds):
         # so we have something to give the observer
         pk = self.pk
@@ -59,6 +66,10 @@
 
         self.__initial = self._dict
 
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            self.save(*args, **kwds)
+
     @property
     def _dict(self):
         return model_to_dict(self, fields=[field.name for field in
diff --git a/planetstack/core/models/reservation.py b/planetstack/core/models/reservation.py
index e445228..e89b4c8 100644
--- a/planetstack/core/models/reservation.py
+++ b/planetstack/core/models/reservation.py
@@ -19,6 +19,22 @@
     def endTime(self):
         return self.startTime + datetime.timedelta(hours=self.duration)
 
+    def can_update(self, user):
+        return self.slice.can_update(user)
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(Reservation, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = Reservation.objects.all()
+        else:
+            slice_ids = [s.id for s in Slice.select_by_user(user)]
+            qs = Reservation.objects.filter(id__in=slice_ids)
+        return qs
+
 class ReservedResource(PlCoreBase):
     sliver = models.ForeignKey(Sliver, related_name="reservedResourrces")
     resource = models.ForeignKey(ServiceResource, related_name="reservedResources")
@@ -30,6 +46,20 @@
 
     def __unicode__(self):  return u'%d %s on %s' % (self.quantity, self.resource, self.sliver)
 
+    def can_update(self, user):
+        return self.sliver.slice.can_update(user)
 
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(ReservedResource, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = ReservedResource.objects.all()
+        else:
+            sliver_ids = [s.id for s in Sliver.select_by_user(user)]
+            qs = ReservedResource.objects.filter(id__in=sliver_ids)
+        return qs
 
 
diff --git a/planetstack/core/models/serviceclass.py b/planetstack/core/models/serviceclass.py
index ce3eaee..3b6ee82 100644
--- a/planetstack/core/models/serviceclass.py
+++ b/planetstack/core/models/serviceclass.py
@@ -27,4 +27,6 @@
         except ServiceClass.DoesNotExist:
             return None
 
-
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(ServiceClass, self).save(*args, **kwds)
diff --git a/planetstack/core/models/site.py b/planetstack/core/models/site.py
index 65d965b..8e77404 100644
--- a/planetstack/core/models/site.py
+++ b/planetstack/core/models/site.py
@@ -27,6 +27,30 @@
 
     def __unicode__(self):  return u'%s' % (self.name)
 
+    def can_update(self, user):
+        if user.is_admin:
+            return True
+        site_privs = SitePrivilege.objects.filter(user=user, site=self)
+        for site_priv in site_privs:
+            if site_priv.role.role_type == 'pi':
+                return True
+        return False 
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(Site, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = Site.objects.all()
+        else:
+            site_ids = [sp.site.id for sp in SitePrivilege.objects.filter(user=user)]
+            site_ids.append(user.site.id)
+            qs = Site.objects.filter(id__in=site_ids)
+        return qs
+
+
 class SiteRole(PlCoreBase):
 
     ROLE_CHOICES = (('admin','Admin'),('pi','PI'),('tech','Tech'),('billing','Billing'))
@@ -48,6 +72,28 @@
     def delete(self, *args, **kwds):
         super(SitePrivilege, self).delete(*args, **kwds)
 
+    def can_update(self, user):
+        if user.is_admin:
+            return True
+        site_privs = SitePrivilege.objects.filter(user=user, site=self)
+        for site_priv in site_privs:
+            if site_priv.role.role_type == 'pi':
+                return True
+        return False 
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(SitePrivilege, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = SitePrivilege.objects.all()
+        else:
+            sp_ids = [sp.id for sp in SitePrivilege.objects.filter(user=user)]
+            qs = SitePrivilege.objects.filter(id__in=sp_ids)
+        return qs
+
 class Deployment(PlCoreBase):
     name = models.CharField(max_length=200, unique=True, help_text="Name of the Deployment")
     #sites = models.ManyToManyField('Site', through='SiteDeployments', blank=True)
@@ -70,6 +116,30 @@
 
     def __unicode__(self):  return u'%s %s %s' % (self.deployment, self.user, self.role)
 
+    def can_update(self, user):
+        if user.is_readonly:
+            return False
+        if user.is_admin:
+            return True
+        dprivs = DeploymentPrivilege.objects.filter(user=user)
+        for dpriv in dprivs:
+            if dpriv.role.role_type == 'admin':
+                return True
+        return False
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(DeploymentPrivilege, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = DeploymentPrivilege.objects.all()
+        else:
+            dpriv_ids = [dp.id for dp in DeploymentPrivilege.objects.filter(user=user)]
+            qs = DeploymentPrivilege.objects.filter(id__in=dpriv_ids)
+        return qs 
+
 class SiteDeployments(PlCoreBase):
     site = models.ForeignKey(Site)
     deployment = models.ForeignKey(Deployment)
diff --git a/planetstack/core/models/slice.py b/planetstack/core/models/slice.py
index 1fa342a..533165f 100644
--- a/planetstack/core/models/slice.py
+++ b/planetstack/core/models/slice.py
@@ -42,6 +42,31 @@
             self.creator = self.caller
         super(Slice, self).save(*args, **kwds)
 
+    def can_update(self, user):
+        if user.is_readonly:
+            return False
+        if user.is_admin:
+            return True
+        slice_privs = SlicePrivilege.objects.filter(user=user, slice=self)
+        for slice_priv in slice_privs:
+            if slice_priv.role.role_type == 'admin':
+                return True
+        return False
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(Slice, self).save(*args, **kwds)
+
+    
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = Slice.objects.all()
+        else:
+            slice_ids = [sp.slice.id for sp in SlicePrivilege.objects.filter(user=user)]
+            qs = Slice.objects.filter(id__in=slice_ids)
+        return qs
+
 class SliceRole(PlCoreBase):
     ROLE_CHOICES = (('admin','Admin'),('default','Default'))
 
@@ -55,3 +80,25 @@
     role = models.ForeignKey('SliceRole')
 
     def __unicode__(self):  return u'%s %s %s' % (self.slice, self.user, self.role)
+
+    def can_update(self, user):
+        if user.is_admin:
+            return True
+        slice_privs = SlicePrivilege.objects.filter(user=user, slice=self)
+        for slice_priv in slice_privs:
+            if slice_priv.role.role_type == 'admin':
+                return True
+        return False
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(SlicePrivilege, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = SlicePrivilege.objects.all()
+        else:
+            sp_ids = [sp.id for sp in SlicePrivilege.objects.filter(user=user)]
+            qs = SlicePrivilege.objects.filter(id__in=sp_ids)
+        return qs
diff --git a/planetstack/core/models/slicetag.py b/planetstack/core/models/slicetag.py
index 76cc669..e815721 100644
--- a/planetstack/core/models/slicetag.py
+++ b/planetstack/core/models/slicetag.py
@@ -10,5 +10,18 @@
     name = models.CharField(help_text="The name of this tag", max_length=30, choices=NAME_CHOICES)
     value = models.CharField(help_text="The value of this tag", max_length=1024)
 
+    def can_update(self, user):
+        return self.slice.can_update(user)
 
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(SliceTag, self).save(*args, **kwds)
 
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = SliceTag.objects.all()
+        else:
+            st_ids = [st.id for st in SliceTag.objects.filter(user=user)]
+            qs = SliceTag.objects.filter(id__in=st_ids)
+        return qs
diff --git a/planetstack/core/models/sliver.py b/planetstack/core/models/sliver.py
index 9c00cee..1c4a134 100644
--- a/planetstack/core/models/sliver.py
+++ b/planetstack/core/models/sliver.py
@@ -43,3 +43,19 @@
         if not self.creator and hasattr(self, 'caller'):
             self.creator = self.caller
         super(Sliver, self).save(*args, **kwds)
+
+    def can_update(self, user):
+        return self.slice.can_update(user)
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.slice.can_update(user):
+            super(Sliver, self).save(*args, **kwds)  
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = Sliver.objects.all()
+        else:
+            slice_ids = [s.id for s in Slice.select_by_user(user)]
+            qs = Sliver.objects.filter(id__in=slice_ids)
+        return qs
diff --git a/planetstack/core/models/tag.py b/planetstack/core/models/tag.py
index cbe63a5..ef746da 100644
--- a/planetstack/core/models/tag.py
+++ b/planetstack/core/models/tag.py
@@ -22,3 +22,16 @@
     def __unicode__(self):
         return self.name
 
+
+    def can_update(self, user):
+        if user.is_admin:
+            return True
+        return False
+
+    def save_by_user(self, user, *args, **kwds):
+        if self.can_update(user):
+            super(Tag, self).save(*args, **kwds)
+
+    @staticmethod
+    def select_by_user(user):
+        return Tag.objects.all()
diff --git a/planetstack/core/models/user.py b/planetstack/core/models/user.py
index a3b82d8..1afb5fc 100644
--- a/planetstack/core/models/user.py
+++ b/planetstack/core/models/user.py
@@ -2,6 +2,7 @@
 import datetime
 from collections import defaultdict
 from django.db import models
+from django.db.models import F, Q
 from core.models import PlCoreBase,Site
 from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
 from timezones.fields import TimeZoneField
@@ -130,4 +131,22 @@
         if not self.id:
             self.set_password(self.password)    
         self.username = self.email
-        super(User, self).save(*args, **kwds)   
+        super(User, self).save(*args, **kwds)  
+
+    @staticmethod
+    def select_by_user(user):
+        if user.is_admin:
+            qs = User.objects.all()
+        else:
+            # can see all users at any site where this user has pi role
+            from core.models.site import SitePrivilege
+            site_privs = SitePrivilege.objects.filter(user=user)
+            sites = [sp.site for sp in site_privs if sp.role.role == 'pi']
+            # get site privs of users at these sites
+            site_privs = SitePrivilege.objects.filter(site__in=sites)
+            user_ids = [sp.user.id for sp in site_privs] + [user.id] 
+            qs = User.objects.filter(Q(site__in=sites) | Q(id__in=user_ids))
+        return qs            
+
+             
+