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
alecs_myu
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