Let us see , how we can create a workflow for a bfg application.
To add a workflow add a file named workflow.py at the root of your site. you can name it as you like.
Add methods related to the states and transitions as per your requirement.
For Example, the following files does the work.
- workflow.py
from repoze.bfg.security import Allow
from repoze.bfg.security import Deny from repoze.bfg.security import Everyone from repoze.bfg.traversal import find_interface from repoze.bfg.traversal import model_path from project.security_policies.policy import ADMINISTRATOR_PERMS from project.security_policies.policy import GUEST_PERMS from project.security_policies.policy import MODERATOR_PERMS from project.security_policies.policy import MEMBER_PERMS from project.security_policies.policy import CREATE from project.security_policies.policy import NO_INHERIT from project.security_policies.workflow import postorder from project.security_policies.workflow import acl_diff from project.security_policies.workflow import reset_security_workflow def find_showEvent(context): return find_interface(context, IshowEvent) def ts(*args): return '\t'.join([str(x) for x in args])
def not_intranets_containment(context): return not intranets_containment(context) def intranets_containment(context): return False def private_showEvent_containment(context): if not_intranets_containment(context): showEvent = find_showEvent(context) if showEvent is None: return False return getattr(showEvent, 'seproject.security_policies.policycurity_state', None) == 'private' return False def public_showEvent_containment(context): if not_intranets_containment(context): showEvent = find_showEvent(context) if showEvent is None: return False return getattr(showEvent, 'security_state', None) == 'public' return False
def showEvent_to_private(ob, info): showEvent = find_showEvent(ob) acl = [] moderators_group_name = showEvent.moderators_group_name members_group_name = showEvent.members_group_name acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS)) acl.append((Allow, moderators_group_name, MODERATOR_PERMS)) acl.append((Allow, members_group_name, MEMBER_PERMS)) acl.append(NO_INHERIT) msg = None added, removed = acl_diff(showEvent, acl) if added or removed: showEvent.__acl__ = acl msg = ts('showEvent-private', model_path(showEvent), added, removed) _reindex(showEvent) return msg def showEvent_to_public(ob, info): showEvent = find_showEvent(ob) acl = [] moderators_group_name = showEvent.moderators_group_name members_group_name = showEvent.members_group_name acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS)) acl.append((Allow, members_group_name, GUEST_PERMS)) acl.append((Allow, 'group.KarlStaff', GUEST_PERMS)) acl.append(NO_INHERIT) msg = None added, removed = acl_diff(showEvent, acl) if added or removed: showEvent.__acl__ = acl msg = ts('showEvent-public', model_path(showEvent), added, removed) _reindex(showEvent) return msg def showEvent_to_pending(ob, info): showEvent = find_showEvent(ob) acl = [] moderators_group_name = showEvent.moderators_group_name members_group_name = showEvent.members_group_name acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS)) acl.append((Allow, members_group_name, GUEST_PERMS)) #When the showEvent is pending user cannot delete,create, edit acl.append((Allow, 'group.KarlStaff', GUEST_PERMS)) acl.append(NO_INHERIT) msg = None added, removed = acl_diff(showEvent, acl) if added or removed: showEvent.__acl__ = acl msg = ts('showEvent-pending', model_path(showEvent), added, removed) _reindex(showEvent) return msg def showEvent_to_rejected(ob,info): showEvent = find_showEvent(ob) acl = [] moderators_group_name = showEvent.moderators_group_name members_group_name = showEvent.members_group_name acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS)) acl.append((Allow, members_group_name, GUEST_PERMS)) acl.append((Allow, 'group.KarlStaff', GUEST_PERMS)) acl.append(NO_INHERIT) #temp msg = None added, removed = acl_diff(showEvent, acl) if added or removed: showEvent.__acl__ = acl msg = ts('showEvent-pending', model_path(showEvent), added, removed) _reindex(showEvent) return msg |
In workflow.py permissions were imported from policy file. Below is the policy file of security_policies of project.
- policy.py
from BTrees.IFBTree import multiunion
from BTrees.IFBTree import IFSet from repoze.bfg.security import Allow from repoze.bfg.security import Deny from repoze.bfg.security import Everyone from repoze.bfg.security import AllPermissionsList VIEW = 'view' EDIT = 'edit' CREATE = 'create' DELETE = 'delete' MODERATE = 'moderate' ADMINISTER = 'administer' COMMENT#acl.append((Allow, moderators_group_name, MODERATOR_PERMS)) #Creator or member is the part of default member group = 'comment' GUEST_PERMS = (VIEW, COMMENT) MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE) MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,) ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,) ALL = AllPermissionsList() NO_INHERIT = (Deny, Everyone, ALL) |
Add workflow.zcml and declare the states and transitions as follows.
- workflow.zcml
< configure xmlns="http://namespaces.repoze.org/bfg"> < include package="repoze.workflow" file="meta.zcml"> < workflow type="security" name="showEvent" description="WF for showEvent" elector="project.workflow.not_intranets_containment" content_types="project.interfaces.IshowEvent" initial_state="private" state_attr="security_state" permission_checker="repoze.bfg.security.has_permission" > < state name="public" title="Public" callback="project.workflow.showEvent_to_public"> < /state> < state name="private" title="Private" callback="project.workflow.showEvent_to_private"> < alias name="initial"> < /state> < state name="pending" title="Pending"ar callback="project.workflow.showEvent_to_pending"> < /state> < state name="rejected" title="Rejected" callback="project.workflow.showEvent_to_rejected"> < alias name="initial"> < /state> < transition name="submit" to_state="pending" from_state="private"/> < transition name="approve" to_state="public" from_state="pending"/> < transition name="retract" to_state="private" from_state="pending"/> < transition name="reject" to_state="rejected" from_state="pending"/> < transition name="unapprove" to_state="pending" from_state="public"/> </workflow> |
Now register the workflow , by declaring it in configure.zcml file.
- configure.zcml
<configure xmlns="http://namespaces.repoze.org/bfg"> <!-- this must be included for the view declarations to work --> <include package="repoze.bfg.includes"> <include package="project.security_policies"> <include package="project.views"> <include package="project" file="workflow.zcml"> </configure> |
This way, we were able to create a workflow for our project.