Work on header validation

This commit is contained in:
Scott Idem
2022-01-05 13:50:12 -05:00
parent 3cfc8a69dc
commit 9a51e75892
3 changed files with 50 additions and 29 deletions

View File

@@ -20,35 +20,49 @@ from app.db_sql import redis_lookup_id_random, sql_select
# ### BEGIN ### API Lib General ### async get_token_header() ### # ### 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': if x_token != 'fake-super-secret-token':
raise HTTPException(status_code=400, detail='X-Token header invalid') raise HTTPException(status_code=400, detail='X-Token header invalid')
# ### END ### API Lib General ### async get_token_header() ### # ### END ### API Lib General ### async get_token_header() ###
# ### BEGIN ### API Lib General ### async get_account_header() ### # ### BEGIN ### API Lib General ### async get_account_header() ###
# Updated 2021-08-23 # Updated 2022-01-05
async def get_account_header(x_account_id:str = Header(...)) -> dict: async def get_account_header(x_account_id: str = Header(..., min_length=11, max_length=22)) -> dict:
log.setLevel(logging.WARNING) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) 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}')
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): if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id):
log.setLevel(logging.DEBUG) log.setLevel(logging.DEBUG)
log.info('Found the account_id with the account_id_random value: '+x_account_id) log.info(f'Found the x-account-id with the value: {x_account_id}')
account = { 'id': account_id, 'id_random': x_account_id } account = { 'id': account_id, 'id_random': x_account_id }
else: log.debug(account)
log.warning('The x-account-id Account ID was not found or it was invalid...') return account
#raise HTTPException(status_code=500) else:
raise HTTPException(status_code=400) # or 404? log.warning(f'The x-account-id Account ID was not found. Account ID: {x_account_id}')
#return False 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.') # if len(x_account_id) >= 11 and len(x_account_id) <= 22:
account = { 'id': None, 'id_random': None } # log.info(f'The x-account-id header has a value. x-account-id: {x_account_id}')
#account = { 'id': 0, 'id_random': 'abcdef123456' } # 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() ### # ### END ### API Lib General ### async get_account_header() ###

View File

@@ -14,7 +14,7 @@ from sqlalchemy import create_engine, text
from sqlalchemy.exc import IntegrityError, OperationalError from sqlalchemy.exc import IntegrityError, OperationalError
from . import config from . import config
# from app.lib_general import log, logging from app.lib_general import get_account_header
from app.log import log, logging from app.log import log, logging
# Import the routers here first: # Import the routers here first:
@@ -82,6 +82,7 @@ app.include_router(
account.router, account.router,
prefix='/account', prefix='/account',
tags=['Account'], tags=['Account'],
dependencies=[Depends(get_account_header)],
) )
app.include_router( app.include_router(
activity_log.router, activity_log.router,
@@ -92,6 +93,7 @@ app.include_router(
address.router, address.router,
prefix='/address', prefix='/address',
tags=['Address'], tags=['Address'],
dependencies=[Depends(get_account_header)],
) )
app.include_router( app.include_router(
archive.router, archive.router,
@@ -107,6 +109,7 @@ app.include_router(
contact.router, contact.router,
prefix='/contact', prefix='/contact',
tags=['Contact'], tags=['Contact'],
dependencies=[Depends(get_account_header)],
) )
app.include_router( app.include_router(
cont_edu_cert.router, cont_edu_cert.router,
@@ -230,6 +233,7 @@ app.include_router(
app.include_router( app.include_router(
membership_person.router, membership_person.router,
tags=['Membership Person'], tags=['Membership Person'],
dependencies=[Depends(get_account_header)],
) )
app.include_router( app.include_router(
membership_type.router, membership_type.router,
@@ -268,11 +272,13 @@ app.include_router(
person.router, person.router,
# prefix='/person', # prefix='/person',
tags=['Person'], tags=['Person'],
# dependencies=[Depends(get_account_header)],
) )
app.include_router( app.include_router(
person_user.router, person_user.router,
prefix='/person_user', prefix='/person_user',
tags=['Person User'], tags=['Person User'],
dependencies=[Depends(get_account_header)],
) )
app.include_router( app.include_router(
post.router, post.router,

View File

@@ -3,7 +3,7 @@ from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query, Resp
from pydantic import BaseModel, EmailStr, Field from pydantic import BaseModel, EmailStr, Field
from typing import Dict, List, Optional, Set, Union 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.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 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(...), x_account_id: str = Header(...),
response: Response = Response, 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()) log.debug(locals())
if create_update_person_obj_result := create_update_person_obj_v4b( 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() ### # ### BEGIN ### API Person ### email_create_url() ###
# Updated 2021-12-03 # 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)
@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_create_url( async def email_auth_key_url(
person_id: Optional[str] = Query(None, min_length=11, max_length=22), 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 root_url: Optional[str] = Query(None, min_length=10, max_length=100), # Absolute min = 7
x_account_id: Optional[str] = Header(..., ), 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. # 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) @router.get('/account/{account_id}/person/list', response_model=Resp_Body_Base)
async def get_account_obj_person_list( 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 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 enabled: str = 'enabled', # For now this covers any included objects or object lists
inc_address: bool = False, 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: 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_product_list: bool = False, # The list of products that give access to a member_type or member_group
inc_user: bool = False, inc_user: bool = False,
x_account_id: str = Header(...), # x_account_id: str = Header(...),
by_alias: Optional[bool] = True, by_alias: Optional[bool] = True,
exclude_unset: Optional[bool] = True, exclude_unset: Optional[bool] = True,
response: Response = Response, 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()) log.debug(locals())
if account_id := redis_lookup_id_random(record_id_random=account_id, table_name='account'): pass if account_id := redis_lookup_id_random(record_id_random=account_id, table_name='account'): pass