なぜそれが起こるのかを把握して理解しようとするのに問題があります。私は解決しようとしている問題をモデル化するために、ポニー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
>>>
ありがとう