rairo commited on
Commit
cc4c695
·
verified ·
1 Parent(s): 785ccbb

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +20 -64
main.py CHANGED
@@ -184,16 +184,27 @@ def send_rotation_notification(job_id, shift_record):
184
  # === Auth Middleware ===
185
  def verify_token(req):
186
  """
187
- Verify Firebase ID token and check if user is admin.
188
- Automatically creates admin entry in DB if email is in ADMIN_EMAILS but UID is not found.
189
- Uses Firebase Admin SDK to get user email if not directly available in token or DB.
190
  Returns decoded token dict if valid admin, None otherwise.
191
  """
192
  auth_header = req.headers.get("Authorization")
 
 
 
193
  if not auth_header:
194
  print("Authorization header missing.")
195
  return None
196
 
 
 
 
 
 
 
 
 
 
197
  try:
198
  # Extract token
199
  if auth_header.startswith("Bearer "):
@@ -201,69 +212,14 @@ def verify_token(req):
201
  else:
202
  token = auth_header.strip()
203
 
204
- # Verify the token to get the UID
205
  decoded = firebase_auth.verify_id_token(token)
206
- # print(f"DEBUG: Token verified successfully. Decoded token keys: {list(decoded.keys())}") # Optional debug
207
-
208
- # Get user UID from decoded token
209
- uid = decoded.get('uid') or decoded.get('user_id') # Fallback for robustness
210
- # print(f"DEBUG: Extracted UID: {uid}") # Optional debug
211
-
212
- if not uid:
213
- print("Verified token does not contain a UID or user_id.")
214
- return None
215
-
216
- # --- Core Logic Change Starts Here ---
217
-
218
- # 1. Check if user is admin by querying Firebase Realtime Database using UID first
219
- admins_ref = db.reference("/admins")
220
- admin_data_db = admins_ref.child(uid).get()
221
- # print(f"DEBUG: Admin data retrieved for UID {uid}: {admin_data_db}") # Optional debug
222
-
223
- if admin_data_db and admin_data_db.get("is_admin", False):
224
- # User is already an admin in the database
225
- email_for_logging = admin_data_db.get("email", "Unknown Email")
226
- print(f"User {uid} ({email_for_logging}) is authorized as admin (found in DB).")
227
- return decoded
228
-
229
- # 2. If not found in DB, get the user's email using the Firebase Admin SDK
230
- email = None
231
- try:
232
- user_record = firebase_auth.get_user(uid)
233
- email = user_record.email
234
- # print(f"DEBUG: Email retrieved via Firebase Admin SDK for UID {uid}: {email}") # Optional debug
235
- except firebase_auth.UserNotFoundError:
236
- print(f"User with UID {uid} not found in Firebase Authentication.")
237
- return None
238
- except Exception as e:
239
- print(f"Error fetching user details for UID {uid} from Firebase Auth: {e}")
240
- # Cannot reliably verify email, deny access
241
- return None
242
-
243
- # 3. Check if the retrieved email is in the approved ADMIN_EMAILS list
244
- if email and email in ADMIN_EMAILS:
245
- # User's email is in the approved list, but UID not found in DB.
246
- # This is likely their first time accessing the API.
247
- # Automatically create their admin entry in the Realtime Database using their UID.
248
- print(f"First time admin access for {email} (UID: {uid}). Creating database entry.")
249
- try:
250
- admins_ref.child(uid).set({
251
- "email": email,
252
- "is_admin": True
253
- })
254
- print(f"Admin entry successfully created for UID {uid}.")
255
- # User is now an admin, grant access
256
- return decoded
257
- except Exception as db_error:
258
- print(f"Failed to create admin entry for UID {uid} in database: {db_error}")
259
- # Failed to record admin status, deny access for security
260
- return None
261
- else:
262
- # User's email is not in the approved list or email could not be retrieved/verified
263
- print(f"Access denied for UID {uid}. Email '{email}' not in approved list or not retrievable.")
264
- return None
265
 
266
- # --- Core Logic Change Ends Here ---
 
267
 
268
  except firebase_auth.InvalidIdTokenError as e:
269
  print(f"Invalid Firebase ID token provided: {e}")
 
184
  # === Auth Middleware ===
185
  def verify_token(req):
186
  """
187
+ Verify Firebase ID token and check if user's email is in ADMIN_EMAILS.
188
+ Email is expected in the 'X-User-Email' header, sent by the client.
 
189
  Returns decoded token dict if valid admin, None otherwise.
190
  """
191
  auth_header = req.headers.get("Authorization")
192
+ # NEW: Get email from custom header sent by client
193
+ user_email = req.headers.get("X-User-Email")
194
+
195
  if not auth_header:
196
  print("Authorization header missing.")
197
  return None
198
 
199
+ # NEW: Check if email header is present and valid
200
+ if not user_email:
201
+ logging.info("X-User-Email header missing from request.")
202
+ return None
203
+
204
+ if user_email not in ADMIN_EMAILS:
205
+ logging.info(f"Email {user_email} from X-User-Email header not found in ADMIN_EMAILS list.")
206
+ return None
207
+
208
  try:
209
  # Extract token
210
  if auth_header.startswith("Bearer "):
 
212
  else:
213
  token = auth_header.strip()
214
 
215
+ # Verify the token (ensures token is genuine and user is authenticated)
216
  decoded = firebase_auth.verify_id_token(token)
217
+ # Note: We are not checking the UID against the database anymore.
218
+ # We are trusting the email provided by the client, verified against ADMIN_EMAILS.
219
+ # The token verification ensures the request is from a logged-in user.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
+ logging.info(f"User with email {user_email} (UID: {decoded.get('uid')}) is authorized as admin (email in ADMIN_EMAILS).")
222
+ return decoded # Return decoded token if needed by other parts of the app
223
 
224
  except firebase_auth.InvalidIdTokenError as e:
225
  print(f"Invalid Firebase ID token provided: {e}")