ciyidogan commited on
Commit
2069381
Β·
verified Β·
1 Parent(s): de3c389

Update admin_routes.py

Browse files
Files changed (1) hide show
  1. admin_routes.py +38 -29
admin_routes.py CHANGED
@@ -37,6 +37,10 @@ class LoginResponse(BaseModel):
37
  token: str
38
  username: str
39
 
 
 
 
 
40
  class EnvironmentUpdate(BaseModel):
41
  work_mode: str
42
  cloud_token: Optional[str] = None
@@ -100,22 +104,19 @@ class TestRequest(BaseModel):
100
  test_type: str # "all", "ui", "backend", "integration", "spark"
101
 
102
  # ===================== Helpers =====================
103
- def hash_password(password: str) -> str:
104
- """Simple SHA256 hash for demo. Use bcrypt in production!"""
105
- return hashlib.sha256(password.encode()).hexdigest()
 
 
 
 
 
 
106
 
107
- def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str:
108
- """Verify JWT token and return username"""
109
- try:
110
- payload = jwt.decode(credentials.credentials, JWT_SECRET, algorithms=[JWT_ALGORITHM])
111
- username = payload.get("sub")
112
- if username is None:
113
- raise HTTPException(status_code=401, detail="Invalid token")
114
- return username
115
- except jwt.ExpiredSignatureError:
116
- raise HTTPException(status_code=401, detail="Token expired")
117
- except jwt.JWTError:
118
- raise HTTPException(status_code=401, detail="Invalid token")
119
 
120
  def load_config() -> Dict[str, Any]:
121
  """Load service_config.jsonc"""
@@ -171,9 +172,11 @@ async def login(request: LoginRequest):
171
  if not user:
172
  raise HTTPException(status_code=401, detail="Invalid credentials")
173
 
174
- # Verify password (simple hash for demo)
175
- if hash_password(request.password) != user["password_hash"]:
176
- raise HTTPException(status_code=401, detail="Invalid credentials")
 
 
177
 
178
  # Create JWT token
179
  expire = datetime.utcnow() + timedelta(hours=JWT_EXPIRATION_HOURS)
@@ -185,14 +188,10 @@ async def login(request: LoginRequest):
185
 
186
  log(f"βœ… User '{request.username}' logged in")
187
  return LoginResponse(token=token, username=request.username)
188
-
189
- log(f"βœ… User '{request.username}' logged in")
190
- return LoginResponse(token=token, username=request.username)
191
-
192
  @router.post("/change-password")
193
  async def change_password(
194
- current_password: str,
195
- new_password: str,
196
  username: str = Depends(verify_token)
197
  ):
198
  """Change user password"""
@@ -200,21 +199,31 @@ async def change_password(
200
 
201
  # Find user
202
  users = config.get("config", {}).get("users", [])
203
- user = next((u for u in users if u["username"] == username), None)
204
 
205
- if not user:
206
  raise HTTPException(status_code=404, detail="User not found")
207
 
 
 
208
  # Verify current password
209
- if hash_password(current_password) != user["password_hash"]:
210
  raise HTTPException(status_code=401, detail="Current password is incorrect")
211
 
212
- # Update password
213
- user["password_hash"] = hash_password(new_password)
 
 
 
 
214
 
215
  # Save config
216
  save_config(config)
217
 
 
 
 
 
218
  log(f"βœ… Password changed for user '{username}'")
219
  return {"success": True, "message": "Password changed successfully"}
220
 
 
37
  token: str
38
  username: str
39
 
40
+ class ChangePasswordRequest(BaseModel):
41
+ current_password: str
42
+ new_password: str
43
+
44
  class EnvironmentUpdate(BaseModel):
45
  work_mode: str
46
  cloud_token: Optional[str] = None
 
104
  test_type: str # "all", "ui", "backend", "integration", "spark"
105
 
106
  # ===================== Helpers =====================
107
+ def hash_password(password: str, salt: str = None) -> tuple[str, str]:
108
+ """Hash password with bcrypt. Returns (hash, salt)"""
109
+ if salt is None:
110
+ salt = bcrypt.gensalt().decode('utf-8')
111
+ else:
112
+ salt = salt.encode('utf-8')
113
+
114
+ hashed = bcrypt.hashpw(password.encode('utf-8'), salt).decode('utf-8')
115
+ return hashed, salt.decode('utf-8') if isinstance(salt, bytes) else salt
116
 
117
+ def verify_password(password: str, hashed: str, salt: str) -> bool:
118
+ """Verify password against hash"""
119
+ return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8'))
 
 
 
 
 
 
 
 
 
120
 
121
  def load_config() -> Dict[str, Any]:
122
  """Load service_config.jsonc"""
 
172
  if not user:
173
  raise HTTPException(status_code=401, detail="Invalid credentials")
174
 
175
+ # Verify password with bcrypt
176
+ if not verify_password(request.password, user["password_hash"], user.get("salt", "")):
177
+ # Fallback to simple hash for backward compatibility
178
+ if hash_password(request.password)[0] != user["password_hash"]:
179
+ raise HTTPException(status_code=401, detail="Invalid credentials")
180
 
181
  # Create JWT token
182
  expire = datetime.utcnow() + timedelta(hours=JWT_EXPIRATION_HOURS)
 
188
 
189
  log(f"βœ… User '{request.username}' logged in")
190
  return LoginResponse(token=token, username=request.username)
191
+
 
 
 
192
  @router.post("/change-password")
193
  async def change_password(
194
+ request: ChangePasswordRequest,
 
195
  username: str = Depends(verify_token)
196
  ):
197
  """Change user password"""
 
199
 
200
  # Find user
201
  users = config.get("config", {}).get("users", [])
202
+ user_index = next((i for i, u in enumerate(users) if u["username"] == username), None)
203
 
204
+ if user_index is None:
205
  raise HTTPException(status_code=404, detail="User not found")
206
 
207
+ user = users[user_index]
208
+
209
  # Verify current password
210
+ if not verify_password(request.current_password, user["password_hash"], user.get("salt", "")):
211
  raise HTTPException(status_code=401, detail="Current password is incorrect")
212
 
213
+ # Generate new hash with new salt
214
+ new_hash, new_salt = hash_password(request.new_password)
215
+
216
+ # Update user
217
+ users[user_index]["password_hash"] = new_hash
218
+ users[user_index]["salt"] = new_salt
219
 
220
  # Save config
221
  save_config(config)
222
 
223
+ # Add activity log
224
+ add_activity_log(config, username, "CHANGE_PASSWORD", "user", username, username, "Password changed")
225
+ save_config(config)
226
+
227
  log(f"βœ… Password changed for user '{username}'")
228
  return {"success": True, "message": "Password changed successfully"}
229