31. Workflow, Roles and Permissions#
How do prospective speakers submit talks? We let them register on the site and grant right to create talks. For this we go back to changing the site through-the-web.
In this part you will:
Allow self-registration
Constrain which content types can be added to the (folderish) talk page
Grant local roles
Create a custom workflow for talks
Tools and techniques covered:
workflow
local roles
Checkout ploneconf.site
at tag "searchable":
git checkout searchable
The code at the end of the chapter:
git checkout user_generated_content
More info in The code for the training
31.1. Self-registration#
Go to the control panel security at http://localhost:3000/controlpanel/security and enable self-registration.
Leave "Enable User Folders" off unless you want a community site, in which users can create any content they want in their home folder.
Select the option 'Use email address as login name'.
31.2. Constrain types to be addable#
On the page
schedule
select Restrictions… http://localhost:8080/Plone/schedule/folder_constraintypes_form from the Add new_ menu. Restrict to adding only talks. This action is by now only available in Classic Plone.
31.3. Grant local roles#
Go to Sharing and grant the role Can add to the group logged-in users. Now every logged-in user can add content in this folder (and only this folder).
By combining the constrain types and the local roles on this folder, we have achieved, that only logged-in users can create and submit talks in this folderish page.
31.4. A custom workflow for talks#
We still need to fix a problem: Authenticated users can see all talks, including those of other users, even if those talks are in the private state. Since we do not want this, we will create a modified workflow for talks. The new workflow will only let them see and edit talks they created themselves and not the ones of other users.
Go to the
See how talks have the same workflow as most content, namely (Default)
Go to the tab Contents, check the box next to simple_publication_workflow, click copy and paste.
Rename the new workflow from copy_of_simple_publication_workflow to talks_workflow.
Edit the workflow by clicking on it: Change the Title to Talks Workflow.
Click on the tab States and click on private to edit this state. In the next view select the tab Permissions.
Find the table column for the role Contributor and remove the permissions for Access contents information and View. Note that the Owner (that's the creator) still has some permissions.
Do the same for the state pending
Go back to
portal_workflow
and set the new workflowtalks_workflow
for talks. ClickChange
and thenUpdate security settings
.
The new workflow allows contributors to see and edit talks they created themselves but not the ones of other contributors.
31.5. Move the changes to the file system#
We don't want to do these steps for every new conference by hand so we move the changes into our package.
Export and import the workflow#
Export the GenericSetup step Workflow Tool in http://localhost:8080/Plone/portal_setup/manage_exportSteps.
Drop the file
workflows.xml
intosrc/ploneconf/site/profiles/default
an clean out everything that is not related to talks.<?xml version="1.0"?> <object name="portal_workflow" meta_type="Plone Workflow Tool"> <object name="talks_workflow" meta_type="Workflow"/> <bindings> <type type_id="talk"> <bound-workflow workflow_id="talks_workflow"/> </type> </bindings> </object>
Drop
workflows/talks_workflow/definition.xml
insrc/ploneconf/site/profiles/default/workflows/talks_workflow/definition.xml
. The other files are just definitions of the default-workflows and we only want things in our package that changes Plone.
Enable self-registration#
To enable self-registration you need to change the global setting that controls this option.
Most global setting are stored in the registry. You can modify it by adding the following to src/ploneconf/site/profiles/default/registry/main.xml
:
<record name="plone.enable_self_reg">
<value>True</value>
</record>
Grant local roles and constrain types to be addable#
Since the granting of local roles applies only to a certain folder in the site we would not always write code for it but do it by hand. But for testability and repeatability (there is a conference every year!) we should create the initial content structure automatically and also apply needed local roles.
We are setting up the initial content of a conference site in an upgrade step explained in upgrade step code.
Let's enhance this by setting local roles and constrain types.
Add the following lines to cleanup_site_structure
.
1from Products.CMFPlone.interfaces import constrains
2
3
4 # Allow logged-in users to create content
5 api.group.grant_roles(
6 groupname='AuthenticatedUsers',
7 roles=['Contributor'],
8 obj=talks_folder)
9
10 # Constrain addable types to talk
11 behavior = constrains.ISelectableConstrainTypes(talks_folder)
12 behavior.setConstrainTypesMode(constrains.ENABLED)
13 behavior.setLocallyAllowedTypes(['talk'])
14 behavior.setImmediatelyAddableTypes(['talk'])
15 logger.info(f'Added and configured {talks_folder.absolute_url()}')
Once we apply the upgrade step or reinstall our package a page talks
is created with the appropriate local roles and constraints.
31.6. Exercise#
We wrote similar code to create the pages in Upgrade steps. We need it to make sure a sane structure gets created when we create a new site by hand or in tests.
You would usually create a list of dictionaries containing the type, parent and title plus optionally workflow state etc. to create an initial structure.
In some projects it could also make sense to have a separate profile besides default
which might be called demo
or content
that creates an initial structure and maybe another testing
that creates dummy content (talks, speakers etc) for tests.
Create an optional GenericSetup profile
content
that creates the content, grants local roles and sets constraints.