More Related Content Similar to プロダクト開発してわかったDjangoの深〜いパーミッション管理の話 @ PyconJP2017 (20) プロダクト開発してわかったDjangoの深〜いパーミッション管理の話 @ PyconJP201727. Lv3 パーミッションでやる
class User(AbstractUser):
def get_permissions():
permissions = set()
if user.is_premium():
permissions.add("view_premium_articles")
permissions.add("view_special_feature")
return permissions
def has_permission(permission):
return permission in self.get_permissions()
30. Lv3 許可設定
class Article(models.Model):
def has_permission(self, user, permission):
permissions = set()
if self.premium and user.is_premium:
permissions.add("view")
if not self.premium:
if user.is_premium or user.is_standard:
permissions.add("view")
return permission in permissions
47. django-rules
>>> @rules.predicate
>>> def is_book_author(user, book):
... return book.author == user
...
>>> rules.add_rule('can_edit_book', is_book_author)
>>> rules.add_rule('can_delete_book', is_book_author)
<Predicate:is_book_author object at 0x10eeaa490>
57. from keeper.security import Allow
from keeper.operators import Everyone
from keeper.operators import IsUser
class Article:
author = models.ForeginKey("myapp.User")
def __acl__(self):
return [
(Allow, Everyone, 'view'),
(Allow, IsUser(self.author), 'edit'),
]
58. keeperを使った解法
from keeper.views import keeper
@keeper(
'edit'
Article,
lambda request, article_id: {'id': article_id}
)
def article_edit(request, article_id):
article = request.k_context
...
65. デフォルトのOperatros
return [
(Allow, Everyone, "view"),
(Allow, Authenticated, "comment"),
(Allow, IsUser(self.author), ("edit", "delete")),
(Allow, IsStaff, ("edit", "delete")),
]
68. from myapp.operators import IsPlan
class Article(models.Model):
premium = models.BooleanField()
def __acl__(self):
if self.premium:
return [
(Allow, IsPlan(PLAN_PREMIUM), 'view'
]
else:
return [
(Allow, IsPlan(PLAN_PREMIUM), 'view'
(Allow, IsPlan(PLAN_STANDARD), 'view'
]
70. テンプレートでの利用方法
{% load keeper %}
{% has_permission article 'edit' as can_edit %}
{% if can_edit %}
<a href="{% url ... %}">編集</a>
{% endif %}
<h1>{{ article.title }}</h1>
<p>{{ article.body }}</p>