XIP LDAP Import Beispiel

Aus SiteparkWiki
Zur Navigation springen Zur Suche springen

Der Importer fragt die LDAP-Daten vom LDAP-Server ab und wandelt Sie in ein XML-Format um. Über eine spezifisch erstellte XSLT werden die XML-Daten in das XML-XIP Format transformiert (XIP ist ein von Sitepark entwickeltes XML-Format, um Daten in den IES zu importieren).

Konfiguration des LDAP-Servers

Die Verbindung zum LDAP-Server wird in IES-Admin unter dem Bereich LDAP konfiguriert. Diese Verbindung wird zur Abfragen der Nutzerdaten für den Import und für die Authentifizierung der Nutzer verwendet.

Die Konfigurationsdateien können z.B. in dem Verzeichnis

/srv/sitepark/ldap/

organisiert werden.

Aufruf des LDAP Imports

Aufruf des LDAP Imports z.B. unter Linux:

/srv/sitepark/bin/iesxip /srv/sitepark/ldap/import.xml

oder als Cronjob:

23 00 * * * /srv/sitepark/bin/iesxip /srv/sitepark/ldap/import.xml

Für Tests der Daten kann der Kommando iesxip mit folgenden Optionen aufgerufen werden:

--dumpXml (Daten nicht importieren, XML-Ausgabe in die Console)
--ignore-xslt (XSLT-Transformation nicht anwenden, XML-Rohdaten ausgeben)

XML Konfiguration: import.xml

import.xml Die Konfigurations-Datei des Imports. In dieser Datei sind folgende Konfigurationen enthalten:

  • Logging des Imports (Import Log in die Datei import.log)
  • Import Nutzer, über den die Nutzer/Artikel im IES gespeichert werden.
  • Import-Optionen: Allgemeine Einstellungen das z.B. neue Einträge angelegt und nicht mehr existierende gelöscht werden solle. Weiter wird hier angegeben welche XSLT-Datei das Daten-Mapping vornimmt (import.xslt) und die Synchronisations-Datei um erkennen zu können welche Datensätze gelöscht werden sollen.
  • LDAP-Optionen: Hier wird der LDAP-Filter angegeben um nur die Datensätze abzufragen, die auch importiert werden sollen. Weiter wird hier angegeben das zwei LDAP-Attribute base64 encodiert werden, da sie Binäredaten enthalten (sASLoginConfiguration, sASLoginConfigurationKey).
<?xml version="1.0" encoding="UTF-8"?>
<import id="ldapimport" name="Import LDAP User">
    <logging>
        <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%d %-5p %m%n"/>
            </layout>
            <param name="File" value="${sitepark.home}/ldap-import.log"/>
            <param name="MaxFileSize" value="10MB"/>
            <param name="MaxBackupIndex" value="10"/>
        </appender>
        <logger name="com.sitepark.ies" additivity="false">
            <appender-ref ref="FILE"/>
            <priority value="INFO"/>
        </logger>
    </logging>
   <ies-connection login="Wartung" password="secret" client="ies2work" module="LDAP Importer"/>
   <options>
      <createElements>true</createElements>
      <deleteWorkDir>true</deleteWorkDir>
      <createPools>true</createPools>
      <updatePools>true</updatePools>
      <updateElements>true</updateElements>
      <deletePools>true</deletePools>
      <deleteOnlyEmptyPools>true</deleteOnlyEmptyPools>
      <deleteElements>true</deleteElements>
      <xslt>${sitepark.home}/ldap/ldap-import.xslt</xslt>
      <syncFile>${sitepark.home}/ldap/ldap-import.sync</syncFile>
   </options>
    <source type="ldap" id="1">
	<encoding attribute="sASLoginConfiguration" encoding="base64"/>
	<encoding attribute="sASLoginConfigurationKey" encoding="base64"/>
        <query>
          <and>
            <ldap-query>
              <search-filter>(uid=quintama)</search-filter>
              <search-base>dc=sitepark,dc=com</search-base>
              <search-scope>subtree</search-scope>
              <!-- <limit>1000</limit> -->
            </ldap-query>
            <or>
              <ldap-group member-dn-attribute="uniqueMember">cn=CMS Redakteure,ou=groups,dc=sitepark,dc=com</ldap-group>
              <ldap-group member-dn-attribute="uniqueMember">cn=CMS Administratoren,ou=groups,dc=sitepark,dc=com</ldap-group>
            </or>
          </and>
        </query>
    </source>
</import>

XSLT Artikelimport: ldap-import.xslt

In dieser Datei ist das Daten-Mapping zwischen LDAP und IES implementiert

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xip="http://ies.sitepark.com/xip"
    extension-element-prefixes="xip">

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <!--
        xip:getFirstLetter(String s)

        Liefert das erste Zeichen der übergebenen Zeichenkette.
        Ist dieses Zeichen ein Großbuchstabe wird er in einen
        Kleinbuchstaben umgewandelt

        Bei den Umlauten ä, ö und ü wird a, o oder ü zurückgeliefert
    -->
    <xsl:function name="xip:getFirstLetter"> <xsl:param name="s"/>

        <!-- Erstes Zeichen ermitteln -->
        <xsl:variable name="fistLetter" select="substring($s,1,1)"/>
        <!-- in Kleinbuchstaben umwandeln -->
        <xsl:variable name="toLowerCase" select="lower-case($fistLetter)"/>
        <!-- Umlaute umwandeln und Zeichen zurückgeben -->
        <xsl:variable name="substituteFrom" select="'äöü'"/>
        <xsl:variable name="substituteTo"   select="'aou'"/>
        <xsl:value-of select="translate($toLowerCase, $substituteFrom, $substituteTo)"/>
    </xsl:function>

    <!--
        Erzeugt eine Map mit den Anfangsbuchstaben als Keys und jeweils einer Liste von Elementen mit
        den entsprechenden Anfangsbuchstaben im Element <bsLastname>
        a=[<row>,<row>,...]
        b=[<row>,<row>,...]
        c=...
        ...
        z=...
    -->
    <xsl:key name="keyLetter" match="row" use="xip:getFirstLetter(bsLastName)"/>

    <xsl:template match="/">
        <xip>
        <!-- Gruppiert die Elemente nach ihrem Anfangsbuchstaben (siehe xip:getFirstLetter()) -->
        <!-- Diese Methode mit XSLT zu gruppieren nennt sich 'Muenchian Method' (siehe: http://www.jenitennison.com/xslt/grouping/muenchian.html) -->

        <!-- Schleife über a,b,c,d -->
        <xsl:for-each select="//row[generate-id() = generate-id(key('keyLetter', xip:getFirstLetter(bsLastName))[1]) ]">

            <xsl:variable name="letter" select="xip:getFirstLetter(bsLastName)"/>

            <!-- Schleife über alle mit dem gleichen Anfangsbuchstaben -->
            <xsl:for-each select="key('keyLetter',$letter)">

                <!-- Eine row der LDAP-Daten in XIP-Artikel umwandeln   altes Template:  template.main.mitarbeiter  -->
                <article parent="vv.informationpool.mitarbeiter.{$letter}" anchor="ldap.import.{bsPersonnalNumber}" name="{cn}" filename="{cn}" template="gui.vv.tpl.output.client.person">

                    <!-- Statische Werte -->
                    <link name="sp_vv_config_template" anchor="gui.vv.tpl.output.client.person" />
                    <text name="sp_vv_objectType">person</text>

                    <!--importierte Werte -->
                    <xsl:if test='contains(lower-case(bsTitle), "prof")'>
                        <text name="sp_vv_title">sp_title_1137574665206</text><!--sp_ldap_title-->
                    </xsl:if>
                    <xsl:if test='contains(lower-case(bsTitle), "dr")'>
                        <text name="sp_vv_title">sp_title_1137574647737</text><!--sp_ldap_title-->
                    </xsl:if>
                    <xsl:if test="contains(lower-case(bsSalutation), 'herr')">
                        <text name="sp_vv_salutation">sp_salut_1137574647733</text><!--sp_ldap_salutation-->
                    </xsl:if>
                    <xsl:if test="contains(lower-case(bsSalutation),'frau')">
                        <text name="sp_vv_salutation">sp_salut_1137574654460</text><!--sp_ldap_salutation-->
                    </xsl:if>

                    <text name="sp_vv_personnel"><xsl:if test="contains(bsPersonnalNumber,'kein Eintrag')!=true()"><xsl:value-of select="bsPersonnalNumber"/></xsl:if></text><!--sp_ldap_personnalNumber-->
                    <text name="sp_vv_firstname"><xsl:if test="contains(bsFirstName,'kein Eintrag')!=true()"><xsl:value-of select="bsFirstName"/></xsl:if></text><!--sp_ldap_firstName-->
                    <text name="sp_vv_lastname"><xsl:if test="contains(bsLastName,'kein Eintrag')!=true()"><xsl:value-of select="bsLastName"/></xsl:if></text><!--sp_ldap_lastName-->
                    <text name="sp_vv_mail"><xsl:if test="contains(bsMail,'kein Eintrag')!=true()"><xsl:value-of select="bsMail"/></xsl:if></text><!--sp_ldap_mail-->
                    <text name="sp_vv_publish_mail">true</text><!--sp_ldap_mail-->
                    <text name="sp_vv_street"><xsl:if test="contains(bsStreet,'kein Eintrag')!=true()"><xsl:value-of select="bsStreet"/></xsl:if></text><!--sp_ldap_street-->
                    <text name="sp_vv_postal_code"><xsl:if test="contains(bsZip,'kein Eintrag')!=true()"><xsl:value-of select="bsZip"/></xsl:if></text><!--sp_ldap_zip-->
                    <text name="sp_vv_city"><xsl:if test="contains(bsTown,'kein Eintrag')!=true()"><xsl:value-of select="bsTown"/></xsl:if></text><!--sp_ldap_town-->
                    <text name="sp_vv_roomNumber"><xsl:if test="contains(bsRoomFloor,'kein Eintrag')!=true()"><xsl:value-of select="bsRoomFloor"/></xsl:if></text><!--sp_ldap_roomFloor-->
                    <text name="sp_vv_phone"><xsl:if test="contains(bsPhoneComp,'kein Eintrag')!=true()"><xsl:value-of select="bsPhoneComp"/></xsl:if></text><!--sp_ldap_phoneComp-->
                    <text name="sp_vv_fax"><xsl:if test="contains(bsFaxComp,'kein Eintrag')!=true()"><xsl:value-of select="bsFaxComp"/></xsl:if></text><!--sp_ldap_faxComp-->
                    <text name="sp_vv_mobile"><xsl:if test="contains(bsMobile,'kein Eintrag')!=true()"><xsl:value-of select="bsMobile"/></xsl:if></text><!--sp_ldap_mobile-->
                    <text name="sp_vv_publish_mobile">true</text><!--sp_ldap_mobile-->
                    <text name="sp_vv_function"><xsl:if test="contains(bsFunction,'kein Eintrag')!=true()"><xsl:value-of select="bsFunction"/></xsl:if></text><!--sp_ldap_function-->

                </article>
            </xsl:for-each>
        </xsl:for-each>
        </xip>
    </xsl:template>
</xsl:stylesheet>

Einfacher XSLT Nutzerimport: ldap-import.xslt

In dieser Datei ist das Daten-Mapping zwischen LDAP und IES implementiert

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:utils="http://ies.sitepark.com/xip/utils"
    xmlns:saxon="http://saxon.sf.net/"
    extension-element-prefixes="utils saxon">

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <xip>
            <userpool parent="system.root.pool.user" anchor="system.import.pool" name="Import">
                <xsl:for-each select="rowset/row">
		    <user parent="system.import.pool"
                                  anchor="system.import.{uid}"
				  login="{uid}"
                                  email="{mail}"
                                  type="3003"
                                  firstname="{firstname}"
                                  lastname="{lastname}" 
				  ldap-server="2"
                                  ldap-dn="{dn}"
                    />
                </xsl:for-each>
            </userpool>
        </xip>
    </xsl:template>
</xsl:stylesheet>

Komplexer XSLT Nutzerimport mit Links auf mehere Nutzerpools: ldap-import.xslt

In dieser Datei ist das Daten-Mapping zwischen LDAP und IES implementiert

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="2.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:utils="http://ies.sitepark.com/xip/utils"
	xmlns:saxon="http://saxon.sf.net/"
	extension-element-prefixes="utils saxon">
 
	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
 
	<xsl:template match="/">
		<xip>
			<xsl:for-each select="rowset/row">

				<!-- Parent -->
				<xsl:variable name="parent">
					<xsl:choose>
						<xsl:when test="groupMembership = 'cn=Mitarbeiter,ou=Groups,o=SITEPARK'">users.sp.all</xsl:when>
						<xsl:when test="groupMembership = 'cn=Partner,ou=Groups,o=SITEPARK'">users.sp.partner</xsl:when>
						<xsl:otherwise></xsl:otherwise>
					</xsl:choose>
				</xsl:variable>

                                <!-- Vorname -->
                                <xsl:variable name="firstname">
                                        <xsl:choose>
                                                <xsl:when test="i18nGN"><xsl:value-of select="i18nGN"/></xsl:when>
                                                <xsl:otherwise><xsl:value-of select="givenName"/></xsl:otherwise>
                                        </xsl:choose>
                                </xsl:variable>

                                <!-- Nachname -->
                                <xsl:variable name="lastname">
                                        <xsl:choose>
                                                <xsl:when test="i18nSN"><xsl:value-of select="i18nSN"/></xsl:when>
                                                <xsl:otherwise><xsl:value-of select="sn"/></xsl:otherwise>
                                        </xsl:choose>
                                </xsl:variable>

				<!-- Für Anrede -->
				<xsl:variable name="sex">
					<xsl:choose>
						<xsl:when test="gender = '1'">1</xsl:when>
						<xsl:when test="gender = '2'">0</xsl:when>
						<xsl:otherwise>-1</xsl:otherwise>
					</xsl:choose>
				</xsl:variable>

				<!-- Login -->
				<xsl:variable name="login">
					<xsl:for-each select="cn">
						<xsl:if test="string-length(text()) = 8"><xsl:value-of select="."/></xsl:if>
					</xsl:for-each>
				</xsl:variable>

                                <!-- Email -->
                                <xsl:variable name="prefix" select="lower-case(i18nGN[text()])"/>
                                <xsl:variable name="email">
                                        <xsl:for-each select="mail">
                                                <xsl:if test='starts-with(lower-case(text()), $prefix)'>
                                                        <xsl:value-of select="text()"/>
                                                </xsl:if>
                                        </xsl:for-each>
                                </xsl:variable>
				
				<xsl:if test="$login != '' and $parent != ''">

					<user parent="{$parent}"
						anchor="users.ldap.{$login}"
						login="{$login}"
						email="{$email}"
						sex="{$sex}"
						firstname="{$firstname}"
						lastname="{$lastname}" 
						ldap-server="1"
						ldap-dn="{dn}"
					/>

					<!-- Gruppen-Zuordnung (Symlinks) -->

					<!-- Mitarbeiter -->
					<xsl:if test="groupMembership = 'cn=Mitarbeiter,ou=Groups,o=SITEPARK'">
						<!-- Develop -->
						<xsl:if test="groupMembership = 'cn=DEVELOP,ou=Groups,o=SITEPARK'">
							<symbolic-link parent="users.sp.develop" anchor="users.ldap.{$login}" />
						</xsl:if>
						<!-- Support -->
						<xsl:if test="groupMembership = 'cn=SUPPORT,ou=Groups,o=SITEPARK'">
							<symbolic-link parent="users.sp.support" anchor="users.ldap.{$login}" />
						</xsl:if>

					</xsl:if>
					<xsl:if test="groupMembership = 'cn=Partner,ou=Groups,o=SITEPARK'">
						<!-- Gold -->
						<xsl:if test="groupMembership = 'cn=gold,ou=Groups,o=SITEPARK'">
							<symbolic-link parent="users.sp.gold.all" anchor="users.ldap.{$login}" />
						</xsl:if>
						<!-- Silber -->
						<xsl:if test="groupMembership = 'cn=silver,ou=Groups,o=SITEPARK'">
							<symbolic-link parent="users.sp.silver.all" anchor="users.ldap.{$login}" />
						</xsl:if>
						<!-- Bronze -->
						<xsl:if test="groupMembership = 'cn=bronze,ou=Groups,o=SITEPARK'">
							<symbolic-link parent="users.sp.bronze.all" anchor="users.ldap.{$login}" />
						</xsl:if>
					</xsl:if>
				</xsl:if>
			</xsl:for-each>
		</xip>
	</xsl:template>
</xsl:stylesheet>