如何在web2py中实现对象/记录级访问控制?

时间:2016-11-17 10:41:55

标签: python authorization web2py access-control

我想添加对象级访问控制。

(用虚拟学生通知模式解释)

学生只有在学生具有相同的班级(标准)和指定为通知的科目时才能访问(编辑/查看)通知(新闻)。 有两个角色/小组 - '学生'和老师'

数据库架构:

# 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)

所有网址都经过数字签名,我也会根据用户的主题和课程在网格中显示记录。

所以我的问题是只有数字签名的网址足以限制用户访问其他记录? (通过更改网址中的ID) 或者我需要做额外的检查,就像我使用装饰器has_ownership

在web2py中是否还有其他替代方法可以实现对象级访问控制?我不想使用CRUD。

谢谢

1 个答案:

答案 0 :(得分:1)

由于query已经将网格显示的记录集限制为用户有权访问的记录集,因此网格的数字签名URL(默认情况下已启用)足以阻止访问任何网格其他记录。不仅会拒绝更改URL中的记录ID,而且如果用户试图篡改隐藏的" id"在编辑表单中的表单字段,表单提交将被拒绝。因此,无需has_ownership检查。

顺便说一句,当所有lambda都调用一个函数并且传递给lambda的相同参数(在这种情况下,没有参数)时,不需要lambda。因此,装饰器可以简化为@auth.requires(has_ownership)(当然,在这种情况下,你实际上并不需要装饰器)。