gpt4 book ai didi

python - 单元测试 Flask-Principal 应用程序

转载 作者:太空狗 更新时间:2023-10-29 22:22:57 25 4
gpt4 key购买 nike

所有,我正在编写一个依赖于 flask-principal 的 flask 应用程序用于管理用户角色。我想编写一些简单的单元测试来检查哪些用户可以访问哪些 View 。已发布代码示例 on pastebin以免弄乱这篇文章。简而言之,我定义了一些路由,装饰了一些路由,以便它们只能由具有适当角色的用户访问,然后尝试在测试中访问它们。

在粘贴的代码中,test_membertest_admin_b 都失败了,提示 PermissionDenied。显然,我没有正确声明用户;至少,关于用户角色的信息不在正确的上下文中。

对于上下文处理的复杂性的任何帮助或见解,我们将不胜感激。

最佳答案

Flask-Principal 不会在请求之间为您存储信息。随心所欲地执行此操作取决于您。请记住这一点并考虑一下您的测试。您在 setUpClass 方法中调用 test_request_context 方法。这将创建一个新的请求上下文。您还在测试中使用 self.client.get(..) 进行测试客户端调用。这些调用创建了彼此之间不共享的额外请求上下文。因此,您对 identity_changed.send(..) 的调用不会在检查权限的请求上下文中发生。我已经继续编辑您的代码以使测试通过,希望它能帮助您理解。请特别注意我在 create_app 方法中添加的 before_request 过滤器。

import hmac
import unittest

from functools import wraps
from hashlib import sha1

import flask

from flask.ext.principal import Principal, Permission, RoleNeed, Identity, \
identity_changed, identity_loaded current_app


def roles_required(*roles):
"""Decorator which specifies that a user must have all the specified roles.
Example::

@app.route('/dashboard')
@roles_required('admin', 'editor')
def dashboard():
return 'Dashboard'

The current user must have both the `admin` role and `editor` role in order
to view the page.

:param args: The required roles.

Source: https://github.com/mattupstate/flask-security/
"""
def wrapper(fn):
@wraps(fn)
def decorated_view(*args, **kwargs):
perms = [Permission(RoleNeed(role)) for role in roles]
for perm in perms:
if not perm.can():
# return _get_unauthorized_view()
flask.abort(403)
return fn(*args, **kwargs)
return decorated_view
return wrapper



def roles_accepted(*roles):
"""Decorator which specifies that a user must have at least one of the
specified roles. Example::

@app.route('/create_post')
@roles_accepted('editor', 'author')
def create_post():
return 'Create Post'

The current user must have either the `editor` role or `author` role in
order to view the page.

:param args: The possible roles.
"""
def wrapper(fn):
@wraps(fn)
def decorated_view(*args, **kwargs):
perm = Permission(*[RoleNeed(role) for role in roles])
if perm.can():
return fn(*args, **kwargs)
flask.abort(403)
return decorated_view
return wrapper


def _on_principal_init(sender, identity):
if identity.id == 'admin':
identity.provides.add(RoleNeed('admin'))
identity.provides.add(RoleNeed('member'))


def create_app():
app = flask.Flask(__name__)
app.debug = True
app.config.update(SECRET_KEY='secret', TESTING=True)
principal = Principal(app)
identity_loaded.connect(_on_principal_init)

@app.before_request
def determine_identity():
# This is where you get your user authentication information. This can
# be done many ways. For instance, you can store user information in the
# session from previous login mechanism, or look for authentication
# details in HTTP headers, the querystring, etc...
identity_changed.send(current_app._get_current_object(), identity=Identity('admin'))

@app.route('/')
def index():
return "OK"

@app.route('/member')
@roles_accepted('admin', 'member')
def role_needed():
return "OK"

@app.route('/admin')
@roles_required('admin')
def connect_admin():
return "OK"

@app.route('/admin_b')
@admin_permission.require()
def connect_admin_alt():
return "OK"

return app


admin_permission = Permission(RoleNeed('admin'))


class WorkshopTest(unittest.TestCase):

@classmethod
def setUpClass(cls):
app = create_app()
cls.app = app
cls.client = app.test_client()

def test_basic(self):
r = self.client.get('/')
self.assertEqual(r.data, "OK")

def test_member(self):
r = self.client.get('/member')
self.assertEqual(r.status_code, 200)
self.assertEqual(r.data, "OK")

def test_admin_b(self):
r = self.client.get('/admin_b')
self.assertEqual(r.status_code, 200)
self.assertEqual(r.data, "OK")


if __name__ == '__main__':
unittest.main()

关于python - 单元测试 Flask-Principal 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16712321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com