Skip to content
315 changes: 315 additions & 0 deletions docs/en/upgrade-3-to-4.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
Upgrade Guide 3.x to 4.x
#########################

Version 4.0 is a major release with several breaking changes focused on
simplifying the API and removing deprecated code.

Breaking Changes
================

IdentifierCollection Removed
-----------------------------

The deprecated ``IdentifierCollection`` has been removed. Authenticators now
accept a nullable ``IdentifierInterface`` directly.

**Before (3.x):**

.. code-block:: php

use Authentication\Identifier\IdentifierCollection;

$identifiers = new IdentifierCollection([
'Authentication.Password',
]);

$authenticator = new FormAuthenticator($identifiers);

**After (4.x):**

.. code-block:: php

use Authentication\Identifier\IdentifierFactory;

// Option 1: Pass identifier directly
$identifier = IdentifierFactory::create('Authentication.Password');
$authenticator = new FormAuthenticator($identifier);

// Option 2: Pass null and let authenticator create default
$authenticator = new FormAuthenticator(null);

// Option 3: Configure identifier in authenticator config
$service->loadAuthenticator('Authentication.Form', [
'identifier' => 'Authentication.Password',
]);

AuthenticationService Changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``loadIdentifier()`` method has been removed from ``AuthenticationService``.
Identifiers are now managed by individual authenticators.

**Before (3.x):**

.. code-block:: php

$service = new AuthenticationService();
$service->loadIdentifier('Authentication.Password');
$service->loadAuthenticator('Authentication.Form');

**After (4.x):**

.. code-block:: php

$service = new AuthenticationService();
$service->loadAuthenticator('Authentication.Form', [
'identifier' => 'Authentication.Password',
]);

CREDENTIAL Constants Moved
---------------------------

The ``CREDENTIAL_USERNAME`` and ``CREDENTIAL_PASSWORD`` constants have been
moved from ``AbstractIdentifier`` to specific identifier implementations.

**Before (3.x):**

.. code-block:: php

use Authentication\Identifier\AbstractIdentifier;

$fields = [
AbstractIdentifier::CREDENTIAL_USERNAME => 'email',
AbstractIdentifier::CREDENTIAL_PASSWORD => 'password',
];

**After (4.x):**

.. code-block:: php

use Authentication\Identifier\PasswordIdentifier;

$fields = [
PasswordIdentifier::CREDENTIAL_USERNAME => 'email',
PasswordIdentifier::CREDENTIAL_PASSWORD => 'password',
];

For LDAP authentication:

.. code-block:: php

use Authentication\Identifier\LdapIdentifier;

$fields = [
LdapIdentifier::CREDENTIAL_USERNAME => 'uid',
LdapIdentifier::CREDENTIAL_PASSWORD => 'password',
];

URL Checker Renamed and Restructured
-------------------------------------

URL checkers have been completely restructured:

- ``CakeRouterUrlChecker`` has been renamed to ``DefaultUrlChecker``
- The old ``DefaultUrlChecker`` (framework-agnostic) has been renamed to ``GenericUrlChecker``
- Auto-detection has been removed - ``DefaultUrlChecker`` is now hardcoded

**Before (3.x):**

.. code-block:: php

// Using CakeRouterUrlChecker explicitly
$service->loadAuthenticator('Authentication.Form', [
'urlChecker' => 'Authentication.CakeRouter',
'loginUrl' => [
'controller' => 'Users',
'action' => 'login',
],
]);

// Using DefaultUrlChecker explicitly (framework-agnostic)
$service->loadAuthenticator('Authentication.Form', [
'urlChecker' => 'Authentication.Default',
'loginUrl' => '/users/login',
]);

// Auto-detection (picks CakeRouter if available, otherwise Default)
$service->loadAuthenticator('Authentication.Form', [
'loginUrl' => '/users/login',
]);

**After (4.x):**

.. code-block:: php

// DefaultUrlChecker is now hardcoded (formerly CakeRouterUrlChecker)
$service->loadAuthenticator('Authentication.Form', [
'loginUrl' => [
'controller' => 'Users',
'action' => 'login',
],
]);

// For framework-agnostic projects, explicitly use GenericUrlChecker
$service->loadAuthenticator('Authentication.Form', [
'urlChecker' => 'Authentication.Generic',
'loginUrl' => '/users/login',
]);

Simplified URL Checker API
---------------------------

URL checkers now accept a single URL in either string or array format.
For multiple URLs, you must explicitly use ``MultiUrlChecker``.

**Multiple URLs - Before (3.x):**

.. code-block:: php

// This would auto-select the appropriate checker
$service->loadAuthenticator('Authentication.Form', [
'loginUrl' => [
'/en/users/login',
'/de/users/login',
],
]);

**Multiple URLs - After (4.x):**

.. code-block:: php

// Must explicitly configure MultiUrlChecker
$service->loadAuthenticator('Authentication.Form', [
'urlChecker' => 'Authentication.Multi',
'loginUrl' => [
'/en/users/login',
'/de/users/login',
],
]);

Single URLs work the same in both versions:

.. code-block:: php

// String URL
$service->loadAuthenticator('Authentication.Form', [
'loginUrl' => '/users/login',
]);

// Array URL (CakePHP route)
$service->loadAuthenticator('Authentication.Form', [
'loginUrl' => ['controller' => 'Users', 'action' => 'login'],
]);

Auto-Detection Removed
----------------------

URL Checkers
^^^^^^^^^^^^

**Important:** Auto-detection has been removed. ``DefaultUrlChecker`` is now hardcoded
and assumes CakePHP is available.

- **4.x default:** Always uses ``DefaultUrlChecker`` (formerly ``CakeUrlChecker``)
- **Framework-agnostic:** Must explicitly configure ``GenericUrlChecker``
- **Multiple URLs:** Must explicitly configure ``MultiUrlChecker``

DefaultUrlChecker is Now CakePHP-Based
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``DefaultUrlChecker`` is now the CakePHP checker (formerly ``CakeRouterUrlChecker``).
It requires CakePHP Router and supports both string and array URLs.

The 3.x framework-agnostic ``DefaultUrlChecker`` has been renamed to ``GenericUrlChecker``.

.. code-block:: php

// DefaultUrlChecker now requires CakePHP Router
$checker = new DefaultUrlChecker();
$checker->check($request, ['controller' => 'Users', 'action' => 'login']); // Works
$checker->check($request, '/users/login'); // Also works

// For framework-agnostic usage:
$checker = new GenericUrlChecker();
$checker->check($request, '/users/login'); // Works
$checker->check($request, ['controller' => 'Users']); // Throws exception

New Features
============

IdentifierFactory
-----------------

New factory class for creating identifiers from configuration:

.. code-block:: php

use Authentication\Identifier\IdentifierFactory;

// Create from string
$identifier = IdentifierFactory::create('Authentication.Password');

// Create with config
$identifier = IdentifierFactory::create('Authentication.Password', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
]);

// Pass existing instance (returns as-is)
$identifier = IdentifierFactory::create($existingIdentifier);

MultiUrlChecker
---------------

New dedicated checker for multiple login URLs:

.. code-block:: php

$service->loadAuthenticator('Authentication.Form', [
'urlChecker' => 'Authentication.Multi',
'loginUrl' => [
'/en/login',
'/de/login',
['lang' => 'fr', 'controller' => 'Users', 'action' => 'login'],
],
]);

Migration Tips
==============

1. **Search and Replace**:

- ``AbstractIdentifier::CREDENTIAL_`` → ``PasswordIdentifier::CREDENTIAL_``
- ``IdentifierCollection`` → ``IdentifierFactory``
- ``'Authentication.CakeRouter'`` → Remove (no longer needed, default is now CakePHP-based)
- ``CakeRouterUrlChecker`` → ``DefaultUrlChecker``
- Old 3.x ``DefaultUrlChecker`` (framework-agnostic) → ``GenericUrlChecker``

2. **Framework-Agnostic Projects**:

If you're using this library without CakePHP, you **must** explicitly configure
``GenericUrlChecker``:

.. code-block:: php

$service->loadAuthenticator('Authentication.Form', [
'urlChecker' => 'Authentication.Generic',
'loginUrl' => '/users/login',
]);

3. **Multiple Login URLs**:

If you have multiple login URLs, add ``'urlChecker' => 'Authentication.Multi'``
to your authenticator configuration.

4. **Custom Identifier Setup**:

If you were passing ``IdentifierCollection`` to authenticators, switch to
either passing a single identifier or null (to use defaults).

5. **Test Thoroughly**:

The changes to identifier management and URL checking are significant.
Test all authentication flows after upgrading.
Loading