Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ekaterina
erp5
Commits
930c7aa9
Commit
930c7aa9
authored
Jan 22, 2015
by
wenjie.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ERP5Workflow: Interface, Assignment of roles to permissions, New class to bind role and permission.
parent
2b781fd2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
271 additions
and
4 deletions
+271
-4
product/ERP5Type/Base.py
product/ERP5Type/Base.py
+10
-0
product/ERP5Workflow/Document/PermissionRoles.py
product/ERP5Workflow/Document/PermissionRoles.py
+92
-0
product/ERP5Workflow/Document/State.py
product/ERP5Workflow/Document/State.py
+100
-3
product/ERP5Workflow/Document/Workflow.py
product/ERP5Workflow/Document/Workflow.py
+69
-1
No files found.
product/ERP5Type/Base.py
View file @
930c7aa9
...
...
@@ -657,6 +657,8 @@ def intializePortalTypeERP5WorkflowMethod(ptype_klass, portal_ERP5Workflow):
for
tr
in
wf5_module
.
_getOb
(
ERP5Workflow_id
).
objectValues
(
portal_type
=
"Transition"
):
tr_id
=
tr
.
id
method_id
=
convertToMixedCase
(
tr_id
)
ptype_klass
.
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
method_id
)
ptype_klass
.
registerERP5WorkflowMethod
(
method_id
,
ERP5Workflow_id
,
tr_id
,
0
)
LOG
(
"ERP5Workflow method %s is generated"
%
tr_id
,
WARNING
,
" for %s"
%
ERP5Workflow_id
)
...
...
@@ -3378,12 +3380,20 @@ class Base( CopyContainer,
There's no check that the document is actually chained to the workflow,
it's caller responsability to perform this check.
"""
workflow
=
self
.
portal_workflow
.
getWorkflowById
(
wf_id
)
erp5workflow
=
self
.
workflow_module
.
_getOb
(
wf_id
,
None
)
if
workflow
is
not
None
:
changed
=
workflow
.
updateRoleMappingsFor
(
self
)
if
changed
:
self
.
reindexObjectSecurity
(
activate_kw
=
{
'priority'
:
4
})
### zwj: update role changed through erp5workflow
if
erp5workflow
is
not
None
:
changed
=
erp5workflow
.
updateRoleMappingFor
(
self
)
if
changed
:
self
.
reindexObjectSecurity
(
activate_kw
=
{
'priority'
:
4
})
# Template Management
security
.
declareProtected
(
Permissions
.
View
,
'getDocumentTemplateList'
)
def
getDocumentTemplateList
(
self
)
:
...
...
product/ERP5Workflow/Document/PermissionRoles.py
0 → 100644
View file @
930c7aa9
##############################################################################
#
# Copyright (c) 2006 Nexedi SARL and Contributors. All Rights Reserved.
# Wenjie ZHENG <wenjie.zheng@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_parent
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLObject
import
XMLObject
from
zLOG
import
LOG
,
ERROR
,
DEBUG
,
WARNING
class
PermissionRoles
(
XMLObject
):
"""
Permission role matrix cell unit,
Used to assign a role to a permission.
"""
meta_type
=
'ERP5 PermissionRoles'
portal_type
=
'PermissionRoles'
add_permission
=
Permissions
.
AddPortalContent
is_selected
=
0
### for checkerbox (True 1 /False 0)
isPortalContent
=
1
isRADContent
=
1
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
# Declarative properties
property_sheets
=
(
PropertySheet
.
Base
,
PropertySheet
.
XMLObject
,
PropertySheet
.
CategoryCore
,
PropertySheet
.
DublinCore
,
PropertySheet
.
State
,)
def
getId
(
self
):
return
self
.
id
def
getPermissionRole
(
self
):
if
self
.
is_selected
==
1
:
permission_id
=
self
.
getId
().
split
(
'_'
)[
1
]
role_id
=
self
.
getId
().
split
(
'_'
)[
2
]
permission_list
=
sorted
(
self
.
getParent
().
getParent
().
getManagedPermissionList
())
role_list
=
sorted
([
"Anonymous"
,
"Assignee"
,
"Assignor"
,
"Associate"
,
"Auditor"
,
"Authenticated"
,
"Author"
,
"Manager"
,
"Member"
,
"Owner"
,
"Reviewer"
])
permission
=
permission_list
[
permission_id
]
role
=
role_list
[
role_id
]
LOG
(
'zwj: Assign %s to %s'
%
(
role
,
permission
),
WARNING
,
"in PermissionRole."
)
return
permission
,
role
def
setPermissionRoleMap
(
self
):
if
is_selected
==
1
:
permission_id
=
self
.
id
.
split
(
'_'
)[
1
]
role_id
=
self
.
id
.
split
(
'_'
)[
2
]
permission_list
=
sorted
(
self
.
getParent
().
getParent
().
getManagedPermissionList
())
role_list
=
sorted
([
"Anonymous"
,
"Assignee"
,
"Assignor"
,
"Associate"
,
"Auditor"
,
"Authenticated"
,
"Author"
,
"Manager"
,
"Member"
,
"Owner"
,
"Reviewer"
])
permission
=
permission_list
[
permission_id
]
role
=
role_list
[
role_id
]
product/ERP5Workflow/Document/State.py
View file @
930c7aa9
...
...
@@ -2,7 +2,7 @@
#
# Copyright (c) 2006 Nexedi SARL and Contributors. All Rights Reserved.
# Romain Courteaud <romain@nexedi.com>
#
#
Wenjie ZHENG <wenjie.zheng@tiolive.com>
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
...
...
@@ -27,10 +27,13 @@
##############################################################################
from
AccessControl
import
ClassSecurityInfo
from
Persistence
import
PersistentMapping
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLMatrix
import
XMLMatrix
from
Products.ERP5Type.XMLObject
import
XMLObject
from
zLOG
import
LOG
,
ERROR
,
DEBUG
,
WARNING
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_parent
class
StateError
(
Exception
):
"""
...
...
@@ -38,7 +41,7 @@ class StateError(Exception):
"""
pass
class
State
(
XMLObject
):
class
State
(
XMLObject
,
XMLMatrix
):
"""
A ERP5 State.
"""
...
...
@@ -47,6 +50,9 @@ class State(XMLObject):
add_permission
=
Permissions
.
AddPortalContent
isPortalContent
=
1
isRADContent
=
1
###zwj: security features
erp5_permission_roles
=
{}
# { permission: [role] or (role,) }
group_roles
=
None
# Declarative security
security
=
ClassSecurityInfo
()
...
...
@@ -120,3 +126,94 @@ class State(XMLObject):
"""
status_dict
=
self
.
getParentValue
().
getCurrentStatusDict
(
document
)
return
status_dict
[
variable_name
]
##### zwj: following parts related to the security features ####################
### zwj: Martix method
# Multiple inheritance definition
updateRelatedContent
=
XMLMatrix
.
updateRelatedContent
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'hasCellContent'
)
def
hasCellContent
(
self
,
base_id
=
'movement'
):
### zwj: findout what is base_id
"""Return true if the object contains cells.
"""
# Do not use XMLMatrix.hasCellContent, because it can generate
# inconsistency in catalog
# Exemple: define a line and set the matrix cell range, but do not create
# cell.
# Line was in this case consider like a movement, and was catalogued.
# But, getVariationText of the line was not empty.
# So, in ZODB, resource as without variation, but in catalog, this was
# the contrary...
cell_range
=
XMLMatrix
.
getCellRange
(
self
,
base_id
=
base_id
)
return
(
cell_range
is
not
None
and
len
(
cell_range
)
>
0
)
# DeliveryLine can be a movement when it does not content any cell and
# matrix cell range is not empty.
# Better implementation is needed.
# We want to define a line without cell, defining a variated resource.
# If we modify the cell range, we need to move the quantity to a new
# cell, which define the same variated resource.
# return XMLMatrix.hasCellContent(self, base_id=base_id)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getCell'
)
def
getCell
(
self
,
*
kw
,
**
kwd
):
"""
This method can be overriden
"""
if
'base_id'
not
in
kwd
:
kwd
[
'base_id'
]
=
'movement'
return
XMLMatrix
.
getCell
(
self
,
*
kw
,
**
kwd
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'newCell'
)
def
newCell
(
self
,
*
kw
,
**
kwd
):
"""
This method creates a new cell
"""
if
'base_id'
not
in
kwd
:
kwd
[
'base_id'
]
=
'movement'
return
XMLMatrix
.
newCell
(
self
,
*
kw
,
**
kwd
)
### matrix method
def
setPermission
(
self
,
permission
,
acquired
,
roles
,
REQUEST
=
None
):
"""Set a permission for this State."""
pr
=
self
.
erp5_permission_roles
if
pr
is
None
:
self
.
erp5_permission_roles
=
pr
=
PersistentMapping
()
if
acquired
:
roles
=
list
(
roles
)
else
:
roles
=
tuple
(
roles
)
pr
[
permission
]
=
roles
def
getPermissionRoleList
(
self
):
return
self
.
erp5_permission_roles
def
getWorkflow
(
self
):
return
aq_parent
(
aq_inner
(
aq_parent
(
aq_inner
(
self
))))
def
setGroups
(
self
,
REQUEST
,
RESPONSE
=
None
):
"""Set the group to role mappings in REQUEST for this State.
"""
map
=
self
.
group_roles
if
map
is
None
:
self
.
group_roles
=
map
=
PersistentMapping
()
map
.
clear
()
all_roles
=
self
.
getWorkflow
().
getRoles
()
for
group
in
self
.
getWorkflow
().
getGroups
():
roles
=
[]
for
role
in
all_roles
:
if
REQUEST
.
get
(
'%s|%s'
%
(
group
,
role
),
0
):
roles
.
append
(
role
)
roles
.
sort
()
roles
=
tuple
(
roles
)
map
[
group
]
=
roles
if
RESPONSE
is
not
None
:
RESPONSE
.
redirect
(
"%s/manage_groups?manage_tabs_message=Groups+changed."
%
self
.
absolute_url
())
product/ERP5Workflow/Document/Workflow.py
View file @
930c7aa9
...
...
@@ -29,6 +29,7 @@
from
AccessControl
import
ClassSecurityInfo
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_parent
from
Products.DCWorkflow.utils
import
modifyRolesForPermission
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.Globals
import
PersistentMapping
...
...
@@ -53,6 +54,12 @@ class Workflow(XMLObject):
isPortalContent
=
1
isRADContent
=
1
### zwj: for security issue
managed_permission
=
()
role
=
None
group
=
()
erp5_permission_roles
=
{}
# { permission: [role] or (role,) }
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
...
...
@@ -127,6 +134,9 @@ class Workflow(XMLObject):
"""
return
DateTime
()
def
getManagedPermissionList
(
self
):
return
self
.
managed_permission
def
getStateChangeInformation
(
self
,
document
,
state
,
transition
=
None
):
"""
Return an object used for variable tales expression.
...
...
@@ -142,15 +152,73 @@ class Workflow(XMLObject):
def
isERP5WorkflowMethodSupported
(
self
,
document
,
transition
):
sdef
=
document
.
_getDefaultAcquiredValue
(
self
.
getStateBaseCategory
())
### zwj: upper line may meet problems when there are other Base categories.
if
sdef
is
None
:
return
0
if
transition
in
sdef
.
getDestinationValueList
():
return
1
return
0
### zwj: following parts related to the security features
security
.
declarePrivate
(
'updateRoleMappingsFor'
)
def
updateRoleMappingsFor
(
self
,
document
):
"""Changes the object permissions according to the current state.
"""
changed
=
0
sdef
=
sdef
=
document
.
_getDefaultAcquiredValue
(
self
.
getStateBaseCategory
())
if
sdef
is
None
:
return
0
"""
# Update the role -> permission map.
if self.permissions:
for p in self.permissions:
roles = []
if sdef.erp5_permission_roles is not None: ### permission is defined in state
roles = sdef.erp5_permission_roles.get(p, roles)
if modifyRolesForPermission(document, p, roles):
changed = 1
"""
### zwj: get all matrix cell objects
permission_role_matrix_cells
=
sdef
.
objectValues
(
portal_type
=
"PermissionRoles"
)
### zwj: build a permission roles dict
for
perm_role
in
permission_role_matrix_cells
:
permission
,
role
=
perm_role
.
getPermissionRole
()
if
erp5_permission_roles
[
permission
]:
erp5_permission_roles
[
permission
]
=
erp5_permission_roles
[
permission
]
+
role
else
:
erp5_permission_roles
.
update
({
permission
:
role
})
### zwj: update role list to permission
for
permission_roles
in
erp5_permission_roles
:
if
modifyRolesForPermission
(
document
,
permission_roles
,
erp5_permission_roles
[
permission_roles
]):
changed
=
1
# Update the group -> role map.
groups
=
self
.
getGroups
()
managed_roles
=
self
.
getRoles
()
if
groups
and
managed_roles
:
for
group
in
groups
:
roles
=
()
if
sdef
.
group_roles
is
not
None
:
roles
=
sdef
.
group_roles
.
get
(
group
,
())
if
modifyRolesForGroup
(
document
,
group
,
roles
,
managed_roles
):
changed
=
1
return
changed
def
_checkTransitionGuard
(
self
,
t
,
document
,
**
kw
):
guard
=
t
.
guard
if
guard
is
None
:
return
1
if
guard
.
check
(
getSecurityManager
(),
self
,
document
,
**
kw
):
return
1
return
### Security feature end
###########
## Graph ##
###########
#
###########
getGraph
=
getGraph
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment