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:
|
||||
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
|
||||
|
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
|
||||
|
||||
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'
|
||||
|
Loading…
Reference in New Issue
Block a user