Newer
Older
This section of documentation refers to the Oauth protocols working hand in hand with our custom proxy and the cozy-stack.
To fully understand its whereabouts, you should also look at the [enedis konnector](/docs/konnectors/enedis.md) and [grdf konnector](/docs/konnectors/grdf.md) documentation.
 [proxy](https://forge.grandlyon.com/pocs/cozy/cozy-oauth-proxy)
## Oauth Dance
To access customer data, one must first obtain customer authorization. This authorization is materialized by an access token and it must be obtained by the APIs exposed by each energy providers.
These APIs implement Oauth 2.0 protocol, it requires authentication from the customer along with its given consent.
See both **[Enedis](./use_cases/enedis.mdx)** and **[Grdf](./use_cases/grdfadict.md)** use cases before going further.
:::info cozy oauth flow documentation
https://docs.cozy.io/en/cozy-stack/konnectors-workflow/#reminder-oauth-flow
:::
The CouchDB database must hold all information needed for the konnector authentication to work properly.
Auth information are stored in the **secrets/io-cozy-account_types** database.
You can create manually the document by entering these parameters for each konnector:
<table>
<thead>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>_id</td>
<td>Name of your konnector, for instance: enedisgrandlyon</td>
</tr>
<tr>
<td>grant_mode</td>
<td>authorization_code</td>
</tr>
<tr>
<td>client_id</td>
<td>Application id given by the API provider</td>
</tr>
<tr>
<td>client_secret</td>
<td>Secret also given by the API provider</td>
</tr>
<tr>
<td>auth_endpoint</td>
<td>Authorize endpoint to request when starting the oauth protocol</td>
</tr>
<tr>
<td>token_endpoint</td>
<td>
Token endpoint to request, will be called when the auth endpoint
response reaches the stack
</td>
</tr>
<tr>
<td>token_mode</td>
<td>get</td>
</tr>
</tbody>
</table>
Once the document is created, when launching the konnector from the cozy-home or inside the running application. The oauth flow will start.
The cozy-stack will request the authorize endpoint, then call the token endpoint with the code received from the auth step.
If the token request is a success. An account/service-name database will be added in CouchDB containing all information needed for authentication and the konnector will be free to work on all endpoints within its scope.
### Why we Need a Proxy
The Oauth dance could be easily wrapped up with the two requests seen above. But since all cozy applications are hosted on different personal clouds, following this guideline would mean that we need a **client_id** and a **client_secret** for each one of all the applications running.
To answer this issue, two solutions are possible depending on what the energy supplier is willing to do.
- Providers could allow wildcard subdomains when registering the callback URI, it would parse the subdomain and adapt its redirection when answering **/auth** call.
https//\*.cozygrandlyon.cloud/account/redirect -> parse subdomain before .cozy
xyz.cozygrandlyon.cloud/account/redirect -> redirect to xyz
toto.cozygrandlyon.cloud/account/redirect -> redirect to toto
:::
- If the provider (Enedis for instance) is not accepting wildcards, then we put a proxy as a middleware to provide a generic endpoint to cater for all Oauth2 redirection.
#### Result
With that in mind, the proxy is now the one calling the auth and token provider endpoints. The instance name will be contained in redirect_uri, the stack will insert this parameters by itself in the /auth call.
3 endpoints are created in the proxy for **each energy supplier**:
- One for the auth
- One for the token
- One for the redirect uri
#### Proxy flow
```plantuml
Stack -> Proxy: calls
Proxy -> Provider: calls
Proxy <-- Provider: responds with oauth code on proxy/redirect
Stack <-- Proxy: redirect to user instance
Stack -> Proxy: calls
Proxy -> Provider: calls for token or refresh
Proxy <-- Provider: responds
Stack <-- Proxy: token
```
## Proxy Code Explained
:::info reminder
Feel free to check the proxy [code](https://forge.grandlyon.com/pocs/cozy/cozy-oauth-proxy) at all time when reading this documentation.
:::
The proxy is coded in golang.
It is composed of six endpoints as seen above. The first endpoint to be called is **/auth**.
Originally called from a cozy-stack trying to setup its konnector. The proxy gets these information from the query:
- client_id
- duration
- redirect_uri (auto inserted by the cozy-stack, except if you specify **skip_redirect_uri:true** in the CouchDB)
- response_type
- state (as it was conceived by the cozy-stack)

The state will be merged with the instance name, then decomposed again when reaching /redirect. This way the proxy is able to keep track of the cozy instance originally calling.
With all these information, the proxy can contact the provider **/auth** endpoint to start the oauth dance.
:::warning
See that a new composed state is sent to enedis, it is made of the former state conceived by the cozy-stack + the original instance name. This will be useful when enedis is leading the oauth dance to the next step and we will need the name of the cozy to answer.
:::
Once the call is sent, enedis will point to the **/redirect** endpoint.
Retrieve the _code_, _usage_point_id_, and _state_ answered by Enedis.
Split the customed state that was modified in the **/auth** process. From this split it creates two variables :
- state
- host
Finally redirect all these parameters in a query to the cozy-stack (the cozy-stack which is still waiting for an answer from its /auth call).
:::warning state / instance
The state must be recovered without the instance name, otherwise the cozy-stack won't recognized it and the handshake will fail.
:::
Gathering from query or parameters all params.
The stack will store the response params in a _accounts_ CouchDB database.