def resources_with_possible_perms(cls, instance, resource_ids=None, resource_types=None, db_session=None): """ returns list of permissions and resources for this user :param instance: :param resource_ids: restricts the search to specific resources :param resource_types: restricts the search to specific resource types :param db_session: :return: """ perms = resource_permissions_for_users(cls.models_proxy, ANY_PERMISSION, resource_ids=resource_ids, resource_types=resource_types, user_ids=[instance.id], db_session=db_session) for resource in instance.resources: perms.append( PermissionTuple(instance, ALL_PERMISSIONS, 'user', None, resource, True, True)) for group in instance.groups_with_resources(): for resource in group.resources: perms.append( PermissionTuple(instance, ALL_PERMISSIONS, 'group', group, resource, True, True)) return perms
def test_resource_users_limited_group_ownage(self, db_session): self.maxDiff = 9999 self.set_up_user_group_and_perms(db_session) resource = TestResourceB(resource_id=99, resource_name='other', owner_user_id=self.user2.id) group3 = add_group(db_session, 'group 3') user2_permission = UserResourcePermission( perm_name='foo_perm', user_id=self.user2.id, ) group3_permission = GroupResourcePermission(perm_name='group_perm', group_id=group3.id) resource.group_permissions.append(group3_permission) resource.user_permissions.append(user2_permission) group3.users.append(self.user3) self.user.resources.append(resource) self.group2.resources.append(resource) db_session.flush() perms = resource.users_for_perm('__any_permission__', db_session=db_session) second = [ PermissionTuple(self.user2, 'foo_perm', 'user', None, resource, False, True), PermissionTuple(self.user, ALL_PERMISSIONS, 'user', None, resource, True, True), PermissionTuple(self.user4, ALL_PERMISSIONS, 'group', self.group2, resource, True, True), PermissionTuple(self.user3, 'group_perm', 'group', group3, resource, False, True) ] check_one_in_other(perms, second)
def test_resource_groups_for_any_perm_just_group_perms_limited_empty_group( self, db_session): self.maxDiff = 99999 self.set_up_user_group_and_perms(db_session) user6 = add_user(db_session, 6, "user 6") user7 = add_user(db_session, 7, "user 7") perm2 = GroupResourcePermission(perm_name="group_perm2", resource_id=self.resource.resource_id) self.group.resource_permissions.append(perm2) self.group.users.append(user6) self.group.users.append(user7) group3 = add_group(db_session, "Empty group") perm3 = GroupResourcePermission(perm_name="group_permx", resource_id=self.resource.resource_id) group3.resource_permissions.append(perm3) perms = ResourceService.groups_for_perm( self.resource, "__any_permission__", limit_group_permissions=True, db_session=db_session, ) second = [ PermissionTuple(None, "group_perm", "group", self.group, self.resource, False, True), PermissionTuple(None, "group_perm2", "group", self.group, self.resource, False, True), PermissionTuple(None, "group_perm", "group", self.group2, self.resource, False, True), PermissionTuple(None, "group_permx", "group", group3, self.resource, False, True), ] check_one_in_other(perms, second)
def test_resource_users_for_any_perm_limited_group_perms(self, db_session): self.maxDiff = 99999 self.set_up_user_group_and_perms(db_session) user6 = add_user(db_session, 6, 'user 6') user7 = add_user(db_session, 7, 'user 7') perm2 = GroupResourcePermission(perm_name='group_perm2', resource_id=self.resource.resource_id) self.group.resource_permissions.append(perm2) self.group.users.append(user6) self.group.users.append(user7) perms = self.resource.users_for_perm('__any_permission__', limit_group_permissions=True, db_session=db_session) second = [ PermissionTuple(None, 'group_perm', 'group', self.group, self.resource, False, True), PermissionTuple(None, 'group_perm2', 'group', self.group, self.resource, False, True), PermissionTuple(self.user, 'test_perm2', 'user', None, self.resource, False, True), PermissionTuple(self.user, 'foo_perm', 'user', None, self.resource, False, True), PermissionTuple(None, 'group_perm', 'group', self.group2, self.resource, False, True), ] check_one_in_other(perms, second)
def test_resources_with_possible_perms(self, db_session): self.set_up_user_group_and_perms(db_session) resource = ResourceTestobjB(resource_id=3, resource_name="other", owner_user_id=self.user.id) self.user.resources.append(resource) resource_g = ResourceTestobjB(resource_id=4, resource_name="group owned") self.group.resources.append(resource_g) db_session.flush() perms = UserService.resources_with_possible_perms( self.user, db_session=db_session) second = [ PermissionTuple(self.user, "foo_perm", "user", None, self.resource, False, True), PermissionTuple(self.user, "group_perm", "group", self.group, self.resource, False, True), PermissionTuple(self.user, "test_perm2", "user", None, self.resource, False, True), PermissionTuple(self.user, ALL_PERMISSIONS, "user", None, resource, True, True), PermissionTuple(self.user, ALL_PERMISSIONS, "group", self.group, resource_g, True, True), ] check_one_in_other(perms, second)
def test_resource_users_for_any_perm_excluding_group_perms( self, db_session): self.maxDiff = 99999 self.set_up_user_group_and_perms(db_session) user6 = add_user(db_session, 6, "user 6") user7 = add_user(db_session, 7, "user 7") perm2 = GroupResourcePermission(perm_name="group_perm2", resource_id=self.resource.resource_id) self.group.resource_permissions.append(perm2) self.group.users.append(user6) self.group.users.append(user7) perms = ResourceService.users_for_perm( self.resource, "__any_permission__", limit_group_permissions=True, skip_group_perms=True, db_session=db_session, ) second = [ PermissionTuple(self.user, "test_perm2", "user", None, self.resource, False, True), PermissionTuple(self.user, "foo_perm", "user", None, self.resource, False, True), ] check_one_in_other(perms, second)
def test_resource_users_limited_group_ownage(self, db_session): self.maxDiff = 9999 self.set_up_user_group_and_perms(db_session) resource = ResourceTestobjB(resource_id=99, resource_name="other", owner_user_id=self.user2.id) group3 = add_group(db_session, "group 3") user2_permission = UserResourcePermission(perm_name="foo_perm", user_id=self.user2.id) group3_permission = GroupResourcePermission(perm_name="group_perm", group_id=group3.id) resource.group_permissions.append(group3_permission) resource.user_permissions.append(user2_permission) group3.users.append(self.user3) self.user.resources.append(resource) self.group2.resources.append(resource) db_session.flush() perms = ResourceService.users_for_perm(resource, "__any_permission__", db_session=db_session) second = [ PermissionTuple(self.user2, "foo_perm", "user", None, resource, False, True), PermissionTuple(self.user, ALL_PERMISSIONS, "user", None, resource, True, True), PermissionTuple(self.user4, ALL_PERMISSIONS, "group", self.group2, resource, True, True), PermissionTuple(self.user3, "group_perm", "group", group3, resource, False, True), ] check_one_in_other(perms, second)
def test_resource_groups_for_any_perm_just_group_perms_limited_empty_group( self, db_session): self.maxDiff = 99999 self.set_up_user_group_and_perms(db_session) user6 = add_user(db_session, 6, 'user 6') user7 = add_user(db_session, 7, 'user 7') perm2 = GroupResourcePermission(perm_name='group_perm2', resource_id=self.resource.resource_id) self.group.resource_permissions.append(perm2) self.group.users.append(user6) self.group.users.append(user7) group3 = add_group(db_session, 'Empty group') perm3 = GroupResourcePermission(perm_name='group_permx', resource_id=self.resource.resource_id) group3.resource_permissions.append(perm3) perms = self.resource.groups_for_perm('__any_permission__', limit_group_permissions=True, db_session=db_session) second = [ PermissionTuple(None, 'group_perm', 'group', self.group, self.resource, False, True), PermissionTuple(None, 'group_perm2', 'group', self.group, self.resource, False, True), PermissionTuple(None, 'group_perm', 'group', self.group2, self.resource, False, True), PermissionTuple(None, 'group_permx', 'group', group3, self.resource, False, True) ] check_one_in_other(perms, second)
def direct_perms_for_user(cls, instance, user, db_session=None): """ returns permissions that given user has for this resource without ones inherited from groups that user belongs to :param instance: :param user: :param db_session: :return: """ db_session = get_db_session(db_session, instance) query = db_session.query( cls.models_proxy.UserResourcePermission.user_id, cls.models_proxy.UserResourcePermission.perm_name) query = query.filter( cls.models_proxy.UserResourcePermission.user_id == user.id) query = query.filter(cls.models_proxy.UserResourcePermission. resource_id == instance.resource_id) perms = [ PermissionTuple(user, row.perm_name, 'user', None, instance, False, True) for row in query ] # include all perms if user is the owner of this resource if instance.owner_user_id == user.id: perms.append( PermissionTuple(user, ALL_PERMISSIONS, 'user', None, instance, True)) return perms
def test_resource_users_for_any_perm(self, db_session): self.maxDiff = 99999 self.set_up_user_group_and_perms(db_session) perms = ResourceService.users_for_perm(self.resource, "__any_permission__", db_session=db_session) second = [ PermissionTuple(self.user, "group_perm", "group", self.group, self.resource, False, True), PermissionTuple(self.user, "test_perm2", "user", None, self.resource, False, True), PermissionTuple(self.user, "foo_perm", "user", None, self.resource, False, True), PermissionTuple( self.user4, "group_perm", "group", self.group2, self.resource, False, True, ), ] check_one_in_other(perms, second)
def users_for_perm( cls, instance, perm_name, user_ids=None, group_ids=None, limit_group_permissions=False, skip_group_perms=False, db_session=None, ): """ return PermissionTuples for users AND groups that have given permission for the resource, perm_name is __any_permission__ then users with any permission will be listed :param instance: :param perm_name: :param user_ids: limits the permissions to specific user ids :param group_ids: limits the permissions to specific group ids :param limit_group_permissions: should be used if we do not want to have user objects returned for group permissions, this might cause performance issues for big groups :param skip_group_perms: do not attach group permissions to the resultset :param db_session: :return: """ # noqa db_session = get_db_session(db_session, instance) users_perms = resource_permissions_for_users( cls.models_proxy, [perm_name], [instance.resource_id], user_ids=user_ids, group_ids=group_ids, limit_group_permissions=limit_group_permissions, skip_group_perms=skip_group_perms, db_session=db_session, ) if instance.owner_user_id: users_perms.append( PermissionTuple( instance.owner, ALL_PERMISSIONS, "user", None, instance, True, True ) ) if instance.owner_group_id and not skip_group_perms: for user in instance.owner_group.users: users_perms.append( PermissionTuple( user, ALL_PERMISSIONS, "group", instance.owner_group, instance, True, True, ) ) return users_perms
def test_user_permissions(self, db_session): created_user = add_user(db_session) permissions = created_user.permissions expected = [ PermissionTuple(created_user, 'alter_users', 'user', None, None, False, True), PermissionTuple(created_user, 'root', 'user', None, None, False, True) ] check_one_in_other(permissions, expected)
def resources_with_possible_perms( cls, instance, perm_names=None, resource_ids=None, resource_types=None, db_session=None, ): """ returns list of permissions and resources for this group, resource_ids restricts the search to specific resources :param instance: :param perm_names: :param resource_ids: :param resource_types: :param db_session: :return: """ db_session = get_db_session(db_session, instance) query = db_session.query( cls.models_proxy.GroupResourcePermission.perm_name, cls.models_proxy.Group, cls.models_proxy.Resource, ) query = query.filter(cls.models_proxy.Resource.resource_id == cls. models_proxy.GroupResourcePermission.resource_id) query = query.filter(cls.models_proxy.Group.id == cls.models_proxy.GroupResourcePermission.group_id) if resource_ids: query = query.filter( cls.models_proxy.GroupResourcePermission.resource_id.in_( resource_ids)) if resource_types: query = query.filter( cls.models_proxy.Resource.resource_type.in_(resource_types)) if perm_names not in ([ANY_PERMISSION], ANY_PERMISSION) and perm_names: query = query.filter( cls.models_proxy.GroupResourcePermission.perm_name.in_( perm_names)) query = query.filter( cls.models_proxy.GroupResourcePermission.group_id == instance.id) perms = [ PermissionTuple(None, row.perm_name, "group", instance, row.Resource, False, True) for row in query ] for resource in instance.resources: perms.append( PermissionTuple(None, ALL_PERMISSIONS, "group", instance, resource, True, True)) return perms
def test_user_permissions(self, db_session): created_user = add_user(db_session) permissions = UserService.permissions(created_user, db_session=db_session) expected = [ PermissionTuple(created_user, "alter_users", "user", None, None, False, True), PermissionTuple(created_user, "root", "user", None, None, False, True), ] check_one_in_other(permissions, expected)
def perms_for_user(cls, instance, user, db_session=None): """ returns all permissions that given user has for this resource from groups and directly set ones too :param instance: :param user: :param db_session: :return: """ db_session = get_db_session(db_session, instance) query = db_session.query( cls.models_proxy.GroupResourcePermission.group_id.label( 'owner_id'), cls.models_proxy.GroupResourcePermission.perm_name, sa.literal('group').label('type')) query = query.filter( cls.models_proxy.GroupResourcePermission.group_id.in_( [gr.id for gr in user.groups])) query = query.filter(cls.models_proxy.GroupResourcePermission. resource_id == instance.resource_id) query2 = db_session.query( cls.models_proxy.UserResourcePermission.user_id.label('owner_id'), cls.models_proxy.UserResourcePermission.perm_name, sa.literal('user').label('type')) query2 = query2.filter( cls.models_proxy.UserResourcePermission.user_id == user.id) query2 = query2.filter(cls.models_proxy.UserResourcePermission. resource_id == instance.resource_id) query = query.union(query2) groups_dict = dict([(g.id, g) for g in user.groups]) perms = [ PermissionTuple( user, row.perm_name, row.type, groups_dict.get(row.owner_id) if row.type == 'group' else None, instance, False, True) for row in query ] # include all perms if user is the owner of this resource if instance.owner_user_id == user.id: perms.append( PermissionTuple(user, ALL_PERMISSIONS, 'user', None, instance, True, True)) groups_dict = dict([(g.id, g) for g in user.groups]) if instance.owner_group_id in groups_dict: perms.append( PermissionTuple(user, ALL_PERMISSIONS, 'group', groups_dict.get(instance.owner_group_id), instance, True, True)) return perms
def test_resource_users_for_any_perm_resource_2(self, db_session): self.set_up_user_group_and_perms(db_session) perms = self.resource2.users_for_perm('__any_permission__', db_session=db_session) second = [ PermissionTuple(self.user2, 'foo_perm', 'user', None, self.resource2, False, True), PermissionTuple(self.user3, 'test_perm', 'user', None, self.resource2, False, True), ] check_one_in_other(perms, second)
def test_resources_with_direct_user_perms(self, db_session): self.set_up_user_group_and_perms(db_session) # test_perm1 from group perms should be ignored perms = self.resource.direct_perms_for_user(self.user, db_session=db_session) second = [ PermissionTuple(self.user, 'foo_perm', 'user', None, self.resource, False, True), PermissionTuple(self.user, 'test_perm2', 'user', None, self.resource, False, True) ] check_one_in_other(perms, second)
def test_resource_users_for_any_perm_resource_2(self, db_session): self.set_up_user_group_and_perms(db_session) perms = ResourceService.users_for_perm(self.resource2, "__any_permission__", db_session=db_session) second = [ PermissionTuple(self.user2, "foo_perm", "user", None, self.resource2, False, True), PermissionTuple(self.user3, "test_perm", "user", None, self.resource2, False, True), ] check_one_in_other(perms, second)
def test_resources_with_user_perms(self, db_session): self.maxDiff = 9999 self.set_up_user_group_and_perms(db_session) perms = self.resource.perms_for_user(self.user, db_session=db_session) second = [ PermissionTuple(self.user, 'foo_perm', 'user', None, self.resource, False, True), PermissionTuple(self.user, 'group_perm', 'group', self.group, self.resource, False, True), PermissionTuple(self.user, 'test_perm2', 'user', None, self.resource, False, True) ] check_one_in_other(perms, second)
def test_resource_users_limited_group(self, db_session): self.maxDiff = 9999 self.set_up_user_group_and_perms(db_session) perms = self.resource.users_for_perm('__any_permission__', user_ids=[self.user.id], group_ids=[self.group2.id], db_session=db_session) second = [ PermissionTuple(self.user, 'test_perm2', 'user', None, self.resource, False, True), PermissionTuple(self.user, 'foo_perm', 'user', None, self.resource, False, True) ] check_one_in_other(perms, second)
def permissions(cls, instance, db_session=None): """ returns all non-resource permissions based on what groups user belongs and directly set ones for this user :param instance: :param db_session: :return: """ db_session = get_db_session(db_session, instance) query = db_session.query( cls.models_proxy.GroupPermission.group_id.label('owner_id'), cls.models_proxy.GroupPermission.perm_name.label('perm_name'), sa.literal('group').label('type')) query = query.filter(cls.models_proxy.GroupPermission.group_id == cls.models_proxy.UserGroup.group_id) query = query.filter( cls.models_proxy.User.id == cls.models_proxy.UserGroup.user_id) query = query.filter(cls.models_proxy.User.id == instance.id) query2 = db_session.query( cls.models_proxy.UserPermission.user_id.label('owner_id'), cls.models_proxy.UserPermission.perm_name.label('perm_name'), sa.literal('user').label('type')) query2 = query2.filter( cls.models_proxy.UserPermission.user_id == instance.id) query = query.union(query2) groups_dict = dict([(g.id, g) for g in instance.groups]) return [ PermissionTuple( instance, row.perm_name, row.type, groups_dict.get(row.owner_id) if row.type == 'group' else None, None, False, True) for row in query ]
def group_perms_for_user(cls, instance, user, db_session=None): """ returns permissions that given user has for this resource that are inherited from groups :param instance: :param user: :param db_session: :return: """ db_session = get_db_session(db_session, instance) perms = resource_permissions_for_users( cls.models_proxy, ANY_PERMISSION, resource_ids=[instance.resource_id], user_ids=[user.id], db_session=db_session) perms = [p for p in perms if p.type == 'group'] # include all perms if user is the owner of this resource groups_dict = dict([(g.id, g) for g in user.groups]) if instance.owner_group_id in groups_dict: perms.append( PermissionTuple(user, ALL_PERMISSIONS, 'group', groups_dict.get(instance.owner_group_id), instance, True, True)) return perms
def groups_for_perm(cls, instance, perm_name, group_ids=None, limit_group_permissions=False, db_session=None): """ return PermissionTuples for groups that have given permission for the resource, perm_name is __any_permission__ then users with any permission will be listed :param instance: :param perm_name: :param group_ids: limits the permissions to specific group ids :param limit_group_permissions: should be used if we do not want to have user objects returned for group permissions, this might cause performance issues for big groups :param db_session: :return: """ db_session = get_db_session(db_session, instance) group_perms = resource_permissions_for_users( cls.models_proxy, [perm_name], [instance.resource_id], group_ids=group_ids, limit_group_permissions=limit_group_permissions, skip_user_perms=True, db_session=db_session) if instance.owner_group_id: for user in instance.owner_group.users: group_perms.append( PermissionTuple(user, ALL_PERMISSIONS, 'group', instance.owner_group, instance, True, True)) return group_perms
def test_resources_with_possible_perms(self, db_session): self.set_up_user_group_and_perms(db_session) perms = self.group.resources_with_possible_perms() second = [ PermissionTuple(None, 'group_perm', 'group', self.group, self.resource, False, True), ] check_one_in_other(perms, second)
def test_resource_users_limited_group(self, db_session): self.maxDiff = 9999 self.set_up_user_group_and_perms(db_session) perms = ResourceService.users_for_perm( self.resource, "__any_permission__", user_ids=[self.user.id], group_ids=[self.group2.id], db_session=db_session, ) second = [ PermissionTuple(self.user, "test_perm2", "user", None, self.resource, False, True), PermissionTuple(self.user, "foo_perm", "user", None, self.resource, False, True), ] check_one_in_other(perms, second)
def test_resources_with_possible_perms(self, db_session): self.set_up_user_group_and_perms(db_session) perms = GroupService.resources_with_possible_perms(self.group) second = [ PermissionTuple(None, "group_perm", "group", self.group, self.resource, False, True) ] check_one_in_other(perms, second)
def test_resource_users_for_perm(self, db_session): self.set_up_user_group_and_perms(db_session) perms = self.resource.users_for_perm('foo_perm', db_session=db_session) second = [ PermissionTuple(self.user, 'foo_perm', 'user', None, self.resource, False, True) ] check_one_in_other(perms, second)
def test_resources_with_possible_perms_group2(self, db_session): self.set_up_user_group_and_perms(db_session) resource3 = add_resource_b(db_session, 3, "other resource") self.group2.resources.append(resource3) group_permission2 = GroupResourcePermission(perm_name="group_perm2", group_id=self.group2.id) self.resource2.group_permissions.append(group_permission2) perms = GroupService.resources_with_possible_perms(self.group2) second = [ PermissionTuple(None, "group_perm", "group", self.group2, self.resource, False, True), PermissionTuple(None, "group_perm2", "group", self.group2, self.resource2, False, True), PermissionTuple(None, ALL_PERMISSIONS, "group", self.group2, resource3, True, True), ] check_one_in_other(perms, second)
def test_permission_convert_from_tuple(self): """ Conversion from Ziggurat :class:`PermissionTuple` object. Validate various implicit conversion of permission elements to explicit definition. """ utils.warn_version(__meta__.__version__, "permission set conversion", "3.0", skip=True) perm = PermissionSet( PermissionTuple( "user-name", "write-deny-match", "user", # important: perm-name & type "group_id", "resource_id", "owner", "allowed")) # these doesn't matter utils.check_val_equal(perm.name, Permission.WRITE) utils.check_val_equal(perm.access, Access.DENY) utils.check_val_equal(perm.scope, Scope.MATCH) utils.check_val_equal( perm.type, PermissionType.DIRECT, msg="PermissionTuple should also help identify type") perm = PermissionSet( PermissionTuple( "user-name", "write-deny-match", "group", # important: perm-name & type "group_id", "resource_id", "owner", "allowed")) # these doesn't matter utils.check_val_equal(perm.name, Permission.WRITE) utils.check_val_equal(perm.access, Access.DENY) utils.check_val_equal(perm.scope, Scope.MATCH) utils.check_val_equal( perm.type, PermissionType.INHERITED, msg="PermissionTuple should also help identify type")
def test_resources_with_possible_perms_group2(self, db_session): self.set_up_user_group_and_perms(db_session) resource3 = add_resource_b(db_session, 3, 'other resource') self.group2.resources.append(resource3) group_permission2 = GroupResourcePermission( perm_name='group_perm2', group_id=self.group2.id, ) self.resource2.group_permissions.append(group_permission2) perms = self.group2.resources_with_possible_perms() second = [ PermissionTuple(None, 'group_perm', 'group', self.group2, self.resource, False, True), PermissionTuple(None, 'group_perm2', 'group', self.group2, self.resource2, False, True), PermissionTuple(None, ALL_PERMISSIONS, 'group', self.group2, resource3, True, True), ] check_one_in_other(perms, second)