Set response headers
The intent of this change is to be able to manage certain HTTP response headers based on traversed documents.
Here is a (non-exchaustive) list of headers which are considered for this feature: Content-Security-Policy
, X-Content-Type-Options
, X-Frame-Options
, Referrer-Policy
.
It is possible to extend (for comma-separated headers), replace and remove headers set by a parent document, to allow (for example) ERP5 to be protected by a given Content-Security-Policy
rule set configured on its ERP5Site
instance, but a contained website (web_site_module/foo
) would be protected by a (possibly completely) different rule set for the same header.
The main design principle is to always have a sane fallback value & behaviour for every declared header, in case any error happen when the associated script is executed: such error could otherwise either cause the protection to be absent (exception caught without fallback), or prevent the issue from being fixed (exception not caught, preventing traversal).
This change has no effect on normal control of these headers: any script with access to current HTTPResponse
object can read/add/remove/replace any header set in this way. It is not intended to replace immediate-context-dependent header generation, but rather to allow adding response headers for every single page published under (in publication traversal subtree sense) a specific object.
This change has no effect on normal document traversal (ex: restrictedTraverse
), only on publication traversal.
To make the API easily available on many document types, I'm reworking class inheritance of Base
/Folder
, which is quite delicate. Using a test I exctracted the value of all Folder
class properties to compare before & after and besides the new API the only changes I see are:
Attribute | Before | After | My comment |
---|---|---|---|
Description |
method from Products/CMFCore/PortalFolder.py | method from ERP5Type/Base.py | Looks like progress |
getId |
method from OFS/SimpleItem | ERP5 accessor | Looks like progress |
getId__roles__ |
None |
PermissionRole object | Looks like progress |
icon |
'' |
method from Products/CMFCore/DynamicType.py | Do we care ? |
Some maybe-not-obvious attention points:
- there is no UI (only an API). Does it need one ?
- the rules are intended to be committed along with the document they are attached to (when such document is itself committed)
- updating the rules attached to known-but-not-committed documents (ex: an instance with multiple ERP5JS websites, and the rules are set by generic code) would be done using upgrader constraints, matching such document in whatever way is applicable (for
Web Site
s it can be a layout property comparison, for example)