[2015/3/20 色々調べて分かった内容にアップデート。なんか別物になった]
ユーザ認証あり & 認証済みページではどの画面でもヘッダ部分にユーザ名を表示、みたいなありがちな Web アプリを作るときの定形処理を自動化。
- 認証済みで user という permission を持っているときだけ view の実行が許可されるような view_decorator を定義する
- 同様に admin という permission でだけ view の実行ができるようにする
- request.user へのアクセスで User オブジェクトにアクセスする
- 最初にアクセスしたときにだけ、SQL を実行して models.User を検索
def permission_view_config(permission):
def pvc(**params):
settings = dict(permission=permission, _depth=1)
settings.update(params)
def wrapped_view_config(original_func):
return view_config(**settings)(original_func)
return wrapped_view_config
return pvc
user_view_config = permission_view_config('user')
admin_view_config = permission_view_config('admin')
__init__.py
def groupfinder(user_code, request):
if not request.user:
return []
elif request.user.is_admin:
return ['group:users', 'group:admin']
else:
return ['group:users']
def get_user(request):
user_id = unauthenticated_userid(request)
if user_id is not None:
return DBSession.query(User).get(user_id)
class RootFactory(object):
__acl__ = [
(Allow, 'group:users', 'user'),
(Allow, 'group:admin', 'admin')
]
def __init__(self, request):
pass
def main(global_config, **settings):
# ...
config = Configurator(settings=settings, root_factory='.RootFactory')
# request の user プロパティにアクセスしたら get_user してね、という指定。これ重要。
config.set_request_property(get_user, 'user', reify=True)
authn_policy = AuthTktAuthenticationPolicy('...', callback=groupfinder, hashalg='sha512')
authz_policy = ACLAuthorizationPolicy()
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
# ...
こんな風に使えば
views.py
@user_view_config(route_name='index', renderer='templates/index.jinja2')
def index(request):
# ここは user の permission を持っている人だけ
do_something_with(request.user) # user が使える
return {'name': 'my_app'}
@admin_view_config(route_name='index', renderer='templates/add_user.jinja2')
def add_user(request):
# ここは admin の permission を持っている人だけ
do_something_with(request.user) # user が使える
return {'name': 'my_app'}
inspired by Pyramid でカスタムの View Decorator を実装する