python - xaxis - Autorización de pirámide para artículos almacenados.
r plotly title (1)
Estoy intentando crear una política de autorización que tenga en cuenta la propiedad del "elemento". Por ejemplo, algunos usuarios X "poseen" los elementos A, B, C. Se accede a ellos a través de URL como /item/{item}/some_options
.
¿Cómo puedo obtener la información acerca de {item}
para el objeto de la política de autorización (permite () llamar)? Es una buena idea poner la información adicional en contexto (estoy haciendo enrutamiento basado en rutas solamente). ¿Como podría hacerlo?
Puede hacer esto usando la ACLAuthorizationPolicy
combinada con el Despacho de URL usando un árbol de recursos personalizado diseñado para este propósito.
Por ejemplo, tiene permisos para objetos Foo
y permisos para objetos Bar
. Estas ACL se pueden encontrar al atravesar el árbol de recursos usando las direcciones URL:
/foos/{obj}
/bars/{obj}
Su árbol de recursos se convierte en una jerarquía de permisos, donde en cualquier punto del árbol puede colocar un __acl__
en el objeto de recurso:
root (Root)
|- foos (FooContainer)
| `- {obj} (Foo)
`- bars (BarContainer)
`- {obj} (Bar)
Puedes representar esta jerarquía en un árbol de recursos:
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'')
]
Con una configuración como esta, puede asignar patrones de ruta a su árbol de recursos:
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}'')
También deberá asignar su ruta a una vista específica:
config.add_view(route_name=''item_options'', view=''.views.options_view'',
permission=''view'', renderer=''item_options.mako'')
Genial, ahora podemos definir nuestra vista y usar el objeto de contexto cargado, ¡sabiendo que si la vista se ejecuta, el usuario tiene los permisos adecuados!
def options_view(request):
foo = request.context
return {
''foo'': foo,
}
Con esta configuración, está utilizando la ACLAuthorizationPolicy
predeterminada y está proporcionando permisos de nivel de fila para sus objetos con el envío de URL. Tenga en cuenta también que, debido a que los objetos establecen la propiedad __parent__
en los hijos, la política aumentará el linaje y heredará los permisos de los padres. Esto se puede evitar simplemente colocando un ACE DENY_ALL
en su ACL, o escribiendo una política personalizada que no utilice el linaje del contexto.
* Actualización * He convertido esta publicación en una demostración real en Github. Esperemos que ayude a alguien. https://github.com/mmerickel/pyramid_auth_demo
* Actualización * He escrito un tutorial completo sobre el sistema de autenticación y autorización de pirámide aquí: http://michael.merickel.org/projects/pyramid_auth_demo/