flask-admin is_accessible usage [英] flask-admin is_accessible usage

查看:128
本文介绍了flask-admin is_accessible usage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是flask admin显示的文档

  class MicroBlogModelView(sqla.ModelView):

def is_accessible(self):
return login.current_user。 is_authenticated()

def inaccessible_callback(self,name,** kwargs):
#如果用户无权访问,则重定向到登录页面
return redirect(url_for ',next = request.url))

我不明白你怎么打电话它是自动调用,或者你必须像这样调用它:

  @expose(/,methods = [ ))
def home(self):
如果self.is_accesible():
返回super().index()
else:
返回self.login()

def is_accesible(self):
return current_user.is_authenticated和管理员在current_user.role

因为这将是相当重要的是把一个

  if self.is_accesible():
return super()。index()

检查我们是否有很多管理员的意见。
,那么我们究竟如何实现呢?该文档展示了如何将其放入您的模型中,而不是如何在您的视图中实现它。解析方案

请参阅下面的示例代码 - 大部分代码是从逐字记录的



<定义一个处理 def is_accessible(self) def _handle_view(self)的 Roled ,name,* args,** kwargs)



在这个例子中,我使用了一个函数, def is_accessible(roles_accepted = None,user = None),来处理确定角色是否可接受的逻辑。

定义一个来自sqla ModelView 的视图类和 Roled mixin,即:

  class AdminView(Roled,ModelView):
$ b $ def __init __(self,* args,** kwargs):
self.roles_accepted = kwargs.pop('roles_accepted',list())
super(AdminView,self) .__ init __(* args,** kwargs)

从这个类派生你的视图模型:

  class UserView(AdminView):
form_excluded_columns =('password')
$ b $ class RoleView ):
传递

类PostView(AdminView):
传递

以正常的方式将您的视图添加到admin类,但通过 roles_accepted 键传递允许的角色名称列表word:

  admin.add_view(UserView(model = User,session = db.session,category ='Account',name = 'Users',roles_accepted = ['admin']))
admin.add_view(RoleView(model = Role,session = db.session,category ='Account',name ='Roles',roles_accepted = ['admin ']))
admin.add_view(PostView(model = Post,session = db.session,category ='Blog',name ='Posts(Editor Only)',roles_accepted = ['editor']))
admin.add_view(PostView(model = Post,session = db.session,category ='Blog',name ='Posts(Admins&编辑)',endpoint =post_special,roles_accepted = ['editor','admin']))



<请参阅下面的完整单个文件代码。这是在Python 2.7.9,Flask 0.10.1,flask-admin 1.1.0,flask-security 1.7.4和flask-login 0.2.11下测试的。

<$ p $从日期时间导入日期时间$ b $从烧瓶进口烧瓶,重定向,current_app $ b $从flask.ext.admin进口管理$ b $从flask.ext.admin.contrib.sqla从flask.ext.admin.menu导入ModelView
从flask.ext.security导入MenuLink
导入(
current_user,$ b $ url_for_security,
UserMixin,
RoleMixin,
SQLAlchemyUserDatastore,
安全

from flask.ext.security.utils import encrypt_password $ b $ from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__ name__)
app.config ['DEBUG'] = True
app.config ['SECRET_KEY'] ='super-secret'
app.config ['SECURITY_PASSWORD_HASH '] ='pbkdf2_sha512'
app.config ['SECURITY_PASSWORD_SALT'] ='16a0af319890f662055ba10aecff37e7e033db3fba737e55'
app.config ['SECURITY_USER_IDENTITY_ATTR IBUTES'] ='email'

app.config ['SQLALCHEMY_DATABASE_URI'] ='sqlite:///:memory:'
app.config ['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)


类角色(db.Model,RoleMixin):
__tablename__ ='角色'

id = db .Column(db.Integer,primary_key = True)
name = db.Column(db.Unicode(length = 64),unique = True)
description = db.Column(db.Unicode(length = 255),nullable = True)

def __unicode __(self):
return u{name}({role})。描述或'角色')

user_to_role = db.Table('user_to_role',
db.Column('user_id',db.Integer(),db.ForeignKey('users.id ')),
db.Column('role_id',db.Integer(),db.ForeignKey('roles.id')))


class User .Model,UserMixin):
__tablename__ ='users'

id = db.Column(db.Integer,primary_key = True)

first_name = db.Column (db.Un icode(length = 255),nullable = False)
last_name = db.Column(db.Unicode(length = 255),nullable = False)

email = db.Column(db。 Unicode(length = 254),unique = True,nullable = True)
password = db.Column(db.Unicode(length = 255),nullable = False)
active = db.Column(db。 Boolean(),default = False)

roles = db.relationship('Role',secondary = user_to_role,backref = db.backref('users',lazy ='select'))

def __unicode __(self):
return u{first_name}({last_name})格式(first_name = self.first_name,last_name = self.last_name)


class Post(db.Model):
id = db.Column(db.Integer,primary_key = True)
title = db.Column(db.String(255))
content = db.Column(db.Text,nullable = False)

def __unicode __(self):
return self.title


def get_current_user():来自flask.ext.security的
导入current_user
尝试:
返回User.objects.get(id = current_user.id)
除了Exception:e
#logger.warning(没有找到用户:%s,str(e))
返回current_user


def is_accessible(roles_accepted = None,user = None):
user = user或get_current_user()
#如果admin有权访问所有内容,则取消注释
#if user。 has_role('admin'):
#return true
如果roles_accepted:
accessible = any(
[role.accepted中角色的user.has_role(角色)]
) b



























$ b $ getattr(self,'roles_accepted',None)
return is_accessible(roles_accepted = roles_accepted,user = current_user)
$ b def _handle_view(self,name,* args,** kwargs):
if not current_user.is_authenticated():
return redirect(url_for_security('login',next =/ admin))
如果不是self.is_accessible():
#return self.render(admin / denied.html)
return< p>拒绝访问< / p>
$ b class AdminView(Roled,ModelView):
$ b $ def __init __(self,* args,** kwargs):
self.roles_accepted = kwargs.pop(' UserView(AdminView):
form_excluded_columns();
super(AdminView,self).__ init __(* args,** kwargs)

$ b $ class UserView =('密码')


类RoleView(AdminView):
通过


类PostView(AdminView):
通过


#安装Flask-Security
security =安全(app,SQLAlchemyUserDatastore(db,User,Role))

@ app.route ('/')
def index():
_login = url_for_security('login',next =/ admin)
_logout = url_for_security('logout',next =/ admin )
return'''
< a href =/ admin />点击我进入管理员< / a>< br>
< a href ={login}>按一下我即可登入!< / a>< br>
< a href ={logout}>点击我即可注销!< / a>
'''.format(login = _login,logout = _logout)


#创建管理员
admin = Admin(app,name ='Admin')
admin.add_view(UserView(model = User,session = db.session,category ='Account',name ='Users',roles_accepted = ['admin']))
admin.add_view(RoleView model = Role,session = db.session,category ='Account',name ='Roles',roles_accepted = ['admin']))
admin.add_view(PostView(model = Post,session = db.session ,category ='Blog',name ='Posts(Editor Only)',roles_accepted = ['editor']))
admin.add_view(PostView(model = Post,session = db.session,category ='Blog ',name ='Posts(Admins& Editors)',endpoint =post_special,roles_accepted = ['editor','admin']))
admin.add_link(MenuLink(name ='Public Website', ()


$ build $ db():
users = [
{
'first_name':'category ='',url ='/'))

$ b $超级',
'姓氏':'用户',
'email':'admin@example.com',
'active':True,
'password':encrypt_password('password'),
'roles':['admin']
},
{
'first_name':u'Post',
'last_name':u'Editor',
'email':'editor @ example。 com',
'active':True,
'password':encrypt_password('password'),
'roles':['editor']
},


$ b b

$ b'title':Finibus Bonorum et Malorum - Part I,
'content': Lorem ipsum dolor sit amet,consectetur adipisicing elit,sed do eiusmod tempor incididunt ut
},
{
'title':de Finibus Bonorum et Malorum - Part II,
'内容':sed ut perspiciatis unde omnis iste natus error sit voluptatem a ccusantium doloremque
},
{
'title':de Finibus Bonorum et Malorum - Part III,
'content':vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium



db.drop_all()
db.create_all()

security = current_app。 (名称=admin,描述= u'Administers系统')
security.datastore.create_role(name = ueditor,description = u'Can编辑帖子)

用户用户:
角色= user.pop('角色')
user_db = security.datastore .create_user(** user)
for role_name在角色中:
role_from_db = security.datastore.find_role(role_name)
security.datastore.add_role_to_user(user_db,role_from_db)
安全性。 datastore.activate_user(user_db)
user_db.confirme d_at = datetime.now()

security.datastore.commit()

用于在帖子中的行:
post = Post(** row)
db.session.add(post)

db.session.commit()

$ b @ app.before_first_request
def create_user():
build_db()
$ b $ if if __name__ =='__main__':
app.run(debug = True)


I've checked the docs and It's pretty vague how the is_accessible method should be implemented.

Here is what the docs of flask admin showed

class MicroBlogModelView(sqla.ModelView):

    def is_accessible(self):
        return login.current_user.is_authenticated()

    def inaccessible_callback(self, name, **kwargs):
        # redirect to login page if user doesn't have access
        return redirect(url_for('login', next=request.url))

what I don't get though is how do you call it is it automatically called or do you have to call it yourself like this:

@expose("/", methods=["GET", "POST"])
    def home(self):
        if self.is_accesible():
            return super().index()
        else:
            return self.login()

    def is_accesible(self):
        return current_user.is_authenticated and "admin" in current_user.role

because It would be pretty darn repetitive to put a

if self.is_accesible():
                return super().index()

check if we had a lot of admin views. so how exactly do we implement it? the docs showed how to put it in your model but not how to implement it on your views

解决方案

See the example code below - most of the code is taken verbatim from Quokka CMS

Define a Roled mixin that handles def is_accessible(self) and def _handle_view(self, name, *args, **kwargs).

In the example I've used a function , def is_accessible(roles_accepted=None, user=None), to handle the logic of determining if a role is acceptable.

Define a view class from sqla ModelView and the Roled mixin, namely:

class AdminView(Roled, ModelView):

    def __init__(self, *args, **kwargs):
        self.roles_accepted = kwargs.pop('roles_accepted', list())
        super(AdminView, self).__init__(*args, **kwargs)

Derive your view models from this class:

class UserView(AdminView):
    form_excluded_columns = ('password')   

class RoleView(AdminView):
    pass

class PostView(AdminView):
    pass

Add your views to the admin class in the normal manner but pass a list of allowed role names via the roles_accepted keyword:

admin.add_view(UserView(model=User, session=db.session, category='Account', name='Users', roles_accepted=['admin']))
admin.add_view(RoleView(model=Role, session=db.session, category='Account', name='Roles', roles_accepted=['admin']))
admin.add_view(PostView(model=Post, session=db.session, category='Blog', name='Posts (Editor Only)', roles_accepted=['editor']))
admin.add_view(PostView(model=Post, session=db.session, category='Blog', name='Posts (Admins & Editors)', endpoint="post_special", roles_accepted=['editor', 'admin']))

See full single file code below. This was tested under Python 2.7.9, Flask 0.10.1, flask-admin 1.1.0, flask-security 1.7.4 and flask-login 0.2.11

from datetime import datetime
from flask import Flask, redirect, current_app
from flask.ext.admin import Admin
from flask.ext.admin.contrib.sqla import ModelView
from flask.ext.admin.menu import MenuLink
from flask.ext.security import (
    current_user,
    url_for_security,
    UserMixin,
    RoleMixin,
    SQLAlchemyUserDatastore,
    Security
)
from flask.ext.security.utils import encrypt_password
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SECURITY_PASSWORD_HASH'] = 'pbkdf2_sha512'
app.config['SECURITY_PASSWORD_SALT'] = '16a0af319890f662055ba10aecff37e7e033db3fba737e55'
app.config['SECURITY_USER_IDENTITY_ATTRIBUTES'] = 'email'

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)


class Role(db.Model, RoleMixin):
    __tablename__ = 'roles'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(length=64), unique=True)
    description = db.Column(db.Unicode(length=255), nullable=True)

    def __unicode__(self):
        return u"{name} ({role})".format(name=self.name, role=self.description or 'Role')

user_to_role = db.Table('user_to_role',
    db.Column('user_id', db.Integer(), db.ForeignKey('users.id')),
    db.Column('role_id', db.Integer(), db.ForeignKey('roles.id')))


class User(db.Model, UserMixin):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)

    first_name = db.Column(db.Unicode(length=255), nullable=False)
    last_name = db.Column(db.Unicode(length=255), nullable=False)

    email = db.Column(db.Unicode(length=254), unique=True, nullable=True)
    password = db.Column(db.Unicode(length=255), nullable=False)
    active = db.Column(db.Boolean(), default=False)

    roles = db.relationship('Role', secondary=user_to_role, backref=db.backref('users', lazy='select'))

    def __unicode__(self):
        return u"{first_name} ({last_name})".format(first_name=self.first_name, last_name=self.last_name)


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255))
    content = db.Column(db.Text, nullable=False)

    def __unicode__(self):
        return self.title


def get_current_user():
    from flask.ext.security import current_user
    try:
        return User.objects.get(id=current_user.id)
    except Exception as e:
        # logger.warning("No user found: %s", str(e))
        return current_user


def is_accessible(roles_accepted=None, user=None):
    user = user or get_current_user()
    # uncomment if "admin" has access to everything
    # if user.has_role('admin'):
    #     return True
    if roles_accepted:
        accessible = any(
            [user.has_role(role) for role in roles_accepted]
        )
        return accessible
    return True


class Roled(object):

    def is_accessible(self):
        roles_accepted = getattr(self, 'roles_accepted', None)
        return is_accessible(roles_accepted=roles_accepted, user=current_user)

    def _handle_view(self, name, *args, **kwargs):
        if not current_user.is_authenticated():
            return redirect(url_for_security('login', next="/admin"))
        if not self.is_accessible():
            # return self.render("admin/denied.html")
            return "<p>Access denied</p>"

class AdminView(Roled, ModelView):

    def __init__(self, *args, **kwargs):
        self.roles_accepted = kwargs.pop('roles_accepted', list())
        super(AdminView, self).__init__(*args, **kwargs)


class UserView(AdminView):
    form_excluded_columns = ('password')


class RoleView(AdminView):
    pass


class PostView(AdminView):
    pass


# Setup Flask-Security
security = Security(app, SQLAlchemyUserDatastore(db, User, Role))

@app.route('/')
def index():
    _login = url_for_security('login', next="/admin")
    _logout = url_for_security('logout', next="/admin")
    return '''
        <a href="/admin/">Click me to get to Admin!</a><br>
        <a href="{login}">Click me to get to login!</a><br>
        <a href="{logout}">Click me to get to logout!</a>
        '''.format(login=_login, logout=_logout)


# Create admin
admin = Admin(app, name='Admin')
admin.add_view(UserView(model=User, session=db.session, category='Account', name='Users', roles_accepted=['admin']))
admin.add_view(RoleView(model=Role, session=db.session, category='Account', name='Roles', roles_accepted=['admin']))
admin.add_view(PostView(model=Post, session=db.session, category='Blog', name='Posts (Editor Only)', roles_accepted=['editor']))
admin.add_view(PostView(model=Post, session=db.session, category='Blog', name='Posts (Admins & Editors)', endpoint="post_special", roles_accepted=['editor', 'admin']))
admin.add_link(MenuLink(name='Public Website', category='', url='/'))


def build_db():
    users = [
        {
            'first_name': 'Super',
            'last_name': 'User',
            'email': 'admin@example.com',
            'active': True,
            'password' : encrypt_password('password'),
            'roles': ['admin']
        },
        {
            'first_name': u'Post',
            'last_name': u'Editor',
            'email': 'editor@example.com',
            'active': True,
            'password': encrypt_password('password'),
            'roles': ['editor']
        },

    ]

    posts = [
        {
            'title': "de Finibus Bonorum et Malorum - Part I",
            'content': "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut"
        },
        {
            'title': "de Finibus Bonorum et Malorum - Part II",
            'content': "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque"
        },
        {
            'title': "de Finibus Bonorum et Malorum - Part III",
            'content': "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium"
        }
    ]

    db.drop_all()
    db.create_all()

    security = current_app.extensions.get('security')

    security.datastore.create_role(name=u"admin", description=u'Administers the system')
    security.datastore.create_role(name=u"editor", description=u'Can edit posts')

    for user in users:
        roles = user.pop('roles')
        user_db = security.datastore.create_user(**user)
        for role_name in roles:
            role_from_db = security.datastore.find_role(role_name)
            security.datastore.add_role_to_user(user_db, role_from_db)
        security.datastore.activate_user(user_db)
        user_db.confirmed_at = datetime.now()

    security.datastore.commit()

    for row in posts:
        post = Post(**row)
        db.session.add(post)

    db.session.commit()


@app.before_first_request
def create_user():
    build_db()

if __name__ == '__main__':
    app.run(debug=True)

这篇关于flask-admin is_accessible usage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆