<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.auth.introduction">

    <title>Wprowadzenie</title>

    <para>
        <classname>Zend_Auth</classname> zapewnia <acronym>API</acronym> do 
        uwierzytelniania oraz zawiera konkretne adaptery uwierzytelniania dla 
        najczęstszych przypadków użycia.
    </para>

    <para>
        Komponent <classname>Zend_Auth</classname> jest związany tylko z
        <emphasis>uwierzytelnianiem</emphasis>, a nie z
        <emphasis>autoryzacją</emphasis>.
        Uwierzytelnianie luźno definiujemy jako określanie w oparciu o pewien
        zestaw danych tego, czy dana jednostka jest tym na co wygląda (np.
        identyfikacja). Autoryzacja, proces decydowania o tym, czy zezwolić
        danej jednostce na dostęp lub przeprowadzanie operacji na innych
        jednostkach, jest poza polem działania <classname>Zend_Auth</classname>. 
        Aby uzyskać więcej informacji o autoryzacji i kontroli dostępu za pomocą 
        Zend Framework, proszę zobacz <link linkend="zend.acl"><classname>Zend_Acl</classname></link>.
    </para>

    <note>
        <para>
            Klasa <classname>Zend_Auth</classname> implementuje wzorzec singletona, czyli
            dostępna jest tylko jej jedna instancja - za pomocą statycznej
            metody <methodname>getInstance()</methodname>. Oznacza to, że użycie operatorów
            <emphasis>new</emphasis> oraz <emphasis>clone</emphasis> nie będzie możliwe z klasą
            <classname>Zend_Auth</classname>; zamiast nich użyj metody
            <methodname>Zend_Auth::getInstance()</methodname>.
        </para>
    </note>

    <sect2 id="zend.auth.introduction.adapters">

        <title>Adaptery</title>

        <para>
            Adapter <classname>Zend_Auth</classname> jest używany do uwierzytelniania 
            na podstawie serwisu konkretnego typu, takiego jak <acronym>LDAP</acronym>, 
            <acronym>RDBMS</acronym>, lub system plików. Różne adaptery mogą 
            mieć różne opcje i mogą inaczej się zachowywać,
            ale niektóre podstawowe funkcjonalności są wspólne dla wszystkich
            adapterów. Na przykład akceptowanie danych uwierzytelniania,
            przeprowadzanie zapytań do serwisu uwierzytelniania i zwracanie
            rezultatów są wspólne dla adapterów <classname>Zend_Auth</classname>.
        </para>

        <para>
            Każda klasa adaptera <classname>Zend_Auth</classname> implementuje interfejs
            <classname>Zend_Auth_Adapter_Interface</classname>. Ten interfejs definiuje
            jedną metodę, <methodname>authenticate()</methodname>, którą klasa adaptera
            musi implementować dla zastosowań przeprowadzania zapytania
            uwierzytelniania. Każda klasa adaptera musi być przygotowana przed
            wywołaniem metody <methodname>authenticate()</methodname>. Przygotowanie takiego
            adaptera obejmuje ustawienie danych uwierzytelniania (np. nazwy
            użytkownika i hasła) oraz zdefiniowanie wartości dla specyficznych
            opcji adaptera, na przykład ustawienie połączenia do bazy danych dla
            adaptera tabeli bazy danych.
        </para>

        <para>
            Poniżej jest przykładowy adapter uwierzytelniania, który do
            przeprowadzenia procesu wymaga ustawionej nazwy użytkownika oraz
            hasła. Inne szczegóły, takie jak sposób przeprowadzania zapytania
            uwierzytelniającego, zostały pominięte w celu zwiększenia
            czytelności:
        </para>

        <programlisting language="php"><![CDATA[
class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
    /**
     * Ustawia nazwę użytkownika oraz hasła dla uwierzytelniania
     *
     * @return void
     */
    public function __construct($username, $password)
    {
        // ...
    }

    /**
     * Przeprowadza próbę uwierzytelniania
     *
     * @throws Zend_Auth_Adapter_Exception Jeśli uwierzytelnianie
     *                                     nie może być przeprowadzone
     * @return Zend_Auth_Result
     */
    public function authenticate()
    {
        // ...
    }
}
]]></programlisting>

        <para>
            Jak pokazano w bloku dokumentacyjnym, metoda <methodname>authenticate()</methodname>
            musi zwracać instancję <classname>Zend_Auth_Result</classname> (lub instancję klasy
            rozszerzającej <classname>Zend_Auth_Result</classname>). Jeśli z jakiegoś
            powodu przeprowadzenie zapytania uwierzytelniającego jest niemożliwe,
            metoda <methodname>authenticate()</methodname> powinna wyrzucić wyjątek
            rozszerzający <classname>Zend_Auth_Adapter_Exception</classname>.
        </para>

    </sect2>

    <sect2 id="zend.auth.introduction.results">

        <title>Resultat</title>

        <para>
            Adaptery <classname>Zend_Auth</classname> zwracają instancję 
            <classname>Zend_Auth_Result</classname> za pomocą metody 
            <methodname>authenticate()</methodname> w celu przekazania
            rezultatu próby uwierzytelniania. Adaptery wypełniają obiekt
            <classname>Zend_Auth_Result</classname> podczas konstrukcji,
            dlatego poniższe cztery metody zapewniają podstawowy zestaw
            operacji, które są wspólne dla rezultatów adapterów 
            <classname>Zend_Auth</classname>:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>isValid()</methodname> - zwraca logiczną wartość true
                    tylko wtedy, gdy rezultat reprezentuje udaną próbę
                    uwierzytelniania.
                </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getCode()</methodname> - zwraca identyfikator w postaci
                    stałej klasy <classname>Zend_Auth_Result</classname> dla
                    określenia powodu nieudanego uwierzytelniania lub
                    sprawdzenia czy uwierzytelnianie się udało. Metoda może
                    być użyta w sytuacjach gdy programista chce rozróżnić
                    poszczególne typy wyników uwierzytelniania. Pozwala to
                    na przykład programiście na zarządzanie szczegółowymi
                    statystykami na temat wyników uwierzytelniania. Innym
                    przykładem użycia tej funkcjonalności może być potrzeba
                    zapewnienia wiadomości informujących użytkownika o
                    przebiegu uwierzytelniania, ale jednak zalecane jest
                    rozważenie ryzyka jakie zachodzi przy przekazywaniu
                    użytkownikowi takich szczegółowych informacji, zamiast
                    podstawowej informacji o błędzie. Aby uzyskać więcej
                    informacji, zobacz poniżej.
                </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getIdentity()</methodname> - zwraca tożsamość próby
                    uwierzytelniania
                </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getMessages()</methodname> - zwraca tablicę wiadomości
                    odnoszących się do nieudanej próby uwierzytelniania
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Programista może chcieć przeprowadzić jakieś specyficzne akcje
            zależne od typu wyniku uwierzytelniania. Przykładami operacji,
            które programiści mogą uznać za użyteczne, mogą być: blokowanie
            kont po zbyt dużej ilości nieudanych próbach logowania, zapiywanie
            adresów IP po wpisaniu przez użytkownika nieistnięjącej nazwy
            tożsamości czy zapewnienie własnych zdefiniowanych komunikatów po
            próbie uwierzytelniania. Dostępne są takie kody wyników:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Auth_Result::SUCCESS
Zend_Auth_Result::FAILURE
Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
Zend_Auth_Result::FAILURE_UNCATEGORIZED
]]></programlisting>

        <para>
            Poniższy przykład pokazuje w jaki sposób programista może obsłużyć
            to kodzie:
        </para>

        <programlisting language="php"><![CDATA[
// wewnątrz akcji loginAction kontrolera AuthController
$result = $this->_auth->authenticate($adapter);

switch ($result->getCode()) {

    case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
        /** obsługujemy nieistniejącą tożsamość **/
        break;

    case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
        /** obsługujemy nieprawidłowe hasło **/
        break;

    case Zend_Auth_Result::SUCCESS:
        /** obsługujemy udane uwierzytelnianie **/
        break;

    default:
        /** obsługujemy inne błędy **/
        break;
}
]]></programlisting>

    </sect2>

    <sect2 id="zend.auth.introduction.persistence">

        <title>Trwałość uwierzytelnionej tożsamości</title>

        <para>
            Uwierzytelnianie żądania, które zawiera dane uwierzytelniające jest
            samo w sobie użyteczne, ale ważna jest także obsługa
            uwierzytelnionej tożsamości bez konieczności dołączania danych
            uwierzytelniających do każdego żądania.
        </para>

        <para>
            <acronym>HTTP</acronym> jest protokołem niezachowującym stanu pomiędzy 
            żądaniami, a techniki takie jak pliki cookie oraz sesje zostały 
            stworzone w celu ułatwienia zarządzania stanem pomiędzy żądaniami w 
            aplikacjach serwerowych.
        </para>

        <sect3 id="zend.auth.introduction.persistence.default">

            <title>Domyślne przechowywanie w sesji PHP</title>

            <para>
                 Domyślnie <classname>Zend_Auth</classname> zapewnia trwały pojemnik do
                 przechowywania tożsamości pochodzącej z udanej próby
                 uwierzytelniania używając sesji <acronym>PHP</acronym>. Po udanej próbie
                 uwierzytelniania, metoda <methodname>Zend_Auth::authenticate()</methodname>
                 przechowuje wtrwałym pojemniku tożsamość pochodzącą z wyniku
                 uwierzytelniania. Jeśli nie skonfigurujemy tego inaczej, klasa
                 <classname>Zend_Auth</classname> użyje klasy pojemnika o nazwie
                 <classname>Zend_Auth_Storage_Session</classname>, który używa klasy
                 <link linkend="zend.session"><classname>Zend_Session</classname></link>. 
                 Zamiast tego za pomocą metody <methodname>Zend_Auth::setStorage()</methodname> 
                 może być ustawiona własna klasa implementująca interfejs
                 <classname>Zend_Auth_Storage_Interface</classname>.

            </para>

            <note>
                <para>
                    Jeśli automatyczne przechowywanie tożsamości w trwałym
                    pojemniku nie jest odpowiednie dla konkretnego przypadku
                    użycia, to programiści mogą obyć się bez klasy
                    <classname>Zend_Auth</classname>, a zamiast niej użyć 
                    bezpośrednio klasy adaptera.
                </para>
            </note>

            <example id="zend.auth.introduction.persistence.default.example">

                <title>Modyfikowanie przestrzeni nazw sesji</title>

                <para>
                    <classname>Zend_Auth_Storage_Session</classname> używa przestrzeni
                    nazw sesji o nazwie '<classname>Zend_Auth</classname>'. Ta przestrzeń
                    nazw może być nadpisana przez przekazanie innej wartości do
                    konstruktora klasy <classname>Zend_Auth_Storage_Session</classname>, a
                    ta wartość wewnętrznie jest przekazywana do konstruktora
                    klasy <classname>Zend_Session_Namespace</classname>. Powinno to
                    nastąpić zanim przeprowadzone zostanie uwierzytelnianie,
                    ponieważ metoda <methodname>Zend_Auth::authenticate()</methodname>
                    automatycznie zapisuje dane tożsamości.
                </para>

                <programlisting language="php"><![CDATA[
// Zapisujemy referencję do pojedynczej instancji Zend_Auth
$auth = Zend_Auth::getInstance();

// Używamy przestrzeni nazw 'someNamespace' zamiast 'Zend_Auth'
$auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));

/**
 * @todo Ustawić adapter uwierzytelniania, $authAdapter
 */

// Uwierzytelniamy, zapisując wynik i przechowując tożsamość
// po udanym uwierzytelnieniu
$result = $auth->authenticate($authAdapter);
]]></programlisting>

            </example>

        </sect3>

        <sect3 id="zend.auth.introduction.persistence.custom">

            <title>Implementacja własnego pojemnika</title>

            <para>
                Czasem programiści mogą potrzebować użyć innego sposobu
                trwałego przechowywania tożsamości niż ten zapewniony przez
                <classname>Zend_Auth_Storage_Session</classname>. W takich przypadkach
                programiści mogą po prostu zaimplementować interfejs
                <classname>Zend_Auth_Storage_Interface</classname> i przekazać instancję
                klasy do metody <methodname>Zend_Auth::setStorage()</methodname>.
            </para>

            <example id="zend.auth.introduction.persistence.custom.example">

                <title>Użycie własnej klasy do przechowywania tożsamości</title>

                <para>
                    W celu użycia klasy trwale przechowującej tożsamość innej
                    niż <classname>Zend_Auth_Storage_Session</classname>, programista
                    implementuje interfejs
                    <classname>Zend_Auth_Storage_Interface</classname>:
                </para>

                <programlisting language="php"><![CDATA[
class MyStorage implements Zend_Auth_Storage_Interface
{
    /**
     * Zwraca wartość logiczną true tylko wtedy gdy pojemnik jest pusty
     *
     * @throws Zend_Auth_Storage_Exception Jeśli okreslenie czy pojemnik
     *                                     jest pusty jest niemożliwe
     * @return boolean
     */
    public function isEmpty()
    {
        /**
         * @todo implementacja
         */
    }

    /**
     * Zwraca zawartość pojemnika
     *
     * Zachowanie jest nieokreślone w przypadku gdy pojemnik jest pusty.
     *
     * @throws Zend_Auth_Storage_Exception Jeśli odczyt zawartości
     *                                     pojemnika jest niemożliwy
     * @return mixed
     */
    public function read()
    {
        /**
         * @todo implementacja
         */
    }

    /**
     * Zapisuje zawartość $contents w pojemniku
     *
     * @param  mixed $contents
     * @throws Zend_Auth_Storage_Exception Jeśli zapisanie zawartości $contents
     *                                     do pojemnika jest niemożliwe
     * @return void
     */
    public function write($contents)
    {
        /**
         * @todo implementacja
         */
    }

    /**
     * Czyści zawartość pojemnika
     *
     * @throws Zend_Auth_Storage_Exception Jeśli wyczyszczenie zawartości
     *                                     pojemnika jest niemożliwe
     * @return void
     */
    public function clear()
    {
        /**
         * @todo implementacja
         */
    }

}
]]></programlisting>

                <para>
                    W celu użycia własnej klasy pojemnika, wywołaj metodę
                    <methodname>Zend_Auth::setStorage()</methodname> przed przeprowadzeniem
                    zapytania uwierzytelniającego:
                </para>

                <programlisting language="php"><![CDATA[<?php
// Instruujemy klasę Zend_Auth aby użyła niestandardowej klasy pojemnika
Zend_Auth::getInstance()->setStorage(new MyStorage());

/**
 * @todo Ustawić adapter uwierzytelniania, $authAdapter
 */

// Uwierzytelniamy, zapisując wynik i przechowując tożsamość po udanym uwierzytelnieniu
$result = Zend_Auth::getInstance()->authenticate($authAdapter);
]]></programlisting>

            </example>

        </sect3>

    </sect2>

    <sect2 id="zend.auth.introduction.using">

        <title>Użycie</title>

        <para>
            Są dwa możliwe sposoby użycia adapterów <classname>Zend_Auth</classname>:
        </para>

        <orderedlist>
            <listitem>
                <para>
                    pośrednio, za pomocą metody
                    <methodname>Zend_Auth::authenticate()</methodname>
                </para>
            </listitem>
            <listitem>
                <para>
                    bezpośrednio, za pomocą metody <methodname>authenticate()</methodname>
                    adaptera
                </para>
            </listitem>
        </orderedlist>

        <para>
            Poniższy przykład pokazuje jak użyć adaptera <classname>Zend_Auth</classname>
            pośrednio, poprzez użycie klasy <classname>Zend_Auth</classname>:
        </para>

        <programlisting language="php"><![CDATA[
// Pobieramy instancję Zend_Auth
$auth = Zend_Auth::getInstance();

// Ustawiamy adapter uwierzytelniania
$authAdapter = new MyAuthAdapter($username, $password);

// Przeprowadzamy uwierzytelnianie, zapisując rezultat
$result = $auth->authenticate($authAdapter);

if (!$result->isValid()) {
    // Uwierzytelnianie nieudane; wyświetlamy powody
    foreach ($result->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // Uwierzytelnianie udane; tożsamość ($username) jest zapisana w sesji
    // $result->getIdentity() === $auth->getIdentity()
    // $result->getIdentity() === $username
}]]></programlisting>

        <para>
            Jeśli uwierzytelnianie zostało przeprowadzone w żądaniu tak jak w
            powyższym przykładzie, prostą sprawą  jest sprawdzenie czy istnieje
            pomyślnie uwierzytelniona tożsamość:
        </para>

        <programlisting language="php"><![CDATA[
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    // Tożsamość istnieje; pobieramy ją
    $identity = $auth->getIdentity();
}
]]></programlisting>

        <para>
            Aby usunąć tożsamość z trwałego pojemnika, użyj po prostu metody
            <methodname>clearIdentity()</methodname>. Typowo może być to użyte do
            implementacji w aplikacji operacji wylogowania:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Auth::getInstance()->clearIdentity();
]]></programlisting>

        <para>
            Gdy automatyczne użycie trwałego pojemnika jest nieodpowiednie w
            konkretnym przypadku, programista może w prostu sposób ominąć
            użycie klasy <classname>Zend_Auth</classname>, używając bezpośrednio klasy
            adaptera. Bezpośrednie użycie klasy adaptera powoduje skonfigurowanie
            i przygotowanie obiektu adaptera, a następnie wywołanie metody
            <methodname>authenticate()</methodname>. Szczegóły specyficzne dla adaptera są
            opisane w dokumentacji dla każdego z adapterów. Poniższy przykład
            bezpośrednio używa <emphasis>MyAuthAdapter</emphasis>:
        </para>

        <programlisting language="php"><![CDATA[
// Ustawiamy adapter uwierzytelniania
$authAdapter = new MyAuthAdapter($username, $password);

// Przeprowadzamy uwierzytelnianie, zapisując rezultat
$result = $authAdapter->authenticate();

if (!$result->isValid()) {
    // Uwierzytelnianie nieudane; wyświetlamy powody
    foreach ($result->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // Uwierzytelnianie udane
    // $result->getIdentity() === $username
}
]]></programlisting>

    </sect2>

</sect1>