Source code for nti.app.pyramid_zope.security

# -*- coding: utf-8 -*-
"""
Integrations for :mod:`zope.security` and :mod:`zope.authentication`.

Many of these are adapters registered automatically by this package's
configure.zcml.

In plain Zope3, the :class:`zope.publisher.interfaces.IRequest` *is*
an :class:`zope.security.interfaces.IParticipation` for the request's
principal (or the unauthenticated or fallback unauthenticated
principal). That request is defined to be the first participation in
the interaction by :mod:`zope.app.publication.zopepublication` (right after
authentication and right before traversal).

Pyramid's request is not a participation, and Pyramid doesn't
establish an interaction either. Something else (typically a
tween like **TODO: Copy Tween**) does that. These adapters will
work only after that is done.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from pyramid.threadlocal import get_current_request
from pyramid.interfaces import IRequest

from zope import component
from zope import interface

from zope.authentication.interfaces import IFallbackUnauthenticatedPrincipal
from zope.security import management as default_interaction_mgmt
from zope.security.interfaces import IInteractionManagement
from zope.security.interfaces import IInteraction
from zope.security.interfaces import IPrincipal
from zope.security.interfaces import NoInteraction

[docs]@component.adapter(IRequest) @interface.implementer(IInteraction) def interaction_from_request(request=None): """ interaction_from_request(request: IRequest) -> IInteraction Find the :class:`.IInteraction` for the *request*. The request is adapted to :class:`IInteractionManagement` (using the default :mod:`zope.security.management` for a thread-local interaction if there is no specific adapter registered), and the current interaction is returned. This is registered as an adapter on the Pyramid ``IRequest`` interface; to provide a more specific policy, register an adapter on the concrete class. :raise zope.security.interfaces.NoInteraction: If there is no interaction. .. seealso:: :class:`zope.security.interfaces.IInteractionManagement` """ request = get_current_request() if request is None else request interaction_mgmt = IInteractionManagement(request, default_interaction_mgmt) # If we return None here, we can use a default value for the interaction # or raise a TypeError with IInteraction(request, <default>); if we # raise NoInteraction it would be propagated unconditionally. return interaction_mgmt.getInteraction() # pylint:disable=too-many-function-args
[docs]@component.adapter(IInteraction) @interface.implementer(IPrincipal) def principal_from_interaction(interaction): """ principal_from_interaction(interaction: IInteraction) -> IPrincipal Find the primary :class:`IPrincipal` for the *interaction*. The primary principal is the principal of the first participation. """ return next(iter(interaction.participations)).principal
[docs]@component.adapter(IRequest) @interface.implementer(IPrincipal) def principal_from_request(request=None): """ principal_from_request(request: IRequest) -> IPrincipal Find the primary :class:`IPrincipal` for the *request*. First adapts the request into an :class:`IInteraction` (probably using :func:`interaction_from_request`), and then adapts the interaction into an ``IPrincipal`` (probably using :func:`principal_from_interaction`). If there is no interaction, the unauthenticated principal is returned. This is registered as an adapter on the Pyramid ``IRequest`` interface; to provide a more specific policy, register an adapter on the concrete class. """ try: interaction = IInteraction( request if request is not None else get_current_request(), ) except NoInteraction: return component.getUtility(IFallbackUnauthenticatedPrincipal) return IPrincipal(interaction)