我从 here开始使用Flask-Admin auth示例并略微更改了它.

我在下面的视图中添加了以下块,但它没有显示导出按钮.我期待它将导出选项添加到管理视图.它确实打印—超级用户到控制台.

if current_user.has_role('superuser'):
            can_export = True
            print ' ---- superuser '

我以前多次使用导出功能.如果我在语句MyModelView(sqla.ModelView)下面放置语句can_export = True,它将起作用:我将此作为基于用户角色控制对创建/编辑/ etc的访问的示例.例如,我想要一个只读的角色,其中can_create = False,can_edit = False等.

有人可以帮忙吗?有人能告诉我我做错了什么吗?

==

这是整个视图.

# Create customized model view class
class MyModelView(sqla.ModelView):

    def is_accessible(self):
        if not current_user.is_active or not current_user.is_authenticated:
            return False

        if current_user.has_role('superuser'):
            return True

        return False

    def _handle_view(self,name,**kwargs):
        """
        Override builtin _handle_view in order to redirect users when a view is not accessible.
        """
        if current_user.has_role('superuser'):
            can_export = True
            print ' ---- superuser '

        if not self.is_accessible():
            if current_user.is_authenticated:
                # permission denied
                abort(403)
            else:
                # login
                return redirect(url_for('security.login',next=request.url))

==

供参考:我把所有代码都放到了here.

解决方法

为了进一步扩展,我继续使用auth示例作为上面的基础,并添加了一些简单的基于角色的访问控制.我希望这可以帮助别人.

完整代码是here.
如果你在这里看到的东西不是一个好的RBAC练习,我想听听它.

主app.py文件是:

import os
from flask import Flask,url_for,redirect,render_template,request,abort
from flask_sqlalchemy import sqlAlchemy
from flask_security import Security,sqlAlchemyUserDatastore,\
    UserMixin,RoleMixin,login_required,current_user
from flask_security.utils import encrypt_password
import flask_admin
from flask_admin.contrib import sqla
from flask_admin import helpers as admin_helpers

# Create Flask application
app = Flask(__name__)
app.config.from_pyfile('config.py')
db = sqlAlchemy(app)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Define models directly without reflection...
class Customer(db.Model):
    CustomerId = db.Column(db.Integer(),primary_key=True)
    FirstName = db.Column(db.Unicode(40),nullable=False)
    LastName = db.Column(db.String(20),nullable=False)
    City = db.Column(db.Unicode(40))
    Email = db.Column(db.Unicode(60),unique = True)

    def __str__(self):
        return self.CustomerID

class City(db.Model):
    Id = db.Column(db.Integer(),primary_key=True)
    City = db.Column(db.Unicode(40),unique = True)

    def __str__(self):
        return self.ID

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Define models
roles_users = db.Table(
    'roles_users',db.Column('user_id',db.Integer(),db.ForeignKey('user.id')),db.Column('role_id',db.ForeignKey('role.id'))
)

class Role(db.Model,RoleMixin):
    id = db.Column(db.Integer(),primary_key=True)
    name = db.Column(db.String(80),unique=True)
    description = db.Column(db.String(255))

    def __str__(self):
        return self.name

class User(db.Model,UserMixin):
    id = db.Column(db.Integer,primary_key=True)
    first_name = db.Column(db.String(255))
    last_name = db.Column(db.String(255))
    email = db.Column(db.String(255),unique=True)
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role',secondary=roles_users,backref=db.backref('users',lazy='dynamic'))

    def __str__(self):
        return self.email

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

# Flask views
@app.route('/')
def index():
    return render_template('index.html')


# Create customized model view class
class dgBaseView(sqla.ModelView):

    column_display_pk = True
    page_size = 20
    can_view_details = True
    #can_export = False
    can_export = True

    def _handle_view(self,**kwargs):
        """
        Override builtin _handle_view in order to redirect users when a view is not accessible.
        """
        if not self.is_accessible():
            if current_user.is_authenticated:
                # permission denied
                abort(403)
            else:
                # login
                return redirect(url_for('security.login',next=request.url))

class regularRbacView(dgBaseView):

    def is_accessible(self):

        # set accessibility...
        if not current_user.is_active or not current_user.is_authenticated:
            return False

        # roles not tied to ascending permissions...
        if  not current_user.has_role('export'):
            self.can_export = False

        # roles with ascending permissions...
        if current_user.has_role('adminrole'):
            self.can_create = True
            self.can_edit = True
            self.can_delete = True
            self.can_export = True
            return True
        if current_user.has_role('supervisor'):
            self.can_create = True
            self.can_edit = True
            self.can_delete = False
            return True
        if current_user.has_role('user'):
            self.can_create = True
            self.can_edit = True
            self.can_delete = False
            return True
        if current_user.has_role('create'):
            self.can_create = True
            self.can_edit = False
            self.can_delete = False
            return True
        if current_user.has_role('read'):
            self.can_create = False
            self.can_edit = False
            self.can_delete = False
            return True
        return False

class lookupRbacView(dgBaseView):

    def is_accessible(self):
        # set accessibility...
        if not current_user.is_active or not current_user.is_authenticated:
            return False

        # roles not tied to ascending permissions...
        if  not current_user.has_role('export'):
            self.can_export = False

        # roles with ascending permissions...
        if current_user.has_role('adminrole'):
            self.can_create = True
            self.can_edit = True
            self.can_delete = True
            self.can_export = True
            return True
        if current_user.has_role('supervisor'):
            self.can_create = True
            self.can_edit = True
            self.can_delete = False
            return True
        if current_user.has_role('user'):
            self.can_create = False
            self.can_edit = False
            self.can_delete = False
            return True
        if current_user.has_role('create'):
            self.can_create = False
            self.can_edit = False
            self.can_delete = False
            return True
        if current_user.has_role('read'):
            self.can_create = False
            self.can_edit = False
            self.can_delete = False
            return True
        return False

class SuperView(dgBaseView):

    can_export = True

    def is_accessible(self):
        if not current_user.is_active or not current_user.is_authenticated:
            return False
        if current_user.has_role('adminrole'):
            self.can_create = True
            self.can_edit = True
            self.can_delete = True
            #self.can_export = True
            return True
        return False


# define a context processor for merging flask-admin's template context into the
# flask-security views.
@security.context_processor
def security_context_processor():
    return dict(
        admin_base_template=admin.base_template,admin_view=admin.index_view,h=admin_helpers,)

# Create admin
admin = flask_admin.Admin(
    app,'Rbac RoleBasedAccess',base_template='my_master.html',template_mode='bootstrap3',)

class customer_view(regularRbacView):

    column_searchable_list = ['CustomerId','City','Email','FirstName','LastName',]
    # make sure the type of your filter matches your hybrid_property
    column_filters = ['FirstName','Email'   ]
    # column_default_sort = ('part_timestamp',True)
    #column_export_list = ['CustomerId',]

# Add model views
admin.add_view(SuperView(Role,db.session))
admin.add_view(SuperView(User,db.session))
admin.add_view(customer_view(Customer,db.session))
admin.add_view(lookupRbacView(City,db.session))


def build_sample_db():
    """
    Populate a small db with some example entries.
    """
    import string

    #db.drop_all()
    db.create_all()

    with app.app_context():
        read_role = Role(name='read')
        user_role = Role(name='user')
        super_user_role = Role(name='adminrole')
        db.session.add(user_role)
        db.session.add(super_user_role)
        db.session.add(Role(name='read'))
        db.session.add(Role(name='create'))     
        db.session.add(Role(name='supervisor'))
        db.session.add(Role(name='delete'))
        db.session.add(Role(name='export'))
        db.session.commit()

        test_user = user_datastore.create_user(
            first_name='Admin',email='admin',password=encrypt_password('admin'),roles=[user_role,super_user_role]
        )


        first_names = [
            'read','create','user','suser','delete','Charlie','Sophie','Mia',]
        last_names = [
            'brown','Smith','Patel','Jones','Williams','Johnson','Taylor','Thomas',]
        roles1 = [
            'read','supervisor','read',]

        for i in range(len(first_names)):
            tmp_email = first_names[i].lower()
            # initialize the users with simple password...  'a'
            tmp_pass = 'a'
            user_datastore.create_user(
                first_name=first_names[i],last_name=last_names[i],email=tmp_email,password=encrypt_password(tmp_pass),roles=[read_role,]
            )
        db.session.commit()
    return

if __name__ == '__main__':

    # Build a sample db on the fly,if one does not exist yet.
    app_dir = os.path.realpath(os.path.dirname(__file__))
    database_path = os.path.join(app_dir,app.config['DATABASE_FILE'])
    if not os.path.exists(database_path):
        build_sample_db()
    app.run(host='0.0.0.0',port=5000,debug=True)

config.py是:

# https://stackoverflow.com/questions/5055042/whats-the-best-practice-using-a-settings-file-in-python
import creds

# Create dummy secret key so we can use sessions
SECRET_KEY = creds.cred['secretkey']

# Create in-memory database
DATABASE_FILE = 'fground.sqlite'
sqlALCHEMY_DATABASE_URI = creds.cred['dbspec'] + DATABASE_FILE
sqlALCHEMY_ECHO = True

# Flask-Security config
Security_URL_PREFIX = "/admin"
Security_PASSWORD_HASH = "pbkdf2_sha512"
Security_PASSWORD_SALT = creds.cred['csalt']

# Flask-Security URLs,overridden because they don't put a / at the end
Security_LOGIN_URL = "/login/"
Security_logoUT_URL = "/logout/"
Security_REGISTER_URL = "/register/"

Security_POST_LOGIN_VIEW = "/admin/"
Security_POST_logoUT_VIEW = "/admin/"
Security_POST_REGISTER_VIEW = "/admin/"

# Flask-Security features
Security_REGISteraBLE = True
Security_SEND_REGISTER_EMAIL = False

creds.py是:

cred = dict(
    secretkey = '123232323238',dbspec    = 'sqlite:///',csalt     = "ATGUOHAELKiubaq3fgo8hiughaerGOJAEGj",dbu = 'user',dbp = 'pass',)

为了运行它,我建议你从上面的flask-admin auth示例开始,然后将这些文件复制到该示例中.运行它应该创建一个包含用户和角色的数据库.此外,您可以准备好在github link上完成所有代码.

python – Flask-Admin基于角色的访问 – 根据角色修改访问权限的更多相关文章

  1. XCode 3.2 Ruby和Python模板

    在xcode3.2下,我的ObjectiveCPython/Ruby项目仍然可以打开更新和编译,但是你无法创建新项目.鉴于xcode3.2中缺少ruby和python的所有痕迹(即创建项目并添加新的ruby/python文件),是否有一种简单的方法可以再次安装模板?我发现了一些关于将它们复制到某个文件夹的信息,但我似乎无法让它工作,我怀疑文件夹的位置已经改变为3.2.解决方法3.2中的应用程序模板

  2. Swift基本使用-函数和闭包(三)

    声明函数和其他脚本语言有相似的地方,比较明显的地方是声明函数的关键字swift也出现了Python中的组元,可以通过一个组元返回多个值。传递可变参数,函数以数组的形式获取参数swift中函数可以嵌套,被嵌套的函数可以访问外部函数的变量。可以通过函数的潜逃来重构过长或者太复杂的函数。

  3. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  4. Swift、Go、Julia与R能否挑战 Python 的王者地位

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 红薯因 Swift 重写开源中国失败,貌似欲改用 Python

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  6. 你没看错:Swift可以直接调用Python函数库

    上周Perfect又推出了新一轮服务器端Swift增强函数库:Perfect-Python。对,你没看错,在服务器端Swift其实可以轻松从其他语种的函数库中直接拿来调用,不需要修改任何内容。以如下python脚本为例:Perfect-Python可以用下列方法封装并调用以上函数,您所需要注意的仅仅是其函数名称以及参数。

  7. Swift中的列表解析

    在Swift中完成这个的最简单的方法是什么?我在寻找类似的东西:从Swift2.x开始,有一些与你的Python样式列表解析相当的东西。(在这个意义上,它更像是Python的xrange。如果你想保持集合懒惰一路通过,只是这样说:与Python中的列表解析语法不同,Swift中的这些操作遵循与其他操作相同的语法。

  8. swift抛出终端的python错误

    每当我尝试启动与python相关的swift时,我都会收到错误.我该如何解决?

  9. 在Android上用Java嵌入Python

    解决方法看看this,它适用于J2SE,你可以尝试在Android上运行.

  10. 在android studio中使用python代码构建android应用程序

    我有一些python代码和它的机器人,我正在寻找一种方法来使用android项目中的那些python代码.有没有办法做到这一点!?解决方法有两种主要工具可供使用,它们彼此不同:>QPython>Kivy使用Kivy,大致相同的代码也可以部署到IOS.

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部