Skip to content

Commit

Permalink
New auth
Browse files Browse the repository at this point in the history
  • Loading branch information
odrusso committed Dec 17, 2023
1 parent c54515a commit 338b259
Show file tree
Hide file tree
Showing 32 changed files with 12,068 additions and 1,116 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/prod-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ jobs:
ParameterKey=hostedZoneId,UsePreviousValue=true \
ParameterKey=lambdaBucket,UsePreviousValue=true \
ParameterKey=apiDomain,UsePreviousValue=true \
ParameterKey=environment,UsePreviousValue=true
ParameterKey=environment,UsePreviousValue=true \
ParameterKey=signingSecretString,UsePreviousValue=true
# Wait for update
aws cloudformation wait stack-update-complete --stack-name ${{ secrets.PROD_API_CF_NAME }}
Expand Down
64 changes: 36 additions & 28 deletions .github/workflows/stage-build.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Build, test, and deploy to Stage
on: [ pull_request ]
jobs:
run:
api:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.STAGE_AWS_ACCESS_KEY_ID }}
Expand All @@ -13,32 +13,6 @@ jobs:
with:
python-version: '3.8'

- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '14.3'

- name: Install dependencies
working-directory: ./web
run: npm i

- name: Test Frontend
working-directory: ./web
run: npx tsc && npm run test

- name: Build
working-directory: ./web
run: npm run build-stage

- name: Deploy Frontend
uses: reggionick/s3-deploy@v3
with:
folder: ./web/build
bucket: ${{ secrets.STAGE_S3_BUCKET }}
bucket-region: us-east-1
dist-id: ${{ secrets.STAGE_CF_DISTRIBUTION_ID }}
invalidation: /*

- name: Test Backend
run: pip install -r requirements.txt && python -m unittest
working-directory: ./app
Expand Down Expand Up @@ -70,10 +44,44 @@ jobs:
ParameterKey=hostedZoneId,UsePreviousValue=true \
ParameterKey=lambdaBucket,UsePreviousValue=true \
ParameterKey=apiDomain,UsePreviousValue=true \
ParameterKey=environment,UsePreviousValue=true
ParameterKey=environment,UsePreviousValue=true \
ParameterKey=signingSecretString,UsePreviousValue=true
# Wait for update
aws cloudformation wait stack-update-complete --stack-name ${{ secrets.STAGE_API_CF_NAME }}
env:
AWS_DEFAULT_REGION: us-east-1
spa:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.STAGE_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.STAGE_AWS_SECRET_ACCESS_KEY }}
steps:
- uses: actions/checkout@v2

- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '14.3'

- name: Install dependencies
working-directory: ./web
run: npm i

- name: Test Frontend
working-directory: ./web
run: npx tsc && npm run test

- name: Build
working-directory: ./web
run: npm run build-stage

- name: Deploy Frontend
uses: reggionick/s3-deploy@v3
with:
folder: ./web/build
bucket: ${{ secrets.STAGE_S3_BUCKET }}
bucket-region: us-east-1
dist-id: ${{ secrets.STAGE_CF_DISTRIBUTION_ID }}
invalidation: /*
43 changes: 22 additions & 21 deletions app/crypto.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
import hashlib
import base64
import hmac
import os
import boto3.dynamodb.types
import dynamo


def verify_password_for_pigeonhole(pigeon_hole_name: str, password: str) -> bool:
pigeonhole = dynamo.get_pigeonhole_data(pigeon_hole_name)
def get_signing_secret():
return os.environ.get('signingSecret', default=False)

verification_password_bytes = get_hash_for_pigeonhole(pigeonhole)
salt = get_salt_for_pigeonhole(pigeonhole)

this_password_bytes = gen_hash_for_password(password, salt)
def verify_password(raw_hash: str, raw_salt: str, password_attempt: str) -> bool:
verification_password_bytes = decode_value(raw_hash)
raw_salt = decode_value(raw_salt)

return this_password_bytes == verification_password_bytes


def get_hash_for_pigeonhole(pigeonhole: dict) -> bytes:
return base64.b64decode(conform((pigeonhole['hash'])))
this_password_bytes = gen_hash_for_password(password_attempt, raw_salt)


def get_salt_for_pigeonhole(pigeonhole: dict) -> bytes:
return base64.b64decode(conform(pigeonhole['salt']))
return this_password_bytes == verification_password_bytes


def conform(value) -> str:
if type(value) == boto3.dynamodb.types.Binary:
return value.value.decode("utf-8")
else:
return value
def decode_value(raw_value: str) -> bytes:
return base64.b64decode(raw_value)


def gen_hash_for_password(password: str, salt: bytes) -> bytes:
Expand All @@ -44,11 +35,21 @@ def create_new_hash_for_password(password: str) -> (str, str):
new_salt = os.urandom(32)
new_hash = gen_hash_for_password(password, new_salt)

new_salt_b64 = base64.b64encode(new_salt)
new_hash_b64 = base64.b64encode(new_hash)
new_salt_b64 = base64.b64encode(new_salt).decode()
new_hash_b64 = base64.b64encode(new_hash).decode()

return new_hash_b64, new_salt_b64


def get_bytes_from_password(password: str) -> bytes:
return str.encode(password)


def create_user_token(username: str) -> str:
signature_bytes = hmac.digest(get_signing_secret().encode(), username.encode(), "SHA256")
return base64.b64encode(signature_bytes).decode()


def validate_user_token(username: str, token: str) -> bool:
new_signature_bytes = hmac.digest(get_signing_secret().encode(), username.encode(), "SHA256")
return hmac.compare_digest(new_signature_bytes, base64.b64decode(token.encode()))
9 changes: 6 additions & 3 deletions app/dynamo.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
import boto3
import os

def get_tableName():

def get_table_name():
return os.environ.get('dynamoTableName', default=False) or "jnl-data"


def get_pigeonhole_data(pigeonhole_name: str) -> Optional[dict]:
# type of get_item is {pigeonhole_name: string, hash: binary, salt: binary, data: string}
# type of data is a string of list<{date: string, message: string}>
db = boto3.resource("dynamodb")
table = db.Table(get_tableName())
table = db.Table(get_table_name())

try:
return table.get_item(Key={'pigeonhole_name': pigeonhole_name})['Item']
Expand All @@ -28,7 +31,7 @@ def get_pigeonhole_data(pigeonhole_name: str) -> Optional[dict]:

def new_pigeonhole(pigeonhole_name: str, hash: str, salt: str, data: str):
db = boto3.resource("dynamodb")
table = db.Table(get_tableName())
table = db.Table(get_table_name())

table.put_item(
Item={
Expand Down
Loading

0 comments on commit 338b259

Please sign in to comment.