rairo commited on
Commit
f4b8e9e
·
verified ·
1 Parent(s): 1f0d5e7

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +74 -0
main.py CHANGED
@@ -264,6 +264,80 @@ def get_single_user(target_uid):
264
  logging.error(f"Admin failed to fetch user {target_uid}: {e}")
265
  return jsonify({'error': 'An internal error occurred'}), 500
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  @app.route('/api/admin/users/<string:target_uid>', methods=['PUT'])
268
  def admin_update_user(target_uid):
269
  """Admin: Update a user's profile information."""
 
264
  logging.error(f"Admin failed to fetch user {target_uid}: {e}")
265
  return jsonify({'error': 'An internal error occurred'}), 500
266
 
267
+ @app.route('/api/admin/users', methods=['POST'])
268
+ def admin_create_user():
269
+ """Admin: Create a new user with email, password, and profile information."""
270
+ try:
271
+ verify_admin_and_get_uid(request.headers.get('Authorization'))
272
+ data = request.get_json()
273
+
274
+ # Validate required fields
275
+ if not data or 'email' not in data or 'password' not in data:
276
+ return jsonify({'error': 'Email and password are required'}), 400
277
+
278
+ email = data['email']
279
+ password = data['password']
280
+
281
+ # Optional fields with defaults
282
+ display_name = data.get('displayName', '')
283
+ phone = data.get('phone', '')
284
+ is_admin = data.get('isAdmin', False)
285
+
286
+ # Create user in Firebase Auth
287
+ user_record = auth.create_user(
288
+ email=email,
289
+ password=password,
290
+ display_name=display_name if display_name else None
291
+ )
292
+
293
+ # Create user document in Firestore
294
+ user_data_for_db = {
295
+ 'uid': user_record.uid,
296
+ 'email': email,
297
+ 'displayName': display_name,
298
+ 'phone': phone,
299
+ 'isAdmin': is_admin,
300
+ 'phoneStatus': 'unsubmitted',
301
+ 'organizationId': None,
302
+ 'createdAt': firestore.SERVER_TIMESTAMP,
303
+ 'updatedAt': firestore.SERVER_TIMESTAMP
304
+ }
305
+
306
+ db.collection('users').document(user_record.uid).set(user_data_for_db)
307
+
308
+ logging.info(f"Admin created new user {user_record.uid} with email {email}")
309
+
310
+ # Create separate dictionary for JSON response with JSON-friendly timestamps
311
+ response_data = user_data_for_db.copy()
312
+ current_time = datetime.utcnow().isoformat() + "Z"
313
+ response_data['createdAt'] = current_time
314
+ response_data['updatedAt'] = current_time
315
+
316
+ return jsonify({
317
+ 'success': True,
318
+ 'message': 'User created successfully',
319
+ 'user': response_data
320
+ }), 201
321
+
322
+ except auth.EmailAlreadyExistsError:
323
+ return jsonify({'error': 'A user with this email already exists'}), 409
324
+ except auth.WeakPasswordError:
325
+ return jsonify({'error': 'Password is too weak. Must be at least 6 characters'}), 400
326
+ except auth.InvalidEmailError:
327
+ return jsonify({'error': 'Invalid email format'}), 400
328
+ except PermissionError as e:
329
+ return jsonify({'error': str(e)}), 403
330
+ except Exception as e:
331
+ logging.error(f"Admin failed to create user: {e}", exc_info=True)
332
+ # Handle JSON serialization error from SERVER_TIMESTAMP
333
+ if 'Object of type Sentinel is not JSON serializable' in str(e):
334
+ return jsonify({
335
+ 'success': True,
336
+ 'message': 'User created successfully, but response generation had a minor issue.',
337
+ 'uid': user_record.uid if 'user_record' in locals() else None
338
+ }), 201
339
+ return jsonify({'error': 'An internal error occurred during user creation'}), 500
340
+
341
  @app.route('/api/admin/users/<string:target_uid>', methods=['PUT'])
342
  def admin_update_user(target_uid):
343
  """Admin: Update a user's profile information."""