From 398897efe138d0074738e13f4efa2c93601b2cc7 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Wed, 15 Dec 2021 21:51:58 -0500 Subject: [PATCH] Just lots of work and tweeks --- app/methods/person_methods.py | 76 ++++++++++++++++++++++++++--- app/models/person_models.py | 11 +++-- app/routers/event.py | 78 +++++++++++++++--------------- app/routers/person.py | 90 ++++++++++++++++++++--------------- 4 files changed, 167 insertions(+), 88 deletions(-) diff --git a/app/methods/person_methods.py b/app/methods/person_methods.py index 1b19f46..b805edc 100644 --- a/app/methods/person_methods.py +++ b/app/methods/person_methods.py @@ -1,5 +1,5 @@ from __future__ import annotations -import datetime +import datetime, pytz from typing import Dict, List, Optional, Set, Union from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator @@ -20,8 +20,10 @@ from app.models.person_models import Person_Base # ### BEGIN ### API Person Methods ### load_person_obj() ### +# Updated 2021-12-15 def load_person_obj( person_id: int|str, + auth_key: str = None, limit: int = 1000, by_alias: bool = True, exclude_unset: bool = True, @@ -57,16 +59,78 @@ def load_person_obj( inc_user: bool = False, inc_user_role_list: bool = False, ) -> Person_Base|dict|bool: - log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if person_id := redis_lookup_id_random(record_id_random=person_id, table_name='person'): pass - else: return False + else: return None - if person_rec := sql_select(table_name='v_person', record_id=person_id): pass - else: return False + if auth_key: + sql = f""" + SELECT * + FROM `v_person` AS person + WHERE person.id = :person_id + AND person.allow_auth_key = 1 + AND person.auth_key = :auth_key + LIMIT 1 + ; + """ + log.debug(sql) + + data = {} + data['person_id'] = person_id + data['auth_key'] = auth_key + log.debug(data) + + if person_rec := sql_select(sql=sql, data=data): + # Only wipe the key if the last update to person record was more than X minutes + updated_on = person_rec.get('updated_on') + updated_on_string = updated_on.isoformat() + log.debug(updated_on_string) + + eastern = pytz.timezone('US/Eastern') + + updated_on_localized = eastern.localize(updated_on) + log.debug(updated_on_localized.isoformat()) + + # updated_on_utc = person_rec.get('updated_on').replace(tzinfo=datetime.timezone.utc) + # updated_on_tz = person_rec.get('updated_on').replace(tzinfo=eastern) + # updated_on_tz_string = updated_on_tz.isoformat() + # log.debug(updated_on_tz_string) + + current_datetime_utc = datetime.datetime.utcnow() + current_datetime_utc_string = current_datetime_utc.isoformat() + log.debug(current_datetime_utc_string) + + # datetime_difference = current_datetime_utc - updated_on_localized + # total_seconds = datetime_difference.total_seconds() + # log.debug(total_seconds) + + current_datetime_utc_localize = pytz.utc.localize(current_datetime_utc) + current_datetime_utc_localize_string = current_datetime_utc_localize.isoformat() + + # test_datetime_utc = datetime.datetime.utcnow()- datetime.timedelta(seconds=120) + datetime_difference = current_datetime_utc_localize - updated_on_localized + total_seconds = datetime_difference.total_seconds() + log.debug(total_seconds) + + if total_seconds > 7200: # 7200 seconds = 2 hours + log.warning('The authorization key has expired') + + update_person_data = {} + update_person_data['id'] = person_id + update_person_data['auth_key'] = None # secrets.token_urlsafe(default_num_bytes) + + if person_rec_update_result := sql_update(table_name='person', data=update_person_data): + log.info('The person record was updated with a new auth_key') + else: + log.warning('The authorization key is still valid') + + else: return person_rec # None or False + else: + if person_rec := sql_select(table_name='v_person', record_id=person_id): pass + else: return person_rec # None or False - # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(person_rec) try: diff --git a/app/models/person_models.py b/app/models/person_models.py index 68c4aac..e6a1833 100644 --- a/app/models/person_models.py +++ b/app/models/person_models.py @@ -56,7 +56,7 @@ class Person_Base(BaseModel): suffix: Optional[str] # NOTE: Phasing out! Use *designations* instead. professional_title: Optional[str] # Professional title - title: Optional[str] # NOTE: Phasing out! Use *professional_title* instead. + # title: Optional[str] # NOTE: Phasing out! Use *professional_title* instead. display_name: Optional[str] # Custom what they want for public display informal_display_name: Optional[str] # Custom what they want for informal public display @@ -75,10 +75,10 @@ class Person_Base(BaseModel): # END # Auto created name variations affiliations: Optional[str] # One or more affiliations with organizations, companies, and other groups - affiliation: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. - organization_name: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. + # affiliation: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. + # organization_name: Optional[str] # NOTE: Phasing out! Use *affiliations* instead. - tagline: Optional[str] + tagline: Optional[Union[None, str]] birth_date: Optional[datetime.date] lu_gender_id: Optional[int] @@ -90,6 +90,9 @@ class Person_Base(BaseModel): external_id: Optional[str] external_import_id: Optional[str] + allow_auth_key: Optional[bool] + auth_key: Optional[str] + enable: Optional[bool] group: Optional[str] diff --git a/app/routers/event.py b/app/routers/event.py index 9c6a6bf..6263106 100644 --- a/app/routers/event.py +++ b/app/routers/event.py @@ -256,45 +256,45 @@ async def get_event_obj( else: return mk_resp(data=None, status_code=404, response=response) if event_obj := load_event_obj( - event_id = event_id, - enabled = enabled, - approved = approved, - hidden = hidden, - review = review, - inc_file_count = inc_file_count, - inc_address = inc_address, - # inc_address_location = inc_address_location, - inc_contact = inc_contact, - # inc_event_abstract_list = inc_event_abstract_list, - # inc_event_badge_list = inc_event_badge_list, - inc_event_cfg = inc_event_cfg, - # inc_event_device_list = inc_event_device_list, - # inc_event_exhibit_list = inc_event_exhibit_list, - inc_event_file_list = inc_event_file_list, - inc_event_location = inc_event_location, - inc_event_location_list = inc_event_location_list, - # inc_event_person = inc_event_person, - inc_event_person_list = inc_event_person_list, - inc_event_presentation_list = inc_event_presentation_list, - inc_event_presenter_cat = inc_event_presenter_cat, - inc_event_presenter_list = inc_event_presenter_list, - inc_event_registration_cfg = inc_event_registration_cfg, - # inc_event_registration_list = inc_event_registration_list, - inc_event_session_list = inc_event_session_list, - # inc_event_track = inc_event_track, - # inc_event_track_list = inc_event_track_list, - # inc_order_list = inc_order_list, - inc_organization = inc_organization, - inc_person = inc_person, - inc_poc_event_person = inc_poc_event_person, - # inc_product = inc_product, - # inc_product_list = inc_product_list, - inc_user = inc_user, - limit = limit, - by_alias = by_alias, - exclude_unset = exclude_unset, - # model_as_dict = model_as_dict, - ): + event_id = event_id, + enabled = enabled, + approved = approved, + hidden = hidden, + review = review, + inc_file_count = inc_file_count, + inc_address = inc_address, + # inc_address_location = inc_address_location, + inc_contact = inc_contact, + # inc_event_abstract_list = inc_event_abstract_list, + # inc_event_badge_list = inc_event_badge_list, + inc_event_cfg = inc_event_cfg, + # inc_event_device_list = inc_event_device_list, + # inc_event_exhibit_list = inc_event_exhibit_list, + inc_event_file_list = inc_event_file_list, + inc_event_location = inc_event_location, + inc_event_location_list = inc_event_location_list, + # inc_event_person = inc_event_person, + inc_event_person_list = inc_event_person_list, + inc_event_presentation_list = inc_event_presentation_list, + inc_event_presenter_cat = inc_event_presenter_cat, + inc_event_presenter_list = inc_event_presenter_list, + inc_event_registration_cfg = inc_event_registration_cfg, + # inc_event_registration_list = inc_event_registration_list, + inc_event_session_list = inc_event_session_list, + # inc_event_track = inc_event_track, + # inc_event_track_list = inc_event_track_list, + # inc_order_list = inc_order_list, + inc_organization = inc_organization, + inc_person = inc_person, + inc_poc_event_person = inc_poc_event_person, + # inc_product = inc_product, + # inc_product_list = inc_product_list, + inc_user = inc_user, + limit = limit, + by_alias = by_alias, + exclude_unset = exclude_unset, + # model_as_dict = model_as_dict, + ): # event_dict = event_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) pass else: diff --git a/app/routers/person.py b/app/routers/person.py index eadb93f..18ea384 100644 --- a/app/routers/person.py +++ b/app/routers/person.py @@ -185,6 +185,7 @@ async def v3_patch_person_obj_exist( else: return mk_resp(data=False, status_code=400, response=response, status_message='The person was not updated. Check the field names and data types.') if isinstance(create_update_person_obj_result, int): + log.info('Create/Update successful') person_id = create_update_person_obj_result if return_obj: if load_person_obj_result := load_person_obj( @@ -474,10 +475,11 @@ async def email_create_url( # ### BEGIN ### API Person ### get_person_obj() ### -# Working well as of 2021-06-25. Using as a template for other routes. +# Updated 2021-12-15 @router.get('/person/{person_id}', response_model=Resp_Body_Base) async def get_person_obj( - person_id: str = Query(..., min_length=1, max_length=22), + person_id: str = Query(..., min_length=11, max_length=22), + auth_key: str = Query(None, min_length=11, max_length=22), # If passed, it must match in the person record. New 2021-12-15 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, # Priority l1 @@ -512,50 +514,60 @@ async def get_person_obj( exclude_unset: Optional[bool] = True, response: Response = Response, ): - log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if person_id := redis_lookup_id_random(record_id_random=person_id, table_name='person'): pass else: return mk_resp(data=None, status_code=404, response=response) - if person_dict := load_person_obj( - person_id = person_id, - limit = limit, - exclude_unset = False, - model_as_dict = False, # NOTE: returning model as a dict - enabled = enabled, - inc_address = inc_address, - # inc_archive_list = inc_archive_list, - inc_contact = inc_contact, - inc_event_list = inc_event_list, - # inc_hosted_file_list = inc_hosted_file_list, - inc_journal_list = inc_journal_list, - # inc_journal_entry_list = inc_journal_entry_list, - inc_membership_group_list = inc_membership_group_list, - inc_membership_group_person_list = inc_membership_group_person_list, - inc_membership_person = inc_membership_person, - inc_membership_person_profile = inc_membership_person_profile, - inc_membership_type = inc_membership_type, - inc_membership_type_person = inc_membership_type_person, - inc_order_closed_count = inc_order_closed_count, - inc_order_line_list = inc_order_line_list, - inc_order_list = inc_order_list, - inc_order_cart = inc_order_cart, - # inc_order_cart_list = inc_order_cart_list, - inc_organization = inc_organization, - # inc_organization_list = inc_organization_list, - inc_post_list = inc_post_list, - inc_post_comment_list = inc_post_comment_list, - inc_user = inc_user, - ): - if isinstance(person_dict, dict): - response_data = person_dict - else: - response_data = person_dict + if person_rec_result := load_person_obj( + person_id = person_id, + auth_key = auth_key, + limit = limit, + exclude_unset = False, + model_as_dict = False, # NOTE: returning model as a dict + enabled = enabled, + inc_address = inc_address, + # inc_archive_list = inc_archive_list, + inc_contact = inc_contact, + inc_event_list = inc_event_list, + # inc_hosted_file_list = inc_hosted_file_list, + inc_journal_list = inc_journal_list, + # inc_journal_entry_list = inc_journal_entry_list, + inc_membership_group_list = inc_membership_group_list, + inc_membership_group_person_list = inc_membership_group_person_list, + inc_membership_person = inc_membership_person, + inc_membership_person_profile = inc_membership_person_profile, + inc_membership_type = inc_membership_type, + inc_membership_type_person = inc_membership_type_person, + inc_order_closed_count = inc_order_closed_count, + inc_order_line_list = inc_order_line_list, + inc_order_list = inc_order_list, + inc_order_cart = inc_order_cart, + # inc_order_cart_list = inc_order_cart_list, + inc_organization = inc_organization, + # inc_organization_list = inc_organization_list, + inc_post_list = inc_post_list, + inc_post_comment_list = inc_post_comment_list, + inc_user = inc_user, + ): + response_data = person_rec_result + # if isinstance(person_rec_result, dict): + # response_data = person_rec_result + # else: + # response_data = person_rec_result + # else: + # return mk_resp(data=False, status_code=400, response=response) # Bad Request + + elif isinstance(person_rec_result, list) or person_rec_result is None: # Empty list or None + log.info('No results') + if auth_key: log.info('It is likely the auth_key did not match.') + return mk_resp(data=False, status_code=404, response=response) # Not Found else: + log.warning('Likely bad request') return mk_resp(data=False, status_code=400, response=response) # Bad Request - return mk_resp(data=response_data) + return mk_resp(data=response_data, response=response) # ### END ### API Person ### get_person_obj() ### @@ -620,7 +632,7 @@ async def get_account_obj_person_list( else: return mk_resp(data=False, status_code=400, response=response) # Bad Request - return mk_resp(data=response_data) + return mk_resp(data=response_data, response=response) # ### END ### API Person ### get_account_obj_person_list() ###