Skip to content

Instantly share code, notes, and snippets.

@hustlzp
Last active February 22, 2019 17:42

Revisions

  1. hustlzp revised this gist Jan 20, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion permissions.py
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@ def require_visitor(func):
    """仅允许非登陆用户访问,如signin页面"""
    @wraps(func)
    def decorator(*args, **kwargs):
    if not g.current_user:
    if g.current_user:
    return redirect(url_for('forum.index'))
    return func(*args, **kwargs)
    return decorator
  2. hustlzp revised this gist Jan 17, 2014. 3 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
  3. hustlzp revised this gist Jan 17, 2014. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions c_samples.py
    Original file line number Diff line number Diff line change
    @@ -11,6 +11,7 @@ def ban_reply(reply_id):
    flash('已将此回复移入回收站')
    return redirect(url_for('.topic', topic_id=reply.topic_id))


    # 在action中使用
    @bp.route('/attachment/delete', methods=['POST'])
    def delete_attachment():
    @@ -23,6 +24,7 @@ def delete_attachment():
    db.session.commit()
    return json.dumps({'result': 'ok'})


    # 用于jinja模板
    @app.context_processor
    def inject_vars():
  4. hustlzp revised this gist Jan 17, 2014. 3 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
  5. hustlzp revised this gist Jan 17, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions roles.py
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    # coding: utf-8
    SuperAdminRole = 5
    AdminRole = 4
    UserRole = 3
  6. hustlzp revised this gist Jan 17, 2014. 2 changed files with 5 additions and 7 deletions.
    8 changes: 4 additions & 4 deletions permissions.py
    Original file line number Diff line number Diff line change
    @@ -58,13 +58,13 @@ def deny(self, next_url=""):

    class TopicOwnerPermission(Permission):
    def __init__(self, topic_id):
    own = g.current_user and Topic.query.filter(Topic.id == topic_id).filter(
    can = g.current_user and Topic.query.filter(Topic.id == topic_id).filter(
    Topic.user_id == g.current_user.id).count() > 0
    Permission.__init__(self, roles.UserRole, own)
    Permission.__init__(self, roles.UserRole, can)


    class AttachmentOwnerPermission(Permission):
    def __init__(self, attachment_id):
    own = g.current_user and Attachment.query.filter(Attachment.id == attachment_id).filter(
    can = g.current_user and Attachment.query.filter(Attachment.id == attachment_id).filter(
    Attachment.user_id == g.current_user.id).count() > 0
    Permission.__init__(self, roles.UserRole, own)
    Permission.__init__(self, roles.UserRole, can)
    4 changes: 1 addition & 3 deletions samples.py
    Original file line number Diff line number Diff line change
    @@ -44,6 +44,4 @@ def inject_vars():
    </a>
    </div>
    {% endif %}
    """


    """
  7. hustlzp revised this gist Jan 17, 2014. 2 changed files with 4 additions and 5 deletions.
    8 changes: 4 additions & 4 deletions permissions.py
    Original file line number Diff line number Diff line change
    @@ -58,13 +58,13 @@ def deny(self, next_url=""):

    class TopicOwnerPermission(Permission):
    def __init__(self, topic_id):
    own = 'user_id' in session and Topic.query.filter(Topic.id == topic_id).filter(
    Topic.user_id == session['user_id']).count() > 0
    own = g.current_user and Topic.query.filter(Topic.id == topic_id).filter(
    Topic.user_id == g.current_user.id).count() > 0
    Permission.__init__(self, roles.UserRole, own)


    class AttachmentOwnerPermission(Permission):
    def __init__(self, attachment_id):
    own = 'user_id' in session and Attachment.query.filter(Attachment.id == attachment_id).filter(
    Attachment.user_id == session['user_id']).count() > 0
    own = g.current_user and Attachment.query.filter(Attachment.id == attachment_id).filter(
    Attachment.user_id == g.current_user.id).count() > 0
    Permission.__init__(self, roles.UserRole, own)
    1 change: 0 additions & 1 deletion samples.py
    Original file line number Diff line number Diff line change
    @@ -32,7 +32,6 @@ def inject_vars():
    permissions=permissions
    )
    """
    实例:
    {% if permissions.TopicOwnerPermission(topic.id).check() %}
    <div class="btn-group btn-group-xs">
    <a class="btn btn-default btn-ban-topic"
  8. hustlzp revised this gist Jan 17, 2014. No changes.
  9. hustlzp revised this gist Jan 17, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion permissions.py
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    from functools import wraps
    from flask import abort, session, redirect, url_for, flash
    from .models import Topic, Attachment
    import roles
    from . import roles


    def require_visitor(func):
  10. hustlzp created this gist Jan 17, 2014.
    70 changes: 70 additions & 0 deletions permissions.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    # coding: utf-8
    from flask import request, g
    from functools import wraps
    from flask import abort, session, redirect, url_for, flash
    from .models import Topic, Attachment
    import roles


    def require_visitor(func):
    """仅允许非登陆用户访问,如signin页面"""
    @wraps(func)
    def decorator(*args, **kwargs):
    if not g.current_user:
    return redirect(url_for('forum.index'))
    return func(*args, **kwargs)
    return decorator


    class Permission(object):
    def __init__(self, role, extra=True, super_extra=True):
    """extra用于在同级别user中筛选,super_extra用于允许高级别用户获取此权限"""
    self.role = role
    self.extra = extra
    self.super_extra = super_extra

    def __call__(self, func):
    @wraps(func)
    def decorator(*args, **kwargs):
    if not self.check():
    return self.deny()
    return func(*args, **kwargs)
    return decorator

    def check(self):
    """判断是否满足权限条件"""
    if g.current_role < self.role:
    return False
    elif g.current_role == self.role:
    return self.extra
    return self.super_extra

    def deny(self, next_url=""):
    """针对不同的role进行不同的处理"""
    if g.current_role == roles.VisitorRole:
    flash('此操作需要登录账户')
    return redirect(url_for('account.signin', next=next_url or request.url))
    elif g.current_role == roles.NewUserRole:
    flash('请登录邮箱激活账户')
    return redirect(url_for('forum.index'))
    abort(403)


    new_user_permission = Permission(roles.NewUserRole)
    user_permission = Permission(roles.UserRole)
    admin_permission = Permission(roles.AdminRole)
    super_admin_permission = Permission(roles.SuperAdminRole)


    class TopicOwnerPermission(Permission):
    def __init__(self, topic_id):
    own = 'user_id' in session and Topic.query.filter(Topic.id == topic_id).filter(
    Topic.user_id == session['user_id']).count() > 0
    Permission.__init__(self, roles.UserRole, own)


    class AttachmentOwnerPermission(Permission):
    def __init__(self, attachment_id):
    own = 'user_id' in session and Attachment.query.filter(Attachment.id == attachment_id).filter(
    Attachment.user_id == session['user_id']).count() > 0
    Permission.__init__(self, roles.UserRole, own)
    6 changes: 6 additions & 0 deletions roles.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    SuperAdminRole = 5
    AdminRole = 4
    UserRole = 3
    NewUserRole = 2
    BanUserRole = 1
    VisitorRole = 0
    50 changes: 50 additions & 0 deletions samples.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    # 装饰action
    @bp.route('/reply/<int:reply_id>/ban')
    @admin_permission
    def ban_reply(reply_id):
    """Proc: ban reply"""
    reply = Reply.query.get_or_404(reply_id)
    reply.ban = True
    reply.baned = datetime.datetime.now()
    db.session.add(reply)
    db.session.commit()
    flash('已将此回复移入回收站')
    return redirect(url_for('.topic', topic_id=reply.topic_id))

    # 在action中使用
    @bp.route('/attachment/delete', methods=['POST'])
    def delete_attachment():
    attachment_id = request.form.get('attachment_id')
    permission = AttachmentOwnerPermission(attachment_id)
    if not permission.check():
    return permission.deny()
    attachment = Attachment.query.get_or_404(attachment_id)
    db.session.delete(attachment)
    db.session.commit()
    return json.dumps({'result': 'ok'})

    # 用于jinja模板
    @app.context_processor
    def inject_vars():
    from . import roles, permissions
    return dict(
    roles=roles,
    permissions=permissions
    )
    """
    实例:
    {% if permissions.TopicOwnerPermission(topic.id).check() %}
    <div class="btn-group btn-group-xs">
    <a class="btn btn-default btn-ban-topic"
    href="{{ url_for('forum.ban_topic', topic_id=topic.id) }}" title="移入回收站">
    <i class="fa fa-trash-o"></i>
    </a>
    <a class="btn btn-default"
    href="{{ url_for('forum.edit_topic', topic_id=topic.id) }}" title="编辑">
    <i class="fa fa-pencil"></i>
    </a>
    </div>
    {% endif %}
    """