์ ์ญ ๊ถํ์ ์ฌ์ฉํ๋ ๋ฃจํด๊ณผ ๊ฐ์ฒด ๊ถํ๋ง ์ฌ์ฉํ๋ ๋ฃจํด์ผ๋ก ์ธํด ๋ง์ ๋ฒ๊ทธ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ด๋ จ ๋ฒ๊ทธ๋ฅผ ๋ซ๊ณ ์ฌ๊ธฐ์์ ์ฐธ์กฐํฉ๋๋ค.
์ด์ ์!
permission_required_or_403์๋ accept_global_perms ๋งค๊ฐ๋ณ์๊ฐ ์์ง๋ง get_obj_perms๋ก ๋์ผํ ์์ ์ ์ํํ ์ ์๋ ๋ฐฉ๋ฒ์ด ๋ณด๊ธฐ์ ์์ต๋๋ค.
์ ์ญ ๊ถํ์ ํฌํจํ๋ get_obj_perms_with_global ํ๊ทธ๋ฅผ ์ ์ํฉ๋๋ค.
์ด ๊ธธ์ ์ด๋ฏธ ์์ํ๋์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง ํจ์น ์์ ์ ์์ํ๊ฒ ์ต๋๋ค. ์ด๋ฏธ ์์ํ์ จ๋ค๋ฉด ์ฃผ์ ํ์ง ๋ง์๊ณ ์ ๋ฅผ ๋ฉ์ถฐ์ฃผ์ธ์ :)
์ถ์ : ๊ธฐ๋ณธ ๋์์ด ์ ์ญ ๊ถํ์ ํฌํจํด์ผ ํ๋ค๋ ์ฃผ์ฅ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. "์ฌ์ฉ์ X๊ฐ Y๋ฅผ ๊ฐ์ฒด Z๋ก ํ ์ ์์ต๋๊น?"๋ผ๊ณ ๋ฌผ์ ๋ ๋ชจ๋ ์ฌ์ฉ์/๊ฐ์ฒด, ๊ทธ๋ฃน/๊ฐ์ฒด๋ฅผ ํ์ธํ๋ ๊ฒ์ ์๋ฏธ , ์ฌ์ฉ์/์ ์ญ, ๊ทธ๋ฃน/์ ์ญ ๊ถํ. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ ๋จ์ง ๋ด๊ฐ ๊ทธ๊ฒ์ ์ฌ์ฉํ๋ ๋ฐฉ์ ๋๋ฌธ์ผ ์ ์์ต๋๋ค.
๋ชจ๋ ๊ฒ์ ๋งํ์ง๋ง, ์ ์ญ ๊ถํ์ ๋ณ๋๋ก ํ์ธํ๋ ๊ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค...ํ .
Pesticles: ์ด๊ฒ์ด ์ผ๋ง๋ ํผ๋์ค๋ฌ์ด์ง์ ๋ํ ์ฆ๊ฑฐ๋ก ๊ฐ๋์ธ์ ๋ํ ์ถฉ๋ถํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ 6๊ฐ์๋ง๋ค ์กฐ๊ธ์ฉ ์์๋ ๋๋ค... ๋ง์ฝ ๊ทธ๋ค์ด ์ ์ญ ๊ถํ์ ์์ง๋ง ๊ฐ์ฒด ์์ค ๊ถํ์ ์๋ ๊ฒฝ์ฐ request.user.has_access('foo', obj)๊ฐ true์ฌ์ผ ํ๋ค๋ฉด. ์ํ๋ฅผ ๋ ๋ฒ ์ฐ๋ ๊ฒ์ ์ข์ง ์์ต๋๋ค.
์ด๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
๋๊ตฐ๊ฐ๊ฐ pull ์์ฒญ์ ์์ฑํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค... ์ด์์ ์ผ๋ก๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ์์์ํค์ง ์๋ ๋ฐฉ์์ ๋๋ค(์ด๊ฒ์ด ์ ์ ์ ์ด๊ณ ์คํ ๊ฐ๋ฅํ์ง ์ฌ๋ถ๋ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค).
์ค๋๋ ๋ฌธ์ ์ง๋ง ์์ง pull ์์ฒญ์ด ํ์๋์ง ์์ต๋๋ค. ์ด๊ฒ์ ๋ํ ์์์ด ์์ต๋๊น? ๋๋ ๊ฐ์ ํ๋์ ํ๊ณ ์๋๋ฐ, ๊ทธ๊ฒ์ ๊ทธ๋ค์ง ์์ธกํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ฌด๋ฆฌ ๊ฐ์ฌ!
๊ฐ์ฒด ์์ค์ด ์คํจํ ๋ ์ ์ญ์ผ๋ก ๋์ฒดํ ์ง ์ฌ๋ถ์ ๋ฐฉ๋ฒ์ ๋ํ ๋ ๋ง์ ํต์ฐฐ๋ ฅ์ด ์์๊ธฐ ๋๋ฌธ์ #49์ ๋ช ๊ฐ์ง ์๊ฒฌ์ ์ถ๊ฐํ์ต๋๋ค. ๋ซํ ๋ฌธ์ ๊ฐ ์๋ฆผ์ ๋ฐ์์ํค๋์ง ํ์คํ์ง ์์ผ๋ฏ๋ก ์ฌ๊ธฐ์ ์ถ๊ฐํฉ๋๋ค.
๋์์ธ ๊ฒฐ์ ์ ๋ฐ๋ผ ์ด๋ฌํ ๋ฌธ์ ์ค ์ผ๋ถ์ ๋ํด ์์ ํ ์๋๊ฐ ์์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ๋์๋๋ฆฌ๊ฒ ์ต๋๋ค.
```
brandon=Person.objects.get(first_name='BRANDON')
brandon.is_superuser
๊ฑฐ์ง
ํ๊ต=School.objects.get(pk=1)
get_users_with_perms(ํ๊ต, attach_perms=์ฐธ, with_superusers=๊ฑฐ์ง, with_group_users=๊ฑฐ์ง)
{}
assign_perm('add_school', ๋ธ๋๋ , ํ๊ต) get_users_with_perms(ํ๊ต, attach_perms=์ฐธ, with_superusers=๊ฑฐ์ง, with_group_users=๊ฑฐ์ง) mehmet=Person.objects.get(first_name='๋ฉํ๋ฉง') get_users_with_perms(ํ๊ต, attach_perms=True, with_superusers=True, with_group_users=False) assign_perm('add_school', mehmet, ํ๊ต) get_users_with_perms(ํ๊ต, attach_perms=True, with_superusers=True, with_group_users=False) get_users_with_perms(ํ๊ต, attach_perms=์ฐธ, with_superusers=๊ฑฐ์ง, with_group_users=๊ฑฐ์ง)
{
mehmet.is_superuser
์ง์ค
{
{
{
#155:
get_obj_perms_field_choices (self)
๋ค์ ๋ ์ค ์ถ๊ฐ๋ฅผ ์์ฒญํฉ๋๋ค.
if self.exclude_default:
choices = list(set(choices).intersection(self.obj._meta.permissions))
๋ชจ๋ธ์ ๊ธฐ๋ณธ ๊ถํ์ ์ ์ธํฉ๋๋ค. ์ฒซ์งธ, intersection
๊ฐ ์ด๋ป๊ฒ ๋๋์ง ๋ช
ํํ์ง ์์ต๋๋ค. ๋์งธ, ๊ฐ์ฒด ๋ ๋ชจ๋ธ ๊ถํ๊ณผ ๊ด๋ จ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ด๊ฐ ๋๋ฝ ๋ ๊ฒ์ด ์์ผ๋ฉด ์ ๋ฅผ ์์ ํ์ญ์์ค.
๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ ์กฐ์ฌํ๋ ๋์ ๋ค์์์ ๊ฐ์ฒด์ ๋ชจ๋ธ ๊ถํ์ ๋ถ๋ฆฌํด์ผ ํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค.
def save_obj_perms(self):
"""
Saves selected object permissions by creating new ones and removing
those which were not selected but already exists.
Should be called *after* form is validated.
"""
perms = self.cleaned_data[self.get_obj_perms_field_name()]
model_perms = [c[0] for c in self.get_obj_perms_field_choices()]
to_remove = set(model_perms) - set(perms)
for perm in to_remove:
remove_perm(perm, self.user, self.obj)
for perm in perms:
assign_perm(perm, self.user, self.obj)
๊ถํ์ด ๋๋ฝ๋ ๋ชจ๋ ๊ถํ์ ๊ฐ์ฒด ์์ค์์ ์ ์ฅํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ ์๊ฐ์๋ ๋ชจ๋ธ ์์ค์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ๊ถํ์ ๊ฑด๋๋ฐ๊ฑฐ๋ ํด๋น ๋ชฉ์ ์ ๋ํ ์ต์ ์ ์ ๊ณตํด์ผ ํฉ๋๋ค.
๋๋ ๋ค์๊ณผ ๊ฐ์ ์ ์ญ ์ค์ ์๊ฐ GUARDIAN_FALLBACK_TO_MODEL=False
์ ๊ฐ์ ์ ์ฉ ๋ฐฉ๋ฒ์ ๋ํ ์ธ์ fallback_to_model=False
๊ฐ์ฒด ์ฌ์ฉ ๊ถํ ๋ฐ ๋ชจ๋ธ ๊ถํ์ ์ ๋๋ก ๋ฌ์ฌ์ ํ์ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ False
์ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ๋ณด์ฅํฉ๋๋ค. ์ ์ญ ๋๋ ์ธ์ ์ค์ ์ค ํ๋๊ฐ True์ด๋ฉด ๋์ฒด๊ฐ ๋ฐ์ํด์ผ ํฉ๋๋ค.
GUARDIAN_FALLBACK_TO_MODEL์ ๋ํด +1์ ๋๋ค.
#49์ ๋ํ ํ ๋ก ์ ๋ฐ๋ฅด๋ฉด ์ด ์ค์ ์ ObjectPermissionBackend๊ฐ ๋ช ์์ ์ธ์ง ์ฌ๋ถ๋ฅผ ์ ์ดํ๋ โโ๋ฐ๋ ์ ์๋ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
ํ ๋ฆฌํ์คํธ(#546)๋ฅผ ์์ฑํ์ต๋๋ค. core.py ์ต์ ์ ๊ฒ์ฌ๊ธฐ ๊ธฐ๋ฅ์ด ๋ชจ๋ธ ์์ค ๊ถํ์ผ๋ก ํด๋ฐฑ(๋๋ ํฌํจ)ํ ์ ์๋๋ก ํฉ๋๋ค. ๋ค๋ฅธ ๋ชจ๋๋ ๊ฒํ ํด์ผ ํฉ๋๋ค. ์ฌ์ฉํ๋ฉด์ ๋ฆฌ๋ทฐํ ์์ ์ ๋๋ค. ๋๊ตฌ๋ ๋ฐ์ด๋ค๊ณ ์ถ๋ค๋ฉด ๊ฐ์ฅ ํ์ํฉ๋๋ค.
#327์ด ๋ ์ด์ ์กด์ฌํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. #332๋ ์๋ฝ๋ ๊ฒฝ์ฐ ์์ pull ์์ฒญ์ ์ํด ์์ ๋ฉ๋๋ค. #155(์์์ ์ธ๊ธ)์ ๊ด๋ จ๋ ๋จ ํ๋์ ์ธก๋ฉด ๋ฌธ์ ๊ฐ ๋จ์ ์์ต๋๋ค. ๊ทธ๊ฒ ๋ํ ์ฒ๋ฆฌ๋์๋ค๋ฉด(๋๋ ๋ณ๋์ ์ด์๋ก ์ฎ๊ฒจ์ก๋ค๋ฉด), ์ด ์ด์๋ ์ข ๊ฒฐ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ์ญ ๊ถํ์ ์ค์ ๋ ๊ฒฝ์ฐ ๊ฐ์ฒด ์์ค ๊ถํ์ ๋ํด ์ฌ์ ํ ์กด์ค๋์ง ์์ต๋๋ค. ์ ๊ฐ ์๋ชป ์๊ณ ์์ต๋๊น?
u = User.objects.get(id=1)
c = Client.objects.get(id=1)
assign_perm('core.change_client', u)
u = User.objects.get(id=1) # reloading user for perm refresh
u.has_perm('core.change_client') # True
u.has_perm('core.change_client', c) # False
u.has_perm('change_client', c) # False
get_perms(u, c) # []
๊ทธ๋ฆฌ๊ณ GUARDIAN_GLOBAL_PERMISSIONS_CARRY_OVER
๋๋ FALLBACK_TO_MODEL
์ ๋ฌด์์ ํฉ๋๊น? ๋ ๋ค ๋ฌธ์ํ ๋ ๊ฒ ๊ฐ์ง ์์ต๋๋ค.
์ด๊ฒ์ core.py
์ ์ถ๊ฐํ๋ ๊ฒ์ผ๋ก ์ถฉ๋ถํ์ง ์์๊น์?
get_user_perms:126
๋ชจ๋ ์ฌ์ฉ์ ๊ถํ ํ์ธ์ ์ค์ฌ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ๋ถ์ธ ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ๋์์ ์ผ๋ก ํธ๋ฆฌ๊ฑฐ ๊ฐ๋ฅ
def get_user_perms(self, obj):
# ....
user_global_perms = Permission.objects.filter(content_type=ctype)\
.filter(user=self.user)\
.values_list('codename', flat=True)
user_object_perms = user_perms_qs.values_list("codename", flat=True)
user_perms = list(chain(user_global_perms, user_object_perms))
return user_perms