Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Update backend_structured/routes.py
Browse files- backend_structured/routes.py +79 -17
backend_structured/routes.py
CHANGED
|
@@ -1018,23 +1018,85 @@ def impersonate_org(current_user, org_id):
|
|
| 1018 |
}
|
| 1019 |
}), 200
|
| 1020 |
|
| 1021 |
-
@auth_bp.route('/users', methods=['GET'])
|
| 1022 |
-
@
|
| 1023 |
-
def
|
| 1024 |
-
|
| 1025 |
-
|
| 1026 |
-
|
| 1027 |
-
|
| 1028 |
-
|
| 1029 |
-
|
| 1030 |
-
|
| 1031 |
-
|
| 1032 |
-
|
| 1033 |
-
|
| 1034 |
-
'
|
| 1035 |
-
|
| 1036 |
-
|
| 1037 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1038 |
|
| 1039 |
|
| 1040 |
@auth_bp.route('/email-logs', methods=['GET'])
|
|
|
|
| 1018 |
}
|
| 1019 |
}), 200
|
| 1020 |
|
| 1021 |
+
@auth_bp.route('/users', methods=['GET', 'POST'])
|
| 1022 |
+
@token_required
|
| 1023 |
+
def manage_users(current_user):
|
| 1024 |
+
if current_user.role not in ('super_admin', 'admin'):
|
| 1025 |
+
return jsonify({'message': 'Permission denied'}), 403
|
| 1026 |
+
|
| 1027 |
+
if request.method == 'GET':
|
| 1028 |
+
if current_user.role == 'admin':
|
| 1029 |
+
users = User.query.filter(User.role != 'super_admin').all()
|
| 1030 |
+
else:
|
| 1031 |
+
users = User.query.all()
|
| 1032 |
+
|
| 1033 |
+
return jsonify({
|
| 1034 |
+
'users': [{
|
| 1035 |
+
'id': u.id,
|
| 1036 |
+
'email': u.email,
|
| 1037 |
+
'role': u.role,
|
| 1038 |
+
'org_id': u.org_id,
|
| 1039 |
+
'first_name': u.first_name,
|
| 1040 |
+
'last_name': u.last_name,
|
| 1041 |
+
'created_at': u.created_at.isoformat() + 'Z' if u.created_at else None,
|
| 1042 |
+
'failed_login_attempts': u.failed_login_attempts or 0,
|
| 1043 |
+
'locked_until': u.locked_until.isoformat() + 'Z' if u.locked_until else None,
|
| 1044 |
+
'status': 'Active' if getattr(u, 'is_active', True) else 'Suspended'
|
| 1045 |
+
} for u in users]
|
| 1046 |
+
}), 200
|
| 1047 |
+
|
| 1048 |
+
# POST method - Create/Add new member
|
| 1049 |
+
data = request.get_json() or {}
|
| 1050 |
+
email = data.get('email')
|
| 1051 |
+
role = data.get('role', 'admin')
|
| 1052 |
+
org_id = data.get('org_id')
|
| 1053 |
+
password = data.get('password')
|
| 1054 |
+
|
| 1055 |
+
if not email or not str(email).strip():
|
| 1056 |
+
return jsonify({'message': 'User email is required'}), 400
|
| 1057 |
+
|
| 1058 |
+
email_clean = str(email).strip().lower()
|
| 1059 |
+
existing = User.query.filter_by(email=email_clean).first()
|
| 1060 |
+
if existing:
|
| 1061 |
+
return jsonify({'message': f'User with email "{email_clean}" already exists'}), 400
|
| 1062 |
+
|
| 1063 |
+
import secrets, uuid
|
| 1064 |
+
temp_pw = password if password else secrets.token_urlsafe(10)
|
| 1065 |
+
|
| 1066 |
+
target_org_id = None
|
| 1067 |
+
if org_id and str(org_id).strip() and str(org_id).lower() not in ('none', 'null', ''):
|
| 1068 |
+
org = db.session.get(Organization, org_id)
|
| 1069 |
+
if org:
|
| 1070 |
+
target_org_id = org.id
|
| 1071 |
+
|
| 1072 |
+
try:
|
| 1073 |
+
new_user = User(
|
| 1074 |
+
id=str(uuid.uuid4()),
|
| 1075 |
+
email=email_clean,
|
| 1076 |
+
role=role,
|
| 1077 |
+
org_id=target_org_id
|
| 1078 |
+
)
|
| 1079 |
+
new_user.set_password(temp_pw)
|
| 1080 |
+
db.session.add(new_user)
|
| 1081 |
+
|
| 1082 |
+
log = AuditLog(admin_id=current_user.id, action=f"Created new member {email_clean} ({role})", target_id=target_org_id or current_user.id)
|
| 1083 |
+
db.session.add(log)
|
| 1084 |
+
db.session.commit()
|
| 1085 |
+
|
| 1086 |
+
return jsonify({
|
| 1087 |
+
'message': 'Member added successfully',
|
| 1088 |
+
'temp_password': temp_pw,
|
| 1089 |
+
'user': {
|
| 1090 |
+
'id': new_user.id,
|
| 1091 |
+
'email': new_user.email,
|
| 1092 |
+
'role': new_user.role,
|
| 1093 |
+
'org_id': new_user.org_id
|
| 1094 |
+
}
|
| 1095 |
+
}), 201
|
| 1096 |
+
except Exception as e:
|
| 1097 |
+
db.session.rollback()
|
| 1098 |
+
current_app.logger.error(f"Error adding member: {e}")
|
| 1099 |
+
return jsonify({'message': f'Failed to add member: {str(e)}'}), 500
|
| 1100 |
|
| 1101 |
|
| 1102 |
@auth_bp.route('/email-logs', methods=['GET'])
|