|
1 | 1 | # `accessmap-api`: AccessMap's user/profiles/auth API |
| 2 | + |
| 3 | +## Why? |
| 4 | + |
| 5 | +AccessMap users want to securely store and access settings, routing profiles, and |
| 6 | +other information across browsers and devices. |
| 7 | + |
| 8 | +## How? |
| 9 | + |
| 10 | +`accessmap-api` is a fairly boilerplate Flask application (a popular Python web |
| 11 | +framework) with roughly RESTful interfaces: it uses HTTP verbs appropriately for GET, |
| 12 | +POST, PUT, etc. `accessmap-api` is only compatible with Python 3.6+. |
| 13 | + |
| 14 | +## Installation |
| 15 | + |
| 16 | +`accessmap-api` is developed using `poetry`, which makes development, releases, and |
| 17 | +installation more simple and reproducible. The best way to install `accessmap-api` |
| 18 | +into a development environment is to use the poetry tool |
| 19 | + |
| 20 | + poetry install |
| 21 | + |
| 22 | +A guide for installing `poetry` itself can be found here: |
| 23 | +https://poetry.eustace.io/docs/ |
| 24 | + |
| 25 | +This command will create an isolated virtual environment for all of `accessmap-api`'s |
| 26 | +dependencies. You can now run any commands in this environment by prepending |
| 27 | +`poetry run` to the command. We'll set up a testing database to show how it works, but |
| 28 | +first we need to set up our configuration. |
| 29 | + |
| 30 | +## Configuration |
| 31 | + |
| 32 | +Configuration of `accessmap-api` is done with environment variables. Flask supports the |
| 33 | +use of a .env file that contains `ENV_VAR=value` lines or using the default environment |
| 34 | +variables available on the system. Note that system environment variables will |
| 35 | +supercede entries in the .env file. |
| 36 | + |
| 37 | +*Please note that all of the following environment variables that are marked "required" |
| 38 | +are necessary for `accessmap-api` to function correctly and securetly.* |
| 39 | + |
| 40 | +- `SECRET_KEY` (required): This is a secret used to sign / secure sessions during a |
| 41 | +request context. It is very imporatnt to keep this value secure, particularly if your |
| 42 | +application is exposed to the internet. It is a best practice to generate the value of |
| 43 | +most secrets using a secure hashing algorithm with a good source of entropy - something |
| 44 | +like `ssh-keygen`. |
| 45 | + |
| 46 | +- `JWT_SECRET_KEY` (required): This is a secret used to sign JWTs issued by |
| 47 | +`accessmap-api` and is the most important secret to get correct, as JWTs will be |
| 48 | +publicly sent to clients (over HTTPS). It must be kept private and generated using best |
| 49 | +practices (like `ssh-keygen`). |
| 50 | + |
| 51 | +- `SQLALCHEMY_DATABASE_URI`: An SQLAlchemy-compatible database URI. This defauls to |
| 52 | +an SQLite3 database stored at `/tmp/accessmap-api.db` (for development), but can be |
| 53 | +any valid SQLAlchemy URI for postgres, mysql, etc. |
| 54 | + |
| 55 | +- `OAUTH_CACHE_DIR`: A path used to cache OAuth data - i.e. user-authorized |
| 56 | +token information. This makes auth workflows more efficient. This defaults to |
| 57 | +`/tmp/accessmap-api-cache`. |
| 58 | + |
| 59 | +- `OSM_CLIENT_ID` (required): AccessMap currently uses OpenStreetMap for |
| 60 | +authentication. This is the OAuth 1.0a client ID of your registered application. |
| 61 | + |
| 62 | +- `OSM_CLIENT_SECRET` (required): AccessMap currently uses OpenStreetMap for |
| 63 | +authentication. This is the OAuth 1.0a client secret of your registered application. |
| 64 | + |
| 65 | +- `OSM_URI`: The base API path to use when talking to OpenStreetMap for authentication. |
| 66 | +It is important to use the testing/development server(s) when trying out new features |
| 67 | +that might impact the data on OpenStreetMap or expose a client's credentials, so this |
| 68 | +is set to the primary OpenStreetMap testing URI by default. For production applications |
| 69 | +using HTTPS and secure secrets, use `https://api.openstreetmap.org`. Keep in mind that |
| 70 | +you will need to separately register OAuth 1.0a applications for the testing |
| 71 | +OpenStreetMap API vs. the main one, so they will have different `OSM_CLIENT_ID` and |
| 72 | +`OSM_CLIENT_SECRET` credentials. |
| 73 | + |
| 74 | +- `CONSUMER_CALLBACK_URI` (required): as a security precaution, this API will currently |
| 75 | +only send OAuth callback redirects to a URI (URL) defined by this environment variable. |
| 76 | +The callback URI defined by this variable will be appended with `access_token` and |
| 77 | +`refresh_token` URL parameters defining a JWT access token and a JWT refresh token for |
| 78 | +use with protected `accessmap-api` endpoints. `CONSUMER_CALLBACK_URI` should therefore |
| 79 | +be a client URI such as an instance of `accessmap-webapp`, e.g. |
| 80 | +`http://localhost:3000/callback` in development mode. |
| 81 | + |
| 82 | +## Creating and migrating the database |
| 83 | + |
| 84 | +`accessmap-api` uses `Flask-Migrate`, which uses the `alembic` library to manage |
| 85 | +database migrations. To initialize a database, run: |
| 86 | + |
| 87 | + poetry run flask db upgrade |
| 88 | + |
| 89 | +If you make changes to the database and need to create a new migration, run: |
| 90 | + |
| 91 | + poetry run flask db migrate |
| 92 | + |
| 93 | +## Running `accessmap-api` |
| 94 | + |
| 95 | +By default, `accessmap-api` runs a `werkzeug` development server. For a production |
| 96 | +system, you should use a WSGI framework. `accessmap-api` comes with a script to assist |
| 97 | +deployments using a WSGI runner: `wsgi.py`. It is important to note that it is |
| 98 | +currently hard-coded to assume that you are running `accessmap-api` at the `/api` |
| 99 | +subdirectory of your production host, for example `https://example.com/api`. |
0 commit comments