From 9a51e758929a1097b277b62ed092569b812bd512 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Wed, 5 Jan 2022 13:50:12 -0500 Subject: [PATCH] Work on header validation --- app/lib_general.py | 54 +++++++++++++++++++++++++++---------------- app/main.py | 8 ++++++- app/routers/person.py | 17 +++++++------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/app/lib_general.py b/app/lib_general.py index 2f81afc..137a811 100644 --- a/app/lib_general.py +++ b/app/lib_general.py @@ -20,35 +20,49 @@ from app.db_sql import redis_lookup_id_random, sql_select # ### BEGIN ### API Lib General ### async get_token_header() ### -async def get_token_header(x_token:str = Header(...)): +async def get_token_header(x_token: str = Header(...)): if x_token != 'fake-super-secret-token': raise HTTPException(status_code=400, detail='X-Token header invalid') # ### END ### API Lib General ### async get_token_header() ### # ### BEGIN ### API Lib General ### async get_account_header() ### -# Updated 2021-08-23 -async def get_account_header(x_account_id:str = Header(...)) -> dict: - log.setLevel(logging.WARNING) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL +# Updated 2022-01-05 +async def get_account_header(x_account_id: str = Header(..., min_length=11, max_length=22)) -> dict: + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) - if len(x_account_id): - log.info(f'The x-account-id header has a value. x-account-id: {x_account_id}') - if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id): - log.setLevel(logging.DEBUG) - log.info('Found the account_id with the account_id_random value: '+x_account_id) - account = { 'id': account_id, 'id_random': x_account_id } - else: - log.warning('The x-account-id Account ID was not found or it was invalid...') - #raise HTTPException(status_code=500) - raise HTTPException(status_code=400) # or 404? - #return False - elif x_account_id == '': - log.info('The x-account-id header was empty.') - account = { 'id': None, 'id_random': None } - #account = { 'id': 0, 'id_random': 'abcdef123456' } + log.info(f'The x-account-id header has a value. x-account-id: {x_account_id}') + + if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id): + log.setLevel(logging.DEBUG) + log.info(f'Found the x-account-id with the value: {x_account_id}') + account = { 'id': account_id, 'id_random': x_account_id } + log.debug(account) + return account + else: + log.warning(f'The x-account-id Account ID was not found. Account ID: {x_account_id}') + raise HTTPException(status_code=403, detail='The x-account-id Account ID was not found.') # Forbidden + + # if len(x_account_id) >= 11 and len(x_account_id) <= 22: + # log.info(f'The x-account-id header has a value. x-account-id: {x_account_id}') + # if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id): + # log.setLevel(logging.DEBUG) + # log.info(f'Found the x-account-id with the value: {x_account_id}') + # account = { 'id': account_id, 'id_random': x_account_id } + # x_account_id = account_id + # else: + # log.warning(f'The x-account-id Account ID was not found. Account ID: {x_account_id}') + # raise HTTPException(status_code=403, detail='The x-account-id Account ID was not found.') # Forbidden + # elif x_account_id == '': + # log.info('The x-account-id header was empty.') + # raise HTTPException(status_code=403, detail='The x-account-id header was empty.') # Forbidden + # # account = { 'id': None, 'id_random': None } + # else: + # log.info('The x-account-id header was not valid.') + # raise HTTPException(status_code=403, detail='The x-account-id header was not valid.') # Forbidden + - return account # ### END ### API Lib General ### async get_account_header() ### diff --git a/app/main.py b/app/main.py index 0934d96..5135e44 100644 --- a/app/main.py +++ b/app/main.py @@ -14,7 +14,7 @@ from sqlalchemy import create_engine, text from sqlalchemy.exc import IntegrityError, OperationalError from . import config -# from app.lib_general import log, logging +from app.lib_general import get_account_header from app.log import log, logging # Import the routers here first: @@ -82,6 +82,7 @@ app.include_router( account.router, prefix='/account', tags=['Account'], + dependencies=[Depends(get_account_header)], ) app.include_router( activity_log.router, @@ -92,6 +93,7 @@ app.include_router( address.router, prefix='/address', tags=['Address'], + dependencies=[Depends(get_account_header)], ) app.include_router( archive.router, @@ -107,6 +109,7 @@ app.include_router( contact.router, prefix='/contact', tags=['Contact'], + dependencies=[Depends(get_account_header)], ) app.include_router( cont_edu_cert.router, @@ -230,6 +233,7 @@ app.include_router( app.include_router( membership_person.router, tags=['Membership Person'], + dependencies=[Depends(get_account_header)], ) app.include_router( membership_type.router, @@ -268,11 +272,13 @@ app.include_router( person.router, # prefix='/person', tags=['Person'], + # dependencies=[Depends(get_account_header)], ) app.include_router( person_user.router, prefix='/person_user', tags=['Person User'], + dependencies=[Depends(get_account_header)], ) app.include_router( post.router, diff --git a/app/routers/person.py b/app/routers/person.py index 18ea384..2524e62 100644 --- a/app/routers/person.py +++ b/app/routers/person.py @@ -3,7 +3,7 @@ from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query, Resp from pydantic import BaseModel, EmailStr, Field from typing import Dict, List, Optional, Set, Union -from app.lib_general import log, logging +from app.lib_general import log, logging, get_account_header from app.config import settings from app.db_sql import sql_insert, sql_update, sql_insert_or_update, sql_select, sql_delete, get_id_random, redis_lookup_id_random @@ -99,7 +99,7 @@ async def v3_post_person_obj_new( x_account_id: str = Header(...), response: Response = Response, ): - log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if create_update_person_obj_result := create_update_person_obj_v4b( @@ -439,9 +439,9 @@ async def lookup_email( # ### BEGIN ### API Person ### email_create_url() ### # Updated 2021-12-03 -# @router.get('/person/email_create_url', response_model=Resp_Body_Base) -@router.get('/person/{person_id}/email_create_url', response_model=Resp_Body_Base) -async def email_create_url( +# @router.get('/person/{person_id}/email_create_url', response_model=Resp_Body_Base) +@router.get('/person/{person_id}/email_auth_key_url', response_model=Resp_Body_Base) +async def email_auth_key_url( person_id: Optional[str] = Query(None, min_length=11, max_length=22), root_url: Optional[str] = Query(None, min_length=10, max_length=100), # Absolute min = 7 x_account_id: Optional[str] = Header(..., ), @@ -575,7 +575,7 @@ async def get_person_obj( # Working well as of 2021-07-09. Using as a template for other routes. @router.get('/account/{account_id}/person/list', response_model=Resp_Body_Base) async def get_account_obj_person_list( - account_id: str = Query(..., min_length=1, max_length=22), + account_id: str = Query(..., min_length=11, max_length=22), limit: int = 500, # For now this covers any included objects or object lists enabled: str = 'enabled', # For now this covers any included objects or object lists inc_address: bool = False, @@ -590,12 +590,13 @@ async def get_account_obj_person_list( # inc_product: bool = False, # The product the person actually purchased for a member_type or member_group # inc_product_list: bool = False, # The list of products that give access to a member_type or member_group inc_user: bool = False, - x_account_id: str = Header(...), + # x_account_id: str = Header(...), by_alias: Optional[bool] = True, exclude_unset: Optional[bool] = True, response: Response = Response, + account: dict = Depends(get_account_header), ): - log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if account_id := redis_lookup_id_random(record_id_random=account_id, table_name='account'): pass