2011-04-23 31 views
18

मैं एक प्राधिकरण नीति बनाने की कोशिश कर रहा हूं जो "आइटम" स्वामित्व को ध्यान में रखे। उदाहरण के लिए कुछ उपयोगकर्ता एक्स "स्वामित्व" आइटम ए, बी, सी हैं जिन्हें /item/{item}/some_options जैसे यूआरएल के माध्यम से एक्सेस किया जाता है।संग्रहीत वस्तुओं के लिए पिरामिड प्रमाणीकरण

प्राधिकरण नीति ऑब्जेक्ट (परमिट() कॉल) पर {item} के बारे में जानकारी कैसे प्राप्त कर सकता हूं? संदर्भ में अतिरिक्त जानकारी को एक अच्छा विचार डाल रहा है (मैं केवल मार्ग-आधारित रूटिंग कर रहा हूं)। मुझे यह कैसे करना है?

उत्तर

50

आप इस उद्देश्य के लिए डिज़ाइन किए गए कस्टम संसाधन पेड़ का उपयोग करके ACLAuthorizationPolicy यूआरएल डिस्पैच के साथ संयुक्त कर सकते हैं।

उदाहरण के लिए, आपके पास Foo ऑब्जेक्ट्स, और Bar ऑब्जेक्ट्स के लिए अनुमतियां हैं।

/foos/{obj} 
/bars/{obj} 

आपके संसाधन पेड़ तो अनुमतियाँ, जहां पेड़ में किसी भी बिंदु पर आप संसाधन वस्तु पर एक __acl__ जगह कर सकते हैं के एक पदानुक्रम हो जाता है:: ये एसीएल संसाधन पेड़ traversing यूआरएल का उपयोग करके पाया जा सकता है

root      (Root) 
|- foos     (FooContainer) 
| `- {obj}    (Foo) 
`- bars     (BarContainer) 
    `- {obj}    (Bar) 

आप एक संसाधन के पेड़ में इस पदानुक्रम का प्रतिनिधित्व कर सकते हैं: इस तरह एक सेटअप के साथ

class Root(dict): 
    # this is the root factory, you can set an __acl__ here for all resources 
    __acl__ = [ 
     (Allow, 'admin', ALL_PERMISSIONS), 
    ] 
    def __init__(self, request): 
     self.request = request 
     self['foos'] = FooContainer(self, 'foos') 
     self['bars'] = BarContainer(self, 'bars') 

class FooContainer(object): 
    # set ACL here for *all* objects of type Foo 
    __acl__ = [ 
    ] 

    def __init__(self, parent, name): 
     self.__parent__ = parent 
     self.__name__ = name 

    def __getitem__(self, key): 
     # get a database connection 
     s = DBSession() 
     obj = s.query(Foo).filter_by(id=key).scalar() 
     if obj is None: 
      raise KeyError 
     obj.__parent__ = self 
     obj.__name__ = key 
     return obj 

class Foo(object): 
    # this __acl__ is computed dynamically based on the specific object 
    @property 
    def __acl__(self): 
     acls = [(Allow, 'u:%d' % o.id, 'view') for o in self.owners] 
     return acls 

    owners = relation('FooOwner') 

class Bar(object): 
    # allow any authenticated user to view Bar objects 
    __acl__ = [ 
     (Allow, Authenticated, 'view') 
    ] 

हैं तो आप अपनी रेस के मार्ग पैटर्न मैप कर सकते हैं स्रोत देखें पेड़:

config = Configurator() 
config.add_route('item_options', '/item/{item}/some_options', 
       # tell pyramid where in the resource tree to go for this url 
       traverse='/foos/{item}') 

तुम भी एक विशेष दृश्य के लिए अपने निकटतम मार्ग की आवश्यकता होगी:

config.add_view(route_name='item_options', view='.views.options_view', 
       permission='view', renderer='item_options.mako') 

बढ़िया है, अब हम हमारे विचार को परिभाषित करने और लोड संदर्भ ऑब्जेक्ट का उपयोग, यह जानकर सकते हैं कि अगर दृश्य निष्पादित किया गया है, उपयोगकर्ता के पास उचित अनुमति है!

def options_view(request): 
    foo = request.context 
    return { 
     'foo': foo, 
    } 

इस स्थापना का उपयोग करना, आप डिफ़ॉल्ट ACLAuthorizationPolicy उपयोग कर रहे हैं, और आप यूआरएल डिस्पैच के साथ अपने वस्तुओं के लिए पंक्ति-स्तर अनुमतियाँ प्रदान कर रहे हैं। ध्यान दें, क्योंकि ऑब्जेक्ट्स बच्चों पर __parent__ संपत्ति सेट करते हैं, तो पॉलिसी माता-पिता से विरासत अनुमतियों को वंशबद्ध करेगी। इसे आपके एसीएल में DENY_ALL एसीई डालने से, या एक कस्टम नीति लिखकर जो संदर्भ के वंश का उपयोग नहीं करता है, से बचा जा सकता है।

* अद्यतन * मैं Github पर एक वास्तविक प्रदर्शन में इस पोस्ट नहीं कर देते। उम्मीद है कि यह किसी की मदद करता है। https://github.com/mmerickel/pyramid_auth_demo

* अद्यतन * मैं पिरामिड के प्रमाणीकरण और प्राधिकरण प्रणाली यहाँ एक पूर्ण ट्यूटोरियल लिखा है: अपने बहुत ही उपयोगी ट्यूटोरियल भी ज्यादा बनाने के लिए http://michael.merickel.org/projects/pyramid_auth_demo/

+0

सुझाव: यह आपके उपयोग पर चर्चा के लिए अच्छा होगा यहां कंटेनर का, क्योंकि मुझे डेटाबेस कनेक्शन का उपयोग करते समय संसाधन पेड़ को कैसे व्यवस्थित करना है, इस बारे में अनिश्चित था। मुझे ट्यूटोरियल देखने के बाद यह जवाब मिला, और इससे बहुत मदद मिली। – abroekhof