<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (c) 2017 Evolveum
  -->

<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:xsd="http://www.w3.org/2001/XMLSchema"
         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:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
         xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
         xmlns:posix="http://sample.evolveum.com/xml/ns/sample-idm/extension"
         xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3">


    <resource oid="9d5d62a6-49bb-11e6-ac4d-3c970e44b9e2">

        <name>OpenLDAP posix</name>
    <description>OpenLDAP with posixAccount and posixGroup support</description>
        <connectorRef type="ConnectorType">
            <filter>
                <q:text>connectorType = "com.evolveum.polygon.connector.ldap.LdapConnector"</q:text>
            </filter>
        </connectorRef>
    <connectorConfiguration>
        <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>389</icfcldap:port>
            <icfcldap:host>localhost</icfcldap:host>
            <icfcldap:baseContext>dc=example,dc=com</icfcldap:baseContext>
            <icfcldap:bindDn>cn=idm,ou=Administrators,dc=example,dc=com</icfcldap:bindDn>
            <icfcldap:bindPassword>
                            <clearValue>secret</clearValue>
            </icfcldap:bindPassword>
<!--                        <icfcldap:groupMemberAttribute>member</icfcldap:groupMemberAttribute>-->
            <icfcldap:passwordHashAlgorithm>SSHA</icfcldap:passwordHashAlgorithm>
            <icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute>
            <icfcldap:vlvSortOrderingRule>2.5.13.3</icfcldap:vlvSortOrderingRule>
            <icfcldap:operationalAttributes>memberOf</icfcldap:operationalAttributes><!-- FIXME no memberOf overlay configured yet FIXME -->
            <icfcldap:operationalAttributes>createTimestamp</icfcldap:operationalAttributes>
<!--                        <icfcldap:useBlocks>true</icfcldap:useBlocks>-->
<!--                        <icfcldap:usePagedResultControl>true</icfcldap:usePagedResultControl>-->
        </icfc:configurationProperties>

        <icfc:resultsHandlerConfiguration>
<!--                        <icfc:enableCaseInsensitiveFilter>true</icfc:enableCaseInsensitiveFilter>-->
            <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>

            <generateObjectClass>ri:posixGroup</generateObjectClass>
            <generateObjectClass>ri:posixAccount</generateObjectClass>
            <generateObjectClass>ri:shadowAccount</generateObjectClass>
        </generationConstraints>
    </schema>
    <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:distinguishedName</matchingRule>
                <volatilityTrigger>true</volatilityTrigger> <!-- XXX Since git-v3.3support-31-g2832d06 2.3.2016: Change of DN may cause change of naming attribute -->
                <outbound>
                    <source>
                        <path>$user/name</path>
                    </source>
                    <expression>
                        <script>
                            <code>
                                'uid=' + name + iterationToken + ',ou=people,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:memberOf</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <fetchStrategy>explicit</fetchStrategy>
            </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>fullName</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:sn</ref>
                <displayName>Surname</displayName>
                <limitations>
                    <minOccurs>0</minOccurs>
                </limitations>
                <outbound>
                    <source>
                        <path>familyName</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:givenName</ref>
                <displayName>Given Name</displayName>
                <outbound>
                    <source>
                        <path>givenName</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:uid</ref>
                <displayName>Login Name</displayName>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>name</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:l</ref>
                <displayName>Location</displayName>
                <outbound>
                    <source>
                        <path>locality</path>
                    </source>
                </outbound>
            </attribute>
            <association>
                <ref>ri:ldapGroup</ref>
                <displayName>LDAP Group Membership</displayName>
                <kind>entitlement</kind>
                <intent>ldapGroup</intent>
                <direction>objectToSubject</direction>
                <associationAttribute>ri:member</associationAttribute>
                <valueAttribute>ri:dn</valueAttribute>
<!-- FIXME no overlay memberOf configured yet -->
<!--                                <shortcutAssociationAttribute>ri:memberOf</shortcutAssociationAttribute>-->
<!--                                <shortcutValueAttribute>ri:dn</shortcutValueAttribute>-->
                <explicitReferentialIntegrity>true</explicitReferentialIntegrity>
            </association>

            <association>
                <ref>ri:unixGroup</ref>
                <displayName>UNIX Group Membership</displayName>
                <auxiliaryObjectClass>posixAccount</auxiliaryObjectClass>
                <kind>entitlement</kind>
                <intent>unixGroup</intent>
                <direction>objectToSubject</direction>
                <associationAttribute>ri:memberUid</associationAttribute>
                <valueAttribute>ri:uid</valueAttribute><!-- 24.2.2016: NOT ri:uidNumber ! -->
                <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>entitlement</kind>
            <intent>ldapGroup</intent>
            <displayName>LDAP Group</displayName>
            <objectClass>ri:groupOfNames</objectClass>
            <baseContext>
                <objectClass>ri:organizationalUnit</objectClass>
                <filter>
                    <q:text>attributes/dn = "ou=groups,dc=example,dc=com"</q:text>
                </filter>
            </baseContext>
            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$focus/identifier</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', identifier.toString()))
                                return dn.toString()
                            </code>
                        </script>
                        </expression>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:member</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <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/identifier</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
        </objectType>
        <objectType>
            <kind>entitlement</kind>
            <intent>unixGroup</intent>
            <displayName>UNIX Group</displayName>

            <objectClass>ri:posixGroup</objectClass>

            <baseContext>
                <objectClass>ri:organizationalUnit</objectClass>
                <filter>
                    <q:text>attributes/dn = "ou=unixgroups,dc=example,dc=com"</q:text>
                </filter>
            </baseContext>
            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
                <outbound>
                    <!-- Name cannot be weak. Changes in name trigger object rename. -->
                    <source>
                        <path>$focus/identifier</path>
                    </source>
                        <expression>
                            <script>
                            <code>
                                import javax.naming.ldap.Rdn
                                import javax.naming.ldap.LdapName

                                dn = new LdapName('ou=unixgroups,dc=example,dc=com')
                                dn.add(new Rdn('cn', identifier.toString()))
                                return dn.toString()
                            </code>
                        </script>
                        </expression>
                </outbound>
            </attribute>
<!--                        <attribute>-->
<!--                                <ref>ri:member</ref>-->
<!--                                <matchingRule>mr:distinguishedName</matchingRule>-->
<!--                        </attribute>-->
            <attribute>
                <ref>ri:memberUid</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>$focus/identifier</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
            </attribute>
            <attribute>
                <ref>ri:gidNumber</ref>
                <outbound>
                    <strength>strong</strength>
                    <source>
                        <path>extension/posix:gidNumber</path>
                    </source>
                </outbound>
            </attribute>
        </objectType>

    </schemaHandling>

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

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

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