2
0
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:
Frederik Ring 2019-07-14 11:50:13 +02:00
parent 3929b88fec
commit 1c20b4ba58
4 changed files with 96 additions and 2 deletions

View File

@ -290,6 +290,9 @@ jobs:
- run:
name: Install dependencies
command: npm install
- run:
name: Install psycopg2 dependencies
command: sudo apt-get install libpq-dev
- save_cache:
paths:
- ~/offen/packages/node_modules

View 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
View File

View File

@ -54,20 +54,53 @@ custom:
fileName: requirements.txt
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:
handler: wsgi_handler.handler
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:
path: '/'
method: any
- http:
path: '{proxy+}'
path: '/{proxy+}'
method: any
environment:
CORS_ORIGIN: https://${self:custom.origin.${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_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}'
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'