如何在web2py中实现object/record级访问控制?
How to achieve object/record level access control in web2py?
我想添加对象级访问控制。
(用虚拟学生通知模式解释)
只有当学生具有与通知相同的class(标准)和主题时,学生才应该访问(edit/view)通知(新闻)。
有两个 roles/groups - 'student' 和 'teacher'
数据库架构:
# model db.py
auth.define_tables(username=False, signature=True)
db.define_table('class', Field('name'))
db.define_table('subject', Field('name'))
db.define_table('notice', Field('title'),
Field('class', db.class),
Field('subject', db.subject))
db.define_table('user_class', Field('user', db.auth_user),
Field('class', db.class))
db.define_table('user_subject', Field('user', db.auth_user),
Field('subject', db.subject))
-
#controller default.py
def has_ownership():
# Check if logged in user has class and subject to view/edit this notice
pass
@auth.requires_login()
@auth.requires(lambda: has_ownership())
def notice():
user_classes = db(db.user_class.auth_user == auth.user.id).select()
user_class_list = [clss['id'] for clss in user_classes]
user_subjects = db(db.user_subject.auth_user == auth.user.id).select()
user_subject_list = [subject['id'] for subject in user_subjects]
query = db.notice.class.belongs(user_class_list) & db.notice.subject.belongs(user_subject_list)
grid = SQLFORM.grid(query, user_signature=True)
return dict(grid=grid)
所有 url 都经过数字签名,而且我还在网格中根据用户主题和 class.
显示记录
所以我的问题只有数字签名 url 足以限制用户访问其他记录? (通过更改 url 中的 id)
或者我需要像使用装饰器那样做额外的检查 has_ownership
?
在 web2py 中是否有其他方法可以实现对象级访问控制?我不想使用增删改查。
谢谢
因为 query
已经将网格显示的记录集限制为用户有权访问的记录集,所以网格的数字签名 URL(默认情况下启用)足以防止访问任何其他记录。不仅在URL中修改记录ID会被拒绝,如果用户试图篡改编辑表单中隐藏的"id"表单域,表单提交也会被拒绝。所以,不需要 has_ownership
检查。
顺便说一句,当所有 lambda 所做的只是使用传递给 lambda 的相同参数(在这种情况下,没有参数)调用单个函数时,不需要 lambda。因此,装饰器可以简化为 @auth.requires(has_ownership)
(当然,在这种情况下您实际上并不需要装饰器)。
我想添加对象级访问控制。
(用虚拟学生通知模式解释)
只有当学生具有与通知相同的class(标准)和主题时,学生才应该访问(edit/view)通知(新闻)。 有两个 roles/groups - 'student' 和 'teacher'
数据库架构:
# model db.py
auth.define_tables(username=False, signature=True)
db.define_table('class', Field('name'))
db.define_table('subject', Field('name'))
db.define_table('notice', Field('title'),
Field('class', db.class),
Field('subject', db.subject))
db.define_table('user_class', Field('user', db.auth_user),
Field('class', db.class))
db.define_table('user_subject', Field('user', db.auth_user),
Field('subject', db.subject))
-
#controller default.py
def has_ownership():
# Check if logged in user has class and subject to view/edit this notice
pass
@auth.requires_login()
@auth.requires(lambda: has_ownership())
def notice():
user_classes = db(db.user_class.auth_user == auth.user.id).select()
user_class_list = [clss['id'] for clss in user_classes]
user_subjects = db(db.user_subject.auth_user == auth.user.id).select()
user_subject_list = [subject['id'] for subject in user_subjects]
query = db.notice.class.belongs(user_class_list) & db.notice.subject.belongs(user_subject_list)
grid = SQLFORM.grid(query, user_signature=True)
return dict(grid=grid)
所有 url 都经过数字签名,而且我还在网格中根据用户主题和 class.
显示记录所以我的问题只有数字签名 url 足以限制用户访问其他记录? (通过更改 url 中的 id)
或者我需要像使用装饰器那样做额外的检查 has_ownership
?
在 web2py 中是否有其他方法可以实现对象级访问控制?我不想使用增删改查。
谢谢
因为 query
已经将网格显示的记录集限制为用户有权访问的记录集,所以网格的数字签名 URL(默认情况下启用)足以防止访问任何其他记录。不仅在URL中修改记录ID会被拒绝,如果用户试图篡改编辑表单中隐藏的"id"表单域,表单提交也会被拒绝。所以,不需要 has_ownership
检查。
顺便说一句,当所有 lambda 所做的只是使用传递给 lambda 的相同参数(在这种情况下,没有参数)调用单个函数时,不需要 lambda。因此,装饰器可以简化为 @auth.requires(has_ownership)
(当然,在这种情况下您实际上并不需要装饰器)。