Ticket Details

A unified response object for Auth and Access

RFC Ticket (pending)

## Data filters are only handled in Form adapter

Due to filters being handled in then Form adapter its possible duplication will arise,
like if someone implements their own handler.

Moving `Form::_filters()` to `Auth` and letting the adapters supply default filters when setting up
configurations would give two upsides:

 * Possible to deliver multiple Auth strategies yet maintain DRY
 * Exposing more generic data to the filters, adressing the next concer

## Filters dont have enough information

Using the Form adapter only `Request::$data` is accessible for the filters.
In order to restrict a single active session for a user currently it requires
filtering `::check()` simply to access the http environment variables that are needed.
If it was possible to hand filters the Request object the filters could handle this.

Consider the following:

{{{
Auth::config(array(
    'fields' => array('username', 'password', 'active.ip'),
    'filters' => array(
        function($data, $params) {
            if ($notTimedOut)
                $data['active.ip'] = $params['request']->env('REMOTE_ADDR');
            else
                unset($data['active.ip']);
            return $data;
        }
    )
));
}}}

The current design with `Auth::check($name, $credentials, $options)` should be changed to `($name, $params, $options)`. `$params` should be `compact('credentials', 'request')` by default — this will break the current API.

Another argument for this change is that it makes it easier to do auth based on cookies or other methods where the username + password itself is not sent, but rather a unique hash to a session.
Consider something like

{{{
class MyController {
    public function funkyAuth() {
        $hash = $this->request->query['funkyHash'];
        $params = array(
            'request' => $this->request,
            'credentials' => User::first(array('conditions' => array('funkyhash' => $hash)))
        );
        if (Auth::check('default', $params)) {
        }
    }
}
}}}

You could argue that all of this is possible to deal with in a new adapter, and yes somehow it is but its limited and these are quite generic issues imo.

`Auth::check()` does not in any way allow you to be consistent in what gets relayed to the adapter.
That means the `$options` array have to be used to pass the `Request` object as well as the credentials — not good, `Request` is not an option.

# Response object
A second change is the introduction of a `Response` object as the return value from `Auth::check()`.

In its simplest form something like this could do:

{{{
class Response extends \lithium\core\Object {
    protected $_autoConfig = array('errors', 'data' => 'merge');
    protected $_data = array();
    protected $_errors = array();

    public function errors($value=null) {
        if (is_array($value))
            $this->_errors = $value;
        elseif ($value)
            return $this->_errors[$value];

        return (count($this->_errors) > 0) ? $this->_errors : false;
    }

    public function data() {
        return $this->_data;
    }
}
}}}

Either a validation like way of settings messages like in Model could be used, or simply have `errors()` return the fields that failed.

- Authored by Raymond Julin, aka Nervetattoo
on 01.25.11 reported by: nate owned by: nate

Updates