Source code for widgethost.enforcement

"""Per-request widget access enforcement for the host site.

The reusable gate compares the user's permission against the widget manifest's
``required_permission`` band for a resolved address count. Each widget resolves
its own bundle/addresses (via the host's ``bundle_and_addresses_from_path``) and
calls :meth:`WidgetAccessMixin.manifest_test_func` with the resolved count, so the
mixin stays agnostic of how a widget reads its URL value. It composes with the
widgets app's existing ``BaseUserPassesTestMixin`` (authentication and profile
presence checks).
"""

from widgethost.manifest import can_access
from widgets.views import BaseUserPassesTestMixin


[docs] class WidgetAccessMixin(BaseUserPassesTestMixin): """Provide a manifest-driven permission gate for widget views. The widget sets ``manifest`` (a class attribute or via ``as_view``) and calls :meth:`manifest_test_func` from its own ``test_func`` after resolving the size. :var WidgetAccessMixin.manifest: the widget's parsed manifest :type WidgetAccessMixin.manifest: :class:`widgethost.manifest.Manifest` """ manifest = None
[docs] def manifest_test_func(self, size): """Return whether the user clears the manifest gate for `size` addresses. :param size: number of resolved Algorand addresses :type size: int :return: Boolean """ return super().test_func(self._access_callback, size)
def _access_callback(self, profile, size): """Return whether `profile` clears the manifest gate for `size` addresses. :param profile: the current user's profile :type profile: :class:`core.models.Profile` :param size: number of resolved Algorand addresses :type size: int :return: Boolean """ return can_access(profile.permission, self.manifest.required_permission, size)