MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / login

Method login

auth_manager.py:432–481  ·  view source on GitHub ↗

Verify credentials and start DB decryption in background. Returns immediately.

(self, username: str, password: str)

Source from the content-addressed store, hash-verified

430 # =========================================================================
431
432 def login(self, username: str, password: str) -> dict:
433 """Verify credentials and start DB decryption in background. Returns immediately."""
434 if not self.is_configured():
435 return {'success': False, 'error': 'Authentication not configured'}
436
437 try:
438 with self._get_auth_conn() as conn:
439 cursor = conn.cursor()
440 cursor.execute("SELECT * FROM auth WHERE username = ?", (username,))
441 row = cursor.fetchone()
442
443 if not row:
444 return {'success': False, 'error': 'Invalid username or password'}
445
446 # Verify password
447 if not self._verify_password(password, row['password_hash'], row['password_salt']):
448 return {'success': False, 'error': 'Invalid username or password'}
449
450 # Verify hardware fingerprint
451 hw_fingerprint = self.get_hardware_fingerprint()
452 if not secrets.compare_digest(row['hardware_fingerprint'], hw_fingerprint):
453 logger.warning("Hardware fingerprint mismatch during login!")
454 return {
455 'success': False,
456 'error': 'Hardware mismatch - this Ragnar instance is bound to different hardware',
457 'hw_mismatch': True
458 }
459
460 # Unwrap the Fernet key
461 wrapping_key = self._derive_wrapping_key(password, hw_fingerprint)
462 try:
463 fernet_key = self._unwrap_fernet_key(row['encrypted_fernet_key'], wrapping_key)
464 except InvalidToken:
465 return {'success': False, 'error': 'Failed to decrypt encryption key'}
466
467 self._fernet_key = fernet_key
468
469 # If encrypted DB exists, decrypt in background so this response returns fast
470 if os.path.exists(self.encrypted_db_path):
471 self._db_ready = False
472 threading.Thread(target=self._background_decrypt, daemon=True).start()
473 else:
474 self._db_ready = True
475
476 logger.info(f"User '{username}' logged in successfully")
477 return {'success': True}
478
479 except Exception as e:
480 logger.error(f"Login failed: {e}")
481 return {'success': False, 'error': f'Login failed: {str(e)}'}
482
483 def _background_decrypt(self):
484 """Decrypt DB and reinitialize in a background thread."""

Callers 3

auth_loginFunction · 0.80
connect_ftpMethod · 0.80
ftp_connectMethod · 0.80

Calls 13

is_configuredMethod · 0.95
_get_auth_connMethod · 0.95
_verify_passwordMethod · 0.95
_derive_wrapping_keyMethod · 0.95
_unwrap_fernet_keyMethod · 0.95
cursorMethod · 0.80
warningMethod · 0.80
infoMethod · 0.80
errorMethod · 0.80
executeMethod · 0.45
fetchoneMethod · 0.45

Tested by

no test coverage detected