<commit_before>pauldevelop/library-auth
========================

Commonly used classes to authenticate and authorize users and resources.

Manual
------

This library enables your application to  check whether a user has a specific role and if this user is allowed to access
certain parts of your application. For now it assumes, that your user objects are accessible via an integer id, and role
objects via a string containing the role's name.

### Usage

First create a new [Authorisator](src/class/Authorisator.php) object; the constructor takes an object implementing the 
[IRoleChecker](src/class/IRoleChecker.php) interface and a collection of variables.

```php
$variables = new VariableCollection();
$variables->add(new Variable('baseHost', 'example.com'));

$authorisator = new Authorisator(
    new MyRoleChecker(), // implements IRoleChecker
    $variables
);
```

The *IRoleChecker* interface defines a *check* method, which takes a user id and role name as parameters; an 
implementation must check whether the user with the id *$id* has the role with the name *$roleName*. You don't call the
*IRoleChecker*'s directly; it will be called from within the *Authorisator*'s check method.

A sample IRoleChecker implementation could look like this:

```php
class RoleChecker implements IRoleChecker
{
    /**
     * @var model\ImpersonationPeer
     */
    private $impersonationPeer;

    /**
     * @var model\RolePeer
     */
    private $rolePeer;

    public function __construct(model\ImpersonationPeer $impersonationPeer = null, model\RolePeer $rolePeer = null)
    {
        $this->impersonationPeer = $impersonationPeer;
        $this->rolePeer = $rolePeer;
    }

    public function check($id = 0, $roleName = '')
    {
        // init
        $result = false;

        // action
        $roles = $this->rolePeer->queryPath('role[@name='.$roleName.']#');
        if (count($roles) == 1) {
            /** @var model\Role $role */
            $role = $roles[0];
            $impersonations = $this->impersonationPeer->queryPath(
                'impersonation[@user='.$id.',@role='.$role->Id.']#'
            );
            if (count($impersonations) == 1) {
                $result = true;
            }
        }

        // return
        return $result;
    }
}
```

In this example, the constructor takes two peer objects, which access data from a data source like a database. The
roles are read by the *RolePeer*, while the information which user impersonates which role is read via the 
*ImpersonationPeer*. First, we query a role with $roleName; if we found a role, we also check, if the user $id 
impersonates the role $roleName. If yes, we return true, otherwise false.

The variables collection noted while instancing the *Authorisator* object contains variables, which can be used in the
patterns as described in the list below.

The next step is to add an access restriction, which is done by calling the *addAccessRestriction* method on the
*Authorisator* object. This method takes a [AccessRestriction](src/class/AccessRestriction.php) object as parameter, 
which has the following properties:
 
- pattern
  
    A pattern describing the resource's url. In this example we defined the variable *baseHost*, which we can use by
    surrounding the name with % signs (%baseUrl%). If you add a wildcard (*) at the end, all urls starting with the 
    given path are protected as well.

- authenticator
  
    An authenticator, which authenticates a user.

- roleName
  
    The name of the role a user must have.

- callbackUrl
  
    A url which is called, if the user is not allowed to access the resource.

- callback
  
    A function which is called when the callbackUrl is empty and if the user is not allowed to access the resource.

- exceptionPaths
  
    An array of resource url patterns, which must not be checked and therefore useful for example for the urls of login
    forms. You may use the *%baseHost%* variable.

To add a new access restriction to only allow users of the role 'Administrator' to access backend resources, call the
*addAccessRestriction* method as follows:

```php
$authorisator->addAccessRestriction(
    new AccessRestriction(
        'backend.%baseHost%/*',
        new DemoAuthenticator(),
        'Administrator',
        'http://backend.%baseHost%/login/',
        null,
        array(
            'backend.%baseHost%/login/',
            'backend.%baseHost%/login/process/'
        )
    )
);
```

Now it's time to actually check if a resource is accessible to an user. Do this with the check method of the 
*Authorisator* object:

```php
// setup credentials
$credentials = new Entity();
$credentials->Properties = new IPropertyCollection();
$result->Properties->add(new Property('name', $name), 'name');
$result->Properties->add(new Property('password', $password), 'password');

if ($authorisator->check($url, $credentials)) {
  // load protected content
}
```<commit_msg>* added short manual to readme<commit_after>pauldevelop/library-auth
========================

Commonly used classes to authenticate and authorize users and resources.

Manual
------

This library enables your application to  check whether a user has a specific role and if this user is allowed to access
certain parts of your application. For now it assumes, that your user objects are accessible via an integer id, and role
objects via a string containing the role's name.

### Usage

First create a new [Authorisator](src/class/Authorisator.php) object; the constructor takes an object implementing the 
[IRoleChecker](src/class/IRoleChecker.php) interface and a collection of variables.

```php
$variables = new VariableCollection();
$variables->add(new Variable('baseHost', 'example.com'));

$authorisator = new Authorisator(
    new MyRoleChecker(), // implements IRoleChecker
    $variables
);
```

The *IRoleChecker* interface defines a *check* method, which takes a user id and role name as parameters; an 
implementation must check whether the user with the id *$id* has the role with the name *$roleName*. You don't call the
*IRoleChecker*'s directly; it will be called from within the *Authorisator*'s check method.

A sample IRoleChecker implementation could look like this:

```php
class MyRoleChecker implements IRoleChecker
{
    /**
     * @var model\ImpersonationPeer
     */
    private $impersonationPeer;

    /**
     * @var model\RolePeer
     */
    private $rolePeer;

    public function __construct(model\ImpersonationPeer $impersonationPeer = null, model\RolePeer $rolePeer = null)
    {
        $this->impersonationPeer = $impersonationPeer;
        $this->rolePeer = $rolePeer;
    }

    public function check($id = 0, $roleName = '')
    {
        // init
        $result = false;

        // action
        $roles = $this->rolePeer->queryPath('role[@name='.$roleName.']#');
        if (count($roles) == 1) {
            /** @var model\Role $role */
            $role = $roles[0];
            $impersonations = $this->impersonationPeer->queryPath(
                'impersonation[@user='.$id.',@role='.$role->Id.']#'
            );
            if (count($impersonations) == 1) {
                $result = true;
            }
        }

        // return
        return $result;
    }
}
```

In this example, the constructor takes two peer objects, which access data from a data source like a database. The
roles are read by the *RolePeer*, while the information which user impersonates which role is read via the 
*ImpersonationPeer*. First, we query a role with $roleName; if we found a role, we also check, if the user $id 
impersonates the role $roleName. If yes, we return true, otherwise false.

The variables collection noted while instancing the *Authorisator* object contains variables, which can be used in the
patterns as described in the list below.

The next step is to add an access restriction, which is done by calling the *addAccessRestriction* method on the
*Authorisator* object. This method takes a [AccessRestriction](src/class/AccessRestriction.php) object as parameter, 
which has the following properties:
 
- pattern
  
    A pattern describing the resource's url. In this example we defined the variable *baseHost*, which we can use by
    surrounding the name with % signs (%baseUrl%). If you add a wildcard (*) at the end, all urls starting with the 
    given path are protected as well.

- authenticator
  
    An authenticator, which authenticates a user.

- roleName
  
    The name of the role a user must have.

- callbackUrl
  
    A url which is called, if the user is not allowed to access the resource.

- callback
  
    A function which is called when the callbackUrl is empty and if the user is not allowed to access the resource.

- exceptionPaths
  
    An array of resource url patterns, which must not be checked and therefore useful for example for the urls of login
    forms. You may use the *%baseHost%* variable.

To add a new access restriction to only allow users of the role 'Administrator' to access backend resources, call the
*addAccessRestriction* method as follows:

```php
$authorisator->addAccessRestriction(
    new AccessRestriction(
        'backend.%baseHost%/*',
        new CredentialAuthenticator(),
        'Administrator',
        'http://backend.%baseHost%/login/',
        null,
        array(
            'backend.%baseHost%/login/',
            'backend.%baseHost%/login/process/'
        )
    )
);
```

An example implementation of the *IAuthenticator* interface could look like this:

```php
class CredentialAuthenticator implements IAuthenticator
{
    /**
     * @var IPathQueryable
     */
    private $storage;

    public function __construct(IPathQueryable $storage = null)
    {
        $this->storage = $storage;
    }

    /**
     * @param Entity $credentialEntity
     *
     * @return bool
     */
    public function check(Entity $credentialEntity)
    {
        // init
        $result = false;

        // action
        if (($nameProperty = $credentialEntity->Properties['name']) !== null) {
            /** @var IPathQueryable $storage */
            $storage = $this->storage;
            $userList = $storage->queryPath('user[@name='.$nameProperty->Value.']#');
            if ( sizeof($userList) > 0 ) {
                /** @var Entity $userEntity */
                $userEntity = $userList[0];
                if ($userEntity != null
                    && password_verify(
                        $credentialEntity->Properties['password']->Value,
                        $storageEntity->Properties['password']->Value
                    )
                ) {
                    $result = $storageEntity->Properties['id']->Value;
                }
            }
        }

        // return
        return $result;
    }
}
```

In this example, the check method gets credentials in form of name and password. If the name property is set, we query
a storage, if a user with this name is known. We then verify the password and return the users id. You can easily adopt
this class to check the user ip or session id.

Now it's time to actually check if a resource is accessible to an user. Do this with the check method of the 
*Authorisator* object:

```php
// setup credentials
$credentials = new Entity();
$credentials->Properties = new IPropertyCollection();
$result->Properties->add(new Property('name', $name), 'name');
$result->Properties->add(new Property('password', $password), 'password');

if ($authorisator->check($url, $credentials)) {
  // load protected content
}
```
{'fraction_non_alphanumeric': 0.1009865005192108, 'fraction_numerical': 0.0008653513326410523, 'mean_word_length': 2.9851724137931033, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2779651', 'n_tokens_mistral': 3152, 'n_tokens_neox': 3062, 'n_words': 1237}