Para los fines de esta discusión, supongo que está utilizando SQLAlchemy para interactuar con su base de datos.
Si tiene config.add_route('pages', '/pages/{id}')
en su __init__.py
, se puede añadir una fábrica encargo para reemplazar/complementar su ACL predeterminada. Por ejemplo:
Su ACL actual puede tener este aspecto:
class RootFactory(object):
__acl__ = [
(Allow, Everyone, 'view'),
(Allow, Authenticated, 'auth'),
]
def __init__(self, request):
self.request = request
Esto permitiría a los usuarios autenticados para acceder a cualquier punto de vista con un permiso de 'auth', y cualquier persona que visita su sitio para acceder a cualquier punto de vista con un permiso de 'ver'.
Al usar una fábrica personalizada , puede omitir su RootFactory o complementarlo.
Para omitir, cambiar su config.add_route original ->config.add_route('pages', '/pages/{id}', factory=PageFactory)
y crear una clase PageFactory así:
class PageFactory(object):
__acl__ = [
(Allow, Everyone, 'view'),
(Allow, Authenticated, 'auth'),
]
def __init__(self, request):
self.request = request
from pyramid.security import authenticated_userid
user_id = authenticated_userid(self.request)
thispage = DBSession.query(Page).filter(Page.id==self.request.matchdict['id']).first()
if thispage.user_id == user_id:
## Pyramid allows Everyone, Authenticated, and authenticated_userid
## (each of these is known as a Principal) to be in the second
## position of the ACL tuple
acl.append((Allow, user_id, 'edit'))
Esto está asumiendo su punto de vista tiene permission='edit'
como uno de sus parámetros.
Ahora, si desea utilizar el RootFactory y suplemento con su de fábrica personalizada, por lo que no tiene que repetirse, sólo tiene que dejar RootFactory como he mostrado en el comienzo de esta puesto, y heredar de la clase RootFactory, como tal:
class PageFactory(RootFactory):
@property
def __acl__(self):
acl = super(PageFactory, self).__acl__[:] ##[:] creates a copy
from pyramid.security import authenticated_userid
user_id = authenticated_userid(self.request)
thispage = DBSession.query(Page).filter(Page.id==self.request.matchdict['id']).first()
if thispage.user_id == user_id:
acl.append((Allow, user_id, 'edit'))
return acl
el groupfinder es muy útil, por cierto, porque entonces se puede colocar simplemente los usuarios en grupos, como 'admin', y todos los que están en el grupo de administración pueden acceder a las vistas con permission='whatever'
o permission='whateverelse'
que desee y no se necesita en fábrica, solo un buscador de grupos que devuelve una lista de grupos para el usuario actual. Por desgracia, estoy divagando, ya que eso no es lo que estabas buscando hacer. Espero que esto responda a su pregunta.
pequeño nitpick, si su fábrica raíz devuelve 'None', entonces el contexto es' None', 404 no se producirá automáticamente a menos que no se pueda encontrar una vista. En su ejemplo, se encontraría 'page_view', pero se prohibiría debido al contexto' None' que no tiene '__acl__'. –
Finalmente se hace clic. Hasta el día de hoy, no veía ninguna relación entre la clase de página con la ACL y la 'clase de tabla' de SQLAlchemy Page. Todo comienza a formarse ahora. – Kane
Michael: buen punto. Una forma de obtener ese comportamiento es agregar context = Page en la invocación view_config. Actualizaré mi respuesta para reflejar eso. –