-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadmin_config.py
More file actions
251 lines (203 loc) · 8.67 KB
/
admin_config.py
File metadata and controls
251 lines (203 loc) · 8.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/usr/bin/env python3
"""
Admin Configuration and Authentication System for UnForkRAG
This module provides:
- Admin user management with secure password hashing
- Environment-based configuration
- Authentication middleware for admin endpoints
- Default admin credentials setup
"""
import os
import json
import hashlib
import secrets
from typing import Dict, Optional, List
from datetime import datetime, timedelta
class AdminConfig:
"""Admin configuration and user management"""
def __init__(self, config_file: str = "admin_config.json"):
self.config_file = config_file
self.config = self._load_config()
def _load_config(self) -> Dict:
"""Load admin configuration from file or create defaults"""
if os.path.exists(self.config_file):
try:
with open(self.config_file, 'r') as f:
return json.load(f)
except Exception as e:
print(f"Warning: Could not load admin config: {e}")
# Create default configuration
return self._create_default_config()
def _create_default_config(self) -> Dict:
"""Create default admin configuration with secure defaults"""
default_config = {
"admin_enabled": True,
"admin_users": {
"admin": {
"password_hash": self._hash_password("admin123"), # Default password
"created_at": datetime.now().isoformat(),
"last_login": None,
"is_active": True,
"roles": ["admin"]
}
},
"security": {
"session_timeout": 3600, # 1 hour
"max_login_attempts": 5,
"lockout_duration": 900, # 15 minutes
"require_https": False
},
"monitoring": {
"log_admin_access": True,
"log_failed_logins": True,
"max_log_entries": 1000
}
}
# Save default config
self._save_config(default_config)
print("⚠️ WARNING: Default admin credentials created!")
print(" Username: admin")
print(" Password: admin123")
print(" Please change the password immediately!")
print(f" Config file: {self.config_file}")
return default_config
def _save_config(self, config: Dict):
"""Save configuration to file"""
try:
with open(self.config_file, 'w') as f:
json.dump(config, f, indent=2)
except Exception as e:
print(f"Error saving admin config: {e}")
def _hash_password(self, password: str) -> str:
"""Create a secure hash of the password"""
# Use SHA-256 with a random salt
salt = secrets.token_hex(16)
password_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100000)
return f"{salt}:{password_hash.hex()}"
def verify_password(self, password: str, password_hash: str) -> bool:
"""Verify a password against its hash"""
try:
salt, stored_hash = password_hash.split(':')
password_hash_bytes = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100000)
return password_hash_bytes.hex() == stored_hash
except:
return False
def add_user(self, username: str, password: str, roles: Optional[List[str]] = None) -> bool:
"""Add a new admin user"""
if username in self.config["admin_users"]:
print(f"User {username} already exists")
return False
if roles is None:
roles = ["admin"]
self.config["admin_users"][username] = {
"password_hash": self._hash_password(password),
"created_at": datetime.now().isoformat(),
"last_login": None,
"is_active": True,
"roles": roles
}
self._save_config(self.config)
print(f"User {username} created successfully")
return True
def authenticate_user(self, username: str, password: str) -> Optional[Dict]:
"""Authenticate a user and return user info if successful"""
user = self.config["admin_users"].get(username)
if not user or not user.get("is_active", True):
return None
if self.verify_password(password, user["password_hash"]):
# Update last login
user["last_login"] = datetime.now().isoformat()
self._save_config(self.config)
return user
return None
def get_user(self, username: str) -> Optional[Dict]:
"""Get user information"""
return self.config["admin_users"].get(username)
def list_users(self) -> List[str]:
"""List all admin users"""
return list(self.config["admin_users"].keys())
def delete_user(self, username: str) -> bool:
"""Delete an admin user"""
if username in self.config["admin_users"]:
del self.config["admin_users"][username]
self._save_config(self.config)
return True
return False
def change_password(self, username: str, old_password: str, new_password: str) -> bool:
"""Change user password"""
user = self.authenticate_user(username, old_password)
if user:
user["password_hash"] = self._hash_password(new_password)
user["last_login"] = datetime.now().isoformat()
self._save_config(self.config)
return True
return False
def is_admin_enabled(self) -> bool:
"""Check if admin interface is enabled"""
return self.config.get("admin_enabled", True)
def get_security_config(self) -> Dict:
"""Get security configuration"""
return self.config.get("security", {})
def get_monitoring_config(self) -> Dict:
"""Get monitoring configuration"""
return self.config.get("monitoring", {}) or {}
# Global admin config instance
admin_config = AdminConfig()
def create_default_admin():
"""Create default admin user if none exists"""
if not admin_config.list_users():
print("Creating default admin user...")
admin_config.add_user("admin", "admin123", ["admin"])
if __name__ == "__main__":
# Command line interface for admin management
import sys
if len(sys.argv) < 2:
print("Usage: python admin_config.py <command> [args]")
print("Commands:")
print(" create-user <username> <password> [roles]")
print(" list-users")
print(" delete-user <username>")
print(" change-password <username> <old_password> <new_password>")
print(" show-config")
sys.exit(1)
cmd = sys.argv[1]
if cmd == "create-user":
if len(sys.argv) < 4:
print("Usage: create-user <username> <password> [roles]")
sys.exit(1)
username = sys.argv[2]
password = sys.argv[3]
roles = sys.argv[4:] if len(sys.argv) > 4 else ["admin"]
admin_config.add_user(username, password, roles)
elif cmd == "list-users":
users = admin_config.list_users()
print("Admin users:")
for user in users:
info = admin_config.get_user(user)
print(f" {user} (roles: {', '.join(info.get('roles', []))})")
elif cmd == "delete-user":
if len(sys.argv) < 3:
print("Usage: delete-user <username>")
sys.exit(1)
username = sys.argv[2]
if admin_config.delete_user(username):
print(f"User {username} deleted")
else:
print(f"User {username} not found")
elif cmd == "change-password":
if len(sys.argv) < 5:
print("Usage: change-password <username> <old_password> <new_password>")
sys.exit(1)
username = sys.argv[2]
old_password = sys.argv[3]
new_password = sys.argv[4]
if admin_config.change_password(username, old_password, new_password):
print(f"Password changed for {username}")
else:
print("Authentication failed or user not found")
elif cmd == "show-config":
print("Admin Configuration:")
print(json.dumps(admin_config.config, indent=2))
else:
print(f"Unknown command: {cmd}")
sys.exit(1)