<?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 389 Directory 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: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: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="b61f63ae-7661-11e4-98b9-001e8c717e5b">

        <!-- Resource name. It will be displayed in GUI.  -->
        <name>389 Directory Server</name>

        <description>
            LDAP resource using a Polygon (ConnId) LDAP connector. It contains configuration
            for use with 389 Directory Servers.
        </description>

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

        <!-- Configuration section contains configuration of the connector,
             such as hostnames and passwords -->
        <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=Special Users,dc=example,dc=com</icfcldap:bindDn>
            <icfcldap:bindPassword><t:clearValue>secret123</t:clearValue></icfcldap:bindPassword>
            <icfcldap:uidAttribute>nsUniqueId</icfcldap:uidAttribute>
            <icfcldap:pagingStrategy>auto</icfcldap:pagingStrategy>
            <icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute>
            <icfcldap:operationalAttributes>memberOf</icfcldap:operationalAttributes>
            <icfcldap:operationalAttributes>createTimestamp</icfcldap:operationalAttributes>
            <icfcldap:operationalAttributes>nsAccountLock</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>
            <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:distinguishedName</matchingRule>
                <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:nsUniqueId</ref>
                <displayName>Entry ID</displayName>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <displayName>Common Name</displayName>
                <limitations>
                    <maxOccurs>1</maxOccurs>
                </limitations>
                <outbound>
                    <source>
                        <path>fullName</path>
                    </source>
                </outbound>
                <inbound>
                    <target>
                        <path>fullName</path>
                    </target>
                </inbound>
            </attribute>
            <attribute>
                <ref>ri:sn</ref>
                <displayName>Surname</displayName>
                <outbound>
                    <source>
                        <path>familyName</path>
                    </source>
                </outbound>
                <inbound>
                    <target>
                        <path>familyName</path>
                    </target>
                </inbound>
            </attribute>
            <attribute>
                <ref>ri:givenName</ref>
                <displayName>Given Name</displayName>
                <outbound>
                    <source>
                        <path>givenName</path>
                    </source>
                </outbound>
                <inbound>
                    <target>
                        <path>givenName</path>
                    </target>
                </inbound>
            </attribute>
            <attribute>
                <ref>ri:uid</ref>
                <displayName>Login Name</displayName>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>name</path>
                    </source>
                    <expression>
                        <script>
                            <code>
                                name + iterationToken
                            </code>
                        </script>
                    </expression>
                </outbound>
                <inbound>
                    <target>
                        <path>name</path>
                    </target>
                </inbound>
            </attribute>
            <attribute>
                <ref>ri:memberOf</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <fetchStrategy>explicit</fetchStrategy>
            </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>
                <shortcutAssociationAttribute>ri:memberOf</shortcutAssociationAttribute>
                <shortcutValueAttribute>ri:dn</shortcutValueAttribute>
                <explicitReferentialIntegrity>true</explicitReferentialIntegrity>
            </association>

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

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

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

            <credentials>
                <password>
                    <outbound>
                        <strength>strong</strength>
                        <expression>
                            <asIs/>
                        </expression>
                    </outbound>
                </password>
            </credentials>
        </objectType>

        <objectType>
            <kind>entitlement</kind>
            <intent>ldapGroup</intent>
            <displayName>LDAP Group</displayName>
            <objectClass>ri:groupOfUniqueNames</objectClass>
            <attribute>
                <ref>ri:dn</ref>
                <matchingRule>mr:distinguishedName</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:uniqueMember</ref>
                <matchingRule>mr:distinguishedName</matchingRule>
            </attribute>
            <attribute>
                <ref>ri:cn</ref>
                <matchingRule>mr:stringIgnoreCase</matchingRule>
                <outbound>
                    <strength>weak</strength>
                    <source>
                        <path>$focus/name</path>
                    </source>
                </outbound>
                <inbound>
                    <target>
                        <path>name</path>
                    </target>
                </inbound>
            </attribute>
            <attribute>
                <ref>ri:description</ref>
                <outbound>
                    <source>
                        <path>description</path>
                    </source>
                </outbound>
                <inbound>
                    <target>
                        <path>description</path>
                    </target>
                </inbound>
            </attribute>
        </objectType>

    </schemaHandling>

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

    <synchronization>
        <objectSynchronization>
            <name>Account sync</name>
            <objectClass>ri:inetOrgPerson</objectClass>
            <kind>account</kind>
            <intent>default</intent>
            <focusType>UserType</focusType>
            <enabled>true</enabled>
            <correlation>
                <q:and>
                    <q:equal>
                        <q:path>c:employeeNumber</q:path>
                        <expression>
                        <path>declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003";
                            $shadow/attributes/ri:employeeNumber</path>
                        </expression>
                    </q:equal>
                    <q:not>
                        <q:equal>
                            <q:path>c:employeeNumber</q:path>
                            <q:value/>
                        </q:equal>
                    </q:not>
                </q:and>
            </correlation>

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

        </objectSynchronization>

        <objectSynchronization>
            <name>Group sync</name>
            <objectClass>ri:groupOfUniqueNames</objectClass>
            <kind>entitlement</kind>
            <intent>ldapGroup</intent>
            <focusType>RoleType</focusType>
            <enabled>true</enabled>
            <correlation>
                <q:equal>
                    <q:path>c:name</q:path>
                    <expression>
                    <path>$shadow/attributes/cn</path>
                    </expression>
                </q:equal>
            </correlation>

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

        </objectSynchronization>
    </synchronization>
  </resource>
</objects>
