• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / grokcore.view / 16248935885

18 Jun 2025 06:52AM UTC coverage: 93.234%. Remained the same
16248935885

push

github

icemac
Back to development: 5.1

151 of 180 branches covered (83.89%)

Branch coverage included in aggregate %.

1475 of 1564 relevant lines covered (94.31%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/grokcore/view/publication.py
1
from zope.app.publication.browser import BrowserPublication
×
2
from zope.app.publication.requestpublicationfactories import BrowserFactory
×
3
from zope.event import notify
×
4
from zope.publisher.interfaces.browser import IBrowserView
×
5
from zope.security.checker import selectChecker
×
6
from zope.security.proxy import removeSecurityProxy
×
7

8
from grokcore.view import IGrokSecurityView
×
9
from grokcore.view.interfaces import AfterTraversalEvent
×
10

11

12
class ZopePublicationSansProxy:
×
13
    """Mixin that makes a publisher remove security proxies.
14

15
    This mixin overrides three methods from the `IPublication`
16
    interface (defined in `zope.publisher.interfaces`) to alter their
17
    security behavior.  The normal Zope machinery wraps a security
18
    proxy around the application object returned by
19
    `getApplication()`, and around each of the objects returned as
20
    `traverseName()` is then called for each URL component.  The
21
    versions here strip the security proxy off instead, returning the
22
    bare object (unless the object is a non-Grok view, in which case
23
    we leave the proxy installed for important security
24
    reasons).  Non-Grok views however, are handled like Grok views, if
25
    they provide `grokcore.view.IGrokSecurityView`.
26

27
    Finally, when `callObject()` is asked to render
28
    the view, we quickly re-install a security proxy on the object, make
29
    sure that the current user is indeed allowed to invoke `__call__()`,
30
    then pass the bare object to the rendering machinery.
31

32
    The result is that, in place of the elaborate series of security
33
    checks made during the processing of a normal Zope request, Grok
34
    makes only a single security check: to see if the view can be
35
    permissibly rendered or not.
36

37
    """
38

39
    def getApplication(self, request):
×
40
        result = super().getApplication(request)
×
41
        return removeSecurityProxy(result)
×
42

43
    def traverseName(self, request, ob, name):
×
44
        result = super().traverseName(
×
45
            request, ob, name)
46
        bare_result = removeSecurityProxy(result)
×
47
        if IBrowserView.providedBy(bare_result):
×
48
            if IGrokSecurityView.providedBy(bare_result):
×
49
                return bare_result
×
50
            else:
51
                return result
×
52
        else:
53
            return bare_result
×
54

55
    def callObject(self, request, ob):
×
56
        checker = selectChecker(ob)
×
57
        if checker is not None:
×
58
            checker.check(ob, '__call__')
×
59
        return super().callObject(request, ob)
×
60

61
    def afterTraversal(self, request, ob):
×
62
        super().afterTraversal(request, ob)
×
63
        notify(AfterTraversalEvent(ob, request))
×
64

65

66
class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
×
67
    """Combines `BrowserPublication` with the Grok sans-proxy mixin.
68

69
    In addition to the three methods that are overridden by the
70
    `ZopePublicationSansProxy`, this class overrides a fourth: the
71
    `getDefaultTraversal()` method, which strips the security proxy from
72
    the object being returned by the normal method.
73

74
    """
75

76
    def getDefaultTraversal(self, request, ob):
×
77
        obj, path = super().getDefaultTraversal(
×
78
            request, ob)
79
        return removeSecurityProxy(obj), path
×
80

81

82
class GrokBrowserFactory(BrowserFactory):
×
83
    """Returns the classes Grok uses for browser requests and publication.
84

85
    When an instance of this class is called, it returns a 2-element
86
    tuple containing:
87

88
    - The request class that Grok uses for browser requests.
89
    - The publication class that Grok uses to publish to a browser.
90

91
    """
92

93
    def __call__(self):
×
94
        request, publication = super().__call__()
×
95
        return request, GrokBrowserPublication
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc