<?xml version="1.0" encoding="ISO-8859-1"?>
<chapter id="customer">
  <title>Kunden (min. OTRS 1.1)</title>

  <para>OTRS ist in der Lage, mit verschiedenen Kundendaten (insbesondere
  Login, eMail, Telefon) umzugehen. Diese Informationen können im
  Agenten-Interface angezeigt werden und können für das Kunden-Interface
  benutzt werden (Benutzer und Authentifizierung).</para>

  <section id="customer-howto">
    <title>Wie es funktioniert</title>

    <para>Die benutzten/angezeigten Kundendaten sind frei konfigurierbar (s.
    Backend), aber es gibt drei benötigte Optionen: BenutzerLogin,
    BenutzerEmail und BenutzerKundenID.</para>

    <section>
      <title>Agenten-Interface</title>

      <para>Wenn Sie die Kundendaten (z.B. Firma, Name, eMail, ...) in Ihrem
      Agenten-Interface anzeigen möchten, benutzen Sie die folgenden
      Konfigurations-Optionen.<programlisting>
    [Kernel/Config.pm]
    # ShowCustomerInfo*
    # (show customer user info on Compose (Phone and Email), Zoom and Queue view)
    $Self-&#62;{ShowCustomerInfoCompose} = 1;
    $Self-&#62;{ShowCustomerInfoZoom} = 1;
    $Self-&#62;{ShowCustomerInfoQueue} = 0;
    [...]
</programlisting></para>
    </section>

    <section>
      <title>Admin-Interface</title>

      <para>Über das Admin-Interface können Sie die Kundendaten editieren
      (http://yourhost/otrs/index.pl?Action=AdminCustomerUser).</para>
    </section>

    <section>
      <title>Kunden-Interface</title>

      <para>Die Kundendaten für das Kunden-Interface
      (http://yourhost/otrs/customer.pl) werden für Login und
      Authentifizierung benutzt.</para>
    </section>
  </section>

  <section id="customer-user-backend">
    <title>Kundenbenutzer-Backend</title>

    <para>Es existieren zwei Kundenbenutzer-Backends, DB und LDAP. Falls Sie
    bereits ein Kunden-Verzeichnis (z.B. SAP, ...) haben, ist es natürlich
    möglich, dafür ein eigenes Backend zu schreiben.</para>

    <para>
    Notiz: Es is auch möglich mehr als einen Kunden-Daten Topf zu definieren.
    Einfach eine weitere Konfig Option wie "CustomerUser" mit einer Nummer
    zwischen 1 und 10. Zum Beispiel "CustomerUser1".
    </para>

    <section>
      <title>Datenbank (Standard)</title>

      <para>Dies ist ein Beispiel für ein Datenbank-Backend.</para>

      <para><programlisting>
    [Kernel/Config.pm]
    # CustomerUser 
    # (customer user database backend and settings)
    $Self-&#62;{CustomerUser} = {
        Name => 'Datenbank Quelle',
        Module =&#62; &#39;Kernel::System::CustomerUser::DB&#39;,
        Params =&#62; {
            # if you want to use an external database, add the
            # required settings 
#            DSN =&#62; &#39;DBI:odbc:yourdsn&#39;,
#            DSN =&#62; &#39;DBI:mysql:database=customerdb;host=customerdbhost&#39;,
#            User =&#62; &#39;&#39;,
#            Password =&#62; &#39;&#39;,
            Table =&#62; &#39;customer_user&#39;,
        },
        # customer uniq id
        CustomerKey =&#62; &#39;login&#39;,
        # customer #
        CustomerID =&#62; &#39;customer_id&#39;,
        CustomerValid =&#62; &#39;valid_id&#39;,
        CustomerUserListFields =&#62; [&#39;login&#39;, &#39;first_name&#39;, &#39;last_name&#39;, &#39;email&#39;],
        CustomerUserSearchFields =&#62; [&#39;login&#39;, &#39;last_name&#39;, &#39;customer_id&#39;],
        CustomerUserPostMasterSearchFields =&#62; [&#39;email&#39;],
        CustomerUserNameFields =&#62; [&#39;salutation&#39;, &#39;first_name&#39;, &#39;last_name&#39;],
        Map =&#62; [
            # note: Login, Email and CustomerID needed!
            # var, frontend, storage, shown, required, storage-type, http-link
            [ &#39;UserSalutation&#39;, &#39;Salutation&#39;, &#39;salutation&#39;, 1, 0, &#39;var&#39; ],
            [ &#39;UserFirstname&#39;, &#39;Firstname&#39;, &#39;first_name&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserLastname&#39;, &#39;Lastname&#39;, &#39;last_name&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserLogin&#39;, &#39;Login&#39;, &#39;login&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserPassword&#39;, &#39;Password&#39;, &#39;pw&#39;, 0, 1, &#39;var&#39; ],
            [ &#39;UserEmail&#39;, &#39;Email&#39;, &#39;email&#39;, 0, 1, &#39;var&#39; ],
#            [ &#39;UserEmail&#39;, &#39;Email&#39;, &#39;email&#39;, 1, 1, &#39;var&#39;, &#39;$Env{&#34;CGIHandle&#34;}?Action=\
AgentCompose&#38;ResponseID=1&#38;TicketID=$Data{&#34;TicketID&#34;}&#38;ArticleID=$Data{&#34;ArticleID&#34;}&#39; ],
            [ &#39;UserCustomerID&#39;, &#39;CustomerID&#39;, &#39;customer_id&#39;, 0, 1, &#39;var&#39; ],
            [ &#39;UserComment&#39;, &#39;Comment&#39;, &#39;comment&#39;, 1, 0, &#39;var&#39; ],
            [ &#39;ValidID&#39;, &#39;Valid&#39;, &#39;valid_id&#39;, 0, 1, &#39;int&#39; ],
        ],
    };
    [...]
</programlisting></para>

      <para>Falls Sie Ihre Kundendaten anpassen möchten, ändern Sie die
      Tabellenspalten oder fügen Sie weitere hinzu:<programlisting>
ALTER TABLE customer_user ADD phone VARCHAR (250);
</programlisting>
Danach fügen Sie Ihre eigenen Spalten dem MAP Array hinzu:<programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ &#39;UserPhone&#39;, &#39;Phone&#39;, &#39;phone&#39;, 1, 0, &#39;var&#39; ],
</programlisting>
Natürlich können Sie all diese Kundeninformationen dann auch
über das Admin-Interface pflegen.
</para>

<para>
MultiCustomerIDs: Es ist auch möglich mehr als nur eine Kunden-Nummer einen Kunden zu geben.
Z. B. wenn ein Kunde auf Tickets anderer Kunden zugreifen muss.
</para>
<para>
Einfach eine Tabellenspalten hinzufügen in der die Kunden-Nummern eingetragen werden
(wie "CustomerID1, CustomerID2, CustomerID3"):
<programlisting>
ALTER TABLE customer_user ADD customer_ids VARCHAR (250);
</programlisting>
</para>
<para>
Nun einen weiteren Eintrag in der CustomerUser MAP Aarray In Kernel/Config.pm hinzufügen:
<programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ 'UserCustomerIDs', 'CustomerIDs', 'customer_ids', 1, 0, 'var' ],
</programlisting>
Natürlich können Sie all die Multi-Kunden-Nummern dann auch
über das Admin-Interface pflegen.
</para>

    </section>

    <section>
      <title>LDAP</title>

      <para>Falls Sie ein existierendes LDAP-Verzeichnis mit Ihren
      Kunden-Benutzern haben, sind Sie in der Lage, dieses auch in OTRS zu
      nutzen.</para>

      <para>Dies ist ein Beispiel für ein LDAP-Backend.</para>

      <para><programlisting>
    [Kernel/Config.pm]
    # CustomerUser 
    # (customer user ldap backend and settings)
    $Self-&#62;{CustomerUser} = {
        Name => 'LDAP Quelle',
        Module =&#62; &#39;Kernel::System::CustomerUser::LDAP&#39;,
        Params =&#62; {
            # ldap host
            Host =&#62; &#39;bay.csuhayward.edu&#39;,
            # ldap base dn
            BaseDN =&#62; &#39;ou=seas,o=csuh&#39;,
            # search scope (one|sub)
            SSCOPE =&#62; &#39;sub&#39;,
            # The following is valid but would only be necessary if the
            # anonymous user does NOT have permission to read from the LDAP tree 
            UserDN =&#62; &#39;&#39;,
            UserPw =&#62; &#39;&#39;,
            # in case you want to add always one filter to each ldap query, use
            # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
            AlwaysFilter => '',
            # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
            Params => {
                port => 389,
                version => 3,
            },
        }, 
        # customer uniq id
        CustomerKey =&#62; &#39;uid&#39;,
        # customer #
        CustomerID =&#62; &#39;mail&#39;,
        CustomerUserListFields =&#62; [&#39;uid&#39;, &#39;cn&#39;, &#39;mail&#39;],
        CustomerUserSearchFields =&#62; [&#39;uid&#39;, &#39;cn&#39;, &#39;mail&#39;],
        CustomerUserPostMasterSearchFields =&#62; [&#39;mail&#39;],
        CustomerUserNameFields =&#62; [&#39;givenname&#39;, &#39;sn&#39;],
        Map =&#62; [
            # note: Login, Email and CustomerID needed!
            # var, frontend, storage, shown, required, storage-type
            [ &#39;UserSalutation&#39;, &#39;Title&#39;, &#39;title&#39;, 1, 0, &#39;var&#39; ],
            [ &#39;UserFirstname&#39;, &#39;Firstname&#39;, &#39;givenname&#39;, 1, 1, &#39;var&#39; ], 
            [ &#39;UserLastname&#39;, &#39;Lastname&#39;, &#39;sn&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserLogin&#39;, &#39;Login&#39;, &#39;uid&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserEmail&#39;, &#39;Email&#39;, &#39;mail&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserCustomerID&#39;, &#39;CustomerID&#39;, &#39;mail&#39;, 0, 1, &#39;var&#39; ],
            [ &#39;UserPhone&#39;, &#39;Phone&#39;, &#39;telephonenumber&#39;, 1, 0, &#39;var&#39; ],
            [ &#39;UserAddress&#39;, &#39;Address&#39;, &#39;postaladdress&#39;, 1, 0, &#39;var&#39; ],
            [ &#39;UserComment&#39;, &#39;Comment&#39;, &#39;description&#39;, 1, 0, &#39;var&#39; ],
        ],
    };
    [...]
</programlisting></para>

      <para>Falls Sie Ihre Kundendaten anpassen möchten, fügen Sie Ihre neuen
      Punkte dem MAP Array hinzu (oder entfernen Sie nicht benötigte Punkte):</para>

      <para><programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ &#39;UserOrganisation&#39;, &#39;Organisation&#39;, &#39;ou&#39;, 1, 0, &#39;var&#39; ],
</programlisting></para>
<para>
MultiCustomerIDs: Es ist auch möglich mehr als nur eine Kunden-Nummer einen Kunden zu geben.
Z. B. wenn ein Kunde auf Tickets anderer Kunden zugreifen muss.
</para>
<para>
Einfach eine Feld im LDAP Baum für die Multi-Kunden-Nummern auswählen in welche die Kunden-Nummern eingetragen werden
(wie "CustomerID1, CustomerID2, CustomerID3"):
</para>
<para>
Nun einen weiteren Eintrag in der CustomerUser MAP Aarray In Kernel/Config.pm hinzufügen:
<programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ 'UserCustomerIDs', 'CustomerIDs', 'second_customer_ids', 1, 0, 'var' ],
</programlisting>
Natürlich müssen die Multi-Kunden-Nummern vom LDAP Admin gepflegt werden.
</para>
    </section>
  </section>

  <section id="customer-auth-backend">
    <title>Kunden-Authentifizierungs-Backend</title>

    <section>
      <title>Datenbank (Standard)</title>

      <para>Das Standard-Kunden-Authentifizierungs-Backend ist die otrs
      Datenbank mit Ihren Kunden-Benutzern, die über das Admin-Interface oder
      Kunden-Interface (Konto anlegen) angelegt werden.</para>

      <para><programlisting>
    [Kernel/Config.pm]
    # This is the auth. module againt the otrs db
    $Self-&#62;{&#39;Customer::AuthModule&#39;} = &#39;Kernel::System::CustomerAuth::DB&#39;;
    [...]
</programlisting></para>
    </section>

    <section>
      <title>LDAP</title>

      <para>Falls ein LDAP-Verzeichnis mit Ihren Kunden-Benutzern verfügbar
      ist, können Sie das Kunden-LDAP-Authentifizierungs-Backend benutzen.
      Dieses Modul ist nur-lesend (d.h. es kann nicht in Ihr LDAP-Verzeichnis
      schreiben - dies sollte nur dem Verzeichnis-Manager möglich sein), so
      dass Sie keine Kunden über das Admin- oder Kunden-Interface anlegen oder
      ändern können.</para>

      <para><programlisting>
    [Kernel/Config.pm]
    # This is an example configuration for an LDAP auth. backend.
    # (take care that Net::LDAP is installed!)
    $Self-&#62;{&#39;Customer::AuthModule&#39;} = &#39;Kernel::System::CustomerAuth::LDAP&#39;;
    $Self-&#62;{&#39;Customer::AuthModule::LDAP::Host&#39;} = &#39;ldap.example.com&#39;;
    $Self-&#62;{&#39;Customer::AuthModule::LDAP::BaseDN&#39;} = &#39;dc=example,dc=com&#39;;
    $Self-&#62;{&#39;Customer::AuthModule::LDAP::UID&#39;} = &#39;uid&#39;;

    # Check if the user is allowed to auth in a posixGroup
    # (e. g. user needs to be in a group xyz to use otrs)
#    $Self-&#62;{&#39;Customer::AuthModule::LDAP::GroupDN&#39;} = &#39;cn=otrsallow,ou=posixGroups,dc=example,dc=com&#39;;
#    $Self-&#62;{&#39;Customer::AuthModule::LDAP::AccessAttr&#39;} = &#39;memberUid&#39;;

    # The following is valid but would only be necessary if the
    # anonymous user do NOT have permission to read from the LDAP tree 
    $Self-&#62;{&#39;Customer::AuthModule::LDAP::SearchUserDN&#39;} = &#39;&#39;;
    $Self-&#62;{&#39;Customer::AuthModule::LDAP::SearchUserPw&#39;} = &#39;&#39;;

    # in case you want to add always one filter to each ldap query, use
    # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
#   $Self->{'Customer::AuthModule::LDAP::AlwaysFilter'} = '';

    # in case you want to add a suffix to each customer login name, then
    # you can use this option. e. g. user just want to use user but
    # in your ldap directory exists user@domain.
#    $Self->{'Customer::AuthModule::LDAP::UserSuffix'} = '@domain.com';

    # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
#    $Self->{'Customer::AuthModule::LDAP::Params'} = {
#        port => 389,
#        version => 3,
#    };
    [...]
</programlisting></para>
    </section>

    <section>
      <title>HTTPBasicAuth</title>

      <para>Falls Sie eine &#34;single sign on&#34;-Lösung für Ihre Kunden
      benutzen, benutzen Sie http basic authentication (für alle Ihre Systeme)
      und benutzen Sie das HTTPBasicAuth Modul (kein OTRS-Login benötigt!).</para>

      <para><programlisting>
    [Kernel/Config.pm]
    # This is the auth. module againt $ENV{REMOTE_USER} (apache
    # http-basic-auth)
    $Self-&#62;{&#39;Customer::AuthModule&#39;} = &#39;Kernel::System::CustomerAuth::HTTPBasicAuth&#39;;
    # Note:
    # If you use this module, you should use as fallback the following
    # config settings if user isn&#39;t login through apache ($ENV{REMOTE_USER})
    $Self-&#62;{CustomerPanelLoginURL} = &#39;http://host/not-authorised-for-otrs.html&#39;;
    $Self-&#62;{CustomerPanelLogoutURL} = &#39;http://host/thanks-for-using-otrs.html&#39;;
    [...]
</programlisting></para>
    </section>

<section>
<title>Radius</title>
<para>
Authentifizierung gegen einen Radius-Server.
<programlisting>
    [Kernel/Config.pm]
    # This is example configuration to auth. agents against a radius server
    $Self->{'Customer::AuthModule'} = 'Kernel::System::Auth::Radius';
    $Self->{'Customer::AuthModule::Radius::Host'} = 'radiushost';
    $Self->{'Customer::AuthModule::Radius::Password'} = 'radiussecret';
    [...]
</programlisting>
</para>
</section>


  </section>

  <section id="customer-self-registration">
    <title>Kunden-Selbstanmeldung anpassen</title>

    <para>Es ist möglich, die Kunden-Selbstanmeldung für neue Kunden über
    &#34;customer.pl&#34; anzupassen. Somit können Sie mehr optionale oder
    benötigte Felder (z.B. Adresse, Ort) hinzufügen.</para>

    <para>In unserem Beispiel wollen wir ein benötigtes Adress-Feld
    hinzufügen.</para>

    <section>
      <title>Vorlage</title>

      <para>Editieren Sie
      &#34;Kernel/Output/HTML/Standard/CustomerCreateAccount.dtl&#34; und
      fügen Sie Ihre gewünschten Felder hinzu. Wir möchten ein Adress-Feld,
      also fügen Sie folgendes hinzu:</para>

      <para><programlisting>
    [...]
    &#60;tr&#62;
      &#60;td&#62;$Text{&#34;Address&#34;}: &#60;/td&#62;
      &#60;td&#62; &#60;input type=&#34;text&#34; name=&#34;Address&#34; value=&#34;$Data{&#34;UserAddress&#34;}&#34; size=&#34;35&#34; maxlength=&#34;50&#34;&#62;&#60;/td&#62;
    &#60;/tr&#62;
    [...]
</programlisting></para>
    </section>

    <section>
      <title>Kunden-Mapping</title>

      <para>Zusätzlich müssen Sie einen &#34;Adress&#34;-Eintrag zu Ihrem
      Kunden-Mapping hinzufügen. Fügen Sie &#34;CustomerUser&#34;
      (Kunden-Mapping) aus &#34;Kernel/Config/Defaults.pm&#34; zu Ihrer
      &#34;Kernel/Config.pm&#34; hinzu und ergänzen Sie das Adress-Feld.
      Danach sollte es ungefähr so aussehen:</para>

      <programlisting>
    [Kernel/Config.pm]
    $Self-&#62;{CustomerUser} = {
        Name => 'Interne Kunden',
        Module =&#62; &#39;Kernel::System::CustomerUser::DB&#39;,
        Params =&#62; {
            Table =&#62; &#39;customer_user&#39;,
        },
        Map =&#62; [
            # note: Login, Email and CustomerID needed!
            # var, frontend, storage, shown, required, storage-type, link
            [ &#39;UserSalutation&#39;, &#39;Salutation&#39;, &#39;salutation&#39;, 1, 0, &#39;var&#39; ],
            [ &#39;UserFirstname&#39;, &#39;Firstname&#39;, &#39;first_name&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserLastname&#39;, &#39;Lastname&#39;, &#39;last_name&#39;, 1, 1, &#39;var&#39; ],
            # our new option
            [ &#39;UserAddress&#39;, &#39;Address&#39;, &#39;address&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserLogin&#39;, &#39;Login&#39;, &#39;login&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserPassword&#39;, &#39;Password&#39;, &#39;pw&#39;, 0, 1, &#39;var&#39; ],
            [ &#39;UserEmail&#39;, &#39;Email&#39;, &#39;email&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserCustomerID&#39;, &#39;CustomerID&#39;, &#39;customer_id&#39;, 1, 1, &#39;var&#39; ],
            [ &#39;UserComment&#39;, &#39;Phone&#39;, &#39;comment&#39;, 1, 0, &#39;var&#39; ],
            [ &#39;ValidID&#39;, &#39;Valid&#39;, &#39;valid_id&#39;, 0, 1, &#39;int&#39; ],
        ],
        Key =&#62; &#39;login&#39;,
        CustomerID =&#62; &#39;customer_id&#39;,
    };
    [...]
</programlisting>
    </section>

    <section>
      <title>Kunden-Tabelle anpassen</title>

      <para>Ausserdem müssen wir eine neue Spalte zu unserer
      &#34;customer_user&#34; Tabelle hinzufügen.</para>

      <para><programlisting>
mysql&#62; ALTER TABLE customer_user ADD address VARCHAR (200);
Query OK, 0 rows affected (0.21 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql&#62; 
</programlisting>Das ist alles - Starten Sie Ihren Webserver neu (falls Sie
      mod_perl benutzen) und gehen Sie auf
      &#34;http://otrs.example.com/otrs/customer.pl&#34;, um es zu testen.</para>
    </section>
  </section>
</chapter>
