feature: root service and account status

This commit is contained in:
2025-12-28 22:31:56 +01:00
parent b566055d0a
commit 2d1ca05bf0
18 changed files with 39 additions and 41 deletions

View File

@ -138,7 +138,6 @@ def disable_user(
steps.append("sessions terminated")
except subprocess.CalledProcessError as exc:
if exc.returncode == 1:
# pkill returns 1 when no matching processes exist; not an error here.
steps.append("no sessions to terminate")
else:
raise

View File

@ -159,15 +159,15 @@ def users(settings: Settings = Depends(get_settings)) -> List[UserStatus]:
dependencies=[Depends(get_current_admin)],
)
def disable_user(
current_user: str = Depends(get_current_admin),
username: str = Depends(validate_user),
payload: ActionRequest | None = Body(default=None),
settings: Settings = Depends(get_settings),
current_user: str = Depends(get_current_admin),
) -> ActionResponse:
if username == current_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Refusing to disable the currently authenticated user",
detail="Cannot disable current user",
)
try:
steps = actions.disable_user(

View File

@ -2,7 +2,7 @@ import datetime as dt
import grp
import pwd
import spwd
from typing import List, Set, Optional
from typing import List, Optional, Set
import jwt
import pam
@ -123,14 +123,9 @@ def list_manageable_users(settings: Settings) -> List[str]:
def is_account_locked(username: str) -> bool:
"""Return True when the account is locked in /etc/shadow."""
try:
shadow_entry = spwd.getspnam(username)
except KeyError:
entry = spwd.getspnam(username)
except (KeyError, PermissionError):
return False
except PermissionError:
return False
shadow_password = shadow_entry.sp_pwdp or ""
if shadow_password in ("*", "!", "!!"):
return True
return shadow_password.startswith("!")
password_hash = entry.sp_pwdp or ""
return password_hash.startswith(("!", "*"))

View File

@ -154,9 +154,7 @@
statusDiv.textContent = 'Lade...';
try {
const data = await api('/users');
statusDiv.textContent = data
.map(u => `${u.user}: ${u.logged_in ? 'eingeloggt' : 'aus'} | ${u.account_locked ? 'deaktiviert' : 'aktiv'}`)
.join('\n') || 'Keine Daten';
statusDiv.textContent = data.map(u => `${u.user}: ${u.account_locked ? 'deaktiviert' : 'aktiv'}, ${u.logged_in ? 'eingeloggt' : 'aus'}`).join('\n') || 'Keine Daten';
const select = document.getElementById('username');
select.innerHTML = '<option value="">-- wählen --</option>';
data.forEach(u => {