Skip to content

Commit

Permalink
feat: implement global jwt token authentication for login (#1574)
Browse files Browse the repository at this point in the history
* feat: implemented jwt token authentication for login

* fix: added audience while decoding

* feat: added pyjwt , updated user id to existing svcfmtm osmid

* feat: change username to svcfmtm

* feat: implemented refresh token and updated dependency lock file

* fix: return user data from refresh endpoint

* changed img_url -> picture, retrieve id from sub field

* feat: exception handling if osm deserialization fails

* build: relock deps after pyjwt added

* refactor: remove auth key path variables, require passing string values

* docs: update install docs with info for gen priv/pub keys

* docs: update all docs for AUTH_PUBLIC_KEY vars

* build: add AUTH_PUBLIC_KEY vars to gen-env.sh script

* refactor: exclude rsa keys from debug printed settings

* fix(backend): improve logic for /me endpoint upsert & return ProjectRoles OrgManagers

* fix(backend): return int type for AuthUser.id

* refactor: create auth_schemas and replace all imports

* refactor: pass user_id only to task_crud functions

* test: update auth user creation for fixtures

* test: guarantee randomness with uuid4 over randint

* fix(backend): create_project existing project check must be scalar

* fix(backend): conform to nominatim usage policy referer header

* test: rename var for clarity

---------

Co-authored-by: spwoodcock <sam.woodcock@protonmail.com>
  • Loading branch information
Sujanadh and spwoodcock committed Jul 3, 2024
1 parent 79db9fb commit e97a04f
Show file tree
Hide file tree
Showing 28 changed files with 560 additions and 351 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ ENCRYPTION_KEY=${ENCRYPTION_KEY:-"pIxxYIXe4oAVHI36lTveyc97FKK2O_l2VHeiuqU-K_4="}
FMTM_DOMAIN=${FMTM_DOMAIN:-"fmtm.localhost"}
FMTM_DEV_PORT=${FMTM_DEV_PORT:-7050}
CERT_EMAIL=${CERT_EMAIL}
AUTH_PUBLIC_KEY=${AUTH_PUBLIC_KEY}
AUTH_PRIVATE_KEY=${AUTH_PRIVATE_KEY}
# Use API_PREFIX if running behind a proxy subpath (e.g. /api)
API_PREFIX=${API_PREFIX:-/}

Expand All @@ -21,7 +23,6 @@ OSM_URL=${OSM_URL:-"https://www.openstreetmap.org"}
OSM_SCOPE=${OSM_SCOPE:-"read_prefs"}
OSM_LOGIN_REDIRECT_URI="http${FMTM_DOMAIN:+s}://${FMTM_DOMAIN:-127.0.0.1:7051}/osmauth/"
OSM_SECRET_KEY=${OSM_SECRET_KEY}
OSM_SVC_ACCOUNT_TOKEN=${OSM_SVC_ACCOUNT_TOKEN}

### S3 File Storage ###
S3_ENDPOINT=${S3_ENDPOINT:-"http://s3:9000"}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,6 @@ envsubst

# Chart dependencies
chart/charts

# Secrets / keys
**/**/*.pem
4 changes: 4 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ bash scripts/gen-env.sh
> Note: If extra cors origins are required for testing, the variable
> `EXTRA_CORS_ORIGINS` is a set of comma separated strings, e.g.:
> <http://fmtm.localhost:7050,http://some.other.domain>
>
> Note: It is possible to generate the auth pub/priv key manually using:
> openssl genrsa -out fmtm-private.pem 4096
> openssl rsa -in fmtm-private.pem -pubout -out fmtm-private.pem
### Start the API with Docker

Expand Down
6 changes: 5 additions & 1 deletion chart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,18 @@ kubectl
- key: OSM_CLIENT_ID
- key: OSM_CLIENT_SECRET
- key: OSM_SECRET_KEY
- key: AUTH_PUBLIC_KEY
- key: AUTH_PRIVATE_KEY

```bash
kubectl create secret generic api-fmtm-vars --namespace fmtm \
--from-literal=ENCRYPTION_KEY=xxxxxxx \
--from-literal=FMTM_DOMAIN=some.domain.com \
--from-literal=OSM_CLIENT_ID=xxxxxxx \
--from-literal=OSM_CLIENT_SECRET=xxxxxxx \
--from-literal=OSM_SECRET_KEY=xxxxxxx
--from-literal=OSM_SECRET_KEY=xxxxxxx \
--from-file=AUTH_PUBLIC_KEY=/path/to/pub/key.pem \
--from-file=AUTH_PRIVATE_KEY=/path/to/priv/key.pem
```

## Deployment
Expand Down
89 changes: 0 additions & 89 deletions docs/dev/Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
- [FMTM frontend](#fmtm-frontend)
- [FMTM backend](#fmtm-backend)
- [Prerequisites for Contribution](#prerequisites-for-contribution)
- [Development: Setup Your Local Environment](#setup-your-local-environment)
- [Verify Setup](#verify-setup)
- [Start Developing](#start-developing)

## Overview
Expand Down Expand Up @@ -312,93 +310,6 @@ your changes and request that they be merged into the main codebase.
That's it! You've now contributed to the Field Mapping Tasking Manager.

### Setup Your Local Environment

These steps are essential to run and test your code!

#### 1. Setup OSM OAUTH 2.0

The FMTM uses OAUTH2 with OSM to authenticate users. To properly configure your
FMTM project, you will need to create keys for OSM.

1. [Login to OSM](https://www.openstreetmap.org/login) (_If you do not have an
account yet, click the signup button at the top navigation bar to create one_).
Click the drop down arrow on the extreme right of the navigation bar and
select My Settings.

2. Register your FMTM instance to OAuth 2 applications. Put your login redirect
url as `http://127.0.0.1:7051/osmauth/`, For Production replace the URL as
production API Url

> Note: `127.0.0.1` is required instead of `localhost` due to OSM restrictions.
<img width="716" alt="image" src="https://user-images.githubusercontent.com/36752999/216319298-1444a62f-ba6b-4439-bb4f-2075fdf03291.png">

3. Right now read user preferences permission is enough later on fmtm may need
permission to modify the map option which should be updated on OSM_SCOPE
variable on .env , Keep read_prefs for now.

4. Now Copy your Client ID and Client Secret. Put them in the `OSM_CLIENT_ID`
and `OSM_CLIENT_SECRET` field of your `.env` file

##### 2. Create an `.env` File

Environmental variables are used throughout this project.
To get started, create `.env` file in the top level dir,
a sample is located at `.env.example`.

This can be created interactively by running:

```bash
bash scripts/gen-env.sh
```

> Note: If extra cors origins are required for testing, the variable
> `EXTRA_CORS_ORIGINS` is a set of comma separated strings, e.g.:
> <http://fmtm.localhost:7050,http://some.other.domain>
### Verify Setup

#### Check Deployment

For details on how to run this project locally for development, please look at:
[Backend Docs](https://docs.fmtm.dev/dev/Backend)

#### Check Authentication

Once you have deployed, you will need to check that you can properly
authenticate.

1. Navigate to `http://api.fmtm.localhost:7050/docs`

Three endpoints are responsible for oauth
<img width="698" alt="image" src="../images/endpoints_responsible_for_auth_screenshot-2023-03-26-092756.png">

2. Select the `/auth/osm-login/` endpoint, click `Try it out` and then
`Execute`.
This would give you the Login URL where you can supply your osm username
and password.

Your response should look like this:

```json
{
"login_url": "https://www.openstreetmap.org/oauth2/authorize/?response_type=code&client_id=xxxx"
}
```

Now copy and paste your login_url in a new tab. You would be redirected to
OSM for your LOGIN. Give FMTM the necessary permission.

After a successful login, you will get your `access_token` for FMTM, Copy
it. Now, you can use it for rest of the endpoints that needs authorization.

3. Check your access token: Select the `/auth/me/` endpoint and click
`Try it out`.
Pass in the `access_token` you copied in the previous step into the
`access-token` field and click `Execute`. You should get your osm id,
username and profile picture id.

### Start Developing

Don't forget to review the
Expand Down
5 changes: 5 additions & 0 deletions docs/dev/Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ OSM_SCOPE
field required (type=value_error.missing)
OSM_LOGIN_REDIRECT_URI
field required (type=value_error.missing)
AUTH_PUBLIC_KEY
field required (type=value_error.missing)
AUTH_PRIVATE_KEY
field required (type=value_error.missing)
```

Then you need to set the env variables on your system.
Expand All @@ -45,5 +49,6 @@ an alternative can be to feed them into the pdm command:
FMTM_DOMAIN="" \
OSM_CLIENT_ID="" OSM_CLIENT_SECRET="" OSM_SECRET_KEY="" \
S3_ACCESS_KEY="" S3_SECRET_KEY="" \
AUTH_PUBLIC_KEY="" AUTH_PRIVATE_KEY="" \
pdm run uvicorn app.main:api --host 0.0.0.0 --port 8000
```
23 changes: 23 additions & 0 deletions scripts/gen-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,28 @@ check_change_port() {
fi
}

generate_auth_keys() {
pretty_echo "Generating Auth Keys"

if ! AUTH_PRIVATE_KEY=$(openssl genrsa 4096 2>/dev/null); then
echo "Error generating private key. Aborting."
return 1
fi

if ! AUTH_PUBLIC_KEY=$(echo "$AUTH_PRIVATE_KEY" | openssl rsa -pubout 2>/dev/null); then
echo "Error generating public key. Aborting."
return 1
fi

# Quotes are required around key variables, else dotenv does not load
export AUTH_PRIVATE_KEY="\"$AUTH_PRIVATE_KEY\""
export AUTH_PUBLIC_KEY="\"$AUTH_PUBLIC_KEY\""

echo
echo "Auth keys generated."
echo
}

generate_dotenv() {
pretty_echo "Generating Dotenv File"

Expand Down Expand Up @@ -390,6 +412,7 @@ prompt_user_gen_dotenv() {
fi

set_osm_credentials
generate_auth_keys
generate_dotenv

pretty_echo "Completed dotenv file generation"
Expand Down
Loading

0 comments on commit e97a04f

Please sign in to comment.