<?xml version="1.0"?>
<ZopeData>
  <record id="1" aka="AAAAAAAAAAE=">
    <pickle>
      <tuple>
        <tuple>
          <string>Products.PythonScripts.PythonScript</string>
          <string>PythonScript</string>
        </tuple>
        <none/>
      </tuple>
    </pickle>
    <pickle>
      <dictionary>
        <item>
            <key> <string>Python_magic</string> </key>
            <value>
              <none/>
            </value>
        </item>
        <item>
            <key> <string>Script_magic</string> </key>
            <value> <int>3</int> </value>
        </item>
        <item>
            <key> <string>__ac_local_roles__</string> </key>
            <value>
              <none/>
            </value>
        </item>
        <item>
            <key> <string>_bind_names</string> </key>
            <value>
              <object>
                <klass>
                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
                </klass>
                <tuple/>
                <state>
                  <dictionary>
                    <item>
                        <key> <string>_asgns</string> </key>
                        <value>
                          <dictionary>
                            <item>
                                <key> <string>name_container</string> </key>
                                <value> <string>container</string> </value>
                            </item>
                            <item>
                                <key> <string>name_context</string> </key>
                                <value> <string>context</string> </value>
                            </item>
                            <item>
                                <key> <string>name_m_self</string> </key>
                                <value> <string>script</string> </value>
                            </item>
                            <item>
                                <key> <string>name_subpath</string> </key>
                                <value> <string>traverse_subpath</string> </value>
                            </item>
                          </dictionary>
                        </value>
                    </item>
                  </dictionary>
                </state>
              </object>
            </value>
        </item>
        <item>
            <key> <string>_body</string> </key>
            <value> <string>"""\n
This script is used to convert a list of categories into an security\n
identifier (security ID). It is invoked by two classes in ERP5:\n
\n
- ERP5Type.py to convert security definitions made of\n
  multiple categories into security ID strings\n
\n
- ERP5GroupManager.py to convert an assignment definition\n
  into a single security ID string. It should be noted here\n
  that ERP5GroupManager.py also tries to invoke ERP5Type_asSecurityGroupIdList\n
  (DEPRECATED) in order associate a user to multiple security groups.\n
  In this case ERP5Type_asSecurityGroupId is not invoked.\n
\n
The script takes the following parameters:\n
\n
category_order - list of base_categories we want to use to generate the group id\n
kw             - keys should be base categories, values should be value\n
                 of corresponding relative urls (obtained by getBaseCategory())\n
\n
Example call:\n
  context.ERP5TypeSecurity_asGroupId(category_order=(\'site\', \'group\', \'function\'),\n
               site=\'france/lille\', group=\'nexedi\', function=\'accounting/accountant\')\n
\n
This will generate a string like \'LIL_NXD_ACT\' where "LIL", "NXD" and "ACT" are\n
the codification of respecively "france/lille", "nexedi" and "accounting/accountant" categories\n
\n
If the category points to a document portal type (ex. trade condition, project, etc.),\n
and if no codification property is defined for this type of object,\n
the security ID group is generated by considering the object reference or\n
the object ID.\n
\n
ERP5Type_asSecurityGroupId can also return a list of users whenever a category points\n
to a Person instance. This is useful to implement user based local role assignments\n
instead of abstract security based local roles.\n
"""\n
\n
# sort the category list lexicographically\n
# this prevents us to choose the exact order we want,\n
# but also prevents some human mistake to break everything by creating site_function instead of function_site\n
if category_order not in (None, \'\'):\n
  category_order = list(category_order)\n
  category_order.sort()\n
else:\n
  category_order = []\n
\n
# Prepare a cartesian product\n
from Products.ERP5Type.Utils import cartesianProduct\n
list_of_list = []\n
user_list = []\n
for base_category in category_order:\n
  # It is acceptable for a category not to be defined\n
  if kw.has_key(base_category):\n
    category_list = kw[base_category]\n
    associative_list = []\n
    if same_type(category_list, \'\'):\n
      category_list = [category_list]\n
    for category in category_list:\n
      if category.endswith(\'*\'):\n
        category = category[:-1]\n
        is_child_category = 1\n
      else:\n
        is_child_category = 0\n
      category_path = \'%s/%s\' % (base_category, category)\n
      category_object = context.portal_categories.getCategoryValue(category_path)\n
      if category_object in (None, \'\'):\n
        raise "SecurityRoleDefinitionError", "Category \'%s\' doesn\'t exist" % (category_path)\n
      portal_type = category_object.getPortalType()\n
      if portal_type == \'Person\':\n
        # We define a person here\n
        user_name = category_object.getReference()\n
        if user_name is not None: user_list.append(user_name)\n
      else:\n
        if portal_type == \'Category\':\n
          category_code  = category_object.getCodification() or category_object.getId()\n
        else:\n
          try:\n
            category_code   = category_object.getReference() or category_object.getId()\n
          except AttributeError:\n
            category_code   = category_object.getId()\n
        if is_child_category: category_code += \'*\'\n
        associative_list.append(category_code)\n
    # Prevent making a cartesian product with an empty set\n
    if associative_list:\n
      list_of_list.append(associative_list)\n
\n
# Return a list of users if any was defined\n
if user_list: return user_list\n
\n
# Compute the cartesian product and return the codes\n
# return filter(lambda x: x, map(lambda x: \'_\'.join(x), cartesianProduct(list_of_list)))\n
return [\'_\'.join(x) for x in cartesianProduct(list_of_list) if x]\n
</string> </value>
        </item>
        <item>
            <key> <string>_code</string> </key>
            <value>
              <none/>
            </value>
        </item>
        <item>
            <key> <string>_filepath</string> </key>
            <value>
              <none/>
            </value>
        </item>
        <item>
            <key> <string>_params</string> </key>
            <value> <string>category_order, **kw</string> </value>
        </item>
        <item>
            <key> <string>errors</string> </key>
            <value>
              <tuple/>
            </value>
        </item>
        <item>
            <key> <string>func_code</string> </key>
            <value>
              <object>
                <klass>
                  <global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
                </klass>
                <tuple/>
                <state>
                  <dictionary>
                    <item>
                        <key> <string>co_argcount</string> </key>
                        <value> <int>1</int> </value>
                    </item>
                    <item>
                        <key> <string>co_varnames</string> </key>
                        <value>
                          <tuple>
                            <string>category_order</string>
                            <string>kw</string>
                            <string>None</string>
                            <string>list</string>
                            <string>_getattr_</string>
                            <string>Products.ERP5Type.Utils</string>
                            <string>cartesianProduct</string>
                            <string>list_of_list</string>
                            <string>user_list</string>
                            <string>_getiter_</string>
                            <string>base_category</string>
                            <string>_getitem_</string>
                            <string>category_list</string>
                            <string>associative_list</string>
                            <string>same_type</string>
                            <string>category</string>
                            <string>is_child_category</string>
                            <string>category_path</string>
                            <string>context</string>
                            <string>category_object</string>
                            <string>portal_type</string>
                            <string>user_name</string>
                            <string>category_code</string>
                            <string>AttributeError</string>
                            <string>append</string>
                            <string>$append0</string>
                            <string>x</string>
                          </tuple>
                        </value>
                    </item>
                  </dictionary>
                </state>
              </object>
            </value>
        </item>
        <item>
            <key> <string>func_defaults</string> </key>
            <value>
              <none/>
            </value>
        </item>
        <item>
            <key> <string>id</string> </key>
            <value> <string>ERP5Type_asSecurityGroupId</string> </value>
        </item>
        <item>
            <key> <string>warnings</string> </key>
            <value>
              <tuple/>
            </value>
        </item>
      </dictionary>
    </pickle>
  </record>
</ZopeData>
