<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (c) 2010-2017 Evolveum
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->


<!--

This file is an example of Resource definition. It defines an LDAP resource
using an Identity Connector Framework LDAP connector. It contains configuration
for use with OpenLDAP servers.

This is "Medium difficulty" resource definition.
It contains outbound mappings to correctly populate new accounts.
It also contains inbound mappings and definition to enable synchronization.

-->

<objects xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
         xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3'
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
         xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
         xmlns:my="http://whatever.com/my"
         xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
         xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
         xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">


    <resource oid="40be7fa0-cbec-11e5-926a-3c970e44b9e2">

        <!-- Resource name. It will be displayed in GUI.  -->
        <name>OpenLDAP for Customers</name>

        <description>
            LDAP resource using a ConnId LDAP connector. It contains configuration
            for use with OpenLDAP servers.
        </description>

        <connectorRef type="ConnectorType">
            <description>
                Reference to the OpenICF LDAP connector. This is dynamic reference, it will be translated to
                OID during import.
            </description>
            <filter>
                <q:text>connectorType = "com.evolveum.polygon.connector.ldap.LdapConnector"</q:text>
            </filter>
        </connectorRef>

        <!-- Configuration section contains configuration of the connector,
             such as hostnames and passwords -->
       <connectorConfiguration
            xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
            xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
        <icfc:configurationProperties>
            <icfcldap:port>389</icfcldap:port>
            <icfcldap:host>localhost</icfcldap:host>
            <icfcldap:baseContext>ou=customers,dc=example,dc=com</icfcldap:baseContext>
            <icfcldap:bindDn>cn=idm,ou=Administrators,dc=example,dc=com</icfcldap:bindDn>
            <icfcldap:bindPassword><t:clearValue>secret</t:clearValue></icfcldap:bindPassword>
            <icfcldap:pagingStrategy>auto</icfcldap:pagingStrategy>
            <icfcldap:passwordHashAlgorithm>SSHA</icfcldap:passwordHashAlgorithm>
            <icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute>
            <icfcldap:vlvSortOrderingRule>2.5.13.3</icfcldap:vlvSortOrderingRule>
            <icfcldap:operationalAttributes>memberOf</icfcldap:operationalAttributes>
            <icfcldap:operationalAttributes>createTimestamp</icfcldap:operationalAttributes>
        </icfc:configurationProperties>
        <icfc:resultsHandlerConfiguration>
            <icfc:enableNormalizingResultsHandler>false</icfc:enableNormalizingResultsHandler>
            <icfc:enableFilteredResultsHandler>false</icfc:enableFilteredResultsHandler>
            <icfc:enableAttributesToGetSearchResultsHandler>false</icfc:enableAttributesToGetSearchResultsHandler>
        </icfc:resultsHandlerConfiguration>
    </connectorConfiguration>


        <!-- Resource schema definition.
             It defines all the object classes that are available to midPoint
             (accounts, groups, ...).
              -->
      <schema>
      <!-- The schema will be generated by midPoint when the resource is first used -->

          <!-- workaround to MID-2723 -->
          <generationConstraints>
              <generateObjectClass>ri:inetOrgPerson</generateObjectClass>
              <generateObjectClass>ri:groupOfUniqueNames</generateObjectClass>
              <generateObjectClass>ri:groupOfNames</generateObjectClass>
              <generateObjectClass>ri:organizationalUnit</generateObjectClass>
          </generationConstraints>

      </schema>


        <!-- Resource Schema Handling definition.
             This part defines how the schema defined above will be used by
             midPoint. It defines expressions and limitations for individual
             schema attributes.

             The expressions that describe both inbound and outbound flow of
             the attributes are defined in this section.

             This is the part where most of the customization takes place.
        -->


    <schemaHandling>
        <objectType>
            <kind>account</kind>
            <displayName>Normal Account</displayName>
            <default>true</default>
            <objectClass>ri:inetOrgPerson</objectClass>
            <attribute>
                <ref>ri:dn</ref>
                <displayName>Distinguished Name</displayName>
                <limitations>
                    <minOccurs>0</minOccurs>
                    <access>
                        <read>true</read>
                        <add>true</add>
                        <modify>true</modify>
                    </access>
                </limitations>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <source>
                        <path>$user/name</path>
                    </source>
                    <source>
                        <path>$user/organizationalUnit</path>
                    </source>
                    <expression>
                        <script>
                            <code>
                                'uid=' + name + ',ou=' + organizationalUnit + ',ou=customers,dc=example,dc=com'
                            </code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:entryUUID</ref>
                <displayName>Entry UUID</displayName>
                <limitations>
                    <access>
                        <read>true</read>
                        <add>false</add>
                        <modify>true</modify>
                    </access>
                </limitations>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <displayName>Common Name</displayName>
                <limitations>
                    <minOccurs>0</minOccurs>
                    <access>
                        <read>true</read>
                        <add>true</add>
                        <modify>true</modify>
                    </access>
                </limitations>

                <outbound>
                    <source>
                        <path>$user/fullName</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:sn</ref>
                <displayName>Surname</displayName>
                <limitations>
                    <minOccurs>0</minOccurs>
                </limitations>
                <outbound>
                    <source>
                        <!-- The path can be shorteden like this. $user is a default source "context" in outbound -->
                        <path>familyName</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:givenName</ref>
            <displayName>Given Name</displayName>
            <outbound>
                <source>
                    <!-- Full namespace prefixes can be used in the path -->
                    <path>$c:user/c:givenName</path>
                </source>
            </outbound>
        </attribute>
        <attribute>
            <ref>ri:uid</ref>
            <displayName>Login Name</displayName>
            <matchingRule>mr:stringIgnoreCase</matchingRule>
            <outbound>
                <strength>weak</strength>
                <source>
                    <description>Source may have description</description>
                    <path>$user/name</path>
                </source>
                <expression>
                    <script>
                        <code>name</code>
                    </script>
                </expression>
            </outbound>
        </attribute>
        <attribute>
            <ref>ri:description</ref>
            <outbound>
                <source>
                    <path>$user/description</path>
                </source>
            </outbound>
        </attribute>
        <attribute>
            <ref>ri:l</ref>
            <displayName>Location</displayName>
            <outbound>
                <source>
                    <path>$user/locality</path>
                </source>
            </outbound>
        </attribute>
        <attribute>
            <ref>ri:employeeType</ref>
            <displayName>Employee Type</displayName>
            <tolerant>false</tolerant>
            <outbound>
                <source>
                    <path>$user/subtype</path>
                </source>
            </outbound>
        </attribute>

        <association>
            <ref>ri:group</ref>
            <displayName>LDAP Group Membership</displayName>
            <kind>entitlement</kind>
            <intent>ldapGroup</intent>
            <intent>group-org-admin</intent>
            <intent>group-org-user</intent>
            <intent>group-org-poweruser</intent>
            <intent>group-custom</intent>
            <direction>objectToSubject</direction>
            <associationAttribute>ri:member</associationAttribute>
            <valueAttribute>ri:dn</valueAttribute>
            <explicitReferentialIntegrity>true</explicitReferentialIntegrity>
        </association>

        <iteration>
            <maxIterations>5</maxIterations>
        </iteration>

        <protected>
        <filter>
            <q:text>attributes/ri:dn =[stringIgnoreCase] "cn=idm,ou=Administrators,dc=example,dc=com"</q:text>
        </filter>
        </protected>

        <activation>
    <administrativeStatus>
        <outbound/>
    </administrativeStatus>
    </activation>

    <credentials>
    <password>
        <outbound>
        <expression>
            <asIs/>
        </expression>
        </outbound>
    </password>
    </credentials>

    </objectType>

        <objectType>
            <kind>generic</kind>
            <intent>ou-customer</intent>
            <displayName>Customer Organizational Unit</displayName>
            <default>true</default>
            <objectClass>ri:organizationalUnit</objectClass>

            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$focus/name</path>
                    </source>
                        <expression>
                            <script>
                            <code>
                            return 'ou=' + name + ',ou=customers,dc=example,dc=com'
                            </code>
                        </script>
                        </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:ou</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>$focus/name</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
        </objectType>
        <objectType>
            <kind>entitlement</kind>
            <intent>ldapGroup</intent>
            <displayName>LDAP Group</displayName>
            <default>true</default>
            <objectClass>ri:groupOfNames</objectClass>

            <attribute>
                <ref>ri:member</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <fetchStrategy>minimal</fetchStrategy>
            </attribute>
            <configuredCapabilities>
                <cap:pagedSearch>
                    <cap:defaultSortField>ri:uid</cap:defaultSortField>
                </cap:pagedSearch>
            </configuredCapabilities>
        </objectType>
        <objectType>
            <kind>entitlement</kind>
            <intent>group-org-poweruser</intent>
            <displayName>LDAP Group - Power Users</displayName>
            <objectClass>ri:groupOfNames</objectClass>

            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$focus/name</path>
                    </source>
                        <expression>
                            <script>
                            <code>
                            return 'cn=' + name + '-powerusers,ou=' + name + ',ou=customers,dc=example,dc=com'
                            </code>
                        </script>
                        </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:member</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <fetchStrategy>minimal</fetchStrategy>
                <outbound>
                    <strength>strong</strength>
                    <!-- Workaround - groupOfNames MUST have at least one member. Even non-existent DN. -->
                    <expression>
                        <value>cn=dummy,o=whatever</value>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>$focus/name</path>
                    </source>
                    <expression>
                        <script>
                            <code>return name + '-powerusers'</code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
            <dependency>
                <kind>generic</kind>
                <intent>ou-customer</intent>
                <strictness>relaxed</strictness>
            </dependency>
            <configuredCapabilities>
                <cap:pagedSearch>
                    <cap:defaultSortField>ri:uid</cap:defaultSortField>
                </cap:pagedSearch>
            </configuredCapabilities>
        </objectType>
        <objectType>
            <kind>entitlement</kind>
            <intent>group-org-user</intent>
            <displayName>LDAP Group - Users</displayName>
            <objectClass>ri:groupOfNames</objectClass>

            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$focus/name</path>
                    </source>
                        <expression>
                            <script>
                            <code>
                            return 'cn=' + name + '-users,ou=' + name + ',ou=customers,dc=example,dc=com'
                            </code>
                        </script>
                        </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:member</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <fetchStrategy>minimal</fetchStrategy>
                <outbound>
                    <strength>strong</strength>
                    <!-- Workaround - groupOfNames MUST have at least one member. Even non-existent DN. -->
                    <expression>
                        <value>cn=dummy,o=whatever</value>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>$focus/name</path>
                    </source>
                    <expression>
                        <script>
                            <code>return name + '-users'</code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
            <dependency>
                <kind>generic</kind>
                <intent>ou-customer</intent>
                <strictness>relaxed</strictness>
            </dependency>
            <configuredCapabilities>
                <cap:pagedSearch>
                    <cap:defaultSortField>ri:uid</cap:defaultSortField>
                </cap:pagedSearch>
            </configuredCapabilities>
        </objectType>
        <objectType>
            <kind>entitlement</kind>
            <intent>group-org-admin</intent>
            <displayName>LDAP Group - Admin</displayName>
            <objectClass>ri:groupOfNames</objectClass>

            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$focus/name</path>
                    </source>
                        <expression>
                            <script>
                            <code>
                            return 'cn=' + name + '-admins,ou=' + name + ',ou=customers,dc=example,dc=com'
                            </code>
                        </script>
                        </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:member</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <fetchStrategy>minimal</fetchStrategy>
                <outbound>
                    <strength>strong</strength>
                    <!-- Workaround - groupOfNames MUST have at least one member. Even non-existent DN. -->
                    <expression>
                        <value>cn=dummy,o=whatever</value>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>$focus/name</path>
                    </source>
                    <expression>
                        <script>
                            <code>return name + '-admins'</code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
            <dependency>
                <kind>generic</kind>
                <intent>ou-customer</intent>
                <strictness>relaxed</strictness>
            </dependency>
            <configuredCapabilities>
                <cap:pagedSearch>
                    <cap:defaultSortField>ri:uid</cap:defaultSortField>
                </cap:pagedSearch>
            </configuredCapabilities>
        </objectType>
        <objectType><!-- Not used yet -->
            <kind>entitlement</kind>
            <intent>group-custom</intent>
            <displayName>LDAP Group - Custom group</displayName>
            <objectClass>ri:groupOfNames</objectClass>

            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$focus/name</path>
                    </source>
                    <source>
                        <path>$focus/identifier</path>
                    </source>
                        <expression>
                            <script>
                            <code>
                            return 'cn=' + name + ',ou=' + identifier + ',ou=customers,dc=example,dc=com'
                            </code>
                        </script>
                        </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:member</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <fetchStrategy>minimal</fetchStrategy>
                <outbound>
                    <strength>strong</strength>
                    <!-- Workaround - groupOfNames MUST have at least one member. Even non-existent DN. -->
                    <expression>
                        <value>cn=dummy,o=whatever</value>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>$focus/name</path>
                    </source>
                    <expression>
                        <script>
                            <code>return name</code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
            <dependency>
                <kind>generic</kind>
                <intent>ou-customer</intent>
                <strictness>relaxed</strictness>
            </dependency>
            <configuredCapabilities>
                <cap:pagedSearch>
                    <cap:defaultSortField>ri:uid</cap:defaultSortField>
                </cap:pagedSearch>
            </configuredCapabilities>
        </objectType>
    </schemaHandling>

<!--
    <capabilities>
        <configured>
            <cap:activation>
                <cap:status>
                    <cap:attribute>ri:ds-pwp-account-disabled</cap:attribute>
                    <cap:enableValue/>
                    <cap:disableValue>true</cap:disableValue>
                </cap:status>
            </cap:activation>
        </configured>
    </capabilities>
-->

        <consistency>
            <avoidDuplicateValues>true</avoidDuplicateValues>
        </consistency>

        <!--
            Synchronization section describes the synchronization policy, timing,
            reactions and similar synchronization settings.
        -->
        <synchronization>
            <objectSynchronization>
                <!--
                    The synchronization for this resource is enabled.
                    It means that the synchronization will react to changes detected by
                    the system (live sync task, discovery or reconciliation) -->
                <enabled>true</enabled>

                <correlation>
                    <q:description>
                        Correlation expression is a search query.
                        Following search query will look for users that have "name"
                        equal to the "uid" attribute of the account. Simply speaking,
                        it will look for match in usernames in the IDM and the resource.
                        The correlation rule always looks for users, so it will not match
                        any other object type.
                    </q:description>
                    <q:equal>
                        <q:path>name</q:path>
                        <expression>
                            <path>
                                declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
                                $account/attributes/ri:uid
                            </path>
                        </expression>
                    </q:equal>
                </correlation>

                <!-- Confirmation rule may be here, but as the search above will
                     always return at most one match, the confirmation rule is not needed. -->

                <!-- Following section describes reactions to a situations.
                     The setting here assumes that this resource is authoritative,
                     therefore all accounts created on the resource should be
                     reflected as new users in IDM.
                     See http://wiki.evolveum.com/display/midPoint/Synchronization+Situations
                 -->

                <reaction>
                    <situation>linked</situation>
                    <synchronize>true</synchronize>
                </reaction>
                <reaction>
                    <situation>deleted</situation>
                    <synchronize>true</synchronize>
                    <action>
                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
                    </action>
                </reaction>

                <reaction>
                    <situation>unlinked</situation>
                    <synchronize>true</synchronize>
                    <action>
                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
                    </action>
                </reaction>
                <reaction>
                    <situation>unmatched</situation>
                </reaction>
            </objectSynchronization>

            <objectSynchronization>
                    <objectClass>ri:organizationalUnit</objectClass>
                    <kind>generic</kind>
                    <intent>ou-customer</intent>
                    <focusType>c:OrgType</focusType>
                <enabled>true</enabled>

                    <condition>
                        <script>
                            <code>
import static com.evolveum.midpoint.schema.constants.SchemaConstants.*
tmpSuffix = '(?i)^ou=.*,ou=customers,dc=example,dc=com$'
re = ~tmpSuffix
basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn') ==~ re
                           </code>
                        </script>
                </condition>
                <correlation>
                    <q:equal>
                        <q:matching>polyStringNorm</q:matching>
                        <q:path>c:name</q:path>
                        <expression>
                            <path>
                declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
                $shadow/attributes/ri:ou
                            </path>
                        </expression>
                    </q:equal>
                </correlation>
            <reaction>
                <situation>linked</situation>
                <synchronize>true</synchronize>
            </reaction>
            <reaction>
                <situation>deleted</situation>
                <synchronize>true</synchronize>
                <action>
                       <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
                </action>
            </reaction>

            <reaction>
                <situation>unlinked</situation>
                <synchronize>true</synchronize>
                <action>
                  <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
                </action>
            </reaction>
            <reaction>
                <situation>unmatched</situation>
            </reaction>
        </objectSynchronization>

            <objectSynchronization>
                    <objectClass>ri:groupOfNames</objectClass>
                    <kind>entitlement</kind>
                    <intent>group-org-poweruser</intent>
                    <focusType>c:OrgType</focusType>
                <enabled>true</enabled>

                    <condition>
                        <script>
                            <code>
import static com.evolveum.midpoint.schema.constants.SchemaConstants.*
tmpSuffix = '(?i)^cn=.*-powerusers,ou=.*,ou=customers,dc=example,dc=com$'
re = ~tmpSuffix
basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn') ==~ re
                           </code>
                        </script>
                </condition>
                <correlation>
                    <q:equal>
                        <q:matching>polyStringNorm</q:matching>
                        <q:path>c:name</q:path>
                        <expression>
                            <script>
                                <code>
                tmpCn = basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'cn')
                re = /(?i)^(.*)-powerusers$/
                matcher = (tmpCn =~ re)
                if (matcher.matches()) return matcher[0][1]
                                </code>
                            </script>
                        </expression>
                    </q:equal>
                </correlation>
            <reaction>
                <situation>linked</situation>
                <synchronize>true</synchronize>
            </reaction>
            <reaction>
                <situation>deleted</situation>
                <synchronize>true</synchronize>
                <action>
                       <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
                </action>
            </reaction>

            <reaction>
                <situation>unlinked</situation>
                <synchronize>true</synchronize>
                <action>
                  <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
                </action>
            </reaction>
            <reaction>
                <situation>unmatched</situation>
            </reaction>
        </objectSynchronization>
            <objectSynchronization>
                    <objectClass>ri:groupOfNames</objectClass>
                    <kind>entitlement</kind>
                    <intent>group-org-user</intent>
                    <focusType>c:OrgType</focusType>
                <enabled>true</enabled>

                    <condition>
                        <script>
                            <code>
import static com.evolveum.midpoint.schema.constants.SchemaConstants.*
tmpSuffix = '(?i)^cn=.*-users,ou=.*,ou=customers,dc=example,dc=com$'
re = ~tmpSuffix
basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn') ==~ re
                           </code>
                        </script>
                </condition>
                <correlation>
                    <q:equal>
                        <q:matching>polyStringNorm</q:matching>
                        <q:path>c:name</q:path>
                        <expression>
                            <script>
                                <code>
                tmpCn = basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'cn')
                re = /(?i)^(.*)-users$/
                matcher = (tmpCn =~ re)
                if (matcher.matches()) return matcher[0][1]
                                </code>
                            </script>
                        </expression>
                    </q:equal>
                </correlation>
            <reaction>
                <situation>linked</situation>
                <synchronize>true</synchronize>
            </reaction>
            <reaction>
                <situation>deleted</situation>
                <synchronize>true</synchronize>
                <action>
                       <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
                </action>
            </reaction>

            <reaction>
                <situation>unlinked</situation>
                <synchronize>true</synchronize>
                <action>
                  <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
                </action>
            </reaction>
            <reaction>
                <situation>unmatched</situation>
            </reaction>
        </objectSynchronization>
            <objectSynchronization>
                    <objectClass>ri:groupOfNames</objectClass>
                    <kind>entitlement</kind>
                    <intent>group-org-admin</intent>
                    <focusType>c:OrgType</focusType>
                <enabled>true</enabled>

                    <condition>
                        <script>
                            <code>
import static com.evolveum.midpoint.schema.constants.SchemaConstants.*
tmpSuffix = '(?i)^cn=.*-admins,ou=.*,ou=customers,dc=example,dc=com$'
re = ~tmpSuffix
basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn') ==~ re
                           </code>
                        </script>
                </condition>
                <correlation>
                    <q:equal>
                        <q:matching>polyStringNorm</q:matching>
                        <q:path>c:name</q:path>
                        <expression>
                            <script>
                                <code>
                tmpCn = basic.getAttributeValue(shadow, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'cn')
                re = /(?i)^(.*)-admins$/
                matcher = (tmpCn =~ re)
                if (matcher.matches()) return matcher[0][1]
                                </code>
                            </script>
                        </expression>
                    </q:equal>
                </correlation>
            <reaction>
                <situation>linked</situation>
                <synchronize>true</synchronize>
            </reaction>
            <reaction>
                <situation>deleted</situation>
                <synchronize>true</synchronize>
                <action>
                       <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
                </action>
            </reaction>

            <reaction>
                <situation>unlinked</situation>
                <synchronize>true</synchronize>
                <action>
                  <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
                </action>
            </reaction>
            <reaction>
                <situation>unmatched</situation>
            </reaction>
        </objectSynchronization>
        </synchronization>
    </resource>

</objects>
