tastypie/authorization.py
(2016 λ
1/4 μμ λ§μ€ν° λΈλμΉ μ½ 133 κ°)λ₯Ό 보면 κΈ°λ³Έκ° μΈ read_list
λ° read_details
user.has_perm()
κ²μ¬λ₯Ό μ°νν©λλ€. μ΄λ λ§€μ° μμ νμ§ μμΌλ©° μλͺ»λ κΈ°λ³Έκ°μ
λλ€.
Djangoμ κ΄λ¦¬μ κΈ°λ³Έκ°μ νμ μ½λ§€μ΄μ§ μμ΅λλ€. κ·Έλμ μ΄λ»κ² μλͺ» ν΄μλμλμ§ μ μμμμ΅λλ€.
https://docs.djangoproject.com/es/1.9/topics/auth/default/#permissions -and-authorization
The Django admin site uses permissions as follows:
* ...
* Access to view the change list, view the βchangeβ form and change an object is limited to users with the βchangeβ permission for that type of object.
κΈ°λ³Έμ μΌλ‘ "change_xyz"λ "μ½κΈ°"λ° "μ λ°μ΄νΈ"λͺ¨λμ λν κΆν μ½λμ λλ€. λ λμ κΈ°λ³Έκ°μ Djangoμ κ΄λ¦¬μλ₯Ό λ°λ₯΄λ κ²μ λλ€.
diff --git a/tastypie/authorization.py b/tastypie/authorization.py
index 1d6f5aa..44b2d56 100644
--- a/tastypie/authorization.py
+++ b/tastypie/authorization.py
@@ -151,22 +151,14 @@ class DjangoAuthorization(Authorization):
return model_klass
def read_list(self, object_list, bundle):
- klass = self.base_checks(bundle.request, object_list.model)
-
- if klass is False:
- return []
+ # By default, follows `ModelAdmin` "convention" to use `app.change_model`
+ # `django.contrib.auth.models.Permission` for both viewing and updating.
+ # https://docs.djangoproject.com/es/1.9/topics/auth/default/#permissions-and-authorization
- # GET-style methods are always allowed.
- return object_list
+ return self.update_list(object_list, bundle)
def read_detail(self, object_list, bundle):
- klass = self.base_checks(bundle.request, bundle.obj.__class__)
-
- if klass is False:
- raise Unauthorized("You are not allowed to access that resource.")
-
- # GET-style methods are always allowed.
- return True
+ return self.update_detail(object_list, bundle)
λλ μ΄κ²μ΄ μ΄λ―Έ ν©λ³λμ΄ κ°μ¬νμ§λ§ μ¬μ ν λ¬Έμ κ° μμ΅λλ€. μ μμ²μ μ΄κΈ° μ μ λ€μκ³Ό κ°μ λ¬Έμ κ° μμ΅λλ€.
μ΄ λ³κ²½ μ¬νμ λΆννλ κΈ°μ‘΄ μ½λλ₯Ό μμμμΌ μ΄μ λ²μ κ³Ό νΈνλμ§ μμ΅λλ€ (μ΄μ μλ λͺ¨λ GET μμ²μ΄ DjangoAuthorizationμ ν΅κ³Ό νμ). μ½λλ₯Ό μμ νκΈ°μν μ μΌν λ κ°μ§ μ΅μ μ λͺ¨λ μ¬μ©μμκ² 'λ³κ²½'κΆνμ λΆμ¬νκ±°λ (λμ) μ½κΈ° μμ μ μ¬μ©μ μ§μ ꡬνμ μν΄ DjangoAuthorizationμ νμ ν΄λμ€λ‘ λ§λλ κ²μ λλ€ (μ μ¬μ μΌλ‘ λ§μ μμ ). μ΄κ²μ μλ λ κ²μ΄ μμ΅λκΉ?
μ₯κ³ κ΄λ¦¬μ 컨ν
μ€νΈμμμ΄ μ΄μ μ λν΄ κ°μ¬νμ§λ§ API 컨ν
μ€νΈμμ 'λ³κ²½'μ ν΄λΉνλ κ²μΌλ‘ 'μ½κΈ°'λ₯Ό μ€μ νλ κ²μ΄ μμλλ λμμ΄ μλκΈ° λλ¬Έμ ν©λ¦¬μ μΈ κΈ°λ³Έ κ°μ μ΄λΌκ³ μκ°ν©λλ€. κ²°κ΅ GETμ΄ DjangoAuthorizationκ³Ό ν¨κ» νμ© λ λ©μλ μΈ κ²½μ° μ¬μ©μμκ² change
κΆνμ΄ μλ€λ μ¬μ€μ λ°λΌ μ‘μΈμ€λ₯Ό κ±°λΆνλ μ΄μ λ 무μμ
λκΉ?
λλ κ·Έκ° λ€μκ³Ό κ°μ λ체 ꡬνμ μ μν©λλ€.
_for read_detail_
view
κΆνμ΄μλ κ²½μ° νμΈ (= νμν μ¬μ©μλ₯Όμν κ°μ )view
κΆνμ΄μλ κ²½μ° νμ νμ© (= μ΄μ λ²μ κ³Ό νΈν λ¨)_for read_list_
list
κΆνμ΄μλ κ²½μ° νμΈ (= νμν μ¬μ©μλ₯Όμν κ°μ )list
κΆνμ΄μλ κ²½μ° νμ νμ© (= μ΄μ λ²μ κ³Ό νΈν λ¨)μ΄ λ°©λ²μΌλ‘ tastypieλ Djangoμ κΆν κΈ°λ³Έκ°κ³Ό νΈνλλ κΈ°λ³Έκ°μ μΆκ°νλ λμμ DjangoAuthorizationμ μ¬μ©μ μ μ ꡬνμ μμ±νλ κ²λ³΄λ€ νμν μ¬λλ€μκ²λ³΄κΈ° λ° λͺ©λ‘ κΆνμ μΆκ°νμ¬ κ°μ ν μμλ μ¬μ΄ κ²½λ‘λ₯Ό μ 곡ν©λλ€.
μ΅μν κΈ°λ³Έ κΆνμ μ§μ νλ λ°©λ²μ΄ μμ΄μΌν©λλ€.
DjangoAuthorization(read_permission='view', # applies to both list, detail if not spec'd
read_list_permission='view', # list only
read_detail_permission='view') # detail only
# while we're at it, why not add the other permissions too
DjangoAuthorization(change_permission='change',
delete_permission='delete',
add_permission='add',
# ... add options as per above for each
# <action>_<level> permission where
# action is `change,delete,add,read`, level is `list,detail`)
@SeanHayes κ° κ²°μ νλ μ¬λμ΄ λ κ²μ λλ€.
λ΄ μ견μ κΈ°λ³Έμ μΌλ‘ μ½κΈ°λ₯Ό νμ©νλ κ²μ΄ 보μ λ¬Έμ λΌκ³ μκ°ν©λλ€. νλ‘λμ μ λ§€μ° κ°κΉμμ§κΈ° μ κΉμ§λ μ ν μμνμ§ λͺ»νμ΅λλ€. μ΄ λ§₯λ½μμ μ΄μ λ²μ κ³Όμ νΈνμ±μ κΉ¨λ κ²μ΄ νμνλ€κ³ μκ°ν©λλ€.
κ·νμ μ μμ λ°λΌ κΈ°μ‘΄ μ½λμ λν λ§€κ° λ³μ μ λ¬μ DjangoAuthorization
λ‘ λ³κ²½ν΄μΌνλ κ² κ°μ΅λλ€.μ΄ κ²½μ° ν΄λμ€λ₯Ό λ€λ₯Έ κ²μΌλ‘ νΈμΆνλ κ²μ΄ λ λͺ
ννλ€κ³ μκ°ν©λλ€.
read_permission='view'
μΌμ΄μ€λ₯Ό κ³ λ €νμμμ€. μ¬κΈ°μ μ νν νμν κ²μ΄μμ μ μμ΅λλ€. λλ κ·Έκ²μ΄ μ λ μ΅μ μΈμ§ λͺ¨λ₯΄κ² λ€.
class ModifiedDjangoAuthorization(DjangoAuthorization):
READ_PERM_CODE = 'view'
λ€λ₯Έ κ²μ λ³κ²½νλ €λ©΄ λ©μλλ₯Ό μ¬μ μνμμμ€. λ³κ²½μ μ€μ λ‘ λ§€μ° μ½κ² ν μ μλλ‘ μ€κ³λμμ΅λλ€.
class ModifiedDjangoAuthorization(DjangoAuthorization):
def delete_list(self, object_list, bundle):
return self.perm_list_checks(bundle.request, 'del', object_list)
def delete_detail(self, object_list, bundle):
return self.perm_obj_checks(bundle.request, 'del', bundle.obj)
λ³κ²½ μ¬νμ μμ μ μΌλμλκ³ μ½κ² λ§λ€μμ΅λλ€. init λ§€κ° λ³μλ‘ μνν΄μΌνλ€κ³ μκ°ν νμλ μμ΅λλ€.
κΈ°λ³Έμ μΌλ‘ μ½κΈ°λ₯Ό νμ©νλ κ²μ΄ 보μ λ¬Έμ λΌκ³ μκ°ν©λλ€.
λλ μλ λ¬Έμ μ μλμ μλ¬Έμ μ κΈ°νλ κ²μ΄ μλλλ€. λ³ν© λ ꡬνμ΄ μ¬λλ€μ κΈ°μ‘΄ μ½λ λ° κ°μ μ 무λ λ¨λ¦¬λ κ²κ³Ό λλ릴 μμλ ν¨μ¨μ μΈ μ΅μ μ΄ μλ€λ μ μ μ§μ νμμμ€.
κ·νμ μ μμ κΈ°μ‘΄ μ½λμ λν DjangoAuthorizationμ λν λ§€κ° λ³μ μ λ¬μ λ³κ²½ ν΄μΌνλ κ²μ²λΌ 보μ λλ€.
μ κ° μ μν μ루μ μ λ€μ μ΄ν΄λ³΄λ©΄ μ κ° μΉνΈνλ κ²μ μ¬λλ€μκ² μμ νκ³ μ΄μ λ²μ κ³Ό νΈνλλ κΈ°λ³Έ μ΅μ μ μ 곡νλ κ²μ λλ€. μ΄ κ²½μ° μ¬μ©μ μ½λλ₯Ό λ³κ²½ν νμκ° μμ΅λλ€.
μ΄ λ§₯λ½μμ μ΄μ λ²μ κ³Όμ νΈνμ±μ κΉ¨λ κ²μ΄ νμνλ€κ³ μκ°ν©λλ€.
λμνμ§ μμ΅λλ€. νμ¬ λ³ν© λ λ³κ²½μ μ΄μ λ²μ κ³Όμ νΈνμ±μ κΉ¨λ¨λ¦΄λΏλ§ μλλΌ λͺ λ°±ν λ°©λ² (νμ¬ κ΅¬νμ μν΄ μμ λ¨)μ΄ GETμ νμ©ν΄μΌνλ λͺ¨λ μ¬μ©μμκ² λ³κ²½ κΆνμ ν λΉνλ κ²μ΄λ―λ‘ ν¨μ¬ λ ν° μ μ¬μ 보μ λ¬Έμ λ₯Ό μΌκΈ°ν©λλ€.
μμ§ν, μ½κΈ° μμ
μ λν change
κΆνμ΄ λ³΄μμ ν₯μμν€λ λμμμ΄ κΆνμ΄ PUTλ νμ©νλ λ°©λ²μ λ³΄μ§ λͺ»νμ΅λλ€. λ€λ₯Έ μμ
μ λν κΆνμ νΌν©νλ κ²μ μ’μ μ νμ΄ μλ κ² κ°μ΅λλ€.
μνκΉκ²λ μ μ λ ModifiedDjangoAuthorization
μ μ€μ λ‘ view
κΆνμ λͺ¨λΈμ μΆκ°νμ§ μλ ν νΈλ¦μ μννμ§ μμΌλ―λ‘ λ€μ μ΄μ λ²μ κ³Όμ νΈνμ±μ΄ κΉ¨μ§λλ€. μ΅μν μ½λ λ³κ²½μ΄ νμνλ―λ‘ μ΄μ λ²μ κ³Όμ νΈνμ±μ κΉ¨κ³ μ¬μ©μκ° μ½λ κΈ°λ°μ λ€μ μμ
ν΄μΌν©λλ€.
λ¬Όλ‘ μ¬μ μλ νμ νΉμ μꡬ μ¬νμ λ¬μ±νλ μ΅μ μ΄μ§λ§ tastypieμ μΌλ°μ μΈ μμ΄λμ΄λ μ¬μ©μ μ§μ μ½λλ₯Ό μΆκ° ν νμκ°μλ ν©λ¦¬μ μ΄κ³ μμ ν κΈ°λ³Έκ°μ μ 곡νλ κ²μ΄λΌκ³ μκ°ν©λλ€.
μ컨λ λ λμ ꡬνμ μν΄μ΄ λ³κ²½ μ¬νμ λλλ € μΌνλ€κ³ μκ°ν©λλ€.
change
κΆνμ Django μ체μμ μ 곡λ©λλ€. Djangoμ κΈ°λ³Έκ°μ΄λ©° Django Admin μ±μ΄ μ€μ λλ λ°©μμ
λλ€. view
μ΅μ
μ κ·Έλ μ§ μμ΅λλ€. μ λ κ°μΈμ μΌλ‘ read
λ‘ μ΄λ¦μ μ§μ νμ΅λλ€.
model
λ₯Ό νμΈνμ¬ λ¬΄μ¨ λ»μΈμ§ μ λͺ¨λ₯΄κ² μ΅λλ€. _meta νμΈμ μλ―Ένλ κ²½μ° λΆμμ ν μ μμ΅λλ€. λΉμ μ΄ dbλ₯Ό μΉλ κ²μ μλ―Ένλ€λ©΄, λλ κ·Έκ²μ΄ λΆνμνκ² λΉμΈλ€λ κ²μ μμμ΅λλ€.
λ΄ μ νΈμ λ°λΌ, λΉμ μ΄ μ μν κ²μ κΈ°λ³Έ μΈμ¦μ λν΄ "λ무 λ§μ λ§λ²"μͺ½μμλ κ² κ°μ΅λλ€. μ½κ² μ¬μ μ ν μμλ μμ ν κΈ°λ³Έκ° λ§ μμΌλ©΄ μΆ©λΆ ν΄ λ³΄μ λλ€. κ·Έλ¬λ κ·Έκ²μ λ¨μ§ λ΄ μ견μ λλ€.
λ³κ²½ μ¬νμ https://github.com/django-tastypie/django-tastypie/blob/master/docs/release_notes/v0.13.2.rst μ λ¬Έμνλμμ΅λλ€.
μμ§ν,μ΄ κΆνμ΄ PUTλ νμ©νλ λμμ μ½κΈ° μμ μ λν λ³κ²½ κΆνμ΄ λ³΄μμ ν₯μμν€λ λ°©λ²μ μμ§ λͺ»ν©λλ€. λ€λ₯Έ μμ μ λν κΆνμ νΌν©νλ κ²μ μ’μ μ νμ΄ μλ κ² κ°μ΅λλ€.
μ°λ¦¬λ μ¬μ©μκ° λ¬΄μΈκ°λ₯Ό λ³κ²½ν μ μλ€λ©΄ κ·Έκ²μ μ½μ μ μλ€λ κ²μ μλλ€. κ·Έκ²μ΄ Django κ΄λ¦¬μκ°νλ λ°©μμ λλ€.
μ΄ λ²μ μ κ°λ°μκ° μμ μ΄νλ μΌμ λν΄ μκ°νκ²νκΈ° λλ¬Έμ λ μμ ν©λλ€. μμ μ "μ½κΈ°"κΆνμ κ°λ°νλ λμ κ°λ°μκ° "μ½κΈ°"κΆν λ§ κ°μ ΈμΌ ν λ μλμ μΌλ‘ λͺ¨λ μ¬λμκ² "λ³κ²½"κΆνμ λΆμ¬νκΈ°λ‘ μ ννλ κ²μ΄ λ¬Έμ μ λλ€. μ λ λ€λ₯Έ κ°λ°μλ€μ΄ μλμ μΌλ‘ μ΄λ¦¬μμ μΌμνλ κ²μ λ§μ μ μμ΅λλ€. μ λ Tastypieκ° μ΄λ¦¬μμ μΌμνλ κ²μ λ§κΈ° μν΄ μ¬κΈ°μ μμ΅λλ€. μ΄ λ³κ²½μ μμ μ DjangoAuthorizationμ μ¬μ©νλ λͺ¨λ 리μμ€μ λν μ μ μ½κΈ° κΆνμ λ°©μ§νλ κ²μ΄ μμ΅λλ€. μλ‘μ΄ λμμ κ°λ°μκ° Django κ΄λ¦¬μμμ κ²½ννλ κ²κ³Ό μΌμΉν©λλ€.
μ΄μ λμμ μνλ κ²½μ° :
read_list and
read_detail` λ©μλλ₯Ό μ¬μ μν©λλ€.λ¬Έμκ° κ°μ λ μ μλ€κ³ μκ°λλ©΄ μμ λ‘κ² PRμ μ μΆνμμμ€.
κ·νμ μ견μ κ°μ¬λ립λλ€. λ¬Έμμ λν λ§ν¬λ₯Ό μ£Όμ μ κ°μ¬ν©λλ€. μΆ©λΆν 곡ννκ², κ·Έκ²μ λμΉ κ²μ λν΄ λμκ² μκ°ν©λλ€ (λ¬Έμ λ v0.13.4μ ν λΉλμμ§λ§ λ¬Έμλ v0.13.2μ μμ΅λλ€).
λ΄ povμμ λͺ κ°μ§ λ§μ§λ§ λ°μΈμνκ² μ΅λλ€.
μ°λ¦¬λ μ¬μ©μκ° λ¬΄μΈκ°λ₯Ό λ³κ²½ν μ μλ€λ©΄ κ·Έκ²μ μ½μ μ μλ€λ κ²μ μλλ€. κ·Έκ²μ΄ Django κ΄λ¦¬μκ°νλ λ°©μμ λλ€.
Django κ΄λ¦¬μλ change
κΆνμ μ¬μ©ν©λλ€. _changing_ κ°μ²΄μ λν κ΄λ¦¬μ μΈν°νμ΄μ€ _is_μ΄κΈ° λλ¬Έμ
λλ€. κ±°κΈ°μμ μλ―Έκ° μμ΅λλ€. REST APIμ λν GET μμ²μ μ μμ λ°λΌ _reading / viewing_μ
λλ€. λλΆλΆμ κ°λ°μλ DjangoAuthorizationμ΄ λ³κ²½ κΆνμ΄ μμ΄μ μ½κΈ°λ₯Ό κ±°λΆ ν κ²μ΄λΌκ³ κΈ°λνμ§ μμ΅λλ€.
μ΄ λ²μ μ κ°λ°μκ° μμ μ΄νλ μΌμ λν΄ μκ°νκ²νκΈ° λλ¬Έμ λ μμ ν©λλ€.
tastypieμ κ΄κ³ κΈ°λ₯ μ€ νλλ _ ν©λ¦¬μ μΈ κΈ°λ³Έκ° _μ μ 곡νλ κ²μ λλ€. APIμ GET (μ μ : μ½κΈ°) λ° PUT (λ³κ²½) λ©μλκ° λͺ¨λ μλμ λͺ©μ μμ μλ‘ λ€λ₯Έ μμ μ΄λ―λ‘ λ€λ₯Έ κΆνλ νμνλ€κ³ κ°μ νλ κ²μ΄ ν©λ¦¬μ μ΄μ§ μμ΅λκΉ?
κ·μ€ν μΆκ°λΌκ³ μκ°νλ€λ©΄ μ κ° μ΄ λ΄μ©μ λ°λΌ PRμ κΈ°κΊΌμ΄ κΈ°κΊΌμ΄ λλ¦¬κ² μ΅λλ€.
λ³κ²½ κΆνμ Django μ체μμ μ 곡λ©λλ€. (...) μ΅μ λ³΄κΈ°κ° μλλλ€.
Djangoμμ view permission
λ₯Ό μΆκ°νκΈ° μν΄ λ³΄λ₯μ€μΈ PRμ΄ μμΌλ―λ‘ λ·°λ₯Ό μ¬μ©νμ΅λλ€.
κΈ°λ³Έμ μΌλ‘ νΌλΈλ¦ / κΈλ‘λ² μ½κΈ° μμ μ νμ©νμ§ μμ΅λλ€. κ·Έκ²μ μ΅μ’ μ λλ€. κ·Έλ¦¬κ³ μ°λ¦¬λ νμ¬ κ·Έλ κ² ν μμλ νμ€μ μΈ λ°©λ²μ΄ μλλ° κ°λ°μλ€μ΄ μ΄λ»κ² κΆνμ μ€μ νλμ§ μΆμΈ‘νμ§ μμ κ²μ λλ€. μ°λ¦¬λ κ·Έκ²μ "μ½κΈ°"λλ "보기"λΌκ³ λΆλ₯Όμ§μ‘°μ°¨ νμ€νμ§ μμΌλ©°, μ¬κΈ°μ μ€λ λ§μ μ¬λλ€μ΄ "λλ μ΄λ° μμΌλ‘νλ€"λλ "μλ‘μ΄ Django 릴리μ€μμ κ·Έκ²μ λ€λ₯Έ κ²μΌλ‘ λΆλ₯΄λ κ²μ μνμ§ μμ΅λλ€." .
Djangoκ° μ¦μ μ½κΈ° /보기 κΆνμ μ§μνλ κ²½μ° ν΄λΉ κΆνμΌλ‘ μ νν©λλ€. μ§κΈμ κ°λ°μκ° κΆνμ μ²λ¦¬νλ μ¬μ©μ μ§μ λ°©μμ μ²λ¦¬νκΈ° μν΄ μ¬μ©μ μ§μ μ½λλ₯Ό μμ±ν΄μΌν©λλ€.
μ΄ λ¬Έμ κ° μ’ κ²° λ κ²μ μκ³ μμ§λ§μ΄ λ³κ²½μΌλ‘ μΈν΄ κΈ°μ‘΄ νλ‘μ νΈλ₯Ό 0.13.xλ‘ λ§μ΄κ·Έλ μ΄μ νλ κ²μ΄ κΈ°λ³Έμ μΌλ‘ μ°¨λ¨λμλ€κ³ λ§νκ³ μΆμ΅λλ€.
@miraculixx λ¨μν λ°μ΄ν°λ₯Όλ³΄κΈ° μν΄ λ³κ²½ κΆνμ μꡬνλ κ²μ΄ μ½κ° λ―ΈμΉ μ§μ΄λΌλ μ¬μ€κ³Ό κ΄λ ¨νμ¬ κ·νκ° μμ ν μ³λ€κ³ μκ°ν©λλ€. λλ μ°λ¦¬κ° μ΄λ»κ² λ μ₯κ³ λ₯Ό λΉλ ν μ μλ€κ³ μκ°ν©λλ€. κ·Έλλ λ·° κΆνμ κ°λ μ΄ μμ΅λλ€. CRUDμ READ λΆλΆ).
μμ°μ μ€λ¨νλ λ³κ²½μ ν λ μ΅μν λ²μ κ΄λ¦¬μ λ°μ ν μ μμ΅λκΉ?
Tastypieμ x.y.z
λ²μ κ΄λ¦¬λ λλΆλΆμ μ¬λλ€μ΄ κΈ°λνλ κ²κ³Ό λ§€μ° μ μ¬ν©λλ€. μΌλ°μ μΌλ‘ λ€μκ³Ό κ°μ΅λλ€.
λ²μ λ²νΈ MAJOR.MINOR.PATCHκ° μ£Όμ΄μ§λ©΄ λ€μμ μ¦κ°μν΅λλ€.
..
μ΄μ λ²μ κ³Ό νΈνλλ λ²κ·Έ μμ μ ν λ ν¨μΉ λ²μ .
μλ‘μ΄ νλ‘λμ λ°°ν¬ μ€μ μ΄κ²μ μΆμ νλ λ° λ§€μ° λΆνΈν μκ°μ 보λμ΅λλ€.
κ°μ₯ μ μ©ν λκΈ
μμ°μ μ€λ¨νλ λ³κ²½μ ν λ μ΅μν λ²μ κ΄λ¦¬μ λ°μ ν μ μμ΅λκΉ?
Tastypieμ
x.y.z
λ²μ κ΄λ¦¬λ λλΆλΆμ μ¬λλ€μ΄ κΈ°λνλ κ²κ³Ό λ§€μ° μ μ¬ν©λλ€. μΌλ°μ μΌλ‘ λ€μκ³Ό κ°μ΅λλ€.μλ‘μ΄ νλ‘λμ λ°°ν¬ μ€μ μ΄κ²μ μΆμ νλ λ° λ§€μ° λΆνΈν μκ°μ 보λμ΅λλ€.