to_json函数的访问规则中的Pony ORM PermissionError

时间:2016-12-08 01:24:28

标签: python pony ponyorm

我有一个问题,试图掌握并理解其发生的原因。 我正在使用Pony ORM https://ponyorm.com来模拟我正在尝试解决的问题。

我正在尝试使用数据库实例中的to_json函数以json格式发送查询结果。

这里是我使用的代码。

from pony.orm import *
db = Database()

#entities definition

class User(db.Entity):
    nama = Required(str)
    admin = Required(bool, default=False)
    diklat = Optional('Diklat')


class Diklat(db.Entity):
    nama = Required(str)
    finished = Required(bool, default=False)
    peserta = Set(User)

# database binding
db.bind('sqlite', ':memory:', create_db=True)
db.generate_mapping(create_tables=True)

# test data
with db_session:
    u1 = User(nama='user 1')
    u2 = User(nama='user 2', admin=True)
    u3 = User(nama='user 3')
    d1 = Diklat(nama='diklat 1')
    d2 = Diklat(nama='diklat 2', finished=True)
    # add user to diklat
    d1.peserta.add(u1)
    d1.peserta.add(u2)
    d2.peserta.add(u3)
    flush()
    commit()

# access rules setup

@user_groups_getter(User)
def user_groups(user):
    if user.admin:
        return ['admin', 'user']
    return ['user']

@user_roles_getter(User, Diklat)
def user_roles(user, diklat):
    if user in diklat.peserta:
        return ['peserta']
    return ['nonpeserta']

@obj_labels_getter(Diklat)
def obj_labels(diklat):
    if diklat.finished:
        return ['finished']
    return ['process']


# permission setup
with db.set_perms_for(Diklat):
    perm('view', role='peserta')

# some function to get data in form of json 
def get_diklat():
    d = select(d for d in Diklat)
    return db.to_json(d)


if __name__ == '__main__':
    with db_session:
        user1 = User[1]
        user2 = User[2]
        user3 = User[3]
        diklat = Diklat[1]
        set_current_user(user1)
        print("current user should 'User[1]':", get_current_user())
        print("User group user should '['user']':", user_groups(user1))
        print("User group user2 should '['admin', 'user']':", user_groups(user2))
        print("User group user3 should '['user']':", user_groups(user3))
        print("Roles for user and diklat should '['peserta']' :", user_roles(user1, diklat))
        print("Roles for user2 and diklat should '['peserta']' :", user_roles(user2, diklat))
        print("Roles for user3 and diklat should '['nonpeserta']' :", user_roles(user3, diklat))
        print("Object labels for diklat, should '['process']':", obj_labels(diklat))
        print(get_diklat())

问题是get_diklat()获取访问角色的权限设置......这里结果追溯

>>>
current user should 'User[1]': User[1]
User group user should '['user']': ['user']
User group user2 should '['admin', 'user']': ['admin', 'user']
User group user3 should '['user']': ['user']
Roles for user and diklat should '['peserta']' : ['peserta']
Roles for user2 and diklat should '['peserta']' : ['peserta']
Roles for user3 and diklat should '['nonpeserta']' : ['nonpeserta']
Object labels for diklat, should '['process']': ['process']
Traceback (most recent call last):
  File "C:/Users/******/test.py", line 82, in <module>
    get_diklat()
  File "C:/Users/******/test.py", line 64, in get_diklat
    return db.to_json(d)
  File "<string>", line 2, in to_json
  File "C:\Miniconda3\envs\env35\lib\site-packages\pony\utils\utils.py", line 58, in cut_traceback
    return func(*args, **kwargs)
  File "C:\Miniconda3\envs\env35\lib\site-packages\pony\orm\core.py", line 1020, in to_json
    data_json = json.dumps(data, default=obj_converter)
  File "C:\Miniconda3\envs\env35\lib\json\__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "C:\Miniconda3\envs\env35\lib\json\encoder.py", line 198, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Miniconda3\envs\env35\lib\json\encoder.py", line 256, in iterencode
    return _iterencode(o, 0)
  File "C:\Miniconda3\envs\env35\lib\site-packages\pony\orm\core.py", line 1014, in obj_converter
    user_has_no_rights_to_see(obj)
  File "C:\Miniconda3\envs\env35\lib\site-packages\pony\orm\core.py", line 1004, in user_has_no_rights_to_see
    % (user, sorted(user_groups), obj))
  File "C:\Miniconda3\envs\env35\lib\site-packages\pony\utils\utils.py", line 96, in throw
    raise exc
pony.orm.core.PermissionError: The current user User[1] which belongs to groups ['anybody', 'user'] has no rights to see the object Diklat[2] on the frontend
>>>

基于上述权限设置,并且错过了一些文档https://docs.ponyorm.com/ponyjs_security.html?highlight=permissions_for,我认为当前用户的角色设置正确,

 # permission setup
    with db.set_perms_for(Diklat):
        perm('view', role='peserta')

当前用户的角色,(参见示例数据)......我认为是对的 那么,问题是什么?为什么小马说:

pony.orm.core.PermissionError: The current user User[1] which belongs to groups ['anybody', 'user'] has no rights to see the object Diklat[2] on the frontend

... 我不明白为什么会这样? 谢谢您的帮助 最好的问候......

[更新] 如果我改变了这样的权限设置,

# permission setup
with db.set_perms_for(Diklat):
    perm('view', group='user')

它的工作方式就像我希望..来自get_diklat()函数的输出:

{"data": [{"class": "Diklat", "pk": 1}, {"class": "Diklat", "pk": 2}], "objects": {"Diklat": {"1": {"nama": "diklat 1", "id": 1, "finished": false}, "2": {"nama": "diklat 2", "id": 2, "finished": true}}}, "schema": [{"name": "Diklat", "newAttrs": [{"auto": true, "kind": "PrimaryKey", "name": "id", "type": "int"}, {"kind": "Required", "name": "nama", "type": "str"}, {"kind": "Required", "name": "finished", "type": "bool"}], "pkAttrs": ["id"]}], "schema_hash": "600696882295084e228d496c580a1f77"}

[更新]

如果我检查交互式控制台,我认为它允许查看diklat对象

>>> diklat
Diklat[1]
>>> user1
User[1]
>>> user2
User[2]
>>> with db_session:
    has_perm(user2, 'view', diklat)


True
>>> 

由于

1 个答案:

答案 0 :(得分:0)

出现异常是因为当前用户对'view'实体的特定实例没有Diklat权限,即Diklat[2]。此信息在错误消息中指定:“属于组User[1]的当前用户['anybody', 'user']无权查看前端上的对象Diklat[2]。”

权限规则定义为:

with db.set_perms_for(Diklat):
    perm('view', role='peserta')

这意味着,要获得view权限,用户需要将'peserta'角色Diklat添加到user_roles_getter的特定实例。

根据'peserta'钩子,为了拥有diklat.peserta角色,用户需要成为@user_roles_getter(User, Diklat) def user_roles(user, diklat): if user in diklat.peserta: return ['peserta'] return ['nonpeserta'] 集合的项目:

User[1]

当前用户Diklat[2].peserta不属于Diklat[2]集合,因此对于peserta对象,它没有User[1]个角色。因此,viewDiklat[2]对象没有权限Diklat[2],因此当前用户为User[1]时,s1 <- "today john jack and joe go to the beach" s2 <- "today joe and john go to the beach" s3 <- "today jack and joe go to the beach" 对象无法序列化为JSON。