νμ€ user.has_perm("perm")
λ©μλλ₯Ό μ¬μ©νλ κ²½μ° μ¬μ©μμκ² μ μ κΆν "perm"
μ΄ μλ κ²½μ°μλ§ True
λ₯Ό λ°νν©λλ€.
κ·Έλ¦¬κ³ user.has_perm("perm", obj)
κ° μ¬μ©λλ©΄ μ¬μ©μκ° μ΄ νΉμ κ°μ²΄μ μ‘μΈμ€ν μ μλ κΆνμ΄ μμΌλ©΄ True
λ₯Ό λ°νν©λλ€.
κ·Έλ¬λ μ¬μ©μμκ² μ μ κΆν "perm"
μ΄ μλλΌλ False
λ₯Ό λ°νν©λλ€. μ΄λ μ μκ°μ μ μ κΆνμ΄ μμ΄μΌ μ¬μ©μμκ² λͺ¨λ κ°μ²΄μ λν μ‘μΈμ€ κΆνμ λΆμ¬ν΄μΌ νλ€κ³ κ°μ νκΈ° λλ¬Έμ μμμΉ λͺ»ν μΌμ
λλ€. λ΄ λ§μ΄ λ§μ?
μ‘°κΈ λ νκ³ λ€μ΄λ³΄λ κ° κΆν λ°±μλκ° λ
립μ μΌλ‘ μλν΄μΌ νλ―λ‘ μμμ μ€λͺ
ν κ²κ³Ό κ°μ μν©μ΄ λ°μν΄μλ μ λ©λλ€. κ·Έλ¬λ μ΄λ€ μ΄μ λ‘ κ°μ²΄ μΈμ€ν΄μ€λ₯Ό μ 곡νλ user.has_perm
λ₯Ό νΈμΆνλ©΄ κ°μ²΄ μμ€ κΆνλ§ νμΈνκ³ μ μ κΆν νμΈμ 건λλλλ€. κ·Έ νλμ μ΄μ κ° λ¬΄μμΈμ§ λͺ¨λ₯΄κ² μ΅λλ€. μ λ Django 1.2.5λ₯Ό μ¬μ©νκ³ μμ΅λλ€.
_AUTHENTICATION_BACKENDS_ μ€μ μ λΆμ¬λ£μ μ μμ΅λκΉ?
μ΄λ―Έ Django λ¬Έμλ₯Ό μ½μμΌλ―λ‘ μ§μ λ λ°±μλμ μμκ° μ€μνλ€λ κ²μ μκ³ μμ΅λλ€.
κ·νμ μμ© νλ‘κ·Έλ¨μ λ€μκ³Ό κ°μ κ²μ΄ μλ€κ³ κ°μ ν©λλ€.
AUTHENTICATION_BACKENDS = (
'guardian.backends.ObjectPermissionBackend',
'django.contrib.auth.backends.ModelBackend',
)
μλλ©΄ μ΄κ±°:
from django.conf import global_settings
AUTHENTICATION_BACKENDS = (
'guardian.backends.ObjectPermissionBackend',
) + global_settings.AUTHENTICATION_BACKENDS
κΈ°λ³Έ λ°±μλκ° λ¨Όμ μ§μ λμλμ§ νμΈνμμμ€.
μ΄κ²μ΄ λ¬Έμ μΈμ§ νμΈν μ μμ΅λκΉ? κ·Έλ μ§ μμ κ²½μ° μ 보λ₯Ό λ μΆκ°νμμμ€(λ€λ₯Έ λ°±μλλ μ¬μ©νκ±°λ _User.has_perm_ λ©μλλ₯Ό μ¬μ©νλ λ€λ₯Έ μ± μμμ΄ ν¨μΉ?).
μκ² μ΅λλ€. λ무 νΌκ³€ν κ² κ°μ΅λλ€. μ£Όλ¬Έμ _has_perm_ κ²°κ³Όμ μν₯μ λ―ΈμΉμ§ μμμΌ ν©λλ€. λ°λΌμ μ¬μ© μ€μΈ μ ν리μΌμ΄μ μ€μ μ λν μΆκ° μ 보λ₯Ό μΆκ°νμμμ€. λν ν μ€νΈ μ€μνΈ(_python manage.py test Guardian_)λ₯Ό μ€ννμ¬ κ°λμΈμ΄ μ λλ‘ μλνλμ§ νμΈν μ μμ΅λλ€.
μ€, μκ² μ΅λλ€. κ·νμ λ¬Έμ λ₯Ό ν λ² λ μ½μμ΅λλ€. κΈ°λ³Έ _auth.ModelBackend_λ _supports_object_permissions_λ₯Ό μ§μνμ§ μμ΅λλ€ (ν΄λΉ μμ±μ _False_μ). Django λ¬Έμμ λ°λ₯΄λ©΄ 1.4λΆν° κΈ°λ³Έ λ°±μλμ λν μ§μμ μΆκ°ν©λλ€.
λ°λΌμ κ·νμ μν©μ λ°λΌ νλμ μ λμ μΌλ‘ μ ννκ³ μμλ©λλ€. κΈ°λ³Έ λ°±μλλ λ¨μν μλ΅λ©λλ€.
μ±μμ κ°μ²΄ μμ€ κΆνμ νμΈνκΈ° μ μ μ μ κΆνμ νμΈν΄μΌ ν©λλ€. λ΄κ° μκ°ν μμλ κ°μ₯ κ°λ¨ν μ루μ μ λλ€.
_invalid_(μΌ)λ‘ μ’ λ£λμ§λ§ μ λκΈλ‘ λ€μ μ΄λ €λ©΄ μμ λ‘κ² νμμμ€!
λ€ λ§μ΄ λ§λ κ² κ°μ΅λλ€. κ·Έλ¬λ μ μ κΆνμ νμΈνμ§ μμΌλ©΄ λμκ² λͺ κ°μ§ μ¬κ°ν λ¬Έμ κ° λ°μν©λλ€. μλ₯Ό λ€μ΄ guardian.decorators.permission_required
μμ κ°μ ν λλ‘ μΆκ° κ°μ²΄ μμ€ κΆν κ²μ¬λ₯Ό ν΅ν΄ μΌλ° django.contrib.auth.decorators.permission_required
μ κΈ°λ₯μ νμ₯ν΄μΌ ν©λλ€.
λ¬Έμ λ μ μ κΆνμ μ¬μ©νλ μμ
μμ© νλ‘κ·Έλ¨μ΄ μκ³ μΆκ° κ°μ²΄ μμ€ κΆνμ μΆκ°νκ³ μΆμκΈ° λλ¬Έμ κΈ°λ³Έ permission_required
λ°μ½λ μ΄ν°λ₯Ό django-guardianμ κ°μ²΄ μμ€ λ°μ½λ μ΄ν°λ‘ λ³κ²½νμ§λ§ κ·Έλ° λ€μ μ¬μ©μλ μ μ κΆνμ κΈ°λ°μΌλ‘ μ‘μΈμ€ κΆνμ μμμ΅λλ€.
λμκ² μκΈ°μΉ μμ λμμ²λΌ 보μ λλ€. μ½λλ₯Ό μ΄ν΄λ³΄μ§ μκ³ λ λͺ ννμ§ μκΈ° λλ¬Έμ μ΅μν μ΄ κ²½μ°λ₯Ό λ¬Έμμ μΆκ°ν΄ μ£Όμκ² μ΅λκΉ?
μ μκ² μ΄κ²μ μ€κ³ κ²°ν¨μΌλ‘ μΈν΄ μ μ λ° κ°μ²΄λ³ κΆνμ λͺ¨λ νμΈν΄μΌ νλ μ½λ μ 체μ λν΄ μΆκ° κ²μ¬κ° νμν©λλ€.
@coagulant : μ€μ λ‘ Djangoμ μΈμ¦μμ λ°μ½λ μ΄ν°λ₯Ό _νμ₯_νλ κ²μ μ μ°νμ§ μμ κ²μ λλ€. μ΄ μ±μ μλ κΆνμ νμ₯νμ§ μκ³ _κ°μ²΄ κΆν_μ ꡬννλ €κ³ ν©λλ€. μλ₯Ό λ€μ΄ 보νΈμ λ° κ°μ²΄ μμ€ κΆνλ§ μ¬μ©νλ λ€λ₯Έ μ±μ μ¬μ©νλ €λ©΄ μ΄λ»κ² ν΄μΌ ν©λκΉ? adminμμλ§ μ μ κΆνμ μ¬μ©νκ³ μΌλ° μ¬μ©μμκ² λΆμ¬λ μ±μμλ κ°μ²΄ μμ€ κΆνμ μ¬μ©νλ €λ©΄ μ΄λ»κ² ν΄μΌ ν©λκΉ? μ±μ΄ μ¬μ©μκ° κ°μ²΄μ λν΄ μΌλΆ μμ μ μνν μ μλλ‘ μ μ κΆν κ³Ό κ°μ²΄ μμ€ κΆνμ λͺ¨λ μꡬνλ€λ©΄ μ΄λ»κ² λ κΉμ? λ§μ κ²½μ°κ° μμΌλ©° 보νΈμκ° λͺ¨λ κ²½μ°λ₯Ό λ€λ£¨μ§λ μμ΅λλ€.
λ°λ©΄μ μ΄ νΉμ μ¬μ© μ¬λ‘κ° λ€λ₯Έ μ¬λ‘λ³΄λ€ λ μΌλ°μ μΌ μ μμμ μΈμ ν μ μμ΅λλ€. μ΄μ κ΄μ¬μ΄ μλ μ¬λμ μꡬ μ¬νμ μ§μ νλ λ€λ₯Έ λ¬Έμ λ₯Ό μ μΆνμμμ€. λλ μ΄κ²μ΄ λ°±μλ λΉνΈνμ± μμ΄, μ¦ μλ‘μ΄ κ΅¬μ± μ€μ μΌλ‘ μ½κ² λ¬μ±λ μ μλ€κ³ λ―Ώμ΅λλ€.
κ°μ²΄ μμ€ κΆνκ³Ό μ μ κΆνμ λͺ¨λ νμΈνλ λ λ€λ₯Έ permission_required λ°μ½λ μ΄ν°κ° μΆκ°λλ©΄ λμκ² μ μ©ν κ²μ λλ€. κ·Έκ²μ λ΄ λ¬Έμ λ₯Ό λ€λ£° κ²μ λλ€.
@Dzejkob , λ§μ§λ§ 컀λ°μ νμΈνκ³ μ΄κ²μ΄ μΆ©λΆνμ§ λ§ν΄ μ£Όμκ² μ΅λκΉ(μ μ κΆν μλ½μ μν νλκ·Έλ₯Ό μΆκ°νμ΅λλ€). λν λ°μ½λ μ΄ν° μ체μμ λ μ€νΈλ§μ νμ₯νλ κ²μΌλ‘ μΆ©λΆνμ§ μλ €μ£Όμμμ€. μλλ©΄ λ λ§μ μμ /μ€λͺ μ μΈ λ¬Έμλ₯Ό μΆκ°ν΄μΌ ν©λκΉ?
μ°Έκ³ : 컀λ°μ μ λΆκΈ°: _feature/add-accept_global_perms-flag-for-decorators_μ μμ΅λλ€.
@lukaszb μ, λ΄ νλ‘μ νΈμ Guardianμ μ λΆκΈ° λ²μ μ μ€μΉνκ³ permission_required
decorators accept_global_perms=True
μ 맀κ°λ³μλ₯Ό μΆκ°νμΌλ©° μ μμ μΌλ‘ μλνλ κ² κ°μ΅λλ€. μ΄ κΈ°λ₯μ λ§λ€μ΄ μ£Όμ
μ κ°μ¬ν©λλ€. νΈλ ν¬μ λ£μ΄λλ©΄ μ’μ κ² κ°μμ.
λ¬Έμμ κ΄ν΄μλ λμκ² λ§€μ° λͺ
ννλ―λ‘ μΆ©λΆνλ€κ³ μκ°ν©λλ€.
μ΄κ²μ μ€λ μ μ μμ λμμ΅λλ€.
μλ νμΈμ, μ λ jango-guardianμ μλνλ©΄μ μ΄ λ¬Έμ λ₯Ό λ°κ²¬νκ³ μ΄ λμμ΄ λ²κ·Έκ° μκ±°λ λ§€μ° νΌλμ€λ½λ€λ κ²μ λ°κ²¬νμ΅λλ€.
μ¬μ©μμκ² μ μ κΆνμ μΆκ°( view_user
)ν λ€μ( joe
) Joeκ° νΉμ μ¬μ©μλ₯Ό λ³Ό μ μλμ§ νμΈνμ΅λλ€( other_user
) λλκ²λ False
λ₯Ό λ°ννμ΅λλ€.
joe = User.objects.get(username="joe")
other_user = User.objects.get(username="other_user")
assign_perm("myapp.view_user", joe)
joe.has_perm("myapp.view_user") # True as expected
joe.has_perm("myapp.view_user", other_user) # False, whaaaat?
μ΄μ $#$ settings.py
$#$μ REST_FRAMEWORK/DEFAULT_PERMISSION_CLASSES
λ° AUTHENTICATION_BACKENDS
λλ¬Έμ λ·° μΈνΈκ° "μλμΌλ‘" κΆνμ νμΈνλ―λ‘ permission_required
λ°μ½λ μ΄ν°λ₯Ό λͺ
μμ μΌλ‘ μ¬μ©νμ§ μμ΅λλ€. . κ·Έλ¬λ©΄ 보νΈμμκ² μμλλ‘ νλνλλ‘ μ΄λ»κ² λ§ν©λκΉ?
(μ λ§ μ΄λ¦¬μμ κ²μ λμΉλ©΄ μ¬κ³Όλ립λλ€. μ΄κ²μ djangolandμμ μΌμ’ μ 2/3μΌμ λλ€)
μ€λ μλμ μΌμΌμΌ μ£μ‘ν©λλ€ guardian.shortcuts.get_objects_for_user()
κ° κΈ°λ³Έμ μΌλ‘ μΈμ¦/μ μ κΆνμ μ‘΄μ€νλ€λ μ μ΄ ν¨μ¬ λ ν₯λ―Έλ‘κ³ /νΌλμ€λ½μ΅λλ€( accept_global_perms
).
accept_global_perms: if True takes global permissions into account.
[...]
Default is True.
λΉλ‘ μ΄ λ¬Έμ κ° λ€λ₯Έ λ¬Έμ λ‘ μΈν΄ μ’ λ£λμμ§λ§ μ¬κΈ°μλ λ§μ ν΅μ°°λ ₯μ΄ μμΌλ―λ‘ λνλ₯Ό λ€μ μΌμΌν€κΈ° μν΄ μ¬κΈ°μ μλλ€. Pythonμ Zenμ λ€μκ³Ό κ°μ΄ λ§ν©λλ€.
μ΄λ₯Ό μννλ νμ€ν λ°©λ²μ΄ νλ μμ΄μΌ ν©λλ€.
κ·Έλ¦¬κ³ λμκ² κ·Έκ²μ _λ‘컬(κ°μ²΄ μμ€)μ΄ μ§μ λμ§ μμμ λ μ μμΌλ‘ λ체νλ κ²μ
λλ€_. μμλ κ²°κ³Όλ₯Ό λ³κ²½νμ§ μμ§λ§(Django returns False if obj is not None
μ΄ν) μ±λ₯μ λ³κ²½ν μ μμ΅λλ€.
μ½λ μ 체μ λν΄ μ΄μ€ νμΈμ νλ κ²μ μ’μ λμμΈμ΄ μλλ©° μ΄λ€ μλ―Έμμλ DRY μμΉμλ μ΄κΈλλ€λ λ° λμν©λλ€. κ·Έλ¬λ Django κΈ°λ³Έ λ°±μλ λ΄μμ μ¬μ©ν μ μλ κΈ°λ₯μ ꡬννλ 보νΈμλ DRYκ° μλλλ€. Djangoλ μ¬λ¬ λ°±μλλ₯Ό νμ©νκ³ μμλλ‘ νλμ© νμΈνλ©΄ λ°±μλκ° μλ‘λ₯Ό λ체νμ§ μκ³ ν¨κ» μ¬μλμ΄μΌ ν¨μ λνλ
λλ€. μ΄κ²μ΄ λ§λ€λ©΄ Djangoλ obj is not None
κ° _wrong_μΌ λ μ μ κ²μ¬λ₯Ό κ±°λΆν©λλ€. Djangoκ° obj
λ₯Ό 무μνλ€λ©΄ κ°μ²΄ κ²μ¬κΈ°μ λν μ μ λμ²΄κ° λ μ μμ΅λλ€.
λλ μ°λ¦¬κ° Djangoλ‘ ν°μΌμ μ΄μ΄ μΈμ¦ λ°±μλκ° μλ‘ μ΄λ»κ² μλνλμ§ λ¬»κ³ κ±°κΈ°μμ κ°μΌ νλ€κ³ μκ°ν©λλ€.
μ¦, Djangoκ° λμμ λ³κ²½νλ κ²μ κ±°μ λΆκ°λ₯νλ€κ³ μκ°νλ―λ‘(μ¬μ ν λ¬Όμ΄λ΄μΌ νλ€κ³ μκ°νμ§λ§) νμ μ μ§λ κ°λμΈμ΄ μνλ κ²μ λ°λΌ λ κ°μ§λ₯Ό λͺ¨λ μ 곡ν μ μλλ‘ μ§νν΄μΌ ν¨μ λνλ λλ€. μ€μ μ΄λ ν¨μμ λν μΈμλ₯Ό ν΅ν΄ μ€μ λ μ μμ). κ·Έλ¬λ κΈ°λ³Έ λμμ 보λ μ 체μμ false_μΌ λ _local fallback to globalμ΄μ΄μΌ νλ€κ³ μκ°ν©λλ€.
Djangoκ° True, False λ° Noneμ 3κ°μ§ μν κΆν μμ€ν
μ μ νΈνλ€λ©΄ λ μ’μν κ²μ
λλ€. μ΄ κ²½μ° λ‘컬 κ²μ¬κΈ°λ False
λ₯Ό ν΅ν΄ μ μμ _μ¬μ μ_ν μ μμ΅λλ€. None
λ₯Ό ν΅ν΄ κ° λ°±μλλ "λͺ¨λ₯΄κ² μ΅λλ€. λ€μ μ€μ λ¬Όμ΄λ³΄μΈμ"λΌκ³ λ§ν μ μμ΅λλ€. μ΄ κ²½μ° Djangoλ λ°±μλ μ€ νλμμ True or False
λ₯Ό μ»μ ν νμΈμ μ€μ§νκ³ μ²λ¦¬ λ₯λ ₯ λλΉλ₯Ό μ€μ§ν©λλ€.
μ΄λ κ² νλ©΄ κ° λ°±μλμ λ λ§μ κΆνμ΄ λΆμ¬λ©λλ€. μ΅μ’ λ΅λ³μ μ 곡νκ±°λ λ€λ₯Έ μ¬λμ μ°Έμ‘°ν μ μμ΅λλ€.
@doganmeh Djangoλ tri-state κΆν μμ€ν μ ꡬνν©λλ€(μ΅μ 1.10 μ΄μ). μ΅μ μ True, None λ° PermissionDenied μ¬λ¦¬κΈ°μ λλ€. λμ€μ μννλ©΄ Djangoκ° κ²μ¬λ₯Ό μ€μ§νκ³ Falseλ₯Ό λ°νν©λλ€.
λΉλ©΄ν λ¬Έμ λ Contrib.Auth λ¬Έμ λΌκ³ μκ°ν©λλ€. κ·Έκ²μ΄ 'μ μ κΆν'μ λ€λ£¨λ λ°±μλμ λλ€. λ¬Έμ λ obj=Noneμ΄ μλ has_permμ΄ 'ν μ΄λΈ κΆν'λ§ νμΈνκ³ objκ° μλ has_permμ΄ 'ν κΆν'λ§ νμΈνλ κ°μ κ·μΉμ μ€μ νλ€λ κ²μ λλ€. κ·Έλ€μ κ·Έκ²μ λ³κ²½ν κ² κ°μ§ μμ§λ§ _should_λ λ λ€ νμΈμ μ§μνλλ‘ APIλ₯Ό νμ₯ν μ μμ΄μΌ ν©λλ€.
(μ μ΄λ λλ κ·Έλ€μ΄ λ κ°μ§ λͺ¨λλ₯Ό νμΈνκΈ° μν΄ νλμ μΆκ°ν μ μκΈ°λ₯Ό λ°λλλ€. κ·Έλ€μ μμ€ν μ λͺ λ°±ν κ²°ν¨μ΄ μλ κ² κ°μ΅λλ€.)
'λ λ€ νμΈ' APIμ λν μ μμ 무μμ λκΉ? λ΄κ° μκ°ν μμλ μ΅μ μ kwargμ λλ€.
λλ Permission ν
μ΄λΈμ NullBooleanFieldκ° μλ λͺ
μμ μΌλ‘ tristate μμ€ν
μ λν΄ μ΄μΌκΈ°νκ³ μμμ΅λλ€. μ¬μ€, True
λΆμ‘±(λλ κΆν λΆμ‘±)μ None
λ‘ κ°μ£Όνλ©΄ μΌκ΅μΌλ‘ κ°μ£Όλ μ μμ΅λλ€. μ΄ κ²½μ° λ³΄νΈμκ° μ§μ νμ§ μμ κΆνμ None
λ‘ κ°μ£Όνμ¬ κ²°μ μ μ μμ μμν΄μΌ ν©λλ€. νμ§λ§ μ νμ μ¬μ§κ° μλ€λ©΄ λͺ
μμ μΈ λμμΈμ μ ννκ² μ΅λλ€.
@airstandley λ€μκ³Ό κ°μ΄ user.has_perm
μ kwargλ₯Ό μΆκ°νλ κ²μ μλ―Ένλ€κ³ μκ°ν©λλ€.
def has_perm(self, perm, obj=None, fallback=False)
λμμ΄ λ κ² κ°μμ. fallback=True
μΈ κ²½μ° λ³΄νΈμλ Django λ°±μλλ₯Ό νΈμΆνκ³ μ μμ λ°νν©λλ€. νμ§λ§ μ νμ μ¬μ§κ° μλ€λ©΄ λ΄λΆλ₯Ό κ°λ‘μ±μ§ μκ³ νλ μμν¬μμ μμ°μ€λ½κ² μ²λ¦¬λλ Djangoλ‘μ ν΄λ°±μ μ νΈν©λλ€.
@doganmeh λ§ μ μλͺ»ν΄μ μ£μ‘ν©λλ€. "True, False λ° PermissionDenied λ°μ"μ μ½μ΄μΌ ν©λλ€. μλλ€:
μ΅μ μ True, None λ° PermissionDenied μ¬λ¦¬κΈ°μ λλ€.
νμλ λ΄ λ¨Έλ¦¬μμ λ°νμ μκ°νλ λ°©λ²μ λλ€ ...
λλ λΉμ μ΄ μλ―Ένλ λ°λ₯Ό μλͺ» μ΄ν΄νμ μ μλ€κ³ μκ°ν©λλ€
Djangoκ° tri-state κΆν μμ€ν μ μ νΈνλ€λ©΄ λ μ’μν κ²μ λλ€.
λͺ νν νμλ©΄, μμ€ν μ μ²΄κ° μλλΌ κ΅¬μ²΄μ μΌλ‘ κΆν λͺ¨λΈ ꡬνμ λν΄ λ§μνμ κ²μ λκΉ?
λ΄ μμ μ μΈμ¦ λ°±μλ μμ€ν
μ΄ κ·νκ° μ€λͺ
ν μ νν λ°λ‘ κ°κΈ°λ₯Ό νμ©νλ€λ κ²μ
λλ€(μ μ΄λ has_perm
, has_module_perms
apiμ κ²½μ°). κ°λ¨νμ§ μλλΌλ λͺ
μμ μ
λλ€.
λͺ¨λ λ°±μλλ μ체μ μΌλ‘ κ²°μ μ λ΄λ¦¬κ±°λ(True λλ PermissionDenied λ°ν) κ²°μ μ 체μΈμ λ€μ λ°±μ
μ μμν μ μμ΅λλ€(False λ°ν). μ΄λ μμ€ν
μ체μ νμ§μ΄ μλλΌ κ΅¬νμ λ°λ₯Έ κ²°μ μ
λλ€.
λͺ μμ ObjectPermissionBackendλ λ΄ νλ‘μ νΈμ λ¬Έμ κ° λ μ μμΌλ―λ‘ λͺ μμ μΌλ‘ μ ννμ§ μμ΅λλ€. ("λͺ μμ±"μ λ€λ₯Έ κΆν κ²μ¬ λ°±μλμμ ν΅ν©μ μ΄λ ΅κ² λ§λλλ€.) κ·νμ λ§μ°¬κ°μ§λ‘ λ€λ₯Έ μ¬λλ€λ λͺ μμ λ°©μμ μ νΈν κ²μ΄λΌκ³ μκ°ν©λλ€. λ°λΌμ μ€μ μΌλ‘ 'λͺ νμ±'μ κ°λ κ²μ΄ λμκ² μλ―Έκ° μμ΅λλ€.
@doganmeh
κ·Έλμ kwargμ λν΄.
λ¨Όμ μΈμ¦ λ°±μλ μμ€ν
μ λμμ΄ μλλ λ°©μμ λν΄ λμΌν νμ΄μ§μ μμ§ μλ€λ μ μ λν΄ κ³μ κ±±μ νκ³ μμ΅λλ€. κ·Έλμ λͺ
ννκ² :
λ΄ μ΄ν΄λ λ°±μλκ° ν¨κ» μλνλλ‘ μλνλ€λ κ²μ
λλ€. μ±μ΄ μΈμ¦μ κΆν μμ€ν
(μ: 'μ μ κΆν', κΈ°μ μ μΌλ‘λ 'ν
μ΄λΈ κΆν'μ΄μ§λ§ κ°μ, κ°μ)μ μ¬μ©νλ €λ κ²½μ° AUTH_BACKENDSμ μΈμ¦ ModelBackendλ₯Ό μ€μΉν©λλ€. ν΄λΉ μ±μ΄ 보νΈμμ ObjectPermission μμ€ν
(μ¦, 'ν κΆν')μ μ¬μ©νλ €λ κ²½μ° AUTH_BACKENDSμ μλ 보νΈμμ ObjectPermissionBackendκ° μλλλ€.
ModelBackendλ μ μ κΆνμ μ²λ¦¬ν©λλ€.
ObjectPermissionBackendλ κ°μ²΄ κΆνμ μ²λ¦¬ν©λλ€.
μ¬μ©μμκ² κ°μ²΄ κΆνλ§ μλ κ²½μ° ModelBackendλ has_perm
μ λν΄ Trueλ₯Ό λ°ννμ§ μμ΅λλ€. μ¬μ©μμκ² μ μ κΆνλ§ μλ κ²½μ° ObjectPermissionBackendλ has_perm
μ λν΄ Trueλ₯Ό λ°ννμ§ μμ΅λλ€. λ κ²½μ° λͺ¨λ user.has_perm(perm, obj)μ λν νΈμΆμ μ¬μ ν ββtrueλ₯Ό λ°νν΄μΌ ν©λλ€. μ¬μ©μλ μ€μΉλ λ°±μλ μ€ _one_μ λν κΆνμ΄ μκΈ° λλ¬Έμ
λλ€. (μ΄ κ³μ μμ ModelBackendκ° μ€ν¨νμ¬ λ¬Έμ κ° λ°μν κ²μ
λλ€.)
μ’μ, κ·Έλμ λͺ¨λ κ²μ΄ μ£Όμ΄μ‘λ€.
νΈνμ±μ΄ λ¬Έμ κ° λμ§ μλ μ΄μμ μΈ μΈμμμλ μ λ contrib.authμ ModelBackendλ₯Ό κ°λ¨ν λ³κ²½νλ κ²μ μ νΈν©λλ€. ModelBackend.has_perm(user_obj, perm, obj=None)
λ μ¬μ©μκ° permμμ μ§μ ν 'μ μ κΆν'μ κ°μ§κ³ μμΌλ©΄ Trueλ₯Ό λ°νν΄μΌ ν©λλ€. objκ° NoneμΈμ§ μ¬λΆμ κ΄κ³μμ΄.
κ·Έλ¬λ νΈνμ±μ΄ λ¬Έμ μ΄λ―λ‘ λ¬Έμ μ λν ν΄κ²°μ± μ΄ μλμ§ λ¬»μ΅λλ€.
λ΄κ° μκ°ν μ μλ μ μΌν _backwards compatible_ μ루μ μ APIμ kwargλ₯Ό μΆκ°νκ±°λ AUTH μ€μ μ μΆκ°νλ κ²μ λλ€.
κ·Έλμ μ½°λ₯΄κ·Έ:
obj_shortcut
λΌκ³ λΆλ₯΄κ² μ΅λλ€. κ·Έκ² μ κ° μκ°ν΄λΌ μ μλ μ΅μ μ λ°©λ²μ΄κΈ° λλ¬Έμ
λλ€. object_shortcut
λ κΈ°λ³Έμ μΌλ‘ Trueλ‘ μ€μ λ©λλ€. object_shortcut
κ° Trueμ΄λ©΄ λ°±μλλ ModelBackendκ° μ§κΈ νλ κ²μ²λΌ λμν΄μΌ ν©λλ€. objκ° Noneμ΄λ©΄ 'ν
μ΄λΈ/μ μ' κΆνμ _λ§_ νμΈν΄μΌ νκ³ , κ·Έλ μ§ μμΌλ©΄ 'ν/κ°μ²΄' κΆνμ _λ§__ νμΈν΄μΌ ν©λλ€. κ·Έλ¬λ object_shortcut
κ° Falseμ΄λ©΄ λ°±μλλ λ λ€ μ νΈνλ λλ‘ λμν΄μΌ ν©λλ€. μ¦, κ°μ²΄κ° Noneμ΄ μλ λ μ μ λ° κ°μ²΄ κΆν _λͺ¨λ_λ₯Ό νμΈν©λλ€. κ·Έλ° λ€μ Guardianκ³Ό κ°μ μΆκ° κΈ°λ₯μ νμ object_shortcut=False
λ₯Ό κΈ°λ³Έκ°μΌλ‘ μ¬μ©νμ¬ has_perm
λ©μλλ‘ λ―Ήμ€μΈμ μ 곡ν μ μμ΅λλ€. permμ΄ λνλ΄λ κΆνμ΄ μ¬μ©μμκ² ν λΉλ κ²½μ° user.has_perm(perm, obj, object_shortcut=False)
λ μ¬λ°λ₯΄κ² Trueλ₯Ό λ°ννμ§λ§ user.has_perm(perm, obj)
μ λν λ κ±°μ νΈμΆμ κ³μ Falseλ₯Ό λ°νν©λλ€.
μ€μ μ λμΌν κ²°κ³Όλ₯Ό κ°μ§λ§ κΈ°λ³Έμ μΌλ‘ ModelBackend._get_permissions
λ‘ μ νλ©λλ€.
if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
return set()
λ€μκ³Ό κ°μ΄ λ κ²μ λλ€.
if not user_obj.is_active or user_obj.is_anonymous or (obj is not None and legacy_behaviour_setting_is _on):
return set()
μ΄λ κ²μ΄ λ λμμ§ νμ€νμ§ μμ΅λλ€. λλ μ€μ μ΄ λ κΉλνλ€κ³ μκ°νμ§λ§ Django κ°λ°μκ° κ·Έκ²μ κ²°μ ν μκ²©μ΄ λ μμ κ²μ΄λΌκ³ νμ ν©λλ€.
μμ μ λ¬Έμ λ₯Ό κ³ μΉ μ μλ€λ κ²μ΄κ³ , λλ κ·Έ λ¬Έμ κ° Guardianμ΄ μλλΌ Django λ²κ·ΈλΌκ³ κ΅³κ² λ―Ώμ΅λλ€.
@airstandley λ§μ΅λλ€. False
λλ None
λ μ€μνμ§ μμ΅λλ€. λ λ€ λ΄κ° λͺ¨λ₯Έλ€λ λ»μ
λλ€. κ²°κ΅ μ무λ λͺ¨λ₯΄λ©΄ νκ°κ° λμ§ μμ΅λλ€.
λλ μΌλ°μ μΌλ‘ λΉμ κ³Ό κ°μ νμ΄μ§μ μμ§λ§ djangoκ° λ°±μλκ° μ΄λ€ μμΌλ‘λ λμνλλ‘ κ°μ νλ κ²μ λμ¨ν κ²°ν©μ±μ μ νμν€λ κ²μ²λΌ 보μ λλ€. κ° λ°±μλκ° μμ μ μλ£νλ λ° νμν μ 보λ₯Ό μ»μ μ μλλ‘ νλ λ©μ»€λμ¦μ΄ μμ΄μΌ νλ€κ³ μκ°ν©λλ€. λλ ν€μλ μΈμμ λν΄ λΉμ κ³Ό ν¨κ»νμ§λ§ μ΄λ€ μ μΌλ‘λ κ°μνμ§λ μμ΅λλ€.
μ΄ λνλ μκ° λλΉμ²λΌ 보μ΄μ§λ§ 보νΈμμκ² νλ½μ΄ μλ κ²μ κ±°λΆκ° μλλΌ μ 보 λΆμ‘±μΌ λΏμμ μ€μ€λ‘ λͺ νν νλ λ° λμμ΄ λμμ΅λλ€.
μ΄μ¨λ λλ ν 리νμ€νΈ #546μ νλ€. κ·Έκ²μ νμΈνκ³ λΉμ μ μκ°μ μλ €μ£Όμμμ€.
django: https://code.djangoproject.com/ticket/29012 λ‘ ν°μΌμ λ§λ€μλλ° κ·Έλ€μ΄ λλΌκ³ ν μ§ κΆκΈν©λλ€.
djangoμ λ€λ₯Έ ν°μΌμ΄ μμλ κ² κ°μ΅λλ€: https://code.djangoproject.com/ticket/20218
λλ λ΄ κ²μ λ«μλ€.
@doganmeh
λλ λΉμ μ΄ #546μΌλ‘ ν₯νλ λ°©ν₯μ μ’μν©λλ€. λμμ΄ λλ€λ©΄ μ΄λ² μ£Όλ§μ λλ¨Έμ§ μ λμ μ΄ν΄λ³΄κ³ μ΄λ¬ν λ체μ λν λͺ κ°μ§ ν
μ€νΈλ₯Ό μμ±ν΄μΌ ν©λλ€.
μ μ μ. νΉμ λ°©μμΌλ‘ λμνλλ‘ "Django forcing backends"μ λν κ·νμ μ견μ μ λ₯Ό νΌλμ€λ½κ² νμ§λ§ λν μ μκ² μκ°μ μ£Όμμ΅λλ€. λ°±μλλ μνλ λλ‘ μλν μ μμ΅λλ€. Guardianμ ObjectPermissionBackendμ λν λμ μ΄κΈ° μ°λ €λ μ΄κ²μ΄ Authμ ModelBackendμ ν¨κ» μ€νλλλ‘ μ€κ³λμμμ μ μνλ λ¬Έμμμ λΉλ‘―λ©λλ€. Guardianμ ModelBackendμ ν¨κ» μλνλλ‘ μ€κ³λ λ°±μλμ λ¨λ
μΌλ‘ μλνλλ‘ μ€κ³λ μ¬λ¬ λ°±μλλ₯Ό μ 곡ν μ μμ΅λλ€. (κ°λμΈμ UserObjectPermission/GroupObjectPermission ν
μ΄λΈλ§ νμΈνλ IE, λ€λ₯Έ νλλ UserObjectPermission/GroupObjectPermission ν
μ΄λΈκ³Ό Authμ κΆν ν
μ΄λΈμ λͺ¨λ νμΈν©λλ€.)
κ°μΈμ μΌλ‘ λλ μ€μ κ³Ό kwargsκ° μλ νμ¬ μ κ·Ό λ°©μμ μ νΈν©λλ€. λ€μ€ λ°±μλ μ κ·Ό λ°©μμ μ£Όμ λ¨μ μ λ°λ‘ κ°κΈ° λ° νΈμ κΈ°λ₯μ΄ μ΄λ»κ² μλν΄μΌ νλμ§κ° λΆλΆλͺ
ν΄μ§λ€λ κ²μ
λλ€.
Django dev λ©μΌλ§ 리μ€νΈμ λν κ²μλ¬Όμ 보μμ΅λλ€. λλ κ·Έλ€μ΄ κ·Έκ²μ λ°μλ€μ΄κ±°λ μ립ν μ μλ λ°©μμΌλ‘ νλμ λ°κΎΈλ λ° λμνκΈ°λ₯Ό λ°λλλ€. APIμ λν νμ¬ μ ν μ¬νμ ν¬λ°ν©λλ€.
κ±°κΈ°μ μ§μν μ μμ΅λκΉ? π
Windows 10μ© λ©μΌμμ 보λ
보λΈμ¬λ: μμ΄μ€ν λ€λ¦¬
λ³΄λΈ λ μ§: 2018λ
1μ 12μΌ κΈμμΌ μ€ν 12:06
λ°λ μ¬λ: django-guardian/django-guardian
μ°Έμ‘°: Mehmet Dogan; μΈκΈνλ€
μ λͺ©: Re: [django-guardian/django-guardian] user.has_perm("perm", obj)μ΄ μκΈ°μΉ μκ² μλν©λλ€(#49).
Django dev λ©μΌλ§ 리μ€νΈμ λν κ²μλ¬Όμ 보μμ΅λλ€. λλ κ·Έλ€μ΄ κ·Έκ²μ λ°μλ€μ΄κ±°λ μ립ν μ μλ λ°©μμΌλ‘ νλμ λ°κΎΈλ λ° λμνκΈ°λ₯Ό λ°λλλ€. APIμ λν νμ¬ μ ν μ¬νμ ν¬λ°ν©λλ€.
β
λΉμ μ΄ μΈκΈλμκΈ° λλ¬Έμ μ΄κ²μ λ°λ κ²μ
λλ€.
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ±°λ GitHubμμ 보거λ μ€λ λλ₯Ό μμκ±°νμΈμ.
μ½ μΌμ£ΌμΌ λμ μ΄ λ¬Έμ λ₯Ό μ²λ¦¬ν ν, κ° λ°±μλλ Guardianμ λν κ°μ²΄ κΆνμ΄λΌλ ν κ°μ§λ§ μνν΄μΌ νλ€λ κ²μ λ νκ³ νκ² λ―Ώκ² λμμ΅λλ€. κ·Έλ κ² νλ €λ©΄ Djangoλ obj
λ₯Ό λ λ©μ§κ² λ€λ£¨μ΄μΌ ν©λλ€.
λ΄κ° Djangoμ λ³΄λΈ ν¨μΉκ° μμ΅λλ€: https://github.com/django/django/pull/9581 (κ°λ₯νλ©΄ λκΈμ λ¬μμ£ΌμΈμ). κ·Έκ²μ λ§λλ κ²λ€, μ°λ¦¬λ Guardianμ μλ λͺ¨λ κ³³μμ λͺ¨λΈ κΆν κ²μμ μ 리νκ³ κΈ°λ³Έ λ°±μλλ₯Ό νΈμΆνκΈ°λ§ νλ©΄ λ©λλ€.
κ°μ₯ μ μ©ν λκΈ
_AUTHENTICATION_BACKENDS_ μ€μ μ λΆμ¬λ£μ μ μμ΅λκΉ?
μ΄λ―Έ Django λ¬Έμλ₯Ό μ½μμΌλ―λ‘ μ§μ λ λ°±μλμ μμκ° μ€μνλ€λ κ²μ μκ³ μμ΅λλ€.
κ·νμ μμ© νλ‘κ·Έλ¨μ λ€μκ³Ό κ°μ κ²μ΄ μλ€κ³ κ°μ ν©λλ€.
μλλ©΄ μ΄κ±°:
κΈ°λ³Έ λ°±μλκ° λ¨Όμ μ§μ λμλμ§ νμΈνμμμ€.
μ΄κ²μ΄ λ¬Έμ μΈμ§ νμΈν μ μμ΅λκΉ? κ·Έλ μ§ μμ κ²½μ° μ 보λ₯Ό λ μΆκ°νμμμ€(λ€λ₯Έ λ°±μλλ μ¬μ©νκ±°λ _User.has_perm_ λ©μλλ₯Ό μ¬μ©νλ λ€λ₯Έ μ± μμμ΄ ν¨μΉ?).