Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -1266,6 +1266,128 @@ def process_credit_request(request_id):
|
|
| 1266 |
except Exception as e:
|
| 1267 |
return jsonify({'error': str(e)}), 500
|
| 1268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1269 |
# ---------- Admin Endpoint to Directly Update Credits ----------
|
| 1270 |
@app.route('/api/admin/users/<string:uid>/credits', methods=['PUT'])
|
| 1271 |
def admin_update_credits(uid):
|
|
|
|
| 1266 |
except Exception as e:
|
| 1267 |
return jsonify({'error': str(e)}), 500
|
| 1268 |
|
| 1269 |
+
|
| 1270 |
+
@app.route('/api/admin/users', methods=['GET'])
|
| 1271 |
+
def admin_list_users():
|
| 1272 |
+
try:
|
| 1273 |
+
verify_admin(request.headers.get('Authorization', ''))
|
| 1274 |
+
|
| 1275 |
+
users_ref = db.reference('users')
|
| 1276 |
+
all_users = users_ref.get() or {}
|
| 1277 |
+
|
| 1278 |
+
# Convert dict to a list of { uid, ...data }
|
| 1279 |
+
user_list = []
|
| 1280 |
+
for uid, user_data in all_users.items():
|
| 1281 |
+
user_list.append({
|
| 1282 |
+
'uid': uid,
|
| 1283 |
+
'email': user_data.get('email'),
|
| 1284 |
+
'credits': user_data.get('credits', 0),
|
| 1285 |
+
'is_admin': user_data.get('is_admin', False),
|
| 1286 |
+
'created_at': user_data.get('created_at', ''),
|
| 1287 |
+
'suspended': user_data.get('suspended', False)
|
| 1288 |
+
})
|
| 1289 |
+
|
| 1290 |
+
return jsonify({'users': user_list}), 200
|
| 1291 |
+
except Exception as e:
|
| 1292 |
+
return jsonify({'error': str(e)}), 500
|
| 1293 |
+
|
| 1294 |
+
@app.route('/api/admin/users/search', methods=['GET'])
|
| 1295 |
+
def admin_search_users():
|
| 1296 |
+
try:
|
| 1297 |
+
verify_admin(request.headers.get('Authorization', ''))
|
| 1298 |
+
email_query = request.args.get('email', '').lower().strip()
|
| 1299 |
+
if not email_query:
|
| 1300 |
+
return jsonify({'error': 'email query param is required'}), 400
|
| 1301 |
+
|
| 1302 |
+
users_ref = db.reference('users')
|
| 1303 |
+
all_users = users_ref.get() or {}
|
| 1304 |
+
|
| 1305 |
+
matched_users = []
|
| 1306 |
+
for uid, user_data in all_users.items():
|
| 1307 |
+
user_email = user_data.get('email', '').lower()
|
| 1308 |
+
# If you want partial match, do `if email_query in user_email:`
|
| 1309 |
+
# If you want exact match, do `if user_email == email_query:`
|
| 1310 |
+
if email_query in user_email:
|
| 1311 |
+
matched_users.append({
|
| 1312 |
+
'uid': uid,
|
| 1313 |
+
'email': user_data.get('email'),
|
| 1314 |
+
'credits': user_data.get('credits', 0),
|
| 1315 |
+
'is_admin': user_data.get('is_admin', False),
|
| 1316 |
+
'created_at': user_data.get('created_at', ''),
|
| 1317 |
+
'suspended': user_data.get('suspended', False)
|
| 1318 |
+
})
|
| 1319 |
+
|
| 1320 |
+
return jsonify({'matched_users': matched_users}), 200
|
| 1321 |
+
except Exception as e:
|
| 1322 |
+
return jsonify({'error': str(e)}), 500
|
| 1323 |
+
|
| 1324 |
+
@app.route('/api/admin/users/<string:uid>/suspend', methods=['PUT'])
|
| 1325 |
+
def admin_suspend_user(uid):
|
| 1326 |
+
try:
|
| 1327 |
+
verify_admin(request.headers.get('Authorization', ''))
|
| 1328 |
+
data = request.get_json()
|
| 1329 |
+
action = data.get('action') # "suspend" or "unsuspend"
|
| 1330 |
+
|
| 1331 |
+
if action not in ["suspend", "unsuspend"]:
|
| 1332 |
+
return jsonify({'error': 'action must be "suspend" or "unsuspend"'}), 400
|
| 1333 |
+
|
| 1334 |
+
user_ref = db.reference(f'users/{uid}')
|
| 1335 |
+
user_data = user_ref.get()
|
| 1336 |
+
if not user_data:
|
| 1337 |
+
return jsonify({'error': 'User not found'}), 404
|
| 1338 |
+
|
| 1339 |
+
if action == "suspend":
|
| 1340 |
+
user_ref.update({'suspended': True})
|
| 1341 |
+
else:
|
| 1342 |
+
user_ref.update({'suspended': False})
|
| 1343 |
+
|
| 1344 |
+
return jsonify({'success': True, 'message': f'User {uid} is now {action}ed'})
|
| 1345 |
+
except Exception as e:
|
| 1346 |
+
return jsonify({'error': str(e)}), 500
|
| 1347 |
+
|
| 1348 |
+
@app.route('/api/admin/stories', methods=['GET'])
|
| 1349 |
+
def admin_list_stories():
|
| 1350 |
+
try:
|
| 1351 |
+
verify_admin(request.headers.get('Authorization', ''))
|
| 1352 |
+
|
| 1353 |
+
stories_ref = db.reference('stories')
|
| 1354 |
+
all_stories = stories_ref.get() or {}
|
| 1355 |
+
total_stories = len(all_stories)
|
| 1356 |
+
|
| 1357 |
+
# If you want to see how many stories each user has, do:
|
| 1358 |
+
stories_per_user = {}
|
| 1359 |
+
for sid, sdata in all_stories.items():
|
| 1360 |
+
user_id = sdata.get('uid')
|
| 1361 |
+
if user_id:
|
| 1362 |
+
stories_per_user[user_id] = stories_per_user.get(user_id, 0) + 1
|
| 1363 |
+
|
| 1364 |
+
return jsonify({
|
| 1365 |
+
'total_stories': total_stories,
|
| 1366 |
+
'stories_per_user': stories_per_user
|
| 1367 |
+
}), 200
|
| 1368 |
+
except Exception as e:
|
| 1369 |
+
return jsonify({'error': str(e)}), 500
|
| 1370 |
+
|
| 1371 |
+
@app.route('/api/admin/reset-password', methods=['PUT'])
|
| 1372 |
+
def admin_reset_own_password():
|
| 1373 |
+
try:
|
| 1374 |
+
auth_header = request.headers.get('Authorization', '')
|
| 1375 |
+
admin_uid = verify_admin(auth_header) # Ensure caller is an admin
|
| 1376 |
+
if not admin_uid:
|
| 1377 |
+
return jsonify({'error': 'Unauthorized: Admin access required'}), 401
|
| 1378 |
+
|
| 1379 |
+
data = request.get_json()
|
| 1380 |
+
new_password = data.get('new_password')
|
| 1381 |
+
if not new_password:
|
| 1382 |
+
return jsonify({'error': 'new_password is required'}), 400
|
| 1383 |
+
|
| 1384 |
+
# Use Firebase Admin SDK to update admin password
|
| 1385 |
+
auth.update_user(admin_uid, password=new_password)
|
| 1386 |
+
|
| 1387 |
+
return jsonify({'success': True, 'message': 'Password updated successfully.'})
|
| 1388 |
+
except Exception as e:
|
| 1389 |
+
return jsonify({'error': str(e)}), 500
|
| 1390 |
+
|
| 1391 |
# ---------- Admin Endpoint to Directly Update Credits ----------
|
| 1392 |
@app.route('/api/admin/users/<string:uid>/credits', methods=['PUT'])
|
| 1393 |
def admin_update_credits(uid):
|