Add system users management
This commit is contained in:
@@ -1475,6 +1475,157 @@ class ServerController
|
||||
$this->view->json(['success' => true, 'data' => $result]);
|
||||
}
|
||||
|
||||
public function systemUsers(int $id): void
|
||||
{
|
||||
$server = $this->serverModel->findById($id);
|
||||
if (!$server) { $this->view->error(404); }
|
||||
|
||||
try {
|
||||
$ssh = new SSHService();
|
||||
if (!$ssh->connect($server)) {
|
||||
throw new \RuntimeException('Could not establish SSH connection');
|
||||
}
|
||||
$this->auditService->logCredentialAccess($id, 'View system users');
|
||||
|
||||
$data = [];
|
||||
|
||||
$usersResult = $ssh->exec("awk -F: '\$3>=1000||\$3==0{printf \"%s|%s|%s|%s\\n\",\$1,\$3,\$6,\$7}' /etc/passwd 2>/dev/null | sort -t: -k2 -n | head -100");
|
||||
$users = [];
|
||||
foreach (explode("\n", trim($usersResult['output'] ?? '')) as $line) {
|
||||
$parts = explode("|", $line);
|
||||
if (count($parts) >= 4 && is_numeric($parts[1])) {
|
||||
$users[] = [
|
||||
'username' => $parts[0],
|
||||
'uid' => (int) $parts[1],
|
||||
'home' => $parts[2],
|
||||
'shell' => $parts[3],
|
||||
];
|
||||
}
|
||||
}
|
||||
$data['users'] = $users;
|
||||
|
||||
$groupsResult = $ssh->exec("awk -F: '{print \$1}' /etc/group 2>/dev/null | sort | head -50");
|
||||
$data['groups'] = array_filter(explode("\n", trim($groupsResult['output'] ?? '')));
|
||||
|
||||
$totalResult = $ssh->exec("awk -F: '\$3>=1000||\$3==0{print \$1}' /etc/passwd 2>/dev/null | wc -l");
|
||||
$data['total_users'] = (int) trim($totalResult['output'] ?? '0');
|
||||
|
||||
$lastResult = $ssh->exec("last -5 -w 2>/dev/null | head -10 || echo 'No login history'");
|
||||
$data['last_logins'] = trim($lastResult['output'] ?? '');
|
||||
|
||||
$ssh->disconnect();
|
||||
|
||||
$this->view->display('servers.system_users', [
|
||||
'title' => 'System Users - ' . $server['name'] . ' - ServerManager',
|
||||
'server' => $server,
|
||||
'sysusers' => $data,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Session::setFlash('error', 'Failed to get users: ' . $e->getMessage());
|
||||
$this->view->redirect("/servers/{$id}");
|
||||
}
|
||||
}
|
||||
|
||||
public function systemUsersAction(int $id): void
|
||||
{
|
||||
$server = $this->serverModel->findById($id);
|
||||
if (!$server) {
|
||||
$this->view->json(['success' => false, 'message' => 'Server not found'], 404);
|
||||
}
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
$allowed = ['add', 'delete', 'lock', 'unlock', 'addgroup'];
|
||||
if (!in_array($action, $allowed, true)) {
|
||||
$this->view->json(['success' => false, 'message' => 'Invalid action']);
|
||||
}
|
||||
|
||||
try {
|
||||
$ssh = new SSHService();
|
||||
if (!$ssh->connect($server)) {
|
||||
throw new \RuntimeException('Could not establish SSH connection');
|
||||
}
|
||||
$this->auditService->logServerAction($id, "sysuser_{$action}", $action);
|
||||
|
||||
if ($action === 'add') {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$password = trim($_POST['password'] ?? '');
|
||||
$groups = trim($_POST['groups'] ?? '');
|
||||
$createHome = !empty($_POST['create_home']);
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
$this->view->json(['success' => false, 'message' => 'Username and password required']);
|
||||
}
|
||||
if (!preg_match('/^[a-z_][a-z0-9_-]*$/', $username)) {
|
||||
$this->view->json(['success' => false, 'message' => 'Invalid username']);
|
||||
}
|
||||
|
||||
$homeFlag = $createHome ? '-m' : '-M';
|
||||
$cmd = "sudo useradd {$homeFlag} -p \$(sudo openssl passwd -6 '{$password}')";
|
||||
if (!empty($groups)) {
|
||||
$sanitized = preg_replace('/[^a-z0-9_,-]/', '', $groups);
|
||||
$cmd .= " -G {$sanitized}";
|
||||
}
|
||||
$cmd .= " {$username} 2>&1; echo EXIT:\$?";
|
||||
|
||||
$result = $ssh->exec($cmd);
|
||||
$exitCode = (int) trim(explode('EXIT:', $result['output'] ?? 'EXIT:-1')[1] ?? '-1');
|
||||
$ssh->disconnect();
|
||||
|
||||
$this->view->json([
|
||||
'success' => $exitCode === 0,
|
||||
'message' => $exitCode === 0 ? "User '{$username}' created." : 'Failed to create user.',
|
||||
'output' => trim($result['output']),
|
||||
]);
|
||||
} elseif ($action === 'delete') {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$removeHome = !empty($_POST['remove_home']);
|
||||
if (empty($username)) {
|
||||
$this->view->json(['success' => false, 'message' => 'Username required']);
|
||||
}
|
||||
$rmFlag = $removeHome ? '-r' : '';
|
||||
$result = $ssh->exec("sudo userdel {$rmFlag} {$username} 2>&1; echo EXIT:\$?");
|
||||
$exitCode = (int) trim(explode('EXIT:', $result['output'] ?? 'EXIT:-1')[1] ?? '-1');
|
||||
$ssh->disconnect();
|
||||
$this->view->json([
|
||||
'success' => $exitCode === 0,
|
||||
'message' => $exitCode === 0 ? "User '{$username}' deleted." : 'Failed to delete user.',
|
||||
]);
|
||||
} elseif ($action === 'lock') {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
if (empty($username)) $this->view->json(['success' => false, 'message' => 'Username required']);
|
||||
$result = $ssh->exec("sudo passwd -l {$username} 2>&1; echo EXIT:\$?");
|
||||
$exitCode = (int) trim(explode('EXIT:', $result['output'] ?? 'EXIT:-1')[1] ?? '-1');
|
||||
$ssh->disconnect();
|
||||
$this->view->json([
|
||||
'success' => $exitCode === 0,
|
||||
'message' => $exitCode === 0 ? "User '{$username}' locked." : 'Failed to lock user.',
|
||||
]);
|
||||
} elseif ($action === 'unlock') {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
if (empty($username)) $this->view->json(['success' => false, 'message' => 'Username required']);
|
||||
$result = $ssh->exec("sudo passwd -u {$username} 2>&1; echo EXIT:\$?");
|
||||
$exitCode = (int) trim(explode('EXIT:', $result['output'] ?? 'EXIT:-1')[1] ?? '-1');
|
||||
$ssh->disconnect();
|
||||
$this->view->json([
|
||||
'success' => $exitCode === 0,
|
||||
'message' => $exitCode === 0 ? "User '{$username}' unlocked." : 'Failed to unlock user.',
|
||||
]);
|
||||
} elseif ($action === 'addgroup') {
|
||||
$group = trim($_POST['group'] ?? '');
|
||||
if (empty($group)) $this->view->json(['success' => false, 'message' => 'Group name required']);
|
||||
$result = $ssh->exec("sudo groupadd -f {$group} 2>&1; echo EXIT:\$?");
|
||||
$exitCode = (int) trim(explode('EXIT:', $result['output'] ?? 'EXIT:-1')[1] ?? '-1');
|
||||
$ssh->disconnect();
|
||||
$this->view->json([
|
||||
'success' => $exitCode === 0,
|
||||
'message' => $exitCode === 0 ? "Group '{$group}' created." : 'Failed to create group.',
|
||||
]);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$this->view->json(['success' => false, 'message' => 'Failed: ' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function metrics(int $id): void
|
||||
{
|
||||
$monitoringService = new MonitoringService();
|
||||
|
||||
Reference in New Issue
Block a user