API documentation and spec setup
This commit is contained in:
parent
99ecb75c83
commit
900cc91197
7 changed files with 226 additions and 0 deletions
92
doc/API.md
Normal file
92
doc/API.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Foodsoft API
|
||||
|
||||
Foodsoft provides a JSON REST API that gives access to operations like
|
||||
like listing open orders, updating the ordergroup's order, and listing financial
|
||||
transactions. Not all Foodsoft functionality is available through the API, but
|
||||
we're open for new additions.
|
||||
|
||||
The API is documented using [Open API 2.0](https://github.com/OAI/OpenAPI-Specification)
|
||||
/ [Swagger](https://swagger.io/) in [swagger.v1.yml](swagger.v1.yml).
|
||||
This provides a machine-readable reference that is used to provide documentation.
|
||||
|
||||
## API endpoint documentation
|
||||
|
||||
>> [View API documentation](http://petstore.swagger.io/?url=https%3A%2F%2Fraw.githubusercontent.com%2Ffoodcoops%2Ffoodsoft%2Fmaster%2Fdoc%2Fswagger.v1.yml) <<
|
||||
|
||||
The above documentation can communicate with the API directly on a local development
|
||||
installation of Foodsoft at [http://localhost:3000/f](http://localhost:3000/f).
|
||||
|
||||
You'll need to give access to the application first. This can be done by going to
|
||||
_Administration_ > _Configuration_ > _Apps_ in Foodsoft. Select _New Application_,
|
||||
enter any name, put `http://petstore.swagger.io/oauth2-redirect.html` in _Redirect URI_
|
||||
and disable _Confidential_. After submission, you will have an _Application UID_ that
|
||||
you can enter that as `client_id` after clicking _Authorize_ in the Swagger UI.
|
||||
|
||||
|
||||
## Security
|
||||
|
||||
Uses the [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) gem,
|
||||
which provides an OAuth2 provider.
|
||||
|
||||
|
||||
### Authorization code flow
|
||||
|
||||
This is the recommended flow for server-side web applications, where
|
||||
members login with Foodsoft, then redirected to the app, which then obtains
|
||||
an access token using the authorization code supplied at redirection.
|
||||
|
||||
Before you can obtain an access token, the client needs to obtain an id and secret.
|
||||
(You can currently skip this for the password credentials flow.) This needs to be
|
||||
done for each Foodsoft scope by an admin.
|
||||
|
||||
1. Click on the _Apps_ button at the right in Foodsoft's configuration screen.
|
||||
2. Click on _New application_
|
||||
3. Enter any _Name_ and put the website of your app in _Redirect URI_ and _Submit_.
|
||||
4. Click on the new applications' name for the app id and secret.
|
||||
5. To quickly test, logging into the app, press _Authorize_.
|
||||
|
||||
Note that the user doesn't need to confirm that he is giving the app access to his
|
||||
Foodsoft account by default, since apps can only be created by admins. If you
|
||||
want to change that, see disable `skip_authorization` in `config/initializers/doorkeeper.rb`.
|
||||
|
||||
[Read more](https://github.com/doorkeeper-gem/doorkeeper/wiki/Authorization-Code-Flow).
|
||||
|
||||
|
||||
### Implicit flow
|
||||
|
||||
This is the recommended flow for client-side web applications. It looks a lot
|
||||
like the authorization code flow, but when redirecting back to the app, the
|
||||
access token is available directly as part of the url _fragment_ (`window.location.hash`).
|
||||
|
||||
This flow also needs to be registered in Foodsoft as in the authorization code flow,
|
||||
but with _Confidential_ disabled. You only need the `client_id`, not the secret.
|
||||
|
||||
**note** please make sure you understand sections
|
||||
[4.4.2](http://tools.ietf.org/html/rfc6819#section-4.4.2) and
|
||||
[4.4.3](http://tools.ietf.org/html/rfc6819#section-4.4.3) of the OAuth2 Threat
|
||||
Model document before using this flow.
|
||||
|
||||
You may find Doorkeeper's [implicit_grant_test](https://github.com/doorkeeper-gem/doorkeeper/blob/master/spec/requests/flows/implicit_grant_spec.rb) useful.
|
||||
|
||||
|
||||
### Password credentials flow
|
||||
|
||||
To obtain a token using a username/password directly, you can do this:
|
||||
|
||||
```ruby
|
||||
require 'oauth2'
|
||||
c = OAuth2::Client.new('client_id', 'secret', site: 'http://localhost:3002/f/', authorize_url: 'oauth/authorize', token_url: 'oauth/token')
|
||||
c.password.get_token('admin', 'secret').token
|
||||
# => "1234567890abcdef1234567890abcdef1234567890abcdef123456790abcdef1"
|
||||
```
|
||||
|
||||
Now use this token as value for the `access_token` when accessing the API, like
|
||||
http://localhost:3002/f/api/v1/financial_transactions/1?access_token=12345...
|
||||
|
||||
[Read more](https://github.com/doorkeeper-gem/doorkeeper/wiki/Client-Credentials-flow).
|
||||
|
||||
|
||||
## Logout
|
||||
|
||||
When the user logs out of Foodsoft, all access tokens are destroyed, except when
|
||||
the token's scope includes `offline_access` (so offline applications are possible).
|
||||
67
doc/swagger.v1.yml
Normal file
67
doc/swagger.v1.yml
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
swagger: '2.0'
|
||||
info:
|
||||
title: Foodsoft API v1
|
||||
version: '1.0.0'
|
||||
description: >
|
||||
[Foodsoft](https://github.com/foodcoops/foodsoft) is web-based software to manage
|
||||
a non-profit food coop (product catalog, ordering, accounting, job scheduling).
|
||||
|
||||
|
||||
This is a description of Foodsoft's API v1.
|
||||
|
||||
|
||||
Note that each food cooperative typically has their own instance (on a shared
|
||||
server or their own installation), and there are just as many APIs (if the Foodsoft
|
||||
version is recent enough).
|
||||
This API description points to the default development url with the default
|
||||
Foodsoft scope - that would be [http://localhost:3000/f](http://localhost:3000/f).
|
||||
externalDocs:
|
||||
description: General Foodsoft API documentation
|
||||
url: https://github.com/foodcoops/foodsoft/blob/master/doc/API.md
|
||||
|
||||
# development url with default scope
|
||||
host: localhost:3000
|
||||
schemes:
|
||||
- 'http'
|
||||
basePath: /f/api/v1
|
||||
|
||||
produces:
|
||||
- 'application/json'
|
||||
|
||||
paths:
|
||||
|
||||
definitions:
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: error code
|
||||
error_description:
|
||||
type: string
|
||||
description: human-readable error message (localized)
|
||||
Error404:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: '<tt>not_found</tt>'
|
||||
error_description:
|
||||
$ref: '#/definitions/Error/properties/error_description'
|
||||
Error401:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: '<tt>unauthorized</tt>'
|
||||
error_description:
|
||||
$ref: '#/definitions/Error/properties/error_description'
|
||||
|
||||
securityDefinitions:
|
||||
foodsoft_auth:
|
||||
type: oauth2
|
||||
flow: implicit
|
||||
authorizationUrl: http://localhost:3000/f/oauth/authorize
|
||||
scopes:
|
||||
all: full access to user functions
|
||||
offline_access: retain access after user has logged out
|
||||
Loading…
Add table
Add a link
Reference in a new issue