diff --git a/.env.swp b/.env.swp
new file mode 100644
index 00000000..e737a79b
Binary files /dev/null and b/.env.swp differ
diff --git a/app/controllers/api/v2/tokens_controller.rb b/app/controllers/api/v2/tokens_controller.rb
index 1170945f..e0474e25 100644
--- a/app/controllers/api/v2/tokens_controller.rb
+++ b/app/controllers/api/v2/tokens_controller.rb
@@ -18,12 +18,6 @@ module Api
create_action
respond_with_resource
end
-
- def my_tokens
- authorize resource_class
- instantiate_collection
- respond_with_collection
- end
end
end
end
diff --git a/bin/build-apidocs.sh b/bin/build-apidocs.sh
index be85012c..28931b2f 100755
--- a/bin/build-apidocs.sh
+++ b/bin/build-apidocs.sh
@@ -2,8 +2,16 @@
# Note: you need to run `npm install` before using this script or raml2html won't be installed
+OLD_DIR=$(pwd)
+cd $(dirname $0)/..
+
if [[ ! -x ./node_modules/.bin/raml2html ]]; then
npm install
fi
-./node_modules/.bin/raml2html -i ./doc/api/api.raml -o ./public/api/index.html
+./node_modules/.bin/raml2html -i ./doc/api/api.raml -o ./public/api/index.html -t doc/api/templates/template.nunjucks
+if [[ -x $(which open) ]]; then
+ open public/api/index.html
+fi
+
+cd $OLD_DIR
diff --git a/config/routes.rb b/config/routes.rb
index b5078d86..79db8599 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -70,9 +70,7 @@ Metamaps::Application.routes.draw do
delete :stars, to: 'stars#destroy', on: :member
end
resources :synapses, only: [:index, :create, :show, :update, :destroy]
- resources :tokens, only: [:create, :destroy] do
- get :my_tokens, on: :collection
- end
+ resources :tokens, only: [:index, :create, :destroy]
resources :topics, only: [:index, :create, :show, :update, :destroy]
resources :users, only: [:index, :show] do
get :current, on: :collection
diff --git a/doc/api/api.raml b/doc/api/api.raml
index 4473a6dd..8703aae9 100644
--- a/doc/api/api.raml
+++ b/doc/api/api.raml
@@ -8,12 +8,12 @@ protocols: [ HTTPS ]
documentation:
- title: Getting Started
content: !include pages/getting-started.md
- - title: Endpoints
- content: ""
securitySchemes:
+ cookie: !include securitySchemes/cookie.raml
+ token: !include securitySchemes/token.raml
oauth_2_0: !include securitySchemes/oauth_2_0.raml
-securedBy: [ oauth_2_0 ]
+securedBy: [ cookie, token, oauth_2_0 ]
traits:
pageable: !include traits/pageable.raml
diff --git a/doc/api/apis/metacodes.raml b/doc/api/apis/metacodes.raml
index 37cbd17a..877e1835 100644
--- a/doc/api/apis/metacodes.raml
+++ b/doc/api/apis/metacodes.raml
@@ -1,4 +1,5 @@
#type: collection
+securedBy: [ null, cookie, token, oauth_2_0 ]
get:
is: [ searchable: { searchFields: "name" }, orderable, pageable ]
responses:
@@ -7,6 +8,7 @@ get:
application/json:
example: !include ../examples/metacodes.json
/{id}:
+ securedBy: [ null, cookie, token, oauth_2_0 ]
#type: item
get:
responses:
diff --git a/doc/api/apis/tokens.raml b/doc/api/apis/tokens.raml
index ef7a8379..5d4eb191 100644
--- a/doc/api/apis/tokens.raml
+++ b/doc/api/apis/tokens.raml
@@ -1,4 +1,13 @@
#type: collection
+get:
+ description: |
+ A list of the current user's tokens.
+ is: [ searchable: { searchFields: description }, pageable, orderable ]
+ responses:
+ 200:
+ body:
+ application/json:
+ example: !include ../examples/tokens.json
post:
body:
application/json:
@@ -11,14 +20,6 @@ post:
body:
application/json:
example: !include ../examples/token.json
-/my_tokens:
- get:
- is: [ searchable: { searchFields: description }, pageable, orderable ]
- responses:
- 200:
- body:
- application/json:
- example: !include ../examples/tokens.json
/{id}:
#type: item
delete:
diff --git a/doc/api/apis/users.raml b/doc/api/apis/users.raml
index 7f421059..1d37bc0d 100644
--- a/doc/api/apis/users.raml
+++ b/doc/api/apis/users.raml
@@ -1,4 +1,5 @@
#type: collection
+securedBy: [ null, cookie, token, oauth_2_0 ]
get:
is: [ searchable: { searchFields: "name" }, orderable, pageable ]
responses:
@@ -6,6 +7,15 @@ get:
body:
application/json:
example: !include ../examples/users.json
+/{id}:
+ #type: item
+ securedBy: [ null, cookie, token, oauth_2_0 ]
+ get:
+ responses:
+ 200:
+ body:
+ application/json:
+ example: !include ../examples/user.json
/current:
#type: item
get:
@@ -14,11 +24,3 @@ get:
body:
application/json:
example: !include ../examples/current_user.json
-/{id}:
- #type: item
- get:
- responses:
- 200:
- body:
- application/json:
- example: !include ../examples/user.json
diff --git a/doc/api/pages/cookie_tutorial.md b/doc/api/pages/cookie_tutorial.md
new file mode 100644
index 00000000..9481b919
--- /dev/null
+++ b/doc/api/pages/cookie_tutorial.md
@@ -0,0 +1,3 @@
+One way to access the API is through your browser. Log into metamaps.cc normally, then browse manually to https://metamaps.cc/api/v2/user/current. You should see a JSON description of your own user object in the database. You can browse any GET endpoint by simply going to that URL and appending query parameters in the URI.
+
+To run a POST or DELETE request, you can use the Fetch API. See the example in the next section.
diff --git a/doc/api/pages/getting-started.md b/doc/api/pages/getting-started.md
index c620e888..429e6971 100644
--- a/doc/api/pages/getting-started.md
+++ b/doc/api/pages/getting-started.md
@@ -1,86 +1,2 @@
-[Skip ahead to the endpoints.](#endpoints)
+There are three ways to log in: cookie-based authentication, token-based authentication, or OAuth 2. If you're testing the API or making simple scripts, cookie-based or token-based is the best. If you're developing and app and want users to be able to log into Metamaps inside your app, you'll be able to use the OAuth 2 mechanism. Check the security tab of any of the endpoints above for instructions on logging in.
-There are three ways to log in: cookie-based authentication, token-based authentication, or OAuth 2. If you're testing the API or making simple scripts, cookie-based or token-based is the best. If you're developing and app and want users to be able to log into Metamaps inside your app, you'll be able to use the OAuth 2 mechanism.
-
-### 1. Cookie-based authentication
-
-One way to access the API is through your browser. Log into metamaps.cc normally, then browse manually to https://metamaps.cc/api/v2/user/current. You should see a JSON description of your own user object in the database. You can browse any GET endpoint by simply going to that URL and appending query parameters in the URI.
-
-To run a POST or DELETE request, you can use the Fetch API. See the example in the next section.
-
-### 2. Token-based authentication
-
-If you are logged into the API via another means, you can create a token. Once you have this token, you can append it to a request. For example, opening a private window in your browser and browsing to `https://metamaps.cc/api/v2/user/current?token=...token here...` would show you your current user, even without logging in by another means.
-
-To get a list of your current tokens, you can log in using cookie-based authentication and run the following fetch request in your browser console (assuming the current tab is on some page within the `metamaps.cc` website.
-
-```javascript
-fetch('/api/v2/tokens', {
- method: 'GET',
- credentials: 'same-origin' // needed to use the cookie-based auth
-}).then(response => {
- return response.json()
-}).then(console.log).catch(console.error)
-```
-
-If this is your first time accessing the API, this list wil be empty. You can create a token using a similar method:
-
-```javascript
-fetch('/api/v2/tokens', {
- method: 'POST',
- credentials: 'same-origin'
-}).then(response => {
- return response.json()
-}).then(payload => {
- console.log(payload)
-}).catch(console.error)
-```
-
-`payload.data.token` will contain a string which you can use to append to requests to access the API from anywhere.
-
-### 3. OAuth 2 Authentication
-
-We use a flow for Oauth 2 authentication called Authorization Code. It basically consists of an exchange of an `authorization` token for an `access token`. For more detailed info, check out the [RFC spec here](http://tools.ietf.org/html/rfc6749#section-4.1)
-
-The first step is to register your client app.
-
-#### Registering the client
-
-Set up a new client in `/oauth/applications/new`. For testing purposes, you should fill in the redirect URI field with `urn:ietf:wg:oauth:2.0:oob`. This will tell it to display the authorization code instead of redirecting to a client application (that you don't have now).
-
-#### Requesting authorization
-
-To request the authorization token, you should visit the `/oauth/authorize` endpoint. You can do that either by clicking in the link to the authorization page in the app details or by visiting manually the URL:
-
-```
-http://metamaps.cc/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code
-```
-
-Once you are there, you should sign in and click on `Authorize`.
-You will then see a response that contains your "authorization code", which you need to exchange for an access token.
-
-#### Requesting the access token
-
-To request the access token, you should use the returned code and exchange it for an access token. To do that you can use any HTTP client. Here's an example with `fetch`
-
-```javascript
-fetch('https://metamaps.cc/oauth/token?client_id=THE_ID&client_secret=THE_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=urn:ietf:wg:oauth:2.0:oob', {
- method: 'POST',
- credentials: 'same-origin'
-}).then(response => {
- return response.json()
-}).then(console.log).catch(console.error)
-```
-
-The response will look like
-
-```json
-{
- "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54",
- "token_type": "bearer",
- "expires_in": 7200,
- "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1"
-}
-```
-
-You can now make requests to the API with the access token returned.
diff --git a/doc/api/pages/oauth_2_0_tutorial.md b/doc/api/pages/oauth_2_0_tutorial.md
new file mode 100644
index 00000000..e419a621
--- /dev/null
+++ b/doc/api/pages/oauth_2_0_tutorial.md
@@ -0,0 +1,41 @@
+We use a flow for Oauth 2 authentication called Authorization Code. It basically consists of an exchange of an `authorization` token for an `access token`. For more detailed info, check out the [RFC spec here](http://tools.ietf.org/html/rfc6749#section-4.1)
+
+The first step is to register your client app.
+
+#### Registering the client
+
+Set up a new client in `/oauth/applications/new`. For testing purposes, you should fill in the redirect URI field with `urn:ietf:wg:oauth:2.0:oob`. This will tell it to display the authorization code instead of redirecting to a client application (that you don't have now).
+
+#### Requesting authorization
+
+To request the authorization token, you should visit the `/oauth/authorize` endpoint. You can do that either by clicking in the link to the authorization page in the app details or by visiting manually the URL:
+
+```
+http://metamaps.cc/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code
+```
+
+Once you are there, you should sign in and click on `Authorize`.
+You will then see a response that contains your "authorization code", which you need to exchange for an access token.
+
+#### Requesting the access token
+
+To request the access token, you should use the returned code and exchange it for an access token. To do that you can use any HTTP client. Here's an example with `fetch`
+
+```javascript
+fetch('https://metamaps.cc/oauth/token?client_id=THE_ID&client_secret=THE_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=urn:ietf:wg:oauth:2.0:oob', {
+ method: 'POST',
+ credentials: 'same-origin'
+}).then(response => {
+ return response.json()
+}).then(console.log).catch(console.error)
+
+# The response will be like
+{
+ "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54",
+ "token_type": "bearer",
+ "expires_in": 7200,
+ "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1"
+}
+```
+
+You can now make requests to the API with the access token returned.
diff --git a/doc/api/pages/token_tutorial.md b/doc/api/pages/token_tutorial.md
new file mode 100644
index 00000000..3a46582a
--- /dev/null
+++ b/doc/api/pages/token_tutorial.md
@@ -0,0 +1,25 @@
+If you are logged into the API via another means, you can create a token. Once you have this token, you can append it to a request. For example, opening a private window in your browser and browsing to `https://metamaps.cc/api/v2/user/current?token=...token here...` would show you your current user, even without logging in by another means.
+
+To get a list of your current tokens, you can log in using cookie-based authentication and run the following fetch request in your browser console (assuming the current tab is on some page within the `metamaps.cc` website.
+
+```
+fetch('/api/v2/tokens', {
+ method: 'GET',
+ credentials: 'same-origin' // needed to use the cookie-based auth
+}).then(response => {
+ return response.json()
+}).then(console.log).catch(console.error)
+```
+
+If this is your first time accessing the API, this list wil be empty. You can create a token using a similar method:
+
+```
+fetch('/api/v2/tokens', {
+ method: 'POST',
+ credentials: 'same-origin'
+}).then(response => {
+ return response.json()
+}).then(console.log).catch(console.error)
+```
+
+`payload.data.token` will contain a string which you can use to append to requests to access the API from anywhere.
diff --git a/doc/api/securitySchemes/cookie.raml b/doc/api/securitySchemes/cookie.raml
new file mode 100644
index 00000000..fb1041b1
--- /dev/null
+++ b/doc/api/securitySchemes/cookie.raml
@@ -0,0 +1,3 @@
+description: !include ../pages/cookie_tutorial.md
+type: x-cookie
+displayName: Secured by cookie-based authentication
diff --git a/doc/api/securitySchemes/oauth_2_0.raml b/doc/api/securitySchemes/oauth_2_0.raml
index b271e03a..3a84e293 100644
--- a/doc/api/securitySchemes/oauth_2_0.raml
+++ b/doc/api/securitySchemes/oauth_2_0.raml
@@ -1,5 +1,4 @@
-description: |
- OAuth 2.0 implementation
+description: !include ../pages/oauth_2_0_tutorial.md
type: OAuth 2.0
settings:
authorizationUri: https://metamaps.cc/api/v2/oauth/authorize
diff --git a/doc/api/securitySchemes/token.raml b/doc/api/securitySchemes/token.raml
new file mode 100644
index 00000000..f83e1177
--- /dev/null
+++ b/doc/api/securitySchemes/token.raml
@@ -0,0 +1,3 @@
+description: !include ../pages/token_tutorial.md
+type: x-token
+displayName: Secured by token-based authentication
diff --git a/doc/api/templates/item.nunjucks b/doc/api/templates/item.nunjucks
new file mode 100644
index 00000000..044c24d9
--- /dev/null
+++ b/doc/api/templates/item.nunjucks
@@ -0,0 +1,61 @@
+