From 5b06147ac6515adf8c482eec417ba049f1321bf0 Mon Sep 17 00:00:00 2001 From: Tony Mack Date: Tue, 4 Feb 2014 07:57:10 -0500 Subject: [PATCH] added rbac for viewing objects --- planetstack/core/admin.py | 184 ++++++++---------------- planetstack/core/models/deployment.py | 24 ++++ planetstack/core/models/network.py | 48 +++++++ planetstack/core/models/plcorebase.py | 11 ++ planetstack/core/models/reservation.py | 30 ++++ planetstack/core/models/serviceclass.py | 4 +- planetstack/core/models/site.py | 70 +++++++++ planetstack/core/models/slice.py | 47 ++++++ planetstack/core/models/slicetag.py | 13 ++ planetstack/core/models/sliver.py | 16 +++ planetstack/core/models/tag.py | 13 ++ planetstack/core/models/user.py | 21 ++- 12 files changed, 356 insertions(+), 125 deletions(-) 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 @@ class ReservationInline(PlStackTabularInline): 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 @@ class TagInline(generic.GenericTabularInline): 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 @@ class SliverInline(PlStackTabularInline): 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 @@ class SiteInline(PlStackTabularInline): 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 @@ class UserInline(PlStackTabularInline): 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 @@ class SliceInline(PlStackTabularInline): 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 @@ class NodeInline(PlStackTabularInline): model = Node extra = 0 suit_classes = 'suit-tab suit-tab-nodes' + fields = ['name','deployment'] class DeploymentPrivilegeROInline(ReadOnlyTabularInline): model = DeploymentPrivilege @@ -296,6 +316,10 @@ class DeploymentPrivilegeInline(PlStackTabularInline): 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 @@ class SitePrivilegeInline(PlStackTabularInline): 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 @@ class SlicePrivilegeInline(PlStackTabularInline): 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 @@ class SiteAdmin(PlanetStackBaseAdmin): 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 @@ class SitePrivilegeAdmin(PlanetStackBaseAdmin): # 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 @@ class SliceAdmin(PlanetStackBaseAdmin): 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 @@ class SliceAdmin(PlanetStackBaseAdmin): 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 @@ class SlicePrivilegeAdmin(PlanetStackBaseAdmin): 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 @@ class SliverAdmin(PlanetStackBaseAdmin): 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 @@ class SliverAdmin(PlanetStackBaseAdmin): # 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 @@ class UserAdmin(UserAdmin): 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 @@ class UserAdmin(UserAdmin): #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 @@ class ReservedResourceInline(PlStackTabularInline): 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 @@ class ReservationAdmin(PlanetStackBaseAdmin): 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 @@ class DeploymentPrivilege(PlCoreBase): 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 @@ class Network(PlCoreBase): 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 @@ class NetworkSlice(PlCoreBase): 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 @@ class NetworkSliver(PlCoreBase): 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 @@ class PlCoreBase(models.Model): 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 @@ class PlCoreBase(models.Model): 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 @@ class Reservation(PlCoreBase): 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 @@ class ReservedResource(PlCoreBase): 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 @@ class ServiceClass(PlCoreBase): 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 @@ class Site(PlCoreBase): 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 @@ class SitePrivilege(PlCoreBase): 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 @@ class DeploymentPrivilege(PlCoreBase): 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 @@ class Slice(PlCoreBase): 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 @@ class SlicePrivilege(PlCoreBase): 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 @@ class SliceTag(PlCoreBase): 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 @@ class Sliver(PlCoreBase): 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 @@ class Tag(PlCoreBase): 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 os 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 @@ class User(AbstractBaseUser): 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 + + + -- 2.43.0