[WIP] Api

This is the implementation for the Rest API of Thelia.

# Authentication

The authentication is done using a token. This token is generated when the API access is created in the admin.
The token must be set in the authorization http header like this : 
```
Authorization: Token MYSUPERTOKEN
```
Example using the symfony Request object : 
```
$request = new Request();
$request->headers->set('Authorization', 'Token MYSUPERTOKEN');
```

Apache authorization header is only used by basic or digest methods. So you must have to force the HTTP_AUTHORIZATION header in your .htaccess file : 
```
 RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
```

The .htaccess file include in Thelia had been already modified.

# Request signature

All request content (even if the content is empty) must be signed using a secure key generated when an API access is created in the admin.

Signature process : 
- create the binary string of the secure key
- create the hash of the request content using ```sha1``` algo and the binary key

example : 
```
$content = "my content";
$key = pack("H*", "my_secret_key");
$sign = hash_hmac('sha1', $content, $key);
```
the signature must be set in the sign parameter send in the request query string. example : ```http://your_thelia.tld/api/customers?sign=request_content_signature```

We use a signature for preventing Man in the middle attack. BTW, use HTTPS connection; it's the most safe way to use your API.

# Controller

All API's controllers must extends ```Thelia\Controller\Api\BaseApiController```. 

# ACL

The already existing profile process is used, nothing change here.

In your controller you must use the ```checkAuth``` with the value you want to use. This method return nothing and thrown an ```AccessDeniedHttpException``` if an error occur.

Example : 
```
$this->checkAuth(AdminResources::CUSTOMER, [], AccessManager::VIEW);
```

# Test

The only way to really test the API is to simulated a request and check the response status, header and content if needed.

The HttpKernel Client class is used for doing that, allowing to create functional test in Thelia.

Each API method must be test extending the ```Thelia\Test\ApiTestCase``` class. This class contain some helpers : 

```getServerParameters()``` : force ```CONTENT_TYPE``` and ```HTTP_AUTHORIZATION``` server parameters
```getSignParameter($content)``` : create the signature for the given content.

Here an example for testing the customer list method : 
```
    /**
     * @covers \Thelia\Controller\Api\CustomerController::listAction
     */
    public function testListActionWithDefaultParameters()
    {
        $client = static::createClient();

        $client->request(
            'GET',
            '/api/customers?sign='.$this->getSignParameter(""),[],[],
            $this->getServerParameters()
        );

        $this->assertEquals(200, $client->getResponse()->getStatusCode(), 'Http status code must be 200');
        $content = json_decode($client->getResponse()->getContent(), true);
        $this->assertCount(10, $content);
    }
```

# PROGRESS

_List_ : get method returning a collection

| Action | List | Get | Post | Put | Delete |
|-------:|-----|-----|------|-----|--------|
|Product | ok |ok | ok | ok | ok |
|Product price | ok | ok  | ok  | ok  | ok  |
|Product image | ok | ok  | ok  |  | ok  |
|Category | ok | ok | ok | ok | ok |
|Customer | ok | ok | ok | ok | ok |
|Customer title | ok | ok | ok | ok | ok |
| Tax rules | ok | ok | | | |

# Notes

* The **PUT** method only update an item


We have to write documentation instead of reading code.