Security policy enforcement on document creation
As part of my custom security policy, I would like to prevent a user from creating a document he/she cannot later access. In order to do so, it would seem reasonable that SecurityPolicy.checkPermission() be at least optionally invoked (with say “ReadWrite” permission parameter) as part of the normal document creation sequence. How would this be best accomplished using the current Nuxeo platform? Would it make sense to enhance the SecurityPolicy extension point to more directly support this use case?
It's true that the security policy system is a low-level core check, and that's why its API is using a Document instance instead of a DocumentModel. It relies on the document to be already in the repository to perform ACL checks, for instance. It is actually checking the permission “AddChildren” on the parent document before creating a document inside it, but it does not allow you to perform checks on the document to be created.
I guess you have several options to handle that using the current Nuxeo platform:
one option is to rollback the transaction when the core detects such an issue, in a listener, as there is an event named “aboutToCreate” with the corresponding document model. I think the quota addon relies on such a mechanism to rollback creation when the core detects that the quota is exceeded. Note that it does have to perform specific work to “revert” the UI state too, and to display a meaningful feedback message to the user. This will involve checking the metadata on a DocumentModel object.
another option is to perform the check just before asking the core session to create the document, defining an alternative “create” action in a seam component. This would involve checking the DocumentModel object too, and handling the UI state revert too.
if your security checks are very specific and involve a lot of different metadata that can be confusing to the user, you may want to be compliant with the JSF validation mechanism, so that the creation method on the seam component is not even called when this high-level validation fails. Even if not perfect, there are ways to perform cross-field validations when checks involve several metadata. UI state revert is not needed here as it's handled by the JSF framework.
In any case, if your policies are complex, it may be a good idea to define your own “security checks” model, with custom API checking your criteria, and to call this common API from UI components as well as core components like security policies.