from typing import Optional
from typing import Union
import pyramid.request
from pyramid.decorator import reify
from pyramid.interfaces import IRequest
from pyramid.security import Allowed
from pyramid.security import Denied
from zope.interface import implementer
from kotti.security import Principal
from kotti.security import get_user
[docs]@implementer(IRequest)
class Request(pyramid.request.Request):
""" Kotti subclasses :class:`pyramid.request.Request` to make additional
attributes / methods available on request objects and override Pyramid's
:meth:`pyramid.request.Request.has_permission`. The latter is needed to
support Kotti's concept of local roles not just for users but also for
groups (:func:`kotti.security.list_groups_callback`).
"""
@reify
def user(self) -> Optional[Principal]:
""" Add the authenticated user to the request object.
:result: the currently authenticated user
:rtype: :class:`kotti.security.Principal` or whatever is returned by
the custom principals database defined in the
``kotti.principals_factory`` setting
"""
return get_user(self)
[docs] def has_permission(
self, permission: str, context: object = None
) -> Union[Allowed, Denied]:
""" Check if the current request has the given permission on the
current or explicitly passed context. This is different from
:meth:`pyramid.request.Request.has_permission`` in that a context other
than the one bound to the request can be passed. This allows to
consider local roles for the check.
:param permission: name of the permission to check
:type permission: str
:param context: context for which the permission is checked.
Defaults to the context on which the request invoked.
:type context: :class:`kotti.resources.Node`
:result: True if has_permission, False else
:rtype: bool
"""
from kotti.security import authz_context
with authz_context(context, self):
return super().has_permission(permission, context)