mirror of
https://github.com/offen/website.git
synced 2024-11-22 09:00:28 +01:00
add basic auth authorizer for admin
This commit is contained in:
parent
3929b88fec
commit
1c20b4ba58
@ -290,6 +290,9 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Install dependencies
|
name: Install dependencies
|
||||||
command: npm install
|
command: npm install
|
||||||
|
- run:
|
||||||
|
name: Install psycopg2 dependencies
|
||||||
|
command: sudo apt-get install libpq-dev
|
||||||
- save_cache:
|
- save_cache:
|
||||||
paths:
|
paths:
|
||||||
- ~/offen/packages/node_modules
|
- ~/offen/packages/node_modules
|
||||||
|
58
accounts/authorizer/__init__.py
Normal file
58
accounts/authorizer/__init__.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import base64
|
||||||
|
from os import environ
|
||||||
|
|
||||||
|
from passlib.hash import bcrypt
|
||||||
|
|
||||||
|
|
||||||
|
def build_api_arn(method_arn):
|
||||||
|
arn_chunks = method_arn.split(":")
|
||||||
|
aws_region = arn_chunks[3]
|
||||||
|
aws_account_id = arn_chunks[4]
|
||||||
|
|
||||||
|
gateway_arn_chunks = arn_chunks[5].split("/")
|
||||||
|
rest_api_id = gateway_arn_chunks[0]
|
||||||
|
stage = gateway_arn_chunks[1]
|
||||||
|
|
||||||
|
return "arn:aws:execute-api:{}:{}:{}/{}/*/*".format(
|
||||||
|
aws_region, aws_account_id, rest_api_id, stage
|
||||||
|
)
|
||||||
|
|
||||||
|
def build_response(api_arn, allow):
|
||||||
|
effect = "Deny"
|
||||||
|
if allow:
|
||||||
|
effect = "Allow"
|
||||||
|
|
||||||
|
return {
|
||||||
|
"principalId": "offen",
|
||||||
|
"policyDocument": {
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Action": ["execute-api:Invoke"],
|
||||||
|
"Effect": effect,
|
||||||
|
"Resource": [api_arn]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def handler(event, context):
|
||||||
|
api_arn = build_api_arn(event["methodArn"])
|
||||||
|
|
||||||
|
auth_string = base64.standard_b64decode(event["authorizationToken"].lstrip("Basic ")).decode()
|
||||||
|
if not auth_string:
|
||||||
|
return build_response(api_arn, False)
|
||||||
|
|
||||||
|
credentials = auth_string.split(":")
|
||||||
|
user = credentials[0]
|
||||||
|
password = credentials[1]
|
||||||
|
|
||||||
|
if user != environ.get("BASIC_AUTH_USER"):
|
||||||
|
return build_response(api_arn, False)
|
||||||
|
|
||||||
|
hashed_password = base64.standard_b64decode(environ.get("HASHED_BASIC_AUTH_PASSWORD")).decode()
|
||||||
|
if not bcrypt.verify(password, hashed_password):
|
||||||
|
return build_response(api_arn, False)
|
||||||
|
|
||||||
|
return build_response(api_arn, True)
|
0
accounts/lambda
Normal file
0
accounts/lambda
Normal file
@ -54,20 +54,53 @@ custom:
|
|||||||
fileName: requirements.txt
|
fileName: requirements.txt
|
||||||
|
|
||||||
functions:
|
functions:
|
||||||
|
authorizer:
|
||||||
|
handler: authorizer.handler
|
||||||
|
environment:
|
||||||
|
BASIC_AUTH_USER: ${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/basicAuthUser~true}
|
||||||
|
HASHED_BASIC_AUTH_PASSWORD: ${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/hashedBasicAuthPassword~true}
|
||||||
app:
|
app:
|
||||||
handler: wsgi_handler.handler
|
handler: wsgi_handler.handler
|
||||||
events:
|
events:
|
||||||
|
- http:
|
||||||
|
path: /admin/
|
||||||
|
method: any
|
||||||
|
authorizer:
|
||||||
|
name: authorizer
|
||||||
|
resultTtlInSeconds: 0
|
||||||
|
identitySource: method.request.header.Authorization
|
||||||
|
- http:
|
||||||
|
path: /admin/{proxy+}
|
||||||
|
method: any
|
||||||
|
authorizer:
|
||||||
|
name: authorizer
|
||||||
|
resultTtlInSeconds: 0
|
||||||
|
identitySource: method.request.header.Authorization
|
||||||
- http:
|
- http:
|
||||||
path: '/'
|
path: '/'
|
||||||
method: any
|
method: any
|
||||||
- http:
|
- http:
|
||||||
path: '{proxy+}'
|
path: '/{proxy+}'
|
||||||
method: any
|
method: any
|
||||||
environment:
|
environment:
|
||||||
CORS_ORIGIN: https://${self:custom.origin.${self:custom.stage}}
|
CORS_ORIGIN: https://${self:custom.origin.${self:custom.stage}}
|
||||||
COOKIE_DOMAIN: ${self:custom.cookieDomain.${self:custom.stage}}
|
COOKIE_DOMAIN: ${self:custom.cookieDomain.${self:custom.stage}}
|
||||||
JWT_PRIVATE_KEY: '${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/jwtPrivateKey~true}'
|
JWT_PRIVATE_KEY: '${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/jwtPrivateKey~true}'
|
||||||
JWT_PUBLIC_KEY: '${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/jwtPublicKey~true}'
|
JWT_PUBLIC_KEY: '${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/jwtPublicKey~true}'
|
||||||
HASHED_PASSWORD: ${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/hashedBasicAuthPassword~true}
|
HASHED_BASIC_AUTH_PASSWORD: ${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/hashedBasicAuthPassword~true}
|
||||||
|
BASIC_AUTH_USER: ${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/basicAuthUser~true}
|
||||||
SESSION_SECRET: '${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/sessionSecret~true}'
|
SESSION_SECRET: '${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/sessionSecret~true}'
|
||||||
SERVER_URL: ${self:custom.serverHost.${self:custom.stage}}
|
SERVER_URL: ${self:custom.serverHost.${self:custom.stage}}
|
||||||
|
POSTGRES_CONNECTION_STRING: '${ssm:/aws/reference/secretsmanager/${self:custom.stage}/accounts/postgresConnectionString~true}'
|
||||||
|
|
||||||
|
resources:
|
||||||
|
Resources:
|
||||||
|
GatewayResponse:
|
||||||
|
Type: 'AWS::ApiGateway::GatewayResponse'
|
||||||
|
Properties:
|
||||||
|
ResponseParameters:
|
||||||
|
gatewayresponse.header.WWW-Authenticate: "'Basic'"
|
||||||
|
ResponseType: UNAUTHORIZED
|
||||||
|
RestApiId:
|
||||||
|
Ref: 'ApiGatewayRestApi'
|
||||||
|
StatusCode: '401'
|
||||||
|
Loading…
Reference in New Issue
Block a user