From f562dc8ed7a378405ad753179a622882abf6b0c4 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 24 Aug 2025 13:11:55 +0300 Subject: [PATCH] fix lazy_loading --- app/core/_crypto/content.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/app/core/_crypto/content.py b/app/core/_crypto/content.py index fdb7c3f..29f2bd2 100644 --- a/app/core/_crypto/content.py +++ b/app/core/_crypto/content.py @@ -48,25 +48,37 @@ async def create_encrypted_content( db_session, decrypted_content: StoredContent, ) -> StoredContent: from sqlalchemy import select - encrypted_content = (await db_session.execute(select(StoredContent).where( - StoredContent.id == decrypted_content.decrypted_content_id - ))).scalars().first() + # Try to find an already created encrypted counterpart for this decrypted content + encrypted_content = ( + await db_session.execute( + select(StoredContent).where(StoredContent.decrypted_content_id == decrypted_content.id) + ) + ).scalars().first() if encrypted_content: make_log("create_encrypted_content", f"(d={decrypted_content.cid.serialize_v2()}) => (e={encrypted_content.cid.serialize_v2()}): already exist (found by decrypted content)", level="debug") return encrypted_content encrypted_content = None - if decrypted_content.key is None: + # Avoid accessing relationship attributes in async context to prevent MissingGreenlet + if not decrypted_content.key_id: key = await create_new_encryption_key(db_session, user_id=decrypted_content.user_id) decrypted_content.key_id = key.id await db_session.commit() - decrypted_content = (await db_session.execute(select(StoredContent).where(StoredContent.id == decrypted_content.id))).scalars().first() assert decrypted_content.key_id, "Key not assigned" + # Explicitly load the key to avoid lazy-loading via relationship in async mode + key = ( + await db_session.execute(select(KnownKey).where(KnownKey.id == decrypted_content.key_id)) + ).scalars().first() + # If the referenced key is missing or malformed, create a fresh one + if not key or not key.seed: + key = await create_new_encryption_key(db_session, user_id=decrypted_content.user_id) + decrypted_content.key_id = key.id + await db_session.commit() + decrypted_path = os.path.join(UPLOADS_DIR, decrypted_content.hash) decrypted_bin = b58decode(decrypted_content.hash) - key = decrypted_content.key cipher = AESCipher(key.seed_bin) encrypted_bin = cipher.encrypt(decrypted_bin) @@ -79,7 +91,7 @@ async def create_encrypted_content( encrypted_content = None - encrypted_meta = decrypted_content.meta + encrypted_meta = dict(decrypted_content.meta or {}) encrypted_meta["encrypt_algo"] = "AES256" encrypted_content = StoredContent( @@ -109,4 +121,3 @@ async def create_encrypted_content( return encrypted_content -