in client/securedrop_client/storage.py [0:0]
def _delete_source_collection_from_db(session: Session, source: Source) -> None:
"""
Delete message, reply, draft, and file records belonging to a given source.
Create new DeletedConversation record to temporarily flag UUIDs of sources whose
conversations have been locally deleted, to prevent them from being re-added to
the database during a network race condition.
Source UUID is used because storing it does not expose any additional identifying
information about the source (compared to the source `id` field).
"""
is_local_db_modified = False
for table in (DraftReply, File, Message, Reply):
try:
query = session.query(table).filter_by(source_id=source.id)
if len(query.all()) > 0:
logger.debug(
f"Locally delete {table.__name__} records associated with source {source.uuid}"
)
query.delete()
is_local_db_modified = True
except NoResultFound:
# Sync logic has deleted the records
logger.debug(
f"Tried to locally delete {table.__name__} records associated with "
f"source {source.uuid}, but none were found"
)
# Add source UUID to deletedconversation table, but only if we actually made
# local database modifications
if is_local_db_modified:
flagged_conversation = DeletedConversation(uuid=source.uuid)
try:
if not session.query(DeletedConversation).filter_by(uuid=source.uuid).one_or_none():
logger.debug(f"Add source {source.uuid} to deletedconversation table")
session.add(flagged_conversation)
except SQLAlchemyError as e:
logger.error(f"Could not add source {source.uuid} to deletedconversation table")
logger.debug(f"Could not add source {source.uuid} to deletedconversation table: {e}")
session.rollback()
try:
session.commit()
except SQLAlchemyError as e:
logger.error(f"Could not locally delete conversation for source {source.uuid}")
logger.debug(f"Could not locally delete conversation for source {source.uuid}: {e}")
session.rollback()