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
Thomas Gambier
erp5
Commits
5272e987
Commit
5272e987
authored
Sep 14, 2012
by
Ivan Tyagov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'security_groups'
parents
90fb36be
88e9c81e
Changes
34
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
1704 additions
and
159 deletions
+1704
-159
bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/z_refresh_roles_and_users.xml
...l_skins/erp5_administration/z_refresh_roles_and_users.xml
+2
-2
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_roles_and_users_list.catalog_keys.xml
...ql_innodb/z_catalog_roles_and_users_list.catalog_keys.xml
+5
-0
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_roles_and_users_list.xml
...alog/erp5_mysql_innodb/z_catalog_roles_and_users_list.xml
+84
-0
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_roles_and_users.catalog_keys.xml
...p5_mysql_innodb/z_create_roles_and_users.catalog_keys.xml
+5
-0
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_roles_and_users.xml
...al_catalog/erp5_mysql_innodb/z_create_roles_and_users.xml
+78
-0
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_search_security.catalog_keys.xml
...alog/erp5_mysql_innodb/z_search_security.catalog_keys.xml
+5
-0
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_search_security.xml
...em/portal_catalog/erp5_mysql_innodb/z_search_security.xml
+73
-0
bt5/erp5_security_uid_innodb_catalog/bt/change_log
bt5/erp5_security_uid_innodb_catalog/bt/change_log
+2
-0
bt5/erp5_security_uid_innodb_catalog/bt/description
bt5/erp5_security_uid_innodb_catalog/bt/description
+7
-0
bt5/erp5_security_uid_innodb_catalog/bt/revision
bt5/erp5_security_uid_innodb_catalog/bt/revision
+1
-0
bt5/erp5_security_uid_innodb_catalog/bt/template_catalog_method_id_list
...ity_uid_innodb_catalog/bt/template_catalog_method_id_list
+3
-0
bt5/erp5_security_uid_innodb_catalog/bt/template_format_version
...p5_security_uid_innodb_catalog/bt/template_format_version
+1
-0
bt5/erp5_security_uid_innodb_catalog/bt/title
bt5/erp5_security_uid_innodb_catalog/bt/title
+1
-0
product/ERP5/Document/BusinessTemplate.py
product/ERP5/Document/BusinessTemplate.py
+84
-11
product/ERP5/bootstrap/erp5_core/CategoryTemplateItem/portal_categories/local_role_group.xml
...tegoryTemplateItem/portal_categories/local_role_group.xml
+117
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/BusinessTemplate_viewCatalog.xml
...m/portal_skins/erp5_core/BusinessTemplate_viewCatalog.xml
+1
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/BusinessTemplate_viewCatalog/my_template_catalog_security_uid_column_list.xml
...wCatalog/my_template_catalog_security_uid_column_list.xml
+298
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/RoleInformation_view.xml
...plateItem/portal_skins/erp5_core/RoleInformation_view.xml
+1
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/RoleInformation_view/my_local_roles_group_id.xml
...rp5_core/RoleInformation_view/my_local_roles_group_id.xml
+277
-0
product/ERP5/bootstrap/erp5_core/bt/template_base_category_list
...t/ERP5/bootstrap/erp5_core/bt/template_base_category_list
+1
-0
product/ERP5/bootstrap/erp5_mysql_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_roles_and_users_list.xml
...alog/erp5_mysql_innodb/z_catalog_roles_and_users_list.xml
+6
-9
product/ERP5/bootstrap/erp5_mysql_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_roles_and_users.xml
...al_catalog/erp5_mysql_innodb/z_create_roles_and_users.xml
+6
-0
product/ERP5/bootstrap/erp5_mysql_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_search_security.xml
...em/portal_catalog/erp5_mysql_innodb/z_search_security.xml
+3
-3
product/ERP5/bootstrap/erp5_property_sheets/PropertySheetTemplateItem/portal_property_sheets/BusinessTemplate/template_catalog_security_uid_column_property.xml
...emplate/template_catalog_security_uid_column_property.xml
+59
-0
product/ERP5/bootstrap/erp5_property_sheets/PropertySheetTemplateItem/portal_property_sheets/RoleInformation/local_role_group_category.xml
...erty_sheets/RoleInformation/local_role_group_category.xml
+20
-0
product/ERP5/tests/testBusinessTemplate.py
product/ERP5/tests/testBusinessTemplate.py
+84
-0
product/ERP5Catalog/CatalogTool.py
product/ERP5Catalog/CatalogTool.py
+120
-51
product/ERP5Catalog/tests/testERP5CatalogSecurityUidOptimization.py
...P5Catalog/tests/testERP5CatalogSecurityUidOptimization.py
+191
-0
product/ERP5Security/tests/testERP5Security.py
product/ERP5Security/tests/testERP5Security.py
+23
-0
product/ERP5Type/Core/RoleInformation.py
product/ERP5Type/Core/RoleInformation.py
+0
-1
product/ERP5Type/ERP5Type.py
product/ERP5Type/ERP5Type.py
+27
-16
product/ERP5Type/interfaces/role_provider.py
product/ERP5Type/interfaces/role_provider.py
+1
-1
product/ERP5Type/patches/WorkflowTool.py
product/ERP5Type/patches/WorkflowTool.py
+34
-15
product/ZSQLCatalog/SQLCatalog.py
product/ZSQLCatalog/SQLCatalog.py
+84
-50
No files found.
bt5/erp5_administration/SkinTemplateItem/portal_skins/erp5_administration/z_refresh_roles_and_users.xml
View file @
5272e987
...
@@ -31,8 +31,8 @@
...
@@ -31,8 +31,8 @@
DELETE FROM roles_and_users\n
DELETE FROM roles_and_users\n
<dtml-var sql_delimiter>
\n
<dtml-var sql_delimiter>
\n
INSERT INTO roles_and_users (uid, allowedRolesAndUsers) VALUES\n
INSERT INTO roles_and_users (uid, allowedRolesAndUsers) VALUES\n
<dtml-in
expr=
"getPortalObject().portal_catalog.getSQLCatalog().getRoleAndSecurityUidList()"
>
\n
<dtml-in
expr=
"
role"
expr=
"
getPortalObject().portal_catalog.getSQLCatalog().getRoleAndSecurityUidList()"
>
\n
(
<dtml-sqlvar
sequence-item
type=
"int"
>
,
<dtml-sqlvar
sequence-key
type=
"string"
>
)
<dtml-if
sequence-end
><dtml-else>
,
</dtml-if>
\n
(
<dtml-sqlvar
expr=
"role_item[0]"
type=
"int"
>
,
<dtml-sqlvar
expr=
"role_item[1]"
type=
"string"
>
,
<dtml-sqlvar
expr=
"role_item[2]"
type=
"string"
>
)
<dtml-if
sequence-end
><dtml-else>
,
</dtml-if>
\n
\n
\n
</dtml-in>
</dtml-in>
...
...
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_roles_and_users_list.catalog_keys.xml
0 → 100644
View file @
5272e987
<catalog_method>
<item
key=
"sql_catalog_object_list"
type=
"int"
>
<value>
1
</value>
</item>
</catalog_method>
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_roles_and_users_list.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"SQL"
module=
"Products.ZSQLMethods.SQL"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
allow_simple_one_argument_traversal
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
arguments_src
</string>
</key>
<value>
<string>
optimised_roles_and_users
</string>
</value>
</item>
<item>
<key>
<string>
cache_time_
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
class_file_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
class_name_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
connection_hook
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
connection_id
</string>
</key>
<value>
<string>
erp5_sql_connection
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
z_catalog_roles_and_users_list
</string>
</value>
</item>
<item>
<key>
<string>
max_cache_
</string>
</key>
<value>
<int>
100
</int>
</value>
</item>
<item>
<key>
<string>
max_rows_
</string>
</key>
<value>
<int>
1000
</int>
</value>
</item>
<item>
<key>
<string>
src
</string>
</key>
<value>
<string
encoding=
"cdata"
>
<![CDATA[
<dtml-let row_list="[]">
\n
<dtml-in
prefix=
"loop"
expr=
"_.range(_.len(optimised_roles_and_users))"
>
\n
<dtml-in
prefix=
"role"
expr=
"optimised_roles_and_users[loop_item]"
>
\n
<dtml-call
expr=
"row_list.append([role_item[0], role_item[1], role_item[2]])"
>
\n
</dtml-in>
\n
</dtml-in>
\n
<dtml-if
expr=
"row_list"
>
\n
INSERT INTO\n
roles_and_users(uid, local_roles_group_id, allowedRolesAndUsers)\n
VALUES\n
<dtml-in
prefix=
"row"
expr=
"row_list"
>
\n
(
<dtml-sqlvar
expr=
"row_item[0]"
type=
"string"
>
,
<dtml-sqlvar
expr=
"row_item[1]"
type=
"string"
>
,
<dtml-sqlvar
expr=
"row_item[2]"
type=
"string"
>
)\n
<dtml-if
sequence-end
><dtml-else>
,
</dtml-if>
\n
</dtml-in>
\n
</dtml-if>
\n
</dtml-let>
\n
]]>
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_roles_and_users.catalog_keys.xml
0 → 100644
View file @
5272e987
<catalog_method>
<item
key=
"sql_clear_catalog"
type=
"int"
>
<value>
1
</value>
</item>
</catalog_method>
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_roles_and_users.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"SQL"
module=
"Products.ZSQLMethods.SQL"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_col
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
allow_simple_one_argument_traversal
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
arguments_src
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
cache_time_
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
class_file_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
class_name_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
connection_hook
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
connection_id
</string>
</key>
<value>
<string>
erp5_sql_connection
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
z_create_roles_and_users
</string>
</value>
</item>
<item>
<key>
<string>
max_cache_
</string>
</key>
<value>
<int>
100
</int>
</value>
</item>
<item>
<key>
<string>
max_rows_
</string>
</key>
<value>
<int>
1000
</int>
</value>
</item>
<item>
<key>
<string>
src
</string>
</key>
<value>
<string>
CREATE TABLE roles_and_users (\n
uid INT UNSIGNED,\n
local_roles_group_id VARCHAR(255) default \'\',\n
allowedRolesAndUsers VARCHAR(255),\n
KEY `uid` (`uid`),\n
KEY `allowedRolesAndUsers` (`allowedRolesAndUsers`),\n
KEY `local_roles_group_id` (`local_roles_group_id`)\n
) ENGINE=InnoDB;\n
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_search_security.catalog_keys.xml
0 → 100644
View file @
5272e987
<catalog_method>
<item
key=
"sql_search_security"
type=
"int"
>
<value>
1
</value>
</item>
</catalog_method>
bt5/erp5_security_uid_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_search_security.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"SQL"
module=
"Products.ZSQLMethods.SQL"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
allow_simple_one_argument_traversal
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
arguments_src
</string>
</key>
<value>
<string>
security_roles_list
</string>
</value>
</item>
<item>
<key>
<string>
cache_time_
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
class_file_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
class_name_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
connection_hook
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
connection_id
</string>
</key>
<value>
<string>
erp5_sql_connection
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
z_search_security
</string>
</value>
</item>
<item>
<key>
<string>
max_cache_
</string>
</key>
<value>
<int>
100
</int>
</value>
</item>
<item>
<key>
<string>
max_rows_
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
src
</string>
</key>
<value>
<string
encoding=
"cdata"
>
<![CDATA[
SELECT\n
DISTINCT uid, local_roles_group_id\n
FROM \n
roles_and_users\n
WHERE \n
allowedRolesAndUsers \n
IN (<dtml-in security_roles_list>
<dtml-var
sequence-item
><dtml-if
sequence-end
><dtml-else>
,
</dtml-if></dtml-in>
)\n
]]>
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_security_uid_innodb_catalog/bt/change_log
0 → 100644
View file @
5272e987
2012-07-12 Ivan
* Initial import
\ No newline at end of file
bt5/erp5_security_uid_innodb_catalog/bt/description
0 → 100644
View file @
5272e987
This bt5 provides generic Z SQL methods that allows a site developer to split security uids into different catalog columns.
In order to use this optimization it's required to:
1. Make analyze which are most common uids
2. Place them in a new catalog column
3. Adjust respective z_catalog_object_list and z_create_catalog
Note: In order to use this technique a full catalog re-index is required.
\ No newline at end of file
bt5/erp5_security_uid_innodb_catalog/bt/revision
0 → 100644
View file @
5272e987
3
\ No newline at end of file
bt5/erp5_security_uid_innodb_catalog/bt/template_catalog_method_id_list
0 → 100644
View file @
5272e987
erp5_mysql_innodb/z_catalog_roles_and_users_list
erp5_mysql_innodb/z_create_roles_and_users
erp5_mysql_innodb/z_search_security
\ No newline at end of file
bt5/erp5_security_uid_innodb_catalog/bt/template_format_version
0 → 100644
View file @
5272e987
1
\ No newline at end of file
bt5/erp5_security_uid_innodb_catalog/bt/title
0 → 100644
View file @
5272e987
erp5_security_uid_innodb_catalog
\ No newline at end of file
product/ERP5/Document/BusinessTemplate.py
View file @
5272e987
...
@@ -545,7 +545,7 @@ class BaseTemplateItem(Implicit, Persistent):
...
@@ -545,7 +545,7 @@ class BaseTemplateItem(Implicit, Persistent):
classname
=
klass
.
__name__
classname
=
klass
.
__name__
attr_set
=
set
((
'_dav_writelocks'
,
'_filepath'
,
'_owner'
,
'last_id'
,
'uid'
,
attr_set
=
set
((
'_dav_writelocks'
,
'_filepath'
,
'_owner'
,
'last_id'
,
'uid'
,
'__ac_local_roles__'
))
'__ac_local_roles__'
,
'__ac_local_roles_group_id_dict__'
))
if
export
:
if
export
:
if
not
keep_workflow_history
:
if
not
keep_workflow_history
:
attr_set
.
add
(
'workflow_history'
)
attr_set
.
add
(
'workflow_history'
)
...
@@ -3047,11 +3047,12 @@ class PortalTypeRolesTemplateItem(BaseTemplateItem):
...
@@ -3047,11 +3047,12 @@ class PortalTypeRolesTemplateItem(BaseTemplateItem):
k
=
k
[
5
:]
k
=
k
[
5
:]
elif
k
==
'role_name'
:
elif
k
==
'role_name'
:
k
,
v
=
'id'
,
'; '
.
join
(
v
)
k
,
v
=
'id'
,
'; '
.
join
(
v
)
elif
k
not
in
(
'title'
,
'description'
):
elif
k
not
in
(
'title'
,
'description'
,
'categories'
):
k
=
{
'id'
:
'object_id'
,
# for stable sort
k
=
{
'id'
:
'object_id'
,
# for stable sort
'role_base_category'
:
'base_category'
,
'role_base_category'
:
'base_category'
,
'role_base_category_script_id'
:
'base_category_script'
,
'role_base_category_script_id'
:
'base_category_script'
,
'role_category'
:
'category'
}.
get
(
k
)
'role_category'
:
'category'
,
'local_roles_group_id'
:
'local_roles_group_id'
}.
get
(
k
)
if
not
k
:
if
not
k
:
continue
continue
type_role_dict
[
k
]
=
v
type_role_dict
[
k
]
=
v
...
@@ -3074,7 +3075,7 @@ class PortalTypeRolesTemplateItem(BaseTemplateItem):
...
@@ -3074,7 +3075,7 @@ class PortalTypeRolesTemplateItem(BaseTemplateItem):
xml_data
+=
"
\
n
<property id='%s'>%s</property>"
%
\
xml_data
+=
"
\
n
<property id='%s'>%s</property>"
%
\
(
property
,
prop_value
)
(
property
,
prop_value
)
# multi
# multi
for
property
in
(
'category'
,
'base_category'
):
for
property
in
(
'categor
ies'
,
'categor
y'
,
'base_category'
):
for
prop_value
in
role
.
get
(
property
,
[]):
for
prop_value
in
role
.
get
(
property
,
[]):
if
isinstance
(
prop_value
,
str
):
if
isinstance
(
prop_value
,
str
):
prop_value
=
prop_value
.
decode
(
'utf-8'
)
prop_value
=
prop_value
.
decode
(
'utf-8'
)
...
@@ -3161,7 +3162,7 @@ class PortalTypeRolesTemplateItem(BaseTemplateItem):
...
@@ -3161,7 +3162,7 @@ class PortalTypeRolesTemplateItem(BaseTemplateItem):
path
=
'portal_types/%s'
%
roles_path
.
split
(
'/'
,
1
)[
1
]
path
=
'portal_types/%s'
%
roles_path
.
split
(
'/'
,
1
)[
1
]
try
:
try
:
obj
=
p
.
unrestrictedTraverse
(
path
)
obj
=
p
.
unrestrictedTraverse
(
path
)
setattr
(
obj
,
'_roles'
,
[
])
obj
.
manage_delObjects
([
x
.
id
for
x
in
obj
.
getRoleInformationList
()
])
except
(
NotFound
,
KeyError
):
except
(
NotFound
,
KeyError
):
pass
pass
...
@@ -4360,6 +4361,12 @@ class CatalogLocalRoleKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
...
@@ -4360,6 +4361,12 @@ class CatalogLocalRoleKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_title
=
'local_role_key_list'
key_list_title
=
'local_role_key_list'
key_title
=
'LocalRole key'
key_title
=
'LocalRole key'
class
CatalogSecurityUidColumnTemplateItem
(
CatalogSearchKeyTemplateItem
):
key_list_attr
=
'sql_catalog_security_uid_columns'
key_list_title
=
'security_uid_column_list'
key_title
=
'Security Uid Columns'
class
MessageTranslationTemplateItem
(
BaseTemplateItem
):
class
MessageTranslationTemplateItem
(
BaseTemplateItem
):
def
build
(
self
,
context
,
**
kw
):
def
build
(
self
,
context
,
**
kw
):
...
@@ -4532,13 +4539,27 @@ class LocalRolesTemplateItem(BaseTemplateItem):
...
@@ -4532,13 +4539,27 @@ class LocalRolesTemplateItem(BaseTemplateItem):
obj
=
p
.
unrestrictedTraverse
(
path
.
split
(
'/'
,
1
)[
1
])
obj
=
p
.
unrestrictedTraverse
(
path
.
split
(
'/'
,
1
)[
1
])
local_roles_dict
=
getattr
(
obj
,
'__ac_local_roles__'
,
local_roles_dict
=
getattr
(
obj
,
'__ac_local_roles__'
,
{})
or
{}
{})
or
{}
self
.
_objects
[
path
]
=
(
local_roles_dict
,
)
local_roles_group_id_dict
=
getattr
(
obj
,
'__ac_local_roles_group_id_dict__'
,
{})
or
{}
self
.
_objects
[
path
]
=
(
local_roles_dict
,
local_roles_group_id_dict
)
# Function to generate XML Code Manually
# Function to generate XML Code Manually
def
generateXml
(
self
,
path
=
None
):
def
generateXml
(
self
,
path
=
None
):
local_roles_dict
=
self
.
_objects
[
path
][
0
]
# With local roles groups id, self._object contains for each path a tuple
# local roles
# containing the dict of local roles and the dict of local roles group ids.
# Before it was only containing the dict of local roles. This method is
# also used on installed business templates to show a diff during
# installation, so it might be called on old format objects.
if
len
(
self
.
_objects
[
path
])
==
2
:
# new format
local_roles_dict
,
local_roles_group_id_dict
=
self
.
_objects
[
path
]
else
:
# old format, before local roles group id
local_roles_group_id_dict
=
dict
()
local_roles_dict
,
=
self
.
_objects
[
path
]
xml_data
=
'<local_roles_item>'
xml_data
=
'<local_roles_item>'
# local roles
xml_data
+=
'
\
n
<local_roles>'
xml_data
+=
'
\
n
<local_roles>'
for
key
in
sorted
(
local_roles_dict
):
for
key
in
sorted
(
local_roles_dict
):
xml_data
+=
"
\
n
<role id='%s'>"
%
(
key
,)
xml_data
+=
"
\
n
<role id='%s'>"
%
(
key
,)
...
@@ -4547,6 +4568,20 @@ class LocalRolesTemplateItem(BaseTemplateItem):
...
@@ -4547,6 +4568,20 @@ class LocalRolesTemplateItem(BaseTemplateItem):
xml_data
+=
"
\
n
<item>%s</item>"
%
(
item
,)
xml_data
+=
"
\
n
<item>%s</item>"
%
(
item
,)
xml_data
+=
'
\
n
</role>'
xml_data
+=
'
\
n
</role>'
xml_data
+=
'
\
n
</local_roles>'
xml_data
+=
'
\
n
</local_roles>'
if
local_roles_group_id_dict
:
# local roles group id dict (not included by default to be stable with
# old bts)
xml_data
+=
'
\
n
<local_roles_group_id>'
for
principal
,
local_roles_group_id_list
in
sorted
(
local_roles_group_id_dict
.
items
()):
xml_data
+=
"
\
n
<principal id='%s'>"
%
escape
(
principal
)
for
local_roles_group_id
in
local_roles_group_id_list
:
for
item
in
local_roles_group_id
:
xml_data
+=
"
\
n
<local_roles_group_id>%s</local_roles_group_id>"
%
\
escape
(
item
)
xml_data
+=
"
\
n
</principal>"
xml_data
+=
'
\
n
</local_roles_group_id>'
xml_data
+=
'
\
n
</local_roles_item>'
xml_data
+=
'
\
n
</local_roles_item>'
if
isinstance
(
xml_data
,
unicode
):
if
isinstance
(
xml_data
,
unicode
):
xml_data
=
xml_data
.
encode
(
'utf8'
)
xml_data
=
xml_data
.
encode
(
'utf8'
)
...
@@ -4571,7 +4606,15 @@ class LocalRolesTemplateItem(BaseTemplateItem):
...
@@ -4571,7 +4606,15 @@ class LocalRolesTemplateItem(BaseTemplateItem):
id
=
role
.
get
(
'id'
)
id
=
role
.
get
(
'id'
)
item_type_list
=
[
item
.
text
for
item
in
role
]
item_type_list
=
[
item
.
text
for
item
in
role
]
local_roles_dict
[
id
]
=
item_type_list
local_roles_dict
[
id
]
=
item_type_list
self
.
_objects
[
'local_roles/%s'
%
(
file_name
[:
-
4
],)]
=
(
local_roles_dict
,
)
# local roles group id
local_roles_group_id_dict
=
{}
for
principal
in
xml
.
findall
(
'//principal'
):
local_roles_group_id_dict
[
principal
.
get
(
'id'
)]
=
set
([
tuple
(
[
group_id
.
text
for
group_id
in
principal
.
findall
(
'./local_roles_group_id'
)])])
self
.
_objects
[
'local_roles/%s'
%
(
file_name
[:
-
4
],)]
=
(
local_roles_dict
,
local_roles_group_id_dict
)
def
install
(
self
,
context
,
trashbin
,
**
kw
):
def
install
(
self
,
context
,
trashbin
,
**
kw
):
update_dict
=
kw
.
get
(
'object_to_update'
)
update_dict
=
kw
.
get
(
'object_to_update'
)
...
@@ -4585,8 +4628,22 @@ class LocalRolesTemplateItem(BaseTemplateItem):
...
@@ -4585,8 +4628,22 @@ class LocalRolesTemplateItem(BaseTemplateItem):
continue
continue
path
=
roles_path
.
split
(
'/'
)[
1
:]
path
=
roles_path
.
split
(
'/'
)[
1
:]
obj
=
p
.
unrestrictedTraverse
(
path
)
obj
=
p
.
unrestrictedTraverse
(
path
)
local_roles_dict
=
self
.
_objects
[
roles_path
][
0
]
# again we might be installing an business template in format before
# existance of local roles group id.
if
len
(
self
.
_objects
[
roles_path
])
==
2
:
local_roles_dict
,
local_roles_group_id_dict
=
self
.
_objects
[
roles_path
]
else
:
local_roles_group_id_dict
=
dict
()
local_roles_dict
,
=
self
.
_objects
[
roles_path
]
setattr
(
obj
,
'__ac_local_roles__'
,
local_roles_dict
)
setattr
(
obj
,
'__ac_local_roles__'
,
local_roles_dict
)
if
local_roles_group_id_dict
:
setattr
(
obj
,
'__ac_local_roles_group_id_dict__'
,
local_roles_group_id_dict
)
# we try to have __ac_local_roles_group_id_dict__ set only if
# it is actually defining something else than default
elif
getattr
(
aq_base
(
obj
),
'__ac_local_roles_group_id_dict__'
,
None
)
is
not
None
:
delattr
(
obj
,
'__ac_local_roles_group_id_dict__'
)
obj
.
reindexObject
()
obj
.
reindexObject
()
def
uninstall
(
self
,
context
,
object_path
=
None
,
**
kw
):
def
uninstall
(
self
,
context
,
object_path
=
None
,
**
kw
):
...
@@ -4748,6 +4805,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
...
@@ -4748,6 +4805,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
'_catalog_scriptable_key_item'
,
'_catalog_scriptable_key_item'
,
'_catalog_role_key_item'
,
'_catalog_role_key_item'
,
'_catalog_local_role_key_item'
,
'_catalog_local_role_key_item'
,
'_catalog_security_uid_column_item'
,
]
]
def
__init__
(
self
,
*
args
,
**
kw
):
def
__init__
(
self
,
*
args
,
**
kw
):
...
@@ -4910,6 +4968,14 @@ Business Template is a set of definitions, such as skins, portal types and categ
...
@@ -4910,6 +4968,14 @@ Business Template is a set of definitions, such as skins, portal types and categ
self
.
_catalog_local_role_key_item
=
\
self
.
_catalog_local_role_key_item
=
\
CatalogLocalRoleKeyTemplateItem
(
CatalogLocalRoleKeyTemplateItem
(
self
.
getTemplateCatalogLocalRoleKeyList
())
self
.
getTemplateCatalogLocalRoleKeyList
())
try
:
self
.
_catalog_security_uid_column_item
=
\
CatalogSecurityUidColumnTemplateItem
(
self
.
getTemplateCatalogSecurityUidColumnList
())
except
AttributeError
:
# be backwards compatible with old zope instances which
# do not contain recent version of erp5_property_sheets
pass
security
.
declareProtected
(
Permissions
.
ManagePortal
,
'build'
)
security
.
declareProtected
(
Permissions
.
ManagePortal
,
'build'
)
def
build
(
self
,
no_action
=
0
):
def
build
(
self
,
no_action
=
0
):
...
@@ -5523,7 +5589,12 @@ Business Template is a set of definitions, such as skins, portal types and categ
...
@@ -5523,7 +5589,12 @@ Business Template is a set of definitions, such as skins, portal types and categ
(
SimpleItem
.
SimpleItem
,),
{
'__module__'
:
module_id
}))
(
SimpleItem
.
SimpleItem
,),
{
'__module__'
:
module_id
}))
for
item_name
in
self
.
_item_name_list
:
for
item_name
in
self
.
_item_name_list
:
getattr
(
self
,
item_name
).
importFile
(
bta
)
item_object
=
getattr
(
self
,
item_name
,
None
)
# this check is due to backwards compatability when there can be a
# difference between install erp5_property_sheets (esp. BusinessTemplate
# property sheet)
if
item_object
is
not
None
:
item_object
.
importFile
(
bta
)
# Remove temporary modules created above to allow import of real modules
# Remove temporary modules created above to allow import of real modules
# (during the installation).
# (during the installation).
...
@@ -5631,6 +5702,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
...
@@ -5631,6 +5702,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
'CatalogScriptableKey'
:
'_catalog_scriptable_key_item'
,
'CatalogScriptableKey'
:
'_catalog_scriptable_key_item'
,
'CatalogRoleKey'
:
'_catalog_role_key_item'
,
'CatalogRoleKey'
:
'_catalog_role_key_item'
,
'CatalogLocalRoleKey'
:
'_catalog_local_role_key_item'
,
'CatalogLocalRoleKey'
:
'_catalog_local_role_key_item'
,
'CatalogSecurityUidColumn'
:
'_catalog_security_uid_column_item'
,
}
}
object_id
=
REQUEST
.
object_id
object_id
=
REQUEST
.
object_id
...
@@ -5693,6 +5765,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
...
@@ -5693,6 +5765,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
'_catalog_scriptable_key_item'
,
'_catalog_scriptable_key_item'
,
'_catalog_role_key_item'
,
'_catalog_role_key_item'
,
'_catalog_local_role_key_item'
,
'_catalog_local_role_key_item'
,
'_catalog_security_uid_column_item'
,
'_portal_type_allowed_content_type_item'
,
'_portal_type_allowed_content_type_item'
,
'_portal_type_hidden_content_type_item'
,
'_portal_type_hidden_content_type_item'
,
'_portal_type_property_sheet_item'
,
'_portal_type_property_sheet_item'
,
...
...
product/ERP5/bootstrap/erp5_core/CategoryTemplateItem/portal_categories/local_role_group.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Base Category"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_Add_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Add_portal_folders_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Copy_or_Move_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Delete_objects_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Modify_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
<string>
Owner
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_count
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
_mt_index
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
_tree
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
local_role_group
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Base Category
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Local Role Group
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Length"
module=
"BTrees.Length"
/>
</pickle>
<pickle>
<int>
0
</int>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"OOBTree"
module=
"BTrees.OOBTree"
/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"OOBTree"
module=
"BTrees.OOBTree"
/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/BusinessTemplate_viewCatalog.xml
View file @
5272e987
...
@@ -91,6 +91,7 @@
...
@@ -91,6 +91,7 @@
<string>
my_template_catalog_topic_key_list
</string>
<string>
my_template_catalog_topic_key_list
</string>
<string>
my_template_catalog_scriptable_key_list
</string>
<string>
my_template_catalog_scriptable_key_list
</string>
<string>
my_template_catalog_local_role_key_list
</string>
<string>
my_template_catalog_local_role_key_list
</string>
<string>
my_template_catalog_security_uid_column_list
</string>
</list>
</list>
</value>
</value>
</item>
</item>
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/BusinessTemplate_viewCatalog/my_template_catalog_security_uid_column_list.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"LinesField"
module=
"Products.Formulator.StandardFields"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_template_catalog_security_uid_column_list
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
<item>
<key>
<string>
line_too_long
</string>
</key>
<value>
<string>
A line was too long.
</string>
</value>
</item>
<item>
<key>
<string>
required_not_found
</string>
</key>
<value>
<string>
Input is required but no input given.
</string>
</value>
</item>
<item>
<key>
<string>
too_long
</string>
</key>
<value>
<string>
You entered too many characters.
</string>
</value>
</item>
<item>
<key>
<string>
too_many_lines
</string>
</key>
<value>
<string>
You entered too many lines.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
height
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_length
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_linelength
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_lines
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
unicode
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
view_separator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
width
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
height
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_length
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_linelength
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_lines
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
unicode
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
view_separator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
width
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
height
</string>
</key>
<value>
<int>
5
</int>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
max_length
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_linelength
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
max_lines
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Security Uid Columns
</string>
</value>
</item>
<item>
<key>
<string>
unicode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
view_separator
</string>
</key>
<value>
<string
encoding=
"cdata"
>
<![CDATA[
<br />
]]>
</string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
width
</string>
</key>
<value>
<int>
40
</int>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/RoleInformation_view.xml
View file @
5272e987
...
@@ -98,6 +98,7 @@
...
@@ -98,6 +98,7 @@
<string>
my_title
</string>
<string>
my_title
</string>
<string>
my_role_name_list
</string>
<string>
my_role_name_list
</string>
<string>
my_condition
</string>
<string>
my_condition
</string>
<string>
my_local_roles_group_id
</string>
</list>
</list>
</value>
</value>
</item>
</item>
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/RoleInformation_view/my_local_roles_group_id.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ListField"
module=
"Products.Formulator.StandardFields"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_local_roles_group_id
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
<item>
<key>
<string>
required_not_found
</string>
</key>
<value>
<string>
Input is required but no input given.
</string>
</value>
</item>
<item>
<key>
<string>
unknown_selection
</string>
</key>
<value>
<string>
You selected an item that was not in the list.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra_item
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
first_item
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
unicode
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra_item
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
first_item
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
unicode
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra_item
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
first_item
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Local Roles Group
</string>
</value>
</item>
<item>
<key>
<string>
unicode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python: [(x,x) for x in context.getPortalObject().portal_catalog.getSQLCatalog().getSQLCatalogSecurityUidGroupsColumnsDict().keys()]
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/bt/template_base_category_list
View file @
5272e987
...
@@ -16,6 +16,7 @@ destination_project
...
@@ -16,6 +16,7 @@ destination_project
destination_section
destination_section
destination_trade
destination_trade
elementary_type
elementary_type
local_role_group
mapping
mapping
order
order
origin
origin
...
...
product/ERP5/bootstrap/erp5_mysql_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_roles_and_users_list.xml
View file @
5272e987
...
@@ -14,8 +14,7 @@
...
@@ -14,8 +14,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
arguments_src
</string>
</key>
<key>
<string>
arguments_src
</string>
</key>
<value>
<string>
security_uid\r\n
<value>
<string>
optimised_roles_and_users
</string>
</value>
optimised_roles_and_users
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
cache_time_
</string>
</key>
<key>
<string>
cache_time_
</string>
</key>
...
@@ -56,16 +55,14 @@ optimised_roles_and_users</string> </value>
...
@@ -56,16 +55,14 @@ optimised_roles_and_users</string> </value>
<value>
<string
encoding=
"cdata"
>
<![CDATA[
<value>
<string
encoding=
"cdata"
>
<![CDATA[
<dtml-let row_list="[]">
\n
<dtml-let row_list="[]">
\n
<dtml-in
prefix=
"loop"
expr=
"_.range(_.len(security_uid))"
>
\n
<dtml-in
prefix=
"loop"
expr=
"_.range(_.len(optimised_roles_and_users))"
>
\n
<dtml-if
expr=
"optimised_roles_and_users[loop_item]"
>
\n
<dtml-in
prefix=
"role"
expr=
"optimised_roles_and_users[loop_item]"
>
\n
<dtml-in
prefix=
"role"
expr=
"optimised_roles_and_users[loop_item]"
>
\n
<dtml-call
expr=
"row_list.append([role_item[0], role_item[2]])"
>
\n
<dtml-call
expr=
"row_list.append([security_uid[loop_item], role_item])"
>
\n
</dtml-in>
\n
</dtml-in>
\n
</dtml-if>
\n
</dtml-in>
\n
</dtml-in>
\n
<dtml-if
expr=
"row_list"
>
\n
<dtml-if
expr=
"row_list"
>
\n
INSERT INTO\n
INSERT INTO\n
roles_and_users\n
roles_and_users
(uid, allowedRolesAndUsers)
\n
VALUES\n
VALUES\n
<dtml-in
prefix=
"row"
expr=
"row_list"
>
\n
<dtml-in
prefix=
"row"
expr=
"row_list"
>
\n
(
<dtml-sqlvar
expr=
"row_item[0]"
type=
"string"
>
,
<dtml-sqlvar
expr=
"row_item[1]"
type=
"string"
>
)\n
(
<dtml-sqlvar
expr=
"row_item[0]"
type=
"string"
>
,
<dtml-sqlvar
expr=
"row_item[1]"
type=
"string"
>
)\n
...
...
product/ERP5/bootstrap/erp5_mysql_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_roles_and_users.xml
View file @
5272e987
...
@@ -6,6 +6,12 @@
...
@@ -6,6 +6,12 @@
</pickle>
</pickle>
<pickle>
<pickle>
<dictionary>
<dictionary>
<item>
<key>
<string>
_col
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<item>
<key>
<string>
allow_simple_one_argument_traversal
</string>
</key>
<key>
<string>
allow_simple_one_argument_traversal
</string>
</key>
<value>
<value>
...
...
product/ERP5/bootstrap/erp5_mysql_innodb_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_search_security.xml
View file @
5272e987
...
@@ -52,10 +52,10 @@
...
@@ -52,10 +52,10 @@
<key>
<string>
src
</string>
</key>
<key>
<string>
src
</string>
</key>
<value>
<string
encoding=
"cdata"
>
<![CDATA[
<value>
<string
encoding=
"cdata"
>
<![CDATA[
SELECT
\n
SELECT\n
DISTINCT uid
\n
DISTINCT uid\n
FROM \n
FROM \n
roles_and_users
\n
roles_and_users\n
WHERE \n
WHERE \n
allowedRolesAndUsers \n
allowedRolesAndUsers \n
IN (<dtml-in security_roles_list>
<dtml-var
sequence-item
><dtml-if
sequence-end
><dtml-else>
,
</dtml-if></dtml-in>
)\n
IN (<dtml-in security_roles_list>
<dtml-var
sequence-item
><dtml-if
sequence-end
><dtml-else>
,
</dtml-if></dtml-in>
)\n
...
...
product/ERP5/bootstrap/erp5_property_sheets/PropertySheetTemplateItem/portal_property_sheets/BusinessTemplate/template_catalog_security_uid_column_property.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Standard Property"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_local_properties
</string>
</key>
<value>
<tuple>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
mode
</string>
</value>
</item>
<item>
<key>
<string>
type
</string>
</key>
<value>
<string>
string
</string>
</value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
elementary_type/lines
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
template_catalog_security_uid_column_property
</string>
</value>
</item>
<item>
<key>
<string>
mode
</string>
</key>
<value>
<string>
w
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Standard Property
</string>
</value>
</item>
<item>
<key>
<string>
property_default
</string>
</key>
<value>
<string>
python: ()
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_property_sheets/PropertySheetTemplateItem/portal_property_sheets/RoleInformation/local_role_group_category.xml
0 → 100644
View file @
5272e987
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Category Property"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
local_role_group_category
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Category Property
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/tests/testBusinessTemplate.py
View file @
5272e987
...
@@ -6597,6 +6597,90 @@ class TestBusinessTemplate(BusinessTemplateMixin):
...
@@ -6597,6 +6597,90 @@ class TestBusinessTemplate(BusinessTemplateMixin):
new_bt5_obj
.
build
()
new_bt5_obj
.
build
()
template_tool
.
export
(
new_bt5_obj
)
template_tool
.
export
(
new_bt5_obj
)
def
test_local_roles_group_id
(
self
):
"""Tests that roles definition defining local roles group ids are properly
exported and installed.
"""
# change security uid columns
sql_catalog
=
self
.
portal
.
portal_catalog
.
getSQLCatalog
()
saved_sql_catalog_security_uid_columns
=
\
sql_catalog
.
sql_catalog_security_uid_columns
sql_catalog
.
sql_catalog_security_uid_columns
=
(
' | security_uid'
,
'Alternate | alternate_security_uid'
,
)
# add category
self
.
portal
.
portal_categories
.
local_role_group
.
newContent
(
portal_type
=
'Category'
,
reference
=
'Alternate'
,
id
=
'Alternate'
)
types_tool
=
self
.
portal
.
portal_types
object_type
=
types_tool
.
newContent
(
'Geek Object'
,
'Base Type'
,
type_class
=
'Person'
)
types_tool
.
newContent
(
'Geek Module'
,
'Base Type'
,
type_class
=
'Folder'
,
type_filter_content_type
=
1
,
type_allowed_content_type_list
=
(
'Geek Object'
,),
)
self
.
portal
.
newContent
(
portal_type
=
'Geek Module'
,
id
=
'geek_module'
)
new_object
=
self
.
portal
.
geek_module
.
newContent
(
portal_type
=
'Geek Object'
,
id
=
'1'
)
# simulate role assignment
new_object
.
__ac_local_roles__
=
dict
(
group
=
[
'Assignee'
])
initial___ac_local_roles_group_id_dict__
=
dict
(
Alternate
=
set
([(
'group'
,
'Assignee'
)]))
new_object
.
__ac_local_roles_group_id_dict__
=
initial___ac_local_roles_group_id_dict__
self
.
tic
()
object_type
.
newContent
(
portal_type
=
'Role Information'
,
local_role_group_value
=
self
.
portal
.
portal_categories
.
local_role_group
.
Alternate
.
getRelativeUrl
(),
role_name_list
=
(
'Assignee'
,
))
bt
=
self
.
portal
.
portal_templates
.
newContent
(
portal_type
=
'Business Template'
,
title
=
self
.
id
(),
template_local_roles_list
=
(
'geek_module/1'
,),
template_path_list
=
(
'geek_module/1'
,),
template_portal_type_role_list
=
(
'Geek Object'
,),)
self
.
tic
()
bt
.
build
()
self
.
tic
()
export_dir
=
tempfile
.
mkdtemp
()
try
:
bt
.
export
(
path
=
export_dir
,
local
=
True
)
self
.
tic
()
new_bt
=
self
.
portal
.
portal_templates
.
download
(
url
=
'file://%s'
%
export_dir
)
finally
:
shutil
.
rmtree
(
export_dir
)
# uninstall role information and paths
object_type
.
manage_delObjects
([
x
.
id
for
x
in
object_type
.
getRoleInformationList
()])
self
.
portal
.
geek_module
.
manage_delObjects
([
'1'
])
self
.
tic
()
new_bt
.
install
()
try
:
role
,
=
object_type
.
getRoleInformationList
()
self
.
assertEquals
(
self
.
portal
.
portal_categories
.
local_role_group
.
Alternate
,
role
.
getLocalRoleGroupValue
())
path
=
self
.
portal
.
geek_module
[
'1'
]
self
.
assertEquals
([(
'group'
,
[
'Assignee'
],)],
[
item
for
item
in
path
.
__ac_local_roles__
.
items
()
if
item
[
1
]
!=
[
'Owner'
]])
self
.
assertEquals
(
initial___ac_local_roles_group_id_dict__
,
path
.
__ac_local_roles_group_id_dict__
)
finally
:
# restore state
sql_catalog
.
sql_catalog_security_uid_columns
=
\
saved_sql_catalog_security_uid_columns
types_tool
.
manage_delObjects
([
'Geek Object'
,
'Geek Module'
])
self
.
portal
.
manage_delObjects
([
'geek_module'
])
self
.
tic
()
def
test_BusinessTemplateWithTest
(
self
):
def
test_BusinessTemplateWithTest
(
self
):
sequence_list
=
SequenceList
()
sequence_list
=
SequenceList
()
sequence_string
=
'
\
sequence_string
=
'
\
...
...
product/ERP5Catalog/CatalogTool.py
View file @
5272e987
...
@@ -101,52 +101,82 @@ class IndexableObjectWrapper(object):
...
@@ -101,52 +101,82 @@ class IndexableObjectWrapper(object):
getSQLCatalogRoleKeysList
())
getSQLCatalogRoleKeysList
())
getUserById
=
portal
.
acl_users
.
getUserById
getUserById
=
portal
.
acl_users
.
getUserById
allowed_dict
=
dict
()
# For each local role of a user:
# For each local role of a user:
# If the local role grants View permission, add it.
# If the local role grants View permission, add it.
# Every addition implies 2 lines:
# Every addition implies 2 lines:
# user:<user_id>
# user:<user_id>
# user:<user_id>:<role_id>
# user:<user_id>:<role_id>
# A line must not be present twice in final result.
# A line must not be present twice in final result.
allowed
=
set
(
rolesForPermissionOn
(
'View'
,
ob
))
allowed
_role_set
=
set
(
rolesForPermissionOn
(
'View'
,
ob
))
# XXX the permission name is included by default for verbose
# XXX the permission name is included by default for verbose
# logging of security errors, but the catalog does not need to
# logging of security errors, but the catalog does not need to
# index it. Unfortunately, rolesForPermissionOn does not have
# index it. Unfortunately, rolesForPermissionOn does not have
# an option to disable this behavior at calling time, so
# an option to disable this behavior at calling time, so
# discard it explicitly.
# discard it explicitly.
allowed
.
discard
(
'_View_Permission'
)
allowed
_role_set
.
discard
(
'_View_Permission'
)
# XXX Owner is hardcoded, in order to prevent searching for user on the
# XXX Owner is hardcoded, in order to prevent searching for user on the
# site root.
# site root.
allowed
.
discard
(
'Owner'
)
allowed_role_set
.
discard
(
'Owner'
)
add
=
allowed
.
add
# XXX make this a method of base ?
local_roles_group_id_group_id
=
getattr
(
ob
,
'__ac_local_roles_group_id_dict__'
,
dict
())
allowed_by_local_roles_group_id
=
{}
allowed_by_local_roles_group_id
[
''
]
=
allowed_role_set
user_role_dict
=
{}
user_role_dict
=
{}
user_view_permission_role_dict
=
{}
user_view_permission_role_dict
=
{}
optimized_role_set
=
set
()
# First parse optimized roles and build optimized_role_set
for
role_definition_group
,
user_and_role_list
in
local_roles_group_id_group_id
.
items
():
try
:
group_allowed_set
=
allowed_by_local_roles_group_id
[
role_definition_group
]
except
KeyError
:
allowed_by_local_roles_group_id
[
role_definition_group
]
=
group_allowed_set
=
set
()
for
user
,
role
in
user_and_role_list
:
prefix
=
'user:'
+
user
group_allowed_set
.
update
((
prefix
,
'%s:%s'
%
(
prefix
,
role
)))
optimized_role_set
.
add
((
user
,
role
))
# Then parse other roles
for
user
,
roles
in
localroles
.
iteritems
():
for
user
,
roles
in
localroles
.
iteritems
():
prefix
=
'user:'
+
user
prefix
=
'user:'
+
user
for
role
in
roles
:
for
role
in
roles
:
if
(
role
in
role_dict
)
and
(
getUserById
(
user
)
is
not
None
):
if
(
role
in
role_dict
)
and
(
getUserById
(
user
)
is
not
None
):
# If role is monovalued, check if key is a user.
# If role is monovalued, check if key is a user.
# If not, continue to index it in roles_and_users table.
# If not, continue to index it in roles_and_users table.
user_role_dict
[
role
]
=
user
if
(
user
,
role
)
not
in
optimized_role_set
:
if
role
in
allowed
:
user_role_dict
[
role
]
=
user
# Only add to user_role_dict if not in optimized_role_set (double check)
if
role
in
allowed_role_set
:
user_view_permission_role_dict
[
role
]
=
user
user_view_permission_role_dict
[
role
]
=
user
elif
role
in
allowed
:
elif
role
in
allowed_role_set
:
add
(
prefix
)
for
group
in
local_roles_group_id_group_id
.
get
(
user
,
(
''
,
)):
add
(
prefix
+
':'
+
role
)
try
:
group_allowed_set
=
allowed_by_local_roles_group_id
[
group
]
self
.
_cache_result
=
result
=
(
sorted
(
allowed
),
user_role_dict
,
except
KeyError
:
allowed_by_local_roles_group_id
[
group
]
=
group_allowed_set
=
set
()
if
(
user
,
role
)
not
in
optimized_role_set
:
# add only if not already added to optimized_role_set to avoid polluting indexation table
group_allowed_set
.
update
((
prefix
,
'%s:%s'
%
(
prefix
,
role
)))
# sort `allowed` principals
sorted_allowed_by_local_roles_group_id
=
{}
for
local_roles_group_id
,
allowed
in
\
allowed_by_local_roles_group_id
.
items
():
sorted_allowed_by_local_roles_group_id
[
local_roles_group_id
]
=
tuple
(
sorted
(
allowed
))
self
.
_cache_result
=
result
=
(
sorted_allowed_by_local_roles_group_id
,
user_role_dict
,
user_view_permission_role_dict
)
user_view_permission_role_dict
)
return
result
return
result
def
allowedRolesAndUsers
(
self
):
def
getLocalRolesGroupIdDict
(
self
):
"""
"""Returns a mapping of local roles group id to roles and users with View
Return a list of roles and users with View permission.
permission.
Used by Portal Catalog to filter out items you're not allowed to see.
WARNING (XXX): some user base local role association is currently
being stored (ex. to be determined). This should be prevented or it will
make the table explode. To analyse the symptoms, look at the
user_and_roles table. You will find some user:foo values
which are not necessary.
"""
"""
return
self
.
_getSecurityParameterList
()[
0
]
return
self
.
_getSecurityParameterList
()[
0
]
...
@@ -456,13 +486,12 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
...
@@ -456,13 +486,12 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
allowedRolesAndUsers
=
new_allowedRolesAndUsers
allowedRolesAndUsers
=
new_allowedRolesAndUsers
role_column_dict
=
new_role_column_dict
role_column_dict
=
new_role_column_dict
return
allowedRolesAndUsers
,
role_column_dict
,
local_role_column_dict
return
allowedRolesAndUsers
,
role_column_dict
,
local_role_column_dict
def
getSecurityUid
Lis
tAndRoleColumnDict
(
self
,
sql_catalog_id
=
None
,
**
kw
):
def
getSecurityUid
Dic
tAndRoleColumnDict
(
self
,
sql_catalog_id
=
None
,
**
kw
):
"""
"""
Return a
list of security Uids and a dictionnary containing available
Return a
dict of local_roles_group_id -> security Uids and a
role columns.
dictionnary containing available
role columns.
XXX: This method always uses default catalog. This should not break a
XXX: This method always uses default catalog. This should not break a
site as long as security uids are considered consistent among all
site as long as security uids are considered consistent among all
...
@@ -477,30 +506,40 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
...
@@ -477,30 +506,40 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
cache_key
=
tuple
(
allowedRolesAndUsers
)
cache_key
=
tuple
(
allowedRolesAndUsers
)
tv
=
getTransactionalVariable
()
tv
=
getTransactionalVariable
()
try
:
try
:
security_uid_cache
=
tv
[
'getSecurityUid
Lis
tAndRoleColumnDict'
]
security_uid_cache
=
tv
[
'getSecurityUid
Dic
tAndRoleColumnDict'
]
except
KeyError
:
except
KeyError
:
security_uid_cache
=
tv
[
'getSecurityUid
Lis
tAndRoleColumnDict'
]
=
{}
security_uid_cache
=
tv
[
'getSecurityUid
Dic
tAndRoleColumnDict'
]
=
{}
try
:
try
:
security_uid_
lis
t
=
security_uid_cache
[
cache_key
]
security_uid_
dic
t
=
security_uid_cache
[
cache_key
]
except
KeyError
:
except
KeyError
:
if
method
is
None
:
if
method
is
None
:
warnings
.
warn
(
"The usage of allowedRolesAndUsers is "
\
warnings
.
warn
(
"The usage of allowedRolesAndUsers is "
\
"deprecated. Please update your catalog "
\
"deprecated. Please update your catalog "
\
"business template."
,
DeprecationWarning
)
"business template."
,
DeprecationWarning
)
security_uid_
list
=
[
x
.
security_uid
for
x
in
\
security_uid_
dict
=
{
None
:
[
x
.
security_uid
for
x
in
\
self
.
unrestrictedSearchResults
(
self
.
unrestrictedSearchResults
(
allowedRolesAndUsers
=
allowedRolesAndUsers
,
allowedRolesAndUsers
=
allowedRolesAndUsers
,
select_expression
=
"security_uid"
,
select_expression
=
"security_uid"
,
group_by_expression
=
"security_uid"
)]
group_by_expression
=
"security_uid"
)]
}
else
:
else
:
# XXX: What with this string transformation ?! Souldn't it be done in
# XXX: What with this string transformation ?! Souldn't it be done in
# dtml instead ?
# dtml instead ?
... yes, but how to be bw compatible ?
allowedRolesAndUsers
=
[
sqlquote
(
role
)
for
role
in
allowedRolesAndUsers
]
allowedRolesAndUsers
=
[
sqlquote
(
role
)
for
role
in
allowedRolesAndUsers
]
security_uid_list
=
[
x
.
uid
for
x
in
method
(
security_roles_list
=
allowedRolesAndUsers
)]
security_uid_cache
[
cache_key
]
=
security_uid_list
security_uid_dict
=
dict
()
for
brain
in
method
(
security_roles_list
=
allowedRolesAndUsers
):
try
:
local_roles_group_id
=
brain
.
local_roles_group_id
except
AttributeError
:
# backwards compatability in cases when catalog use default schema
local_roles_group_id
=
''
security_uid_dict
.
setdefault
(
local_roles_group_id
,
[]).
append
(
brain
.
uid
)
security_uid_cache
[
cache_key
]
=
security_uid_dict
else
:
else
:
security_uid_
lis
t
=
[]
security_uid_
dic
t
=
[]
return
security_uid_
lis
t
,
role_column_dict
,
local_role_column_dict
return
security_uid_
dic
t
,
role_column_dict
,
local_role_column_dict
security
.
declarePublic
(
'getSecurityQuery'
)
security
.
declarePublic
(
'getSecurityQuery'
)
def
getSecurityQuery
(
self
,
query
=
None
,
sql_catalog_id
=
None
,
**
kw
):
def
getSecurityQuery
(
self
,
query
=
None
,
sql_catalog_id
=
None
,
**
kw
):
...
@@ -516,24 +555,42 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
...
@@ -516,24 +555,42 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
# We need no security check for super user.
# We need no security check for super user.
return
query
return
query
original_query
=
query
original_query
=
query
security_uid_list
,
role_column_dict
,
local_role_column_dict
=
\
security_uid_dict
,
role_column_dict
,
local_role_column_dict
=
\
self
.
getSecurityUidListAndRoleColumnDict
(
self
.
getSecurityUidDictAndRoleColumnDict
(
sql_catalog_id
=
sql_catalog_id
,
**
kw
)
sql_catalog_id
=
sql_catalog_id
,
**
kw
)
role_query
=
None
security_uid_query
=
None
if
role_column_dict
:
if
role_column_dict
:
query_list
=
[]
query_list
=
[]
for
key
,
value
in
role_column_dict
.
items
():
for
key
,
value
in
role_column_dict
.
items
():
new_query
=
Query
(
**
{
key
:
value
})
new_query
=
Query
(
**
{
key
:
value
})
query_list
.
append
(
new_query
)
query_list
.
append
(
new_query
)
operator_kw
=
{
'operator'
:
'OR'
}
operator_kw
=
{
'operator'
:
'OR'
}
query
=
ComplexQuery
(
*
query_list
,
**
operator_kw
)
role_query
=
ComplexQuery
(
*
query_list
,
**
operator_kw
)
# If security_uid_list is empty, adding it to criterions will only
if
security_uid_dict
:
# result in "false or [...]", so avoid useless overhead by not
catalog_security_uid_groups_columns_dict
=
\
# adding it at all.
self
.
getSQLCatalog
().
getSQLCatalogSecurityUidGroupsColumnsDict
()
if
security_uid_list
:
query
=
ComplexQuery
(
Query
(
security_uid
=
security_uid_list
,
operator
=
'IN'
),
query_list
=
[]
query
,
operator
=
'OR'
)
for
local_roles_group_id
,
security_uid_list
in
\
elif
security_uid_list
:
security_uid_dict
.
iteritems
():
query
=
Query
(
security_uid
=
security_uid_list
,
operator
=
'IN'
)
assert
security_uid_list
query_list
.
append
(
Query
(
**
{
catalog_security_uid_groups_columns_dict
[
local_roles_group_id
]:
security_uid_list
,
'operator'
:
'IN'
}))
security_uid_query
=
ComplexQuery
(
*
query_list
,
operator
=
'OR'
)
if
role_query
:
if
security_uid_query
:
# merge
query
=
ComplexQuery
(
security_uid_query
,
role_query
,
operator
=
'OR'
)
else
:
query
=
role_query
elif
security_uid_query
:
query
=
security_uid_query
else
:
else
:
# XXX A false query has to be generated.
# XXX A false query has to be generated.
# As it is not possible to use SQLKey for now, pass impossible value
# As it is not possible to use SQLKey for now, pass impossible value
...
@@ -672,16 +729,28 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
...
@@ -672,16 +729,28 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
else
:
else
:
document_w
=
w
document_w
=
w
(
security_uid
,
optimised_roles_and_users
)
=
catalog
.
getSecurityUid
(
document_w
)
(
security_uid_dict
,
optimised_roles_and_users
)
=
\
#LOG('catalog_object optimised_roles_and_users', 0, str(optimised_roles_and_users))
catalog
.
getSecurityUidDict
(
document_w
)
# XXX we should build vars begore building the wrapper
w
.
optimised_roles_and_users
=
optimised_roles_and_users
w
.
optimised_roles_and_users
=
optimised_roles_and_users
catalog_security_uid_groups_columns_dict
=
\
catalog
.
getSQLCatalogSecurityUidGroupsColumnsDict
()
default_security_uid_column
=
catalog_security_uid_groups_columns_dict
[
''
]
for
local_roles_group_id
,
security_uid
in
security_uid_dict
.
items
():
catalog_column
=
catalog_security_uid_groups_columns_dict
.
get
(
local_roles_group_id
,
default_security_uid_column
)
setattr
(
w
,
catalog_column
,
security_uid
)
# XXX we should build vars begore building the wrapper
predicate_property_dict
=
catalog
.
getPredicatePropertyDict
(
object
)
predicate_property_dict
=
catalog
.
getPredicatePropertyDict
(
object
)
if
predicate_property_dict
is
not
None
:
if
predicate_property_dict
is
not
None
:
w
.
predicate_property_dict
=
predicate_property_dict
w
.
predicate_property_dict
=
predicate_property_dict
else
:
else
:
w
.
predicate_property_dict
=
{}
w
.
predicate_property_dict
=
{}
w
.
security_uid
=
security_uid
(
subject_set_uid
,
optimised_subject_list
)
=
catalog
.
getSubjectSetUid
(
document_w
)
(
subject_set_uid
,
optimised_subject_list
)
=
catalog
.
getSubjectSetUid
(
document_w
)
w
.
optimised_subject_list
=
optimised_subject_list
w
.
optimised_subject_list
=
optimised_subject_list
w
.
subject_set_uid
=
subject_set_uid
w
.
subject_set_uid
=
subject_set_uid
...
...
product/ERP5Catalog/tests/testERP5CatalogSecurityUidOptimization.py
0 → 100644
View file @
5272e987
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
# Ivan Tyagov <ivan@nexedi.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.
#
##############################################################################
import
unittest
from
Testing
import
ZopeTestCase
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
from
AccessControl.SecurityManagement
import
newSecurityManager
class
TestERP5CatalogSecurityUidOptimization
(
ERP5TypeTestCase
):
"""
TestERP5CatalogSecurityUidOptimization tests security_uid optmization.
It is in a different test than TestERP5Catalog as it requires erp5_security_uid_innodb_catalog
bt5 to be installed in advance.
XXX: Inherit from TestERP5Catalog so we test default and security_uid optmization with same tests.
"""
business_template_list
=
[
'erp5_security_uid_innodb_catalog'
,
'erp5_full_text_myisam_catalog'
,
'erp5_base'
]
def
getBusinessTemplateList
(
self
):
return
self
.
business_template_list
def
afterSetUp
(
self
):
self
.
login
()
portal
=
self
.
getPortal
()
def
test_local_roles_group_id_on_role_information
(
self
):
"""Test usage of local_roles_group_id when searching catalog.
"""
sql_connection
=
self
.
getSQLConnection
()
sql_catalog
=
self
.
portal
.
portal_catalog
.
getSQLCatalog
()
# Add a catalog table (uid, alternate_security_uid)
sql_connection
.
manage_test
(
"""DROP TABLE IF EXISTS alternate_roles_and_users"""
)
sql_connection
.
manage_test
(
"""
CREATE TABLE alternate_roles_and_users (
`uid` BIGINT UNSIGNED NOT NULL,
`alternate_security_uid` INT UNSIGNED) """
)
# make it a search table
current_sql_search_tables
=
sql_catalog
.
sql_search_tables
sql_catalog
.
sql_search_tables
=
sql_catalog
.
sql_search_tables
+
[
'alternate_roles_and_users'
]
# Configure sql method to insert this table
sql_catalog
.
manage_addProduct
[
'ZSQLMethods'
].
manage_addZSQLMethod
(
id
=
'z_catalog_alternate_roles_and_users_list'
,
title
=
''
,
connection_id
=
'erp5_sql_connection'
,
arguments
=
"
\
n
"
.
join
([
'uid'
,
'alternate_security_uid'
]),
template
=
"""REPLACE INTO alternate_roles_and_users VALUES
<dtml-in prefix="loop" expr="_.range(_.len(uid))">
( <dtml-sqlvar expr="uid[loop_item]" type="int">,
<dtml-sqlvar expr="alternate_security_uid[loop_item]" type="int" optional>
)<dtml-unless sequence-end>,</dtml-unless>
</dtml-in>"""
)
current_sql_catalog_object_list
=
sql_catalog
.
sql_catalog_object_list
sql_catalog
.
sql_catalog_object_list
=
\
current_sql_catalog_object_list
+
\
(
'z_catalog_alternate_roles_and_users_list'
,)
# configure Alternate local roles group id to go in alternate_security_uid
current_sql_catalog_security_uid_columns
=
\
sql_catalog
.
sql_catalog_security_uid_columns
sql_catalog
.
sql_catalog_security_uid_columns
=
(
' | security_uid'
,
'Alternate | alternate_security_uid'
,
)
# add category
self
.
portal
.
portal_categories
.
local_role_group
.
newContent
(
portal_type
=
'Category'
,
reference
=
'Alternate'
,
id
=
'Alternate'
)
# configure security on person, each user will be able to see his own
# person thanks to an Auditor role on "Alternate" local roles group id.
self
.
portal
.
portal_types
.
Person
.
newContent
(
portal_type
=
'Role Information'
,
role_name
=
'Auditor'
,
role_base_category_script_id
=
'ERP5Type_getSecurityCategoryFromSelf'
,
role_base_category
=
'agent'
,
local_role_group_value
=
self
.
portal
.
portal_categories
.
local_role_group
.
Alternate
.
getRelativeUrl
())
self
.
portal
.
portal_caches
.
clearAllCache
()
self
.
tic
()
try
:
# create two persons and users
user1
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
'user1'
)
user1
.
newContent
(
portal_type
=
'Assignment'
).
open
()
user1
.
updateLocalRolesOnSecurityGroups
()
self
.
assertEquals
(
user1
.
__ac_local_roles__
.
get
(
'user1'
),
[
'Auditor'
])
user2
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
'user2'
)
user2
.
newContent
(
portal_type
=
'Assignment'
).
open
()
user2
.
updateLocalRolesOnSecurityGroups
()
self
.
assertEquals
(
user2
.
__ac_local_roles__
.
get
(
'user2'
),
[
'Auditor'
])
self
.
tic
()
# security_uid_dict in catalog contains entries for user1 and user2:
user1_alternate_security_uid
=
sql_catalog
.
security_uid_dict
[
(
'Alternate'
,
(
'user:user1'
,
'user:user1:Auditor'
))]
bob_alternate_security_uid
=
sql_catalog
.
security_uid_dict
[
(
'Alternate'
,
(
'user:user2'
,
'user:user2:Auditor'
))]
# those entries are in alternate security table
alternate_roles_and_users
=
sql_connection
.
manage_test
(
"SELECT * from alternate_roles_and_users"
).
dictionaries
()
self
.
assertTrue
(
dict
(
uid
=
user1
.
getUid
(),
alternate_security_uid
=
user1_alternate_security_uid
)
in
alternate_roles_and_users
)
self
.
assertTrue
(
dict
(
uid
=
user2
.
getUid
(),
alternate_security_uid
=
bob_alternate_security_uid
)
in
alternate_roles_and_users
)
# low level check of the security query of a logged in user
self
.
login
(
'user1'
)
security_query
=
self
.
portal
.
portal_catalog
.
getSecurityQuery
()
# This query is a complex query wrapping another complex query with a
# criterion on altenate_security_uid. This check is quite low level and
# is subject to change.
security_uid_query
=
security_query
.
query_list
[
0
]
alternate_security_query
,
=
[
q
for
q
in
security_query
.
query_list
[
0
].
query_list
if
q
.
kw
.
get
(
'alternate_security_uid'
)]
self
.
assertEquals
([
user1_alternate_security_uid
],
alternate_security_query
.
kw
[
'alternate_security_uid'
])
# high level check that that logged in user can see document
self
.
assertEquals
([
user1
],
[
o
.
getObject
()
for
o
in
self
.
portal
.
portal_catalog
(
portal_type
=
'Person'
)])
# also with local_roles= argument which is used in worklists
self
.
assertEquals
([
user1
],
[
o
.
getObject
()
for
o
in
self
.
portal
.
portal_catalog
(
portal_type
=
'Person'
,
local_roles
=
'Auditor'
)])
# searches still work for other users
self
.
login
(
'ERP5TypeTestCase'
)
self
.
assertSameSet
([
user1
,
user2
],
[
o
.
getObject
()
for
o
in
self
.
portal
.
portal_catalog
(
portal_type
=
'Person'
)])
finally
:
# restore catalog configuration
sql_catalog
.
sql_search_tables
=
current_sql_search_tables
sql_catalog
.
sql_catalog_object_list
=
current_sql_catalog_object_list
sql_catalog
.
sql_catalog_security_uid_columns
=
\
current_sql_catalog_security_uid_columns
self
.
portal
.
portal_types
.
Person
.
manage_delObjects
(
[
role
.
getId
()
for
role
in
self
.
portal
.
portal_types
.
Person
.
contentValues
(
portal_type
=
'Role Information'
)])
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
TestERP5CatalogSecurityUidOptimization
))
return
suite
product/ERP5Security/tests/testERP5Security.py
View file @
5272e987
...
@@ -580,6 +580,29 @@ class TestLocalRoleManagement(ERP5TypeTestCase):
...
@@ -580,6 +580,29 @@ class TestLocalRoleManagement(ERP5TypeTestCase):
self
.
assertFalse
(
'Assignee'
in
user
.
getRolesInContext
(
obj
))
self
.
assertFalse
(
'Assignee'
in
user
.
getRolesInContext
(
obj
))
self
.
abort
()
self
.
abort
()
def
testLocalRolesGroupId
(
self
):
"""Assigning a role with local roles group id.
"""
self
.
portal
.
portal_categories
.
local_role_group
.
newContent
(
portal_type
=
'Category'
,
reference
=
'Alternate'
,
id
=
'Alternate'
)
self
.
_getTypeInfo
().
newContent
(
portal_type
=
'Role Information'
,
role_name
=
'Assignor'
,
local_role_group_value
=
self
.
portal
.
portal_categories
.
local_role_group
.
Alternate
.
getRelativeUrl
(),
role_category
=
self
.
defined_category
)
self
.
loginAsUser
(
self
.
username
)
user
=
getSecurityManager
().
getUser
()
obj
=
self
.
_makeOne
()
self
.
assertEqual
([
'Assignor'
],
obj
.
__ac_local_roles__
.
get
(
'F1_G1_S1'
))
self
.
assertTrue
(
'Assignor'
in
user
.
getRolesInContext
(
obj
))
self
.
assertEqual
(
set
([(
'F1_G1_S1'
,
'Assignor'
)]),
obj
.
__ac_local_roles_group_id_dict__
.
get
(
'Alternate'
))
self
.
abort
()
def
testDynamicLocalRole
(
self
):
def
testDynamicLocalRole
(
self
):
"""Test simple case of setting a dynamic role.
"""Test simple case of setting a dynamic role.
The site category is not defined explictly the role, and will have the
The site category is not defined explictly the role, and will have the
...
...
product/ERP5Type/Core/RoleInformation.py
View file @
5272e987
...
@@ -183,5 +183,4 @@ class RoleInformation(XMLObject):
...
@@ -183,5 +183,4 @@ class RoleInformation(XMLObject):
return
group_id_role_dict
return
group_id_role_dict
InitializeClass
(
RoleInformation
)
InitializeClass
(
RoleInformation
)
product/ERP5Type/ERP5Type.py
View file @
5272e987
...
@@ -89,8 +89,26 @@ class LocalRoleAssignorMixIn(object):
...
@@ -89,8 +89,26 @@ class LocalRoleAssignorMixIn(object):
else
:
else
:
user_name
=
getSecurityManager
().
getUser
().
getId
()
user_name
=
getSecurityManager
().
getUser
().
getId
()
group_id_role_dict
=
self
.
getLocalRolesFor
(
ob
,
user_name
)
group_id_role_dict
=
{}
local_roles_group_id_group_id
=
{}
# Merge results from applicable roles
for
role_generator
in
self
.
getFilteredRoleListFor
(
ob
):
local_roles_group_id
=
''
if
getattr
(
role_generator
,
'getLocalRoleGroupValue'
,
None
)
is
not
None
:
# only some role generators like 'Role Information' support it
local_role_group
=
role_generator
.
getLocalRoleGroupValue
()
if
local_role_group
is
not
None
:
# role definitions use category to classify different types of local roles
# so use their categories' reference
local_roles_group_id
=
local_role_group
.
getReference
()
or
local_role_group
.
getId
()
for
group_id
,
role_list
\
in
role_generator
.
getLocalRolesFor
(
ob
,
user_name
).
iteritems
():
group_id_role_dict
.
setdefault
(
group_id
,
set
()).
update
(
role_list
)
if
local_roles_group_id
:
for
role
in
role_list
:
# Feed local_roles_group_id_group_id with local roles assigned to a group
local_roles_group_id_group_id
.
setdefault
(
local_roles_group_id
,
set
()).
update
(((
group_id
,
role
),))
## Update role assignments to groups
## Update role assignments to groups
# Save the owner
# Save the owner
for
group
,
role_list
in
(
ob
.
__ac_local_roles__
or
{}).
iteritems
():
for
group
,
role_list
in
(
ob
.
__ac_local_roles__
or
{}).
iteritems
():
...
@@ -101,24 +119,17 @@ class LocalRoleAssignorMixIn(object):
...
@@ -101,24 +119,17 @@ class LocalRoleAssignorMixIn(object):
for
group
,
role_list
in
group_id_role_dict
.
iteritems
():
for
group
,
role_list
in
group_id_role_dict
.
iteritems
():
if
role_list
:
if
role_list
:
ac_local_roles
[
group
]
=
list
(
role_list
)
ac_local_roles
[
group
]
=
list
(
role_list
)
if
local_roles_group_id_group_id
:
ob
.
__ac_local_roles_group_id_dict__
=
local_roles_group_id_group_id
elif
getattr
(
aq_base
(
ob
),
'__ac_local_roles_group_id_dict__'
,
None
)
is
not
None
:
delattr
(
ob
,
'__ac_local_roles_group_id_dict__'
)
## Make sure that the object is reindexed
## Make sure that the object is reindexed
if
reindex
:
if
reindex
:
ob
.
reindexObjectSecurity
()
ob
.
reindexObjectSecurity
()
security
.
declarePrivate
(
"getLocalRolesFor"
)
def
getLocalRolesFor
(
self
,
ob
,
user_name
=
None
):
"""Compute the security that should be applied on an object
Returned value is a dict: {groud_id: role_name_set, ...}
"""
group_id_role_dict
=
{}
# Merge results from applicable roles
for
role
in
self
.
getFilteredRoleListFor
(
ob
):
for
group_id
,
role_list
\
in
role
.
getLocalRolesFor
(
ob
,
user_name
).
iteritems
():
group_id_role_dict
.
setdefault
(
group_id
,
set
()).
update
(
role_list
)
return
group_id_role_dict
security
.
declarePrivate
(
'getFilteredRoleListFor'
)
security
.
declarePrivate
(
'getFilteredRoleListFor'
)
def
getFilteredRoleListFor
(
self
,
ob
=
None
):
def
getFilteredRoleListFor
(
self
,
ob
=
None
):
"""Return all role generators applicable to the object."""
"""Return all role generators applicable to the object."""
...
...
product/ERP5Type/interfaces/role_provider.py
View file @
5272e987
...
@@ -39,7 +39,7 @@ class ILocalRoleGenerator(Interface):
...
@@ -39,7 +39,7 @@ class ILocalRoleGenerator(Interface):
Returned value is a dict: {groud_id: role_name_set, ...}
Returned value is a dict: {groud_id: role_name_set, ...}
"""
"""
class
ILocalRoleAssignor
(
I
LocalRoleGenerator
):
class
ILocalRoleAssignor
(
I
nterface
):
"""
"""
"""
"""
def
updateLocalRolesOnDocument
(
ob
,
user_name
=
None
,
reindex
=
True
):
def
updateLocalRolesOnDocument
(
ob
,
user_name
=
None
,
reindex
=
True
):
...
...
product/ERP5Type/patches/WorkflowTool.py
View file @
5272e987
...
@@ -36,6 +36,7 @@ from Persistence import Persistent
...
@@ -36,6 +36,7 @@ from Persistence import Persistent
from
Products.ERP5Type.Globals
import
PersistentMapping
from
Products.ERP5Type.Globals
import
PersistentMapping
from
itertools
import
izip
from
itertools
import
izip
from
MySQLdb
import
ProgrammingError
,
OperationalError
from
MySQLdb
import
ProgrammingError
,
OperationalError
from
DateTime
import
DateTime
def
DCWorkflowDefinition_notifyWorkflowMethod
(
self
,
ob
,
transition_list
,
args
=
None
,
kw
=
None
):
def
DCWorkflowDefinition_notifyWorkflowMethod
(
self
,
ob
,
transition_list
,
args
=
None
,
kw
=
None
):
'''
'''
...
@@ -89,7 +90,6 @@ DCWorkflowDefinition.notifySuccess = DCWorkflowDefinition_notifySuccess
...
@@ -89,7 +90,6 @@ DCWorkflowDefinition.notifySuccess = DCWorkflowDefinition_notifySuccess
WORKLIST_METADATA_KEY
=
'metadata'
WORKLIST_METADATA_KEY
=
'metadata'
SECURITY_PARAMETER_ID
=
'local_roles'
SECURITY_PARAMETER_ID
=
'local_roles'
SECURITY_COLUMN_ID
=
'security_uid'
COUNT_COLUMN_TITLE
=
'count'
COUNT_COLUMN_TITLE
=
'count'
class
ExclusionList
(
list
):
class
ExclusionList
(
list
):
...
@@ -145,7 +145,7 @@ def updateWorklistSetDict(worklist_set_dict, workflow_worklist_key, valid_criter
...
@@ -145,7 +145,7 @@ def updateWorklistSetDict(worklist_set_dict, workflow_worklist_key, valid_criter
[
workflow_worklist_key
]
=
valid_criterion_dict
[
workflow_worklist_key
]
=
valid_criterion_dict
def
groupWorklistListByCondition
(
worklist_dict
,
sql_catalog
,
def
groupWorklistListByCondition
(
worklist_dict
,
sql_catalog
,
getSecurityUid
Lis
tAndRoleColumnDict
=
None
):
getSecurityUid
Dic
tAndRoleColumnDict
=
None
):
"""
"""
Get a list of dict of WorklistVariableMatchDict grouped by compatible
Get a list of dict of WorklistVariableMatchDict grouped by compatible
conditions.
conditions.
...
@@ -185,7 +185,7 @@ def groupWorklistListByCondition(worklist_dict, sql_catalog,
...
@@ -185,7 +185,7 @@ def groupWorklistListByCondition(worklist_dict, sql_catalog,
for
workflow_id
,
worklist
in
worklist_dict
.
iteritems
():
for
workflow_id
,
worklist
in
worklist_dict
.
iteritems
():
for
worklist_id
,
worklist_match_dict
in
worklist
.
iteritems
():
for
worklist_id
,
worklist_match_dict
in
worklist
.
iteritems
():
workflow_worklist_key
=
'/'
.
join
((
workflow_id
,
worklist_id
))
workflow_worklist_key
=
'/'
.
join
((
workflow_id
,
worklist_id
))
if
getSecurityUid
Lis
tAndRoleColumnDict
is
None
:
if
getSecurityUid
Dic
tAndRoleColumnDict
is
None
:
valid_criterion_dict
,
metadata
=
getValidCriterionDict
(
valid_criterion_dict
,
metadata
=
getValidCriterionDict
(
worklist_match_dict
=
worklist_match_dict
,
worklist_match_dict
=
worklist_match_dict
,
sql_catalog
=
sql_catalog
,
sql_catalog
=
sql_catalog
,
...
@@ -201,15 +201,18 @@ def groupWorklistListByCondition(worklist_dict, sql_catalog,
...
@@ -201,15 +201,18 @@ def groupWorklistListByCondition(worklist_dict, sql_catalog,
security_kw
=
{}
security_kw
=
{}
if
len
(
security_parameter
):
if
len
(
security_parameter
):
security_kw
[
SECURITY_PARAMETER_ID
]
=
security_parameter
security_kw
[
SECURITY_PARAMETER_ID
]
=
security_parameter
uid_
lis
t
,
role_column_dict
,
local_role_column_dict
=
\
uid_
dic
t
,
role_column_dict
,
local_role_column_dict
=
\
getSecurityUid
Lis
tAndRoleColumnDict
(
**
security_kw
)
getSecurityUid
Dic
tAndRoleColumnDict
(
**
security_kw
)
for
key
,
value
in
local_role_column_dict
.
items
():
for
key
,
value
in
local_role_column_dict
.
items
():
worklist_match_dict
[
key
]
=
[
value
]
worklist_match_dict
[
key
]
=
[
value
]
if
len
(
uid_list
):
catalog_security_uid_groups_columns_dict
=
\
uid_list
.
sort
()
sql_catalog
.
getSQLCatalogSecurityUidGroupsColumnsDict
()
role_column_dict
[
SECURITY_COLUMN_ID
]
=
uid_list
for
local_roles_group_id
,
uid_list
in
uid_dict
.
iteritems
():
role_column_dict
[
catalog_security_uid_groups_columns_dict
[
local_roles_group_id
]]
=
uid_list
# Make sure every item is a list - or a tuple
# Make sure every item is a list - or a tuple
for
security_column_id
in
role_column_dict
.
iterkeys
():
for
security_column_id
in
role_column_dict
.
iterkeys
():
value
=
role_column_dict
[
security_column_id
]
value
=
role_column_dict
[
security_column_id
]
...
@@ -271,6 +274,8 @@ def generateNestedQuery(priority_list, criterion_dict,
...
@@ -271,6 +274,8 @@ def generateNestedQuery(priority_list, criterion_dict,
**
{
my_criterion_id
:
criterion_value
})
**
{
my_criterion_id
:
criterion_value
})
if
isinstance
(
criterion_value
,
ExclusionTuple
):
if
isinstance
(
criterion_value
,
ExclusionTuple
):
query
=
NegatedQuery
(
query
)
query
=
NegatedQuery
(
query
)
query
=
ComplexQuery
(
operator
=
'OR'
,
*
(
query
,
Query
(
**
{
my_criterion_id
:
None
})))
append
(
ComplexQuery
(
query
,
subcriterion_query
,
operator
=
'AND'
))
append
(
ComplexQuery
(
query
,
subcriterion_query
,
operator
=
'AND'
))
else
:
else
:
possible_value_list
=
tuple
()
possible_value_list
=
tuple
()
...
@@ -296,6 +301,8 @@ def generateNestedQuery(priority_list, criterion_dict,
...
@@ -296,6 +301,8 @@ def generateNestedQuery(priority_list, criterion_dict,
if
len
(
impossible_value_list
):
if
len
(
impossible_value_list
):
query
=
Query
(
operator
=
'IN'
,
**
{
my_criterion_id
:
impossible_value_list
})
query
=
Query
(
operator
=
'IN'
,
**
{
my_criterion_id
:
impossible_value_list
})
query
=
NegatedQuery
(
query
)
query
=
NegatedQuery
(
query
)
query
=
ComplexQuery
(
operator
=
'OR'
,
*
(
query
,
Query
(
**
{
my_criterion_id
:
None
})))
value_query_list
.
append
(
query
)
value_query_list
.
append
(
query
)
append
(
ComplexQuery
(
operator
=
'AND'
,
*
value_query_list
))
append
(
ComplexQuery
(
operator
=
'AND'
,
*
value_query_list
))
if
len
(
query_list
):
if
len
(
query_list
):
...
@@ -334,6 +341,17 @@ def getWorklistListQuery(grouped_worklist_dict):
...
@@ -334,6 +341,17 @@ def getWorklistListQuery(grouped_worklist_dict):
assert
COUNT_COLUMN_TITLE
not
in
total_criterion_id_dict
assert
COUNT_COLUMN_TITLE
not
in
total_criterion_id_dict
return
(
total_criterion_id_list
,
query
)
return
(
total_criterion_id_list
,
query
)
# XXX: see ZMySQLDA/db.py:DB.defs
# This dict is used to tell which cast to apply to worklist parameters to get
# values comparable with SQL result content.
_sql_cast_dict
=
{
'i'
:
long
,
'l'
:
long
,
'n'
:
float
,
'd'
:
DateTime
,
}
_sql_cast_fallback
=
str
def
sumCatalogResultByWorklist
(
grouped_worklist_dict
,
catalog_result
):
def
sumCatalogResultByWorklist
(
grouped_worklist_dict
,
catalog_result
):
"""
"""
Return a dict regrouping each worklist's result, extracting it from
Return a dict regrouping each worklist's result, extracting it from
...
@@ -354,8 +372,8 @@ def sumCatalogResultByWorklist(grouped_worklist_dict, catalog_result):
...
@@ -354,8 +372,8 @@ def sumCatalogResultByWorklist(grouped_worklist_dict, catalog_result):
if
len
(
catalog_result
)
>
0
:
if
len
(
catalog_result
)
>
0
:
# Transtype all worklist definitions where needed
# Transtype all worklist definitions where needed
criterion_id_list
=
[]
criterion_id_list
=
[]
class_dict
=
dict
(((
name
,
value
.
__class__
)
for
name
,
value
in
\
class_dict
=
dict
(((
name
,
_sql_cast_dict
.
get
(
x
[
'type'
],
_sql_cast_fallback
))
izip
(
catalog_result
.
names
(),
catalog_result
[
0
]
)))
for
name
,
x
in
catalog_result
.
data_dictionary
().
iteritems
(
)))
for
criterion_dict
in
grouped_worklist_dict
.
itervalues
():
for
criterion_dict
in
grouped_worklist_dict
.
itervalues
():
for
criterion_id
,
criterion_value_list
in
criterion_dict
.
iteritems
():
for
criterion_id
,
criterion_value_list
in
criterion_dict
.
iteritems
():
if
type
(
criterion_value_list
)
is
not
ExclusionList
:
if
type
(
criterion_value_list
)
is
not
ExclusionList
:
...
@@ -462,8 +480,8 @@ def WorkflowTool_listActions(self, info=None, object=None, src__=False):
...
@@ -462,8 +480,8 @@ def WorkflowTool_listActions(self, info=None, object=None, src__=False):
else
:
else
:
search_result
=
portal_catalog
.
unrestrictedSearchResults
search_result
=
portal_catalog
.
unrestrictedSearchResults
select_expression_prefix
=
'count(*) as %s'
%
(
COUNT_COLUMN_TITLE
,
)
select_expression_prefix
=
'count(*) as %s'
%
(
COUNT_COLUMN_TITLE
,
)
getSecurityUid
Lis
tAndRoleColumnDict
=
\
getSecurityUid
Dic
tAndRoleColumnDict
=
\
portal_catalog
.
getSecurityUid
Lis
tAndRoleColumnDict
portal_catalog
.
getSecurityUid
Dic
tAndRoleColumnDict
security_query_cache_dict
=
{}
security_query_cache_dict
=
{}
def
_getWorklistActionList
():
def
_getWorklistActionList
():
worklist_result_dict
=
{}
worklist_result_dict
=
{}
...
@@ -474,8 +492,8 @@ def WorkflowTool_listActions(self, info=None, object=None, src__=False):
...
@@ -474,8 +492,8 @@ def WorkflowTool_listActions(self, info=None, object=None, src__=False):
groupWorklistListByCondition
(
groupWorklistListByCondition
(
worklist_dict
=
worklist_dict
,
worklist_dict
=
worklist_dict
,
sql_catalog
=
sql_catalog
,
sql_catalog
=
sql_catalog
,
getSecurityUid
Lis
tAndRoleColumnDict
=
\
getSecurityUid
Dic
tAndRoleColumnDict
=
\
getSecurityUid
Lis
tAndRoleColumnDict
)
getSecurityUid
Dic
tAndRoleColumnDict
)
if
src__
:
if
src__
:
action_list
=
[]
action_list
=
[]
for
grouped_worklist_dict
in
worklist_list_grouped_by_condition
:
for
grouped_worklist_dict
in
worklist_list_grouped_by_condition
:
...
@@ -587,7 +605,8 @@ def WorkflowTool_refreshWorklistCache(self):
...
@@ -587,7 +605,8 @@ def WorkflowTool_refreshWorklistCache(self):
sql_catalog
=
portal_catalog
.
getSQLCatalog
()
sql_catalog
=
portal_catalog
.
getSQLCatalog
()
table_column_id_set
=
ImmutableSet
(
table_column_id_set
=
ImmutableSet
(
[
COUNT_COLUMN_TITLE
]
+
self
.
Base_getWorklistTableColumnIDList
())
[
COUNT_COLUMN_TITLE
]
+
self
.
Base_getWorklistTableColumnIDList
())
security_column_id_list
=
[
'security_uid'
]
+
\
security_column_id_list
=
list
(
sql_catalog
.
getSQLCatalogSecurityUidGroupsColumnsDict
().
values
())
+
\
[
x
[
1
]
for
x
in
sql_catalog
.
getSQLCatalogRoleKeysList
()]
+
\
[
x
[
1
]
for
x
in
sql_catalog
.
getSQLCatalogRoleKeysList
()]
+
\
[
x
[
1
]
for
x
in
sql_catalog
.
getSQLCatalogLocalRoleKeysList
()]
[
x
[
1
]
for
x
in
sql_catalog
.
getSQLCatalogLocalRoleKeysList
()]
(
worklist_list_grouped_by_condition
,
worklist_metadata
)
=
\
(
worklist_list_grouped_by_condition
,
worklist_metadata
)
=
\
...
...
product/ZSQLCatalog/SQLCatalog.py
View file @
5272e987
...
@@ -524,6 +524,14 @@ class Catalog(Folder,
...
@@ -524,6 +524,14 @@ class Catalog(Folder,
'a monovalued local role'
,
'a monovalued local role'
,
'type'
:
'lines'
,
'type'
:
'lines'
,
'mode'
:
'w'
},
'mode'
:
'w'
},
{
'id'
:
'sql_catalog_security_uid_columns'
,
'title'
:
'Security Uid Columns'
,
'description'
:
'A list of mappings "local_roles_group_id | security_uid_column"'
' local_roles_group_id will be the name of a local roles'
' group, and security_uid_column is the corresponding'
' column in catalog table'
,
'type'
:
'lines'
,
'mode'
:
'w'
},
{
'id'
:
'sql_catalog_table_vote_scripts'
,
{
'id'
:
'sql_catalog_table_vote_scripts'
,
'title'
:
'Table vote scripts'
,
'title'
:
'Table vote scripts'
,
'description'
:
'Scripts helping column mapping resolution'
,
'description'
:
'Scripts helping column mapping resolution'
,
...
@@ -575,6 +583,7 @@ class Catalog(Folder,
...
@@ -575,6 +583,7 @@ class Catalog(Folder,
sql_catalog_scriptable_keys
=
()
sql_catalog_scriptable_keys
=
()
sql_catalog_role_keys
=
()
sql_catalog_role_keys
=
()
sql_catalog_local_role_keys
=
()
sql_catalog_local_role_keys
=
()
sql_catalog_security_uid_columns
=
(
' | security_uid'
,)
sql_catalog_table_vote_scripts
=
()
sql_catalog_table_vote_scripts
=
()
sql_catalog_raise_error_on_uid_check
=
True
sql_catalog_raise_error_on_uid_check
=
True
...
@@ -626,6 +635,18 @@ class Catalog(Folder,
...
@@ -626,6 +635,18 @@ class Catalog(Folder,
role_key_dict
[
role
.
strip
()]
=
column
.
strip
()
role_key_dict
[
role
.
strip
()]
=
column
.
strip
()
return
role_key_dict
.
items
()
return
role_key_dict
.
items
()
def
getSQLCatalogSecurityUidGroupsColumnsDict
(
self
):
"""
Return a mapping of local_roles_group_id name to the name of the column
storing corresponding security_uid.
The default mappiny is {'': 'security_uid'}
"""
local_roles_group_id_dict
=
{}
for
local_roles_group_id_key
in
self
.
sql_catalog_security_uid_columns
:
local_roles_group_id
,
column
=
local_roles_group_id_key
.
split
(
'|'
)
local_roles_group_id_dict
[
local_roles_group_id
.
strip
()]
=
column
.
strip
()
return
local_roles_group_id_dict
def
getSQLCatalogLocalRoleKeysList
(
self
):
def
getSQLCatalogLocalRoleKeysList
(
self
):
"""
"""
Return the list of local role keys.
Return the list of local role keys.
...
@@ -765,61 +786,73 @@ class Catalog(Folder,
...
@@ -765,61 +786,73 @@ class Catalog(Folder,
self
.
subject_set_uid_dict
=
OIBTree
()
self
.
subject_set_uid_dict
=
OIBTree
()
self
.
subject_set_uid_index
=
None
self
.
subject_set_uid_index
=
None
security
.
declarePrivate
(
'getSecurityUid'
)
security
.
declarePrivate
(
'getSecurityUid
Dict
'
)
def
getSecurityUid
(
self
,
wrapped_object
):
def
getSecurityUid
Dict
(
self
,
wrapped_object
):
"""
"""
Cache a uid for each security permission
returns a tuple with a dict of security uid by local group id, and a tuple
Return a tuple with a security uid (string) and a new tuple content the
containing optimised_roles_and_users that might have been created.
roles and users if not exist already.
With the roles of object, search the security_uid associate in the
catalog_innodb:
- if the security not exist a security uid is generated with id_tool
or security_uid_index property and
return the new security_uid and the tuple contains the new roles
to add the roles in roles_and_user table of the database.
- if the security exist the security uid is returned and the second
element is None for not recreate the security in roles_and_user
table of the database.
We try to create a unique security (to reduce number of lines)
and to assign security only to root document
"""
"""
# Get security information
allowed_roles_and_users
=
tuple
(
wrapped_object
.
allowedRolesAndUsers
())
# Make sure no duplicates
if
getattr
(
aq_base
(
self
),
'security_uid_dict'
,
None
)
is
None
:
if
getattr
(
aq_base
(
self
),
'security_uid_dict'
,
None
)
is
None
:
self
.
_clearSecurityCache
()
self
.
_clearSecurityCache
()
elif
self
.
security_uid_dict
.
has_key
(
allowed_roles_and_users
):
return
(
self
.
security_uid_dict
[
allowed_roles_and_users
],
None
)
# If the id_tool is there, it is better to use it, it allows
# to create many new security uids by the same time
# because with this tool we are sure that we will have 2 different
# uids if two instances are doing this code in the same time
id_tool
=
getattr
(
self
.
getPortalObject
(),
'portal_ids'
,
None
)
id_tool
=
getattr
(
self
.
getPortalObject
(),
'portal_ids'
,
None
)
if
id_tool
is
not
None
:
default
=
1
optimised_roles_and_users
=
[]
# We must keep compatibility with existing sites
local_roles_group_id_to_security_uid_mapping
=
dict
()
previous_security_uid
=
getattr
(
self
,
'security_uid_index'
,
None
)
if
previous_security_uid
is
not
None
:
# Get security information
# At some point, it was a Length
for
local_roles_group_id
,
allowed_roles_and_users
in
\
if
isinstance
(
previous_security_uid
,
Length
):
wrapped_object
.
getLocalRolesGroupIdDict
().
iteritems
():
default
=
previous_security_uid
()
+
1
allowed_roles_and_users
=
tuple
(
sorted
(
allowed_roles_and_users
))
key
=
(
local_roles_group_id
,
allowed_roles_and_users
)
if
self
.
security_uid_dict
.
has_key
(
key
):
local_roles_group_id_to_security_uid_mapping
[
local_roles_group_id
]
\
=
self
.
security_uid_dict
[
key
]
elif
self
.
security_uid_dict
.
has_key
(
allowed_roles_and_users
)
\
and
not
local_roles_group_id
:
# This key is present in security_uid_dict without
# local_roles_group_id, it has been inserted before
# local_roles_group_id were introduced.
local_roles_group_id_to_security_uid_mapping
[
local_roles_group_id
]
=
\
self
.
security_uid_dict
[
allowed_roles_and_users
]
else
:
# If the id_tool is there, it is better to use it, it allows
# to create many new security uids by the same time
# because with this tool we are sure that we will have 2 different
# uids if two instances are doing this code in the same time
if
id_tool
is
not
None
:
default
=
1
# We must keep compatibility with existing sites
previous_security_uid
=
getattr
(
self
,
'security_uid_index'
,
None
)
if
previous_security_uid
is
not
None
:
# At some point, it was a Length
if
isinstance
(
previous_security_uid
,
Length
):
default
=
previous_security_uid
()
+
1
else
:
default
=
previous_security_uid
security_uid
=
int
(
id_tool
.
generateNewId
(
id_generator
=
'uid'
,
id_group
=
'security_uid_index'
,
default
=
default
))
else
:
else
:
default
=
previous_security_uid
previous_security_uid
=
getattr
(
self
,
'security_uid_index'
,
None
)
security_uid
=
int
(
id_tool
.
generateNewId
(
id_generator
=
'uid'
,
if
previous_security_uid
is
None
:
id_group
=
'security_uid_index'
,
default
=
default
))
previous_security_uid
=
0
else
:
# At some point, it was a Length
previous_security_uid
=
getattr
(
self
,
'security_uid_index'
,
None
)
if
isinstance
(
previous_security_uid
,
Length
):
if
previous_security_uid
is
None
:
previous_security_uid
=
previous_security_uid
()
previous_security_uid
=
0
security_uid
=
previous_security_uid
+
1
# At some point, it was a Length
self
.
security_uid_index
=
security_uid
if
isinstance
(
previous_security_uid
,
Length
):
previous_security_uid
=
previous_security_uid
()
self
.
security_uid_dict
[
key
]
=
security_uid
security_uid
=
previous_security_uid
+
1
local_roles_group_id_to_security_uid_mapping
[
local_roles_group_id
]
\
self
.
security_uid_index
=
security_uid
=
security_uid
self
.
security_uid_dict
[
allowed_roles_and_users
]
=
security_uid
return
(
security_uid
,
allowed_roles_and_users
)
# If some optimised_roles_and_users are returned by this method it
# means that new entries will have to be added to roles_and_users table.
for
user
in
allowed_roles_and_users
:
optimised_roles_and_users
.
append
((
security_uid
,
local_roles_group_id
,
user
))
return
(
local_roles_group_id_to_security_uid_mapping
,
optimised_roles_and_users
)
def
getRoleAndSecurityUidList
(
self
):
def
getRoleAndSecurityUidList
(
self
):
"""
"""
...
@@ -828,7 +861,8 @@ class Catalog(Folder,
...
@@ -828,7 +861,8 @@ class Catalog(Folder,
"""
"""
result
=
[]
result
=
[]
extend
=
result
.
extend
extend
=
result
.
extend
for
role_list
,
security_uid
in
getattr
(
aq_base
(
self
),
'security_uid_dict'
,
{}).
iteritems
():
for
role_list
,
security_uid
in
getattr
(
aq_base
(
self
),
'security_uid_dict'
,
{}).
iteritems
():
extend
([(
role
,
security_uid
)
for
role
in
role_list
])
extend
([(
role
,
security_uid
)
for
role
in
role_list
])
return
result
return
result
...
...
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