<?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.
  -->

<!-- Resource definition for an embedded OpenDJ instance. -->

<resource oid="10000000-0000-0000-0000-000000000003"
          xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
          xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
          xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
          xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
          xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
          xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
          xmlns:func="http://midpoint.evolveum.com/xml/ns/public/function/basic-3"
          xmlns:ext="http://midpoint.evolveum.com/xml/ns/story/orgsync/ext">

    <name>Localhost OpenDJ - generic synchronization</name>

    <connectorRef type="ConnectorType">
        <description>Localhost OpenDJ for test generic synchronization</description>
        <filter>
            <q:text>c:connectorType = "org.identityconnectors.ldap.LdapConnector"</q:text>
        </filter>
    </connectorRef>

    <connectorConfiguration
            xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/org.identityconnectors.ldap.LdapConnector"
            xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
        <icfc:configurationProperties
            xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
                <icfcldap:port>1389</icfcldap:port>
                <icfcldap:host>localhost</icfcldap:host>
                <icfcldap:baseContext>dc=example,dc=com</icfcldap:baseContext>
                <icfcldap:bindDn>uid=idm,ou=Administrators,dc=example,dc=com</icfcldap:bindDn>
                <icfcldap:bindPassword>
                        <t:clearValue>secret</t:clearValue>
                </icfcldap:bindPassword>
                <icfcldap:pagingStrategy>auto</icfcldap:pagingStrategy>
                <icfcldap:vlvSortAttribute>entryUUID</icfcldap:vlvSortAttribute>
<!--                                <icfcldap:accountOperationalAttributes>ds-pwp-account-disabled</icfcldap:accountOperationalAttributes>-->
                <icfcldap:operationalAttributes>ds-pwp-account-disabled</icfcldap:operationalAttributes>
                 <icfcldap:operationalAttributes>isMemberOf</icfcldap:operationalAttributes>
            </icfc:configurationProperties>
        <icfc:resultsHandlerConfiguration>
                <icfc:enableNormalizingResultsHandler>false</icfc:enableNormalizingResultsHandler>
                <icfc:enableFilteredResultsHandler>false</icfc:enableFilteredResultsHandler>
                <icfc:enableAttributesToGetSearchResultsHandler>false</icfc:enableAttributesToGetSearchResultsHandler>
            </icfc:resultsHandlerConfiguration>
    </connectorConfiguration>

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

    <schemaHandling>

        <objectType>
            <kind>account</kind>
            <intent>default</intent>
            <displayName>Default Account</displayName>
            <default>true</default>
            <objectClass>ri:inetOrgPerson</objectClass>
            <attribute>
                <ref>ri:dn</ref>
                <displayName>Distinguished Name</displayName>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$user/name</path>
                    </source>
                    <source>
                        <path>$focus/extension/ext:orgpath</path>
                    </source>
                    <expression>
                        <script>
                            <code>
                                import javax.naming.ldap.Rdn
                                import javax.naming.ldap.LdapName

                                dn = new LdapName('dc=example,dc=com')
                                if (orgpath) {
                                    orgpath.tokenize('/').reverse().each { ouname -> dn.add(new Rdn('ou',ouname)) }
                                } else {
                                    dn.add(new Rdn('ou','people'));
                                }
                                dn.add(new Rdn('uid',name.toString()))
                                return dn.toString()
                            </code>
                        </script>
                    </expression>
                </outbound>
            </attribute>

            <attribute>
                <ref>ri:cn</ref>
                <displayName>Common Name</displayName>
                <outbound>
                    <source>
                        <path>$user/fullName</path>
                    </source>
                </outbound>
            </attribute>

            <attribute>
                <ref>ri:sn</ref>
                <outbound>
                    <source>
                        <path>familyName</path>
                    </source>
                </outbound>
            </attribute>

            <attribute>
                <ref>ri:givenName</ref>
                <outbound>
                    <source>
                        <path>givenName</path>
                    </source>
                </outbound>
            </attribute>

            <attribute>
                <ref>ri:uid</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- This MUST be weak in case of OpenDJ. If DN (name) is changed then the uid will be changed
                         as a side-effect as it is a naming attribute. -->
                    <strength>weak</strength>
                    <source>
                        <path>$user/name</path>
                    </source>
                </outbound>
            </attribute>

            <association>
                <ref>ri:group</ref>
                <displayName>LDAP Group Membership</displayName>
                <kind>entitlement</kind>
                <intent>ldapGroup</intent>
                <direction>objectToSubject</direction>
                <associationAttribute>ri:uniqueMember</associationAttribute>
                <valueAttribute>ri:dn</valueAttribute>
            </association>

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

            <credentials>
                <password>
                    <outbound/>
                </password>
            </credentials>

        </objectType>

        <objectType>
            <kind>entitlement</kind>
            <intent>ldapGroup</intent>
            <displayName>LDAP Group</displayName>
            <objectClass>ri:groupOfUniqueNames</objectClass>
            <attribute><!-- MID-2419 -->
                <ref>ri:uniqueMember</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <fetchStrategy>minimal</fetchStrategy>
            </attribute>
            <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>
                                import javax.naming.ldap.Rdn
                                import javax.naming.ldap.LdapName

                                dn = new LdapName('ou=groups,dc=example,dc=com')
                                dn.add(new Rdn('cn', name.toString()))
                                return dn.toString()
                            </code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- This MUST be weak in case of OpenDJ. If DN (name) is changed then the uid will be changed
                         as a side-effect as it is a naming attribute. -->
                    <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>generic</kind>
            <intent>ou</intent>
            <displayName>Organizational Unit</displayName>
            <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>
                    <source>
                        <path>$focus/extension/ext:orgpath</path>
                    </source>
                    <expression>
                        <script>
                            <code>
                                import javax.naming.ldap.Rdn
                                import javax.naming.ldap.LdapName

                                dn = new LdapName('dc=example,dc=com')
                                orgpath.tokenize('/').reverse().each { ouname -> dn.add(new Rdn('ou',ouname)) }
                                return dn.toString()
                            </code>
                        </script>
                    </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:ou</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <!-- This MUST be weak in case of OpenDJ. If DN (name) is changed then the uid will be changed
                         as a side-effect as it is a naming attribute. -->
                    <strength>weak</strength>
                    <source>
                        <path>$focus/name</path>
                    </source>
                </outbound>
                <inbound>
                    <strength>weak</strength>
                    <target>
                        <path>$focus/name</path>
                    </target>
                </inbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
        </objectType>

    </schemaHandling>

    <capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
        <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>

    <synchronization>
        <objectSynchronization>
            <objectClass>ri:inetOrgPerson</objectClass>
            <enabled>true</enabled>
            <correlation>
                <q:equal>
                    <q:path>c:name</q:path>
                    <expression>
                        <path>$shadow/attributes/ri:uid</path>
                    </expression>
                </q:equal>
            </correlation>

            <objectTemplateRef oid="c0c010c0-d34d-b33f-f00d-777111111111"/>

            <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>
                <synchronize>true</synchronize>
                <action>
                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
                </action>
            </reaction>
        </objectSynchronization>

        <objectSynchronization>
            <name>org sync</name>
            <objectClass>ri:organizationalUnit</objectClass>
            <kind>generic</kind>
            <intent>ou</intent>
            <focusType>c:OrgType</focusType>
            <enabled>true</enabled>
            <correlation>
                <q:equal>
                    <q:path>c:name</q:path>
                    <expression>
                        <path>$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>
    </synchronization>

</resource>
