* $options = new ezcAuthenticationGroupOptions();
* $options->mode = ezcAuthenticationGroupFilter::MODE_AND;
*
* // $filter1 and $filter2 are authentication filters which all need to succeed
* // in order for the group to succeed
* $filter = new ezcAuthenticationGroupFilter( array( $filter1, $filter2 ), $options );
*
*
* Example of using the group filter with LDAP and Database filters:
*
* $credentials = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 'qwerty' );
*
* // create a database filter
* $database = new ezcAuthenticationDatabaseInfo( ezcDbInstance::get(), 'users', array( 'user', 'password' ) );
* $databaseFilter = new ezcAuthenticationDatabaseFilter( $database );
*
* // create an LDAP filter
* $ldap = new ezcAuthenticationLdapInfo( 'localhost', 'uid=%id%', 'dc=example,dc=com', 389 );
* $ldapFilter = new ezcAuthenticationLdapFilter( $ldap );
* $authentication = new ezcAuthentication( $credentials );
*
* // use the database and LDAP filters in paralel (at least one needs to succeed in
* // order for the user to be authenticated)
* $authentication->addFilter( new ezcAuthenticationGroupFilter( array( $databaseFilter, $ldapFilter ) ) );
* // add more filters if needed
* if ( !$authentication->run() )
* {
* // authentication did not succeed, so inform the user
* $status = $authentication->getStatus();
* $err = array(
* array( 'ezcAuthenticationLdapFilter' => array(
* ezcAuthenticationLdapFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
* ezcAuthenticationLdapFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
* ) ),
* array( 'ezcAuthenticationDatabaseFilter' => array(
* ezcAuthenticationDatabaseFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
* ezcAuthenticationDatabaseFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
* ) )
* );
* foreach ( $status as $line => $error )
* {
* list( $key, $value ) = each( $error );
* echo $err[$line][$key][$value] . "\n";
* }
* }
* else
* {
* // authentication succeeded, so allow the user to see his content
* }
*
*
* It is possible to use multiple credentials when grouping filters together, by
* enabling the option multipleCredentials for the Group filter object. When this
* option is enabled, each filter added to the group must have a credentials
* object passed along with it.
*
* Example of using the Group filter to handle multiple credentials:
*
* $credentials1 = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 'b1b3773a05c0ed0176787a4f1574ff0075f7521e' ); // incorrect password
* $credentials2 = new ezcAuthenticationPasswordCredentials( 'john.doe', 'wpeE20wyWHnLE' ); // correct username + password
*
* $options = new ezcAuthenticationGroupOptions();
* $options->multipleCredentials = true;
* $options->mode = ezcAuthenticationGroupFilter::MODE_AND;
* $group = new ezcAuthenticationGroupFilter( array(), $options );
*
* $group->addFilter( new ezcAuthenticationHtpasswdFilter( '../../tests/filters/htpasswd/data/htpasswd' ), $credentials1 );
* $group->addFilter( new ezcAuthenticationHtpasswdFilter( '../../tests/filters/htpasswd/data/htpasswd' ), $credentials2 );
*
* $authentication = new ezcAuthentication( $credentials1 );
* $authentication->addFilter( $group );
* // add more filters if needed
*
* if ( !$authentication->run() )
* {
* // authentication did not succeed, so inform the user
* $status = $authentication->getStatus();
*
* $err = array(
* array( 'ezcAuthenticationHtpasswdFilter' => array(
* ezcAuthenticationHtpasswdFilter::STATUS_OK => '',
* ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username ' . $credentials1->id,
* ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password for ' . $credentials1->id
* ) ),
*
* array( 'ezcAuthenticationHtpasswdFilter' => array(
* ezcAuthenticationHtpasswdFilter::STATUS_OK => '',
* ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username ' . $credentials2->id,
* ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password for ' . $credentials2->id
* ) )
* );
*
* foreach ( $status as $line => $error )
* {
* list( $key, $value ) = each( $error );
* echo $err[$line][$key][$value] . "\n";
* }
* }
* else
* {
* // authentication succeeded, so allow the user to see his content
* }
*
*
* @property ezcAuthenticationStatus $status
* The status object which holds the status of the run filters.
*
* @package Authentication
* @version 1.2
* @mainclass
*/
class ezcAuthenticationGroupFilter extends ezcAuthenticationFilter
{
/**
* All or some of the filters in the group failed (depeding on the mode
* option).
*/
const STATUS_GROUP_FAILED = 1;
/**
* At least one filter needs to succeed in order for the group to succeed.
*/
const MODE_OR = 1;
/**
* All the filters need to succeed in order for the group to succeed.
*/
const MODE_AND = 2;
/**
* Authentication filters.
*
* @var array(ezcAuthenticationFilter)
*/
protected $filters = array();
/**
* The properties of this class.
*
* @var array(string=>mixed)
*/
private $properties = array();
/**
* Creates a new object of this class.
*
* The filters can be specified as an array of filter objects, or as an
* array of array(fiter,credentials) when the multipleCredentials option is
* enabled.
*
* Example of using multipleCredentials:
*
* $credentials1 = new ezcAuthenticationPasswordCredentials( 'john.doe', '1234' );
* $credentials1 = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 'qwerty' );
*
* $filter1 = new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd1' );
* $filter2 = new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd2' );
*
* // enable multiple credentials
* $options = new ezcAuthenticationGroupOptions();
* $options->multipleCredentials = true;
*
* // add the filters to the group with the constructor
* $group = new ezcAuthenticationGroupFilter( array(
* array( $filter1, $credentials1 ),
* array( $filter2, $credentials2 ) ), $options );
*
* // the filters can also be added to the group with addFilter()
*
*
* @throws ezcAuthenticationException
* if the multipleCredentials option is enabled and a credentials
* object was not specified
* @param array(ezcAuthenticationFilter|mixed) $filters Authentication filters
* @param ezcAuthenticationGroupOptions $options Options for this class
*/
public function __construct( array $filters, ezcAuthenticationGroupOptions $options = null )
{
$this->options = ( $options === null ) ? new ezcAuthenticationGroupOptions() : $options;
foreach ( $filters as $filter )
{
if ( is_array( $filter ) )
{
if ( count( $filter ) > 1 )
{
$this->addFilter( $filter[0], $filter[1] );
}
else
{
$this->addFilter( $filter[0] );
}
}
else
{
$this->addFilter( $filter );
}
}
$this->status = new ezcAuthenticationStatus();
}
/**
* Sets the property $name to $value.
*
* @throws ezcBasePropertyNotFoundException
* if the property $name does not exist
* @throws ezcBaseValueException
* if $value is not correct for the property $name
* @param string $name The name of the property to set
* @param mixed $value The new value of the property
* @ignore
*/
public function __set( $name, $value )
{
switch ( $name )
{
case 'status':
if ( $value instanceof ezcAuthenticationStatus )
{
$this->properties[$name] = $value;
}
else
{
throw new ezcBaseValueException( $name, $value, 'ezcAuthenticationStatus' );
}
break;
default:
throw new ezcBasePropertyNotFoundException( $name );
}
}
/**
* Returns the value of the property $name.
*
* @throws ezcBasePropertyNotFoundException
* if the property $name does not exist
* @param string $name The name of the property for which to return the value
* @return mixed
* @ignore
*/
public function __get( $name )
{
switch ( $name )
{
case 'status':
return $this->properties[$name];
default:
throw new ezcBasePropertyNotFoundException( $name );
}
}
/**
* Returns true if the property $name is set, otherwise false.
*
* @param string $name The name of the property to test if it is set
* @return bool
* @ignore
*/
public function __isset( $name )
{
switch ( $name )
{
case 'status':
return isset( $this->properties[$name] );
default:
return false;
}
}
/**
* Runs the filter and returns a status code when finished.
*
* @param ezcAuthenticationCredentials $credentials Authentication credentials
* @return int
*/
public function run( $credentials )
{
if ( count( $this->filters ) === 0 )
{
return self::STATUS_OK;
}
$success = false;
if ( $this->options->mode === self::MODE_OR )
{
$success = false;
foreach ( $this->filters as $filter )
{
$credentials = ( $this->options->multipleCredentials === true ) ? $filter[1] :
$credentials;
$code = $filter[0]->run( $credentials );
$this->status->append( get_class( $filter[0] ), $code );
if ( $code === self::STATUS_OK )
{
$success = true;
}
}
}
if ( $this->options->mode === self::MODE_AND )
{
$success = true;
foreach ( $this->filters as $filter )
{
$credentials = ( $this->options->multipleCredentials === true ) ? $filter[1] :
$credentials;
$code = $filter[0]->run( $credentials );
$this->status->append( get_class( $filter[0] ), $code );
if ( $code !== self::STATUS_OK )
{
$success = false;
}
}
}
// other modes are not possible due to the way mode is set in __set()
// in the options class
return ( $success === true ) ? self::STATUS_OK :
self::STATUS_GROUP_FAILED;
}
/**
* Adds an authentication filter at the end of the filter list.
*
*
* Example of using multipleCredentials:
*
* $credentials1 = new ezcAuthenticationPasswordCredentials( 'john.doe', '1234' );
* $credentials1 = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 'qwerty' );
*
* $filter1 = new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd1' );
* $filter2 = new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd2' );
*
* // enable multiple credentials
* $options = new ezcAuthenticationGroupOptions();
* $options->multipleCredentials = true;
*
* // add the filters to the group with addFilter()
* $group = new ezcAuthenticationGroupFilter( array(), $options );
* $group->addFilter( $filter1, $credentials1 );
* $group->addFilter( $filter2, $credentials2 );
*
* // the filters can also be added to the group with the constructor
*
*
* @throws ezcAuthenticationException
* if the multipleCredentials option is enabled and a credentials
* object was not specified
* @param ezcAuthenticationFilter $filter The authentication filter to add
* @param ezcAuthenticationCredentials $credentials Credentials object associated
* with $filter if the multipleCredentials
* option is enabled
*/
public function addFilter( ezcAuthenticationFilter $filter, ezcAuthenticationCredentials $credentials = null )
{
if ( $this->options->multipleCredentials === true )
{
if ( $credentials === null )
{
throw new ezcAuthenticationException( 'A credentials object must be specified for each filter when the multipleCredentials option is enabled.' );
}
$this->filters[] = array( $filter, $credentials );
}
else
{
$this->filters[] = array( $filter );
}
}
}
?>