Base._getAcquireLocalRoles: Optimise.
This is called when checking access permission on objects, which happens very often. CachingMethod has a hit cost which is too high for this use. Instead, generate this method as part of the portal type class, removing all call-time logic.
-
Developer
I have a project overriding for some portal types like "PDF" or "Image" the method _getAcquireLocalRoles:
def _getAcquireLocalRoles(self): """ Override for MyProject default method to acquire local roles only if document is embedded """ result = False if not(self.getRelativeUrl().startswith("document_module/")): result = True return result
So it was able to have different behavior depending if we had the portal type embedded in another type or not (in document module, documents are not embedded, in other places they are).
So with this patch, _getAcquireLocalRoles is not retrieved at the class level any more, thus my code is no longer called. So we looks like to have now way to make dynamic the choice of having or not acquisition of roles.
In my case, some documents like PDF are embedded inside other types of objects (like Mail Message), each having it's own security setup. So this method was very convenient. I can hardly find a way to solve my issue, and I don't want to patch portal_type_class itself.
@nexedi No one else having trouble with this ?
-
Owner
So with this patch, _getAcquireLocalRoles is not retrieved at the class level any more, thus my code is no longer called.
I think a generic fix can be:
- Remove
Base._getAcquireLocalRoles
: anyway a missing portal type will likely not work properly, and I seegeneratePortalTypeClass
actually raises when it fails to find one. - Make
generatePortalTypeClass
only set_getAcquireLocalRoles
constant getter from Portal Type configuration if this method is not already implemented by a superclass.
Another idea would be to change/add the possibility of inputing a TALES expression at portal_type level, but I am worried this will have a non-trivial run-time cost: every single restricted action on that object will cause a TALES environment to be setup (I do not think we can cache it in this case), and TALES evaluator involved instead of just 4 lines of nice, native python... There can be a lot of such accesses because of zope security magic, so even a tiny per-call slowdown can cause a much bigger effect at whole-transaction level.
Also, I think your use-case is a very good one, and I'm surprised this is not in generic code (maybe I missed a discussion about this ?).
- Remove
-
Owner
Also, I think your use-case is a very good one, and I'm surprised this is not in generic code (maybe I missed a discussion about this ?).
Generic code address this by using two different portal types,
Embedded File
(acquire local roles) vsFile
(does not acquire local roles). -
Owner
Oh, that's a good fix too indeed. But I think I can also make
_getAcquireLocalRoles
ConstantGetter less disruptive. -
Owner
I opened !857 (closed) with a tentative fix.
-
Owner
I vote for using
Embedded File
or introducing yet another Embedded Xxx portal types. Maybe Embedded File can have more intelligent 'preview' action by checking content_type ? -
Developer
So I was not so happy with the "Embedded" dedicated portal type solution. For Mail Message I wanted to use various types instead of only "Embedded File", because "PDF", "Image", "Text", "Drawing", etc have nice preview and are not just files. This is not the only issue of preview, we might also think about cases where we would like also the benefit of dedicated gadget editors depending on types. So I would need "Embedded PDF", "Embedded Image", etc. This makes a lot of duplication while the only difference I need is this property of acquisition of roles. All security setting is dynamic and very flexible (all roles), except that property.
So I think it is nice to keep flexibility.
Thanks Vincent for patch, I'm going to try.
-
Owner
In my understanding,
File
has this special semantic that ERP5 does not try to perform any conversion and the only thing one can do with aFile
is download it. I think it's intentionally not clever, because we have DMS for "clever" types.@seb what was the reason not to use document module to store the documents ?
-
Developer
@jerome my usage is to see attachments of mail message in a user friendly way. It is still possible to create document in document module and display a listbox showing related documents. But email attachments are not supposed to be used outside of email, and all their security is strictly linked to the security of mail message. In document module, I prefer in this project to have documents created by users, not whatever mess can come from emails. Then they are free to create a document if they really need to share something that was received by mail message. So if at the end I need to create an "hidden document module", this is still possible, but not sure it sounds nice.
@kazuhiko probably possible, but I need in such case to duplicate all role definition of Mail Message, and then also add interactions every time security is calculated on Mail Message itself. And this would need to be done for all types PDF, Image, etc... I clearly prefer to have the flexibility to define a 4 lines of code method like I was doing up to now.
@vpelletier many thanks, my failing tests checking security are now passing with your patch
-
Owner
my failing tests checking security are now passing with your patch
Great to hear.
So I'll rebase & push to public master once testrunner 2 is happy (which likely means: beginning of next week).
-
Owner
(which likely means: beginning of next week).
Sadly, some tests failed because we have at least 2 "document" types which do not have a portal type, so they do not go through portal type class generation and raise when indexed:
- testERP5Promise.TestERP5Promise.test_promise_certificate_autority_tool : Certificate Authority Tool has no portal type.
- ERP5Form has no portal type. Or does. Sometimes. But apparently not when created the ZMI way (which creates
Products.ERP5Form.Form.ERP5Form
which is mistaken by catalog as a document type), but still somehow someone could create them as document objects, because they are committed as instance oferp5.portal_types.ERP5 Form
. And the portal type gets created when migrating ERP5 Catalog from old version to latest version by installing it from a non-bootstrap business template by using a bootstrap-only method which still somehow works in that case... What a mess.
I suspect there are more cases, but so far these are the ones I found by checking failing tests. And I also found a few more failing tests (one because of my ZSQLCatalog fixes).
I cannot spend more time on this now, so I sadly have to give up. Please, someone familiar with
ERP5 Form
vs.ERP5Form
:- move the portal type into erp5_core, with all essential portal types
- alias ERP5Form product class to the portal type class somehow, so that all existing instances are automatically migrated on instanciation
-
Owner
And I could find some time today and got ideas of simpler fixes for the 2 classes requiring special handling. The result passes tests. I closed the merge request.