This commit is contained in:
n 2025-07-09 06:12:33 +00:00
parent 071b472221
commit 701758e5c5
3 changed files with 21 additions and 15 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
.env .env
.env.public .env.public
.env.private .env.private
.callback_uri
.client_id
.client_secret

View File

@ -1,5 +1,4 @@
from collections import OrderedDict from collections import OrderedDict
from dotenv import load_dotenv
from fastapi import FastAPI, Query, Request, Response, status from fastapi import FastAPI, Query, Request, Response, status
from fastapi.responses import RedirectResponse from fastapi.responses import RedirectResponse
from uuid import uuid4 from uuid import uuid4
@ -10,15 +9,14 @@ import os
UUIDPattern = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}" UUIDPattern = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"
UUIDQuery = Query(min_length=36, max_length=36, pattern=f"^{UUIDPattern}$") UUIDQuery = Query(min_length=36, max_length=36, pattern=f"^{UUIDPattern}$")
load_dotenv() with open('/run/secrets/monzo-api_client-id') as file: client_id = file.read().rstrip()
client_id = os.environ['MONZO_CLIENT_ID'] with open('/run/secrets/monzo-api_client-secret') as file: client_secret = file.read().rstrip()
client_secret = os.environ['MONZO_CLIENT_SECRET'] with open('/run/secrets/monzo-api_callback-uri') as file: callback_uri = file.read().rstrip()
callback_uri = os.environ['MONZO_CALLBACK_URI']
app = FastAPI(root_path='/monzo') app = FastAPI(root_path='/monzo')
@app.get('/') @app.get('/')
def read_root(): return {'version': 'v0.0.9'} def read_root(): return {'version': 'v0.0.10'}
@app.get('/redirect', response_class=RedirectResponse) @app.get('/redirect', response_class=RedirectResponse)
@ -29,15 +27,15 @@ def read_redirect(res: Response):
client_id=client_id, client_id=client_id,
redirect_uri=callback_uri, redirect_uri=callback_uri,
state=state, state=state,
response_type="code", response_type='code',
)) ))
res.set_cookie(key="monzo-api:state", value=state) res.set_cookie(key='monzo-api:state', value=state)
return f"https://auth.monzo.com/?{query}" return f"https://auth.monzo.com/?{query}"
@app.get('/callback') @app.get('/callback')
def read_callback(code: str, state: Annotated[str, UUIDQuery], req: Request, res: Response): def read_callback(code: str, state: Annotated[str, UUIDQuery], req: Request, res: Response):
stored_state = req.cookies['monzo-api:state'] stored_state = req.cookies["monzo-api:state"]
if (state != stored_state): if (state != stored_state):
res.status_code = status.HTTP_400_BAD_REQUEST res.status_code = status.HTTP_400_BAD_REQUEST
return { 'error': True, 'data': f"Callback state '{state}' does not match stored state '{stored_state}'." } return { 'error': True, 'data': f"Callback state '{state}' does not match stored state '{stored_state}'." }
@ -51,5 +49,5 @@ def read_callback(code: str, state: Annotated[str, UUIDQuery], req: Request, res
'redirect_uri': callback_uri, 'redirect_uri': callback_uri,
'code': code, 'code': code,
} }
token = requests.post("https://api.monzo.com/oauth2/token", data=data) token = requests.post('https://api.monzo.com/oauth2/token', data=data)
return { 'error': False, 'data': token.json() } return { 'error': False, 'data': token.json() }

View File

@ -1,11 +1,8 @@
services: services:
monzo-api: monzo-api:
image: git.wnd.sh/n/monzo-api:v0.0.9 image: git.wnd.sh/n/monzo-api:v0.0.10
networks: [traefik-public] networks: [traefik-public]
environment: secrets: [monzo-api_client-id, monzo-api_client-secret, monzo-api_callback-uri]
- MONZO_CALLBACK_URI=https://api.wnd.sh/monzo/callback
- MONZO_CLIENT_ID=oauth2client_0000AtdcjWWYX35lpL2REI
- MONZO_CLIENT_SECRET=mnzconf.K78nqT+k2QKOlR6oSoF6CHLLSMII9SqWxg5smZfc5wgWDGH94HO1h338SEOFCH8rSy6EDKDtgFvA8qnkiQhpFA==
deploy: deploy:
labels: labels:
- traefik.enable=true - traefik.enable=true
@ -25,3 +22,11 @@ services:
networks: networks:
traefik-public: traefik-public:
external: true external: true
secrets:
monzo-api_client-id:
external: true
monzo-api_client-secret:
external: true
monzo-api_callback-uri:
external: true