Ahmed Mostafa commited on
Commit
c29587d
·
1 Parent(s): 4577288

fix log v1.5.3

Browse files
Files changed (4) hide show
  1. src/auth/dependencies.py +31 -20
  2. src/db/firebase.py +25 -14
  3. test_gen.py +25 -0
  4. test_verify.py +29 -0
src/auth/dependencies.py CHANGED
@@ -21,43 +21,54 @@ from firebase_admin import auth as firebase_auth
21
  from src.db.firebase import verify_token
22
 
23
 
 
 
 
24
  async def get_current_user(
25
  token: str = Depends(oauth2_scheme)
26
  ) -> User:
27
  """
28
- Get the currently authenticated user with improved error reporting.
29
  """
30
  db = get_firebase_db()
31
  firebase_error = None
 
32
 
33
  # Log token prefix for debugging
34
  token_prefix = token[:10] if token else "None"
35
- logger.info(f"Received token starting with: {token_prefix}...")
36
 
37
  # 1. Try Firebase Verification
38
  try:
 
 
 
 
 
 
 
 
 
 
39
  firebase_result = verify_token(token)
40
- # Log type for absolute certainty
41
- logger.info(f"[v4] Firebase result type: {type(firebase_result)}")
42
 
43
  if not isinstance(firebase_result, dict):
44
- firebase_error = f"[v4] Internal Error [CP0]: verify_token returned {type(firebase_result)}"
45
  firebase_payload = None
46
  else:
47
  firebase_payload = firebase_result.get("payload")
48
  firebase_error = firebase_result.get("error")
49
 
50
- # CHANGED: Use explicit None check to handle empty dicts {} which are falsy
51
  if firebase_payload is not None:
52
  uid = firebase_payload.get("uid")
53
  email = firebase_payload.get("email")
54
  if not uid:
55
- logger.error("[v4] Firebase payload missing 'uid' [CP1]")
56
- # Adding full payload string to help debug if it's truly empty
57
- raise HTTPException(status_code=401, detail=f"Invalid Firebase token payload [CP1-v4]. Payload: {str(firebase_payload)}")
58
 
59
  if db is None:
60
- logger.warning(f"[v4] Firestore not available, returning transient user for {email} [CP2]")
61
  return User(id=uid, email=email or "unknown@example.com", username=firebase_payload.get("name", uid), role="user")
62
 
63
  # Retrieve from Firestore
@@ -71,7 +82,7 @@ async def get_current_user(
71
  user_data.setdefault("role", user_data.get("role", "user"))
72
  return User(**user_data)
73
  else:
74
- logger.info(f"[v4] New Firebase user detected: {email or uid} [CP3]")
75
  return User(
76
  id=uid,
77
  email=email or "unknown@example.com",
@@ -82,8 +93,8 @@ async def get_current_user(
82
  except HTTPException:
83
  raise
84
  except Exception as e:
85
- logger.error(f"[v4] Unexpected error in Firebase auth path: {repr(e)} [CP4]")
86
- firebase_error = f"Exception [CP4-v4]: {repr(e)}"
87
 
88
  # 2. Fallback to Custom JWT Decoding
89
  try:
@@ -91,7 +102,7 @@ async def get_current_user(
91
  if payload:
92
  username: Optional[str] = payload.get("sub")
93
  if not username:
94
- raise HTTPException(status_code=401, detail="Token missing subject claim [CP5-v4]")
95
 
96
  if db is None:
97
  return User(id="mock_id", email="mock@example.com", username=username, password_hash="mock", role="user")
@@ -105,18 +116,18 @@ async def get_current_user(
105
  user_data["id"] = user_doc.id
106
  return User(**user_data)
107
  else:
108
- logger.error(f"[v4] User {username} not found in database [CP6]")
109
- raise HTTPException(status_code=401, detail="User account not found [CP6-v4]")
110
  except HTTPException:
111
  raise
112
  except Exception as e:
113
- logger.error(f"[v4] Unexpected error in custom JWT auth path: {repr(e)} [CP7]")
114
 
115
  # If both failed, then it's a 401
116
- fb_diag = f"Firebase(v4): {firebase_error if firebase_error else f'Payload is {type(firebase_payload)}({str(firebase_payload)})'}"
117
- error_detail = f"Auth Failure [CP8-v4] | Token: {token_prefix}... | {fb_diag}"
118
 
119
- logger.error(f"Authentication failed (v4): {error_detail}")
120
  raise HTTPException(
121
  status_code=status.HTTP_401_UNAUTHORIZED,
122
  detail=error_detail,
 
21
  from src.db.firebase import verify_token
22
 
23
 
24
+ import inspect
25
+ import time
26
+
27
  async def get_current_user(
28
  token: str = Depends(oauth2_scheme)
29
  ) -> User:
30
  """
31
+ Get the currently authenticated user with extreme diagnostic introspection (v5).
32
  """
33
  db = get_firebase_db()
34
  firebase_error = None
35
+ session_id = str(int(time.time()))[-4:] # Last 4 digits of timestamp
36
 
37
  # Log token prefix for debugging
38
  token_prefix = token[:10] if token else "None"
39
+ logger.info(f"[v5-{session_id}] Received token {token_prefix}...")
40
 
41
  # 1. Try Firebase Verification
42
  try:
43
+ # INTROSPECTION: Where does verify_token come from?
44
+ vt_file = "Unknown"
45
+ try:
46
+ vt_file = inspect.getfile(verify_token)
47
+ except:
48
+ pass
49
+ vt_module = getattr(verify_token, "__module__", "Unknown")
50
+
51
+ logger.info(f"[v5-{session_id}] Calling verify_token from {vt_module} ({vt_file})")
52
+
53
  firebase_result = verify_token(token)
54
+ logger.info(f"[v5-{session_id}] Firebase result type: {type(firebase_result)}")
 
55
 
56
  if not isinstance(firebase_result, dict):
57
+ firebase_error = f"[v5] Internal Error [CP0]: verify_token returned {type(firebase_result)} (Expected dict)"
58
  firebase_payload = None
59
  else:
60
  firebase_payload = firebase_result.get("payload")
61
  firebase_error = firebase_result.get("error")
62
 
 
63
  if firebase_payload is not None:
64
  uid = firebase_payload.get("uid")
65
  email = firebase_payload.get("email")
66
  if not uid:
67
+ logger.error(f"[v5-{session_id}] Firebase payload missing 'uid' [CP1]")
68
+ raise HTTPException(status_code=401, detail=f"Invalid Firebase token payload [CP1-v5]. Payload keys: {list(firebase_payload.keys())}")
 
69
 
70
  if db is None:
71
+ logger.warning(f"[v5-{session_id}] Firestore not available, returning transient user for {email} [CP2]")
72
  return User(id=uid, email=email or "unknown@example.com", username=firebase_payload.get("name", uid), role="user")
73
 
74
  # Retrieve from Firestore
 
82
  user_data.setdefault("role", user_data.get("role", "user"))
83
  return User(**user_data)
84
  else:
85
+ logger.info(f"[v5-{session_id}] New Firebase user detected: {email or uid} [CP3]")
86
  return User(
87
  id=uid,
88
  email=email or "unknown@example.com",
 
93
  except HTTPException:
94
  raise
95
  except Exception as e:
96
+ logger.error(f"[v5-{session_id}] Unexpected error in Firebase auth path: {repr(e)} [CP4]")
97
+ firebase_error = f"Exception [CP4-v5]: {repr(e)}"
98
 
99
  # 2. Fallback to Custom JWT Decoding
100
  try:
 
102
  if payload:
103
  username: Optional[str] = payload.get("sub")
104
  if not username:
105
+ raise HTTPException(status_code=401, detail="Token missing subject claim [CP5-v5]")
106
 
107
  if db is None:
108
  return User(id="mock_id", email="mock@example.com", username=username, password_hash="mock", role="user")
 
116
  user_data["id"] = user_doc.id
117
  return User(**user_data)
118
  else:
119
+ logger.error(f"[v5-{session_id}] User {username} not found in database [CP6]")
120
+ raise HTTPException(status_code=401, detail="User account not found [CP6-v5]")
121
  except HTTPException:
122
  raise
123
  except Exception as e:
124
+ logger.error(f"[v5-{session_id}] Unexpected error in custom JWT auth path: {repr(e)} [CP7]")
125
 
126
  # If both failed, then it's a 401
127
+ fb_diag = f"Firebase(v5-{session_id}): {firebase_error if firebase_error else f'Payload is {type(firebase_payload)}({str(firebase_payload)})'}"
128
+ error_detail = f"Auth Failure [CP8-v5] | Token: {token_prefix}... | {fb_diag}"
129
 
130
+ logger.error(f"Authentication failed (v5): {error_detail}")
131
  raise HTTPException(
132
  status_code=status.HTTP_401_UNAUTHORIZED,
133
  detail=error_detail,
src/db/firebase.py CHANGED
@@ -26,11 +26,16 @@ def get_firebase_db():
26
  import json
27
  service_account_info = json.loads(settings.firebase_service_account_json)
28
  cred = credentials.Certificate(service_account_info)
 
 
 
 
29
  firebase_admin.initialize_app(cred, {
30
- 'storageBucket': settings.firebase_storage_bucket
 
31
  })
32
  _db = firestore.client()
33
- logger.info("Firebase initialized successfully using environment variable JSON.")
34
  return _db
35
 
36
  # Priority 2: Check for service account file
@@ -42,11 +47,12 @@ def get_firebase_db():
42
 
43
  cred = credentials.Certificate(str(service_account_path))
44
  firebase_admin.initialize_app(cred, {
45
- 'storageBucket': settings.firebase_storage_bucket
 
46
  })
47
 
48
  _db = firestore.client()
49
- logger.info("Firebase initialized successfully using service account file.")
50
  return _db
51
  except Exception as e:
52
  logger.error(f"Failed to initialize Firebase: {e}")
@@ -54,23 +60,28 @@ def get_firebase_db():
54
 
55
  def verify_token(id_token: str):
56
  """
57
- Verify a Firebase ID token with detailed error logging.
 
58
  """
59
  try:
60
  # Check if any app is initialized, if not try to initialize
61
  if not firebase_admin._apps:
62
- logger.warning("Firebase app not initialized. Attempting default initialization...")
63
  get_firebase_db()
64
 
65
  if not firebase_admin._apps:
66
- logger.error("Firebase app could not be initialized. Cannot verify token.")
67
- return None
68
 
 
69
  decoded_token = auth.verify_id_token(id_token)
70
- return decoded_token
 
 
 
 
 
 
71
  except Exception as e:
72
- logger.error(f"Firebase token verification failed: {str(e)}")
73
- # Log more info about the token context if possible (length, etc)
74
- if id_token:
75
- logger.debug(f"Token length: {len(id_token)}, starts with: {id_token[:10]}...")
76
- return None
 
26
  import json
27
  service_account_info = json.loads(settings.firebase_service_account_json)
28
  cred = credentials.Certificate(service_account_info)
29
+
30
+ # Explicitly extract project_id from JSON if possible
31
+ project_id = service_account_info.get('project_id') or settings.firebase_project_id
32
+
33
  firebase_admin.initialize_app(cred, {
34
+ 'storageBucket': settings.firebase_storage_bucket,
35
+ 'projectId': project_id
36
  })
37
  _db = firestore.client()
38
+ logger.info(f"Firebase initialized successfully for project: {project_id} (using JSON)")
39
  return _db
40
 
41
  # Priority 2: Check for service account file
 
47
 
48
  cred = credentials.Certificate(str(service_account_path))
49
  firebase_admin.initialize_app(cred, {
50
+ 'storageBucket': settings.firebase_storage_bucket,
51
+ 'projectId': settings.firebase_project_id
52
  })
53
 
54
  _db = firestore.client()
55
+ logger.info(f"Firebase initialized successfully for project: {settings.firebase_project_id} (using file)")
56
  return _db
57
  except Exception as e:
58
  logger.error(f"Failed to initialize Firebase: {e}")
 
60
 
61
  def verify_token(id_token: str):
62
  """
63
+ Verify a Firebase ID token with v5 absolute diagnostic clarity.
64
+ Returns: {"payload": decoded_token, "error": error_message}
65
  """
66
  try:
67
  # Check if any app is initialized, if not try to initialize
68
  if not firebase_admin._apps:
69
+ logger.warning("[v5] Firebase app not initialized. Attempting default initialization...")
70
  get_firebase_db()
71
 
72
  if not firebase_admin._apps:
73
+ return {"payload": None, "error": "[v5] Firebase app could not be initialized."}
 
74
 
75
+ # The core SDK call
76
  decoded_token = auth.verify_id_token(id_token)
77
+
78
+ if decoded_token is None:
79
+ logger.error("[v5] auth.verify_id_token returned None unexpectedly.")
80
+ return {"payload": None, "error": "[v5] Firebase SDK returned None for token verification."}
81
+
82
+ logger.info(f"[v5] Firebase token successfully verified for UID: {decoded_token.get('uid')}")
83
+ return {"payload": decoded_token, "error": None}
84
  except Exception as e:
85
+ error_msg = f"[v5] Exception during verify_id_token: {repr(e)}"
86
+ logger.error(error_msg)
87
+ return {"payload": None, "error": error_msg}
 
 
test_gen.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ from pathlib import Path
4
+
5
+ # Add project root to path
6
+ sys.path.append(str(Path(__file__).parent))
7
+
8
+ from src.summarization.note_generator import NoteGenerator
9
+ from src.utils.config import settings
10
+
11
+ def test_note_generator():
12
+ print("Testing NoteGenerator initialization after fix...")
13
+ try:
14
+ # We need an API key for initialization if it's not in env
15
+ api_key = os.getenv("GOOGLE_API_KEY", "dummy_key")
16
+ gen = NoteGenerator(api_key=api_key)
17
+ print("✅ Initialization successful")
18
+ print(f"Model ID: {gen.model_id}")
19
+ except Exception as e:
20
+ print(f"❌ Initialization failed: {e}")
21
+ import traceback
22
+ traceback.print_exc()
23
+
24
+ if __name__ == "__main__":
25
+ test_note_generator()
test_verify.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ # Add src to path
5
+ sys.path.append(str(Path(__file__).parent))
6
+
7
+ from src.db.firebase import verify_token
8
+ import firebase_admin
9
+
10
+ def test_verify():
11
+ print("Testing verify_token with invalid token...")
12
+ # This should return a dict with error and no payload
13
+ result = verify_token("invalid_token")
14
+ print(f"Result type: {type(result)}")
15
+ print(f"Result content: {result}")
16
+
17
+ if isinstance(result, dict):
18
+ payload = result.get("payload")
19
+ error = result.get("error")
20
+ print(f"Payload: {payload} (Type: {type(payload)})")
21
+ print(f"Error: {error} (Type: {type(error)})")
22
+
23
+ if not payload:
24
+ print("Payload is falsy")
25
+ if not error:
26
+ print("Error is falsy")
27
+
28
+ if __name__ == "__main__":
29
+ test_verify()