Skip to content

Commit 95a2c80

Browse files
authored
Merge pull request #2 from csoni111/nau-specs
Update specs for HDA user authentication
2 parents 97bc75f + 5482594 commit 95a2c80

3 files changed

Lines changed: 133 additions & 41 deletions

File tree

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ DEPENDENCIES
1818
github-markup
1919

2020
BUNDLED WITH
21-
1.16.0
21+
1.16.1

README.html

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
background-color: #f8fafc;
2525
}
2626
</style>
27-
<h1>Amahi Anywhere Client API Specification - v0.12</h1>
27+
<h1>Amahi Anywhere Client API Specification - v0.13</h1>
2828
<p>The Amahi Anywhere Clients use a REST HTTP protocol for browsing, downloading and streaming files and more.</p>
2929
<p>The clients can be in local mode (known as &quot;LAN&quot; or &quot;LAN Access&quot; to the user), or remote mode (known as &quot;Remote&quot;). Internally we just call them local or remote. The client can perform streaming and the rest of the functions much faster when using the local mode, being inside the user's LAN, so that should be the favored mode, when available. The client should test for local mode availability dynamically, but only when the user is interacting with the app, <em>never</em> in the background, as this will be costly in terms of battery.</p>
3030
<h2>API Endpoints</h2>
@@ -42,12 +42,13 @@ <h2>API Endpoints</h2>
4242
<p><img src="API-interaction.png" alt="API Interaction Diagram" /></p>
4343
<p>Example of a typical sequence of accesses:</p>
4444
<ol>
45-
<li>Authenticate the user against the Amahi API endpoint</li>
45+
<li>Authenticate the amahi user against the Amahi API endpoint</li>
4646
<li>GET /servers (this gives a session token to use for each server)</li>
47+
<li>POST /auth expects JSON type data with pin key in request body and returns auth token for that hda user</li>
4748
<li>GET /shares will return the visible shares on a given server (with the session for that server)</li>
4849
<li>GET /files?s=SomeShare&amp;p=/som/path/or/file.png to get a directory or a file from a server (with the proper session key)</li>
4950
</ol>
50-
<p>The user navigates their files by repeating calls like 4 above with different share names and paths.</p>
51+
<p>The user navigates through their files by repeating calls like 5 above with different share names and paths.</p>
5152
<h2>Authentication</h2>
5253
<hr />
5354
<p>The app must collect 1) a username/email and 2) a password, from the user and authenticate this information against Amahi's servers using the <a href="http://oauth.net/">OAuth 2 protocol</a> with the <em>Amahi API</em> endpoint.</p>
@@ -100,18 +101,18 @@ <h2>Initial request for Amahi servers</h2>
100101
<p>Example:</p>
101102
<pre lang="json"><code> [
102103
{
103-
&quot;name&quot; = &quot;server1&quot;,
104-
&quot;active&quot; = 1,
105-
&quot;session&quot; = &quot;6337fc16d9b31049e3137bb8fc74b86e6b4cb35c&quot;,
106-
&quot;ip_addr&quot; = &quot;1.2.3.4&quot;,
107-
&quot;fqdn&quot; = &quot;server1.yourhda.com&quot;
104+
&quot;name&quot;: &quot;server1&quot;,
105+
&quot;active&quot;: 1,
106+
&quot;session&quot;: &quot;6337fc16d9b31049e3137bb8fc74b86e6b4cb35c&quot;,
107+
&quot;ip_addr&quot;: &quot;1.2.3.4&quot;,
108+
&quot;fqdn&quot;: &quot;server1.yourhda.com&quot;
108109
},
109110
{
110-
&quot;name&quot; = &quot;server2&quot;,
111-
&quot;active&quot; = 0,
112-
&quot;session&quot; = &quot;&quot;,
113-
&quot;ip_addr&quot; = &quot;&quot;,
114-
&quot;fqdn&quot; = &quot;&quot;
111+
&quot;name&quot;: &quot;server2&quot;,
112+
&quot;active&quot;: 0,
113+
&quot;session&quot;: &quot;&quot;,
114+
&quot;ip_addr&quot;: &quot;&quot;,
115+
&quot;fqdn&quot;: &quot;&quot;
115116
}
116117
]
117118
</code></pre>
@@ -161,6 +162,44 @@ <h3>Initial Client Connection</h3>
161162
<p>From this point on, the calls below can be done to the local_addr or the relay_addr.</p>
162163
<p>If the client is in local mode, the API endpoint is the address given by <code>local_addr</code>. This should be the preferred mode if it's available.</p>
163164
<p>If the client is in remote mode, the API endpoint is the address given by <code>relay_addr</code>.</p>
165+
<h3>HDA User Authentication</h3>
166+
<p>Since different users can have different access permissions on HDA so each user must identify himself/herself to the HDA. In order to do that the app must request a PIN from the user. This PIN can be sent to the HDA either directly or via Proxy.</p>
167+
<p>To authenticate, the client app has to issue a <code>POST</code> to <code>/auth</code> with an <code>application/json</code> content-type body containing the following in it:</p>
168+
<ul>
169+
<li>
170+
<p><code>POST /auth</code></p>
171+
<pre lang="json"><code> {
172+
&quot;pin&quot;: &quot;1234&quot;
173+
}
174+
</code></pre>
175+
<ul>
176+
<li>The PIN must be 3 to 5 characters and must match <code>[A-Za-z0-9]+</code>.</li>
177+
</ul>
178+
</li>
179+
<li>
180+
<p>On successful authentication, a <code>200 OK</code> response will be sent by the server.</p>
181+
<pre lang="json"><code> {
182+
&quot;auth_token&quot;: &quot;51e3088a2da8f1c8b9285f0fae25b95c&quot;
183+
}
184+
</code></pre>
185+
<ul>
186+
<li>This auth_token must be sent in <code>Authorization</code> header for <code>/shares</code>, <code>/files</code> and <code>/logout</code> requests.</li>
187+
</ul>
188+
</li>
189+
<li>
190+
<p>On unsuccessful authentication, server will respond with <code>401 Unauthorized</code>.</p>
191+
</li>
192+
</ul>
193+
<h3>HDA User Logout</h3>
194+
<ul>
195+
<li><code>POST /logout</code></li>
196+
<li>Logs out the user whose auth_token has been provided and removes its session</li>
197+
<li>It will return a <code>200 OK</code> response on successful logout</li>
198+
</ul>
199+
<h4>Headers</h4>
200+
<ul>
201+
<li><strong>Authorization</strong> the <code>auth_token</code> must be sent here.</li>
202+
</ul>
164203
<h3>Shares</h3>
165204
<ul>
166205
<li>
@@ -176,14 +215,17 @@ <h3>Shares</h3>
176215
<p>The <code>tags</code> field is a json list of tags associated to a share. The user can put arbitrary information in these fields.</p>
177216
</li>
178217
<li>
218+
<p>The <code>writable</code> field denotes if that share is writable or not for the logged-in user. Client app must appropriately display/hide the Upload or Delete button as per the value of writable field for a given share.</p>
219+
</li>
220+
<li>
179221
<p>Example:</p>
180222
<pre lang="json"><code>[
181-
{ &quot;name&quot;: &quot;Books&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;books&quot; ] },
182-
{ &quot;name&quot;: &quot;Docs&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ ] },
183-
{ &quot;name&quot;: &quot;Movies&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;movies&quot; ] },
184-
{ &quot;name&quot;: &quot;Pictures&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;pictures&quot; ] },
185-
{ &quot;name&quot;: &quot;Torrents&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;movies&quot;, &quot;tv&quot; ] }
186-
{ &quot;name&quot;: &quot;TV&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;tv&quot; ] }
223+
{ &quot;name&quot;: &quot;Books&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;books&quot; ], &quot;writable&quot;: false },
224+
{ &quot;name&quot;: &quot;Docs&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ ], &quot;writable&quot;: true },
225+
{ &quot;name&quot;: &quot;Movies&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;movies&quot; ], &quot;writable&quot;: false },
226+
{ &quot;name&quot;: &quot;Pictures&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;pictures&quot; ], &quot;writable&quot;: false },
227+
{ &quot;name&quot;: &quot;Torrents&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;movies&quot;, &quot;tv&quot; ], &quot;writable&quot;: false }
228+
{ &quot;name&quot;: &quot;TV&quot;, &quot;mtime&quot;: &quot;Sat, 17 Aug 2013 02:38:32 GMT&quot;, &quot;tags&quot;: [ &quot;tv&quot; ], &quot;writable&quot;: true }
187229
]
188230
</code></pre>
189231
</li>
@@ -247,6 +289,10 @@ <h3>Reading Files</h3>
247289
<p>It returns a 200 code if it succeeded, else there is an error</p>
248290
</li>
249291
</ul>
292+
<h4>Headers</h4>
293+
<ul>
294+
<li><strong>Authorization</strong> the <code>auth_token</code> must be sent here.</li>
295+
</ul>
250296
<h4>Parameters</h4>
251297
<ul>
252298
<li><strong>s</strong> is the name of the share where the file is located</li>
@@ -258,6 +304,7 @@ <h4>Parameters</h4>
258304
</ul>
259305
<h4>Errors</h4>
260306
<ul>
307+
<li>If the <code>Authorization</code> header is not supplied or is wrong, a <code>403 Forbidden</code> is returned.</li>
261308
<li>If the share does not exist, a <code>400 Bad Request</code> is returned.</li>
262309
<li>If the path cannot be found, a <code>404 Not Found</code> HTTP error is returned.</li>
263310
<li>If the path is to a directory, a json representation of all the files and directories therein is returned.</li>
@@ -270,6 +317,10 @@ <h3>Deleting Files</h3>
270317
<li>Deletes the file or the directory in the given share <code>:sharename</code> in the <code>s</code> parameter, with the given path <code>:path</code> in the <code>p</code> parameter</li>
271318
<li>It returns a 200 code if it succeeded, else there is an error</li>
272319
</ul>
320+
<h4>Headers</h4>
321+
<ul>
322+
<li><strong>Authorization</strong> the <code>auth_token</code> must be sent here.</li>
323+
</ul>
273324
<h4>Parameters</h4>
274325
<p>Same parameter as in reading a file, a share and a path to the file.</p>
275326
<h4>Errors</h4>

README.md

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Amahi Anywhere Client API Specification - v0.12
1+
Amahi Anywhere Client API Specification - v0.13
22
===============================================
33

44
The Amahi Anywhere Clients use a REST HTTP protocol for browsing, downloading and streaming files and more.
@@ -20,12 +20,13 @@ Through this document we will have the following API endpoints. The interaction
2020

2121
Example of a typical sequence of accesses:
2222

23-
1) Authenticate the user against the Amahi API endpoint
23+
1) Authenticate the amahi user against the Amahi API endpoint
2424
2) GET /servers (this gives a session token to use for each server)
25-
3) GET /shares will return the visible shares on a given server (with the session for that server)
26-
4) GET /files?s=SomeShare&p=/som/path/or/file.png to get a directory or a file from a server (with the proper session key)
25+
3) POST /auth expects JSON type data with pin key in request body and returns auth token for that hda user
26+
4) GET /shares will return the visible shares on a given server (with the session for that server)
27+
5) GET /files?s=SomeShare&p=/som/path/or/file.png to get a directory or a file from a server (with the proper session key)
2728

28-
The user navigates their files by repeating calls like 4 above with different share names and paths.
29+
The user navigates through their files by repeating calls like 5 above with different share names and paths.
2930

3031
## Authentication
3132
-----------------
@@ -82,18 +83,18 @@ After authenticating in the user, the client should log the user in. Then it nee
8283
```json
8384
[
8485
{
85-
"name" = "server1",
86-
"active" = 1,
87-
"session" = "6337fc16d9b31049e3137bb8fc74b86e6b4cb35c",
88-
"ip_addr" = "1.2.3.4",
89-
"fqdn" = "server1.yourhda.com"
86+
"name": "server1",
87+
"active": 1,
88+
"session": "6337fc16d9b31049e3137bb8fc74b86e6b4cb35c",
89+
"ip_addr": "1.2.3.4",
90+
"fqdn": "server1.yourhda.com"
9091
},
9192
{
92-
"name" = "server2",
93-
"active" = 0,
94-
"session" = "",
95-
"ip_addr" = "",
96-
"fqdn" = ""
93+
"name": "server2",
94+
"active": 0,
95+
"session": "",
96+
"ip_addr": "",
97+
"fqdn": ""
9798
}
9899
]
99100
```
@@ -147,22 +148,55 @@ If the client is in local mode, the API endpoint is the address given by `local_
147148

148149
If the client is in remote mode, the API endpoint is the address given by `relay_addr`.
149150

151+
### HDA User Authentication
152+
153+
Since different users can have different access permissions on HDA so each user must identify himself/herself to the HDA. In order to do that the app must request a PIN from the user. This PIN can be sent to the HDA either directly or via Proxy.
154+
155+
To authenticate, the client app has to issue a `POST` to `/auth` with an `application/json` content-type body containing the following in it:
156+
157+
* `POST /auth`
158+
```json
159+
{
160+
"pin": "1234"
161+
}
162+
```
163+
* The PIN must be 3 to 5 characters and must match `[A-Za-z0-9]+`.
164+
165+
* On successful authentication, a `200 OK` response will be sent by the server.
166+
```json
167+
{
168+
"auth_token": "51e3088a2da8f1c8b9285f0fae25b95c"
169+
}
170+
```
171+
* This auth_token must be sent in `Authorization` header for `/shares`, `/files` and `/logout` requests.
172+
* On unsuccessful authentication, server will respond with `401 Unauthorized`.
173+
174+
### HDA User Logout
175+
176+
* `POST /logout`
177+
* Logs out the user whose auth_token has been provided and removes its session
178+
* It will return a `200 OK` response on successful logout
179+
180+
#### Headers
181+
* **Authorization** the `auth_token` must be sent here.
182+
150183
### Shares
151184

152185
* `GET /shares`
153186
* Lists all the shares on the HDA that are available to the logged-in user
154187
* The return type is a json array with a list of shares, sorted alphabetically (without capitalization), with their name as a string in the `name` element, their modification time in the `mtime` element and `tags`.
155188
* The `tags` field is a json list of tags associated to a share. The user can put arbitrary information in these fields.
189+
* The `writable` field denotes if that share is writable or not for the logged-in user. Client app must appropriately display/hide the Upload or Delete button as per the value of writable field for a given share.
156190
* Example:
157191

158192
```json
159193
[
160-
{ "name": "Books", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "books" ] },
161-
{ "name": "Docs", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ ] },
162-
{ "name": "Movies", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "movies" ] },
163-
{ "name": "Pictures", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "pictures" ] },
164-
{ "name": "Torrents", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "movies", "tv" ] }
165-
{ "name": "TV", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "tv" ] }
194+
{ "name": "Books", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "books" ], "writable": false },
195+
{ "name": "Docs", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ ], "writable": true },
196+
{ "name": "Movies", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "movies" ], "writable": false },
197+
{ "name": "Pictures", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "pictures" ], "writable": false },
198+
{ "name": "Torrents", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "movies", "tv" ], "writable": false }
199+
{ "name": "TV", "mtime": "Sat, 17 Aug 2013 02:38:32 GMT", "tags": [ "tv" ], "writable": true }
166200
]
167201
```
168202

@@ -199,6 +233,9 @@ If the client is in remote mode, the API endpoint is the address given by `relay
199233
* Deletes the file or the directory in the given share `:sharename` in the `s` parameter, with the given path `:path` in the `p` parameter
200234
* It returns a 200 code if it succeeded, else there is an error
201235

236+
#### Headers
237+
* **Authorization** the `auth_token` must be sent here.
238+
202239
#### Parameters
203240
* **s** is the name of the share where the file is located
204241
* It must be URL-encoded and the share must exist
@@ -208,6 +245,7 @@ If the client is in remote mode, the API endpoint is the address given by `relay
208245
* If no path is given, the file system root directory is returned.
209246

210247
#### Errors
248+
* If the `Authorization` header is not supplied or is wrong, a `403 Forbidden` is returned.
211249
* If the share does not exist, a `400 Bad Request` is returned.
212250
* If the path cannot be found, a `404 Not Found` HTTP error is returned.
213251
* If the path is to a directory, a json representation of all the files and directories therein is returned.
@@ -220,6 +258,9 @@ If the client is in remote mode, the API endpoint is the address given by `relay
220258
* Deletes the file or the directory in the given share `:sharename` in the `s` parameter, with the given path `:path` in the `p` parameter
221259
* It returns a 200 code if it succeeded, else there is an error
222260

261+
#### Headers
262+
* **Authorization** the `auth_token` must be sent here.
263+
223264
#### Parameters
224265
Same parameter as in reading a file, a share and a path to the file.
225266

0 commit comments

Comments
 (0)