GeoNetAgent, LDAPWeb, server-audit, server-connection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

194 lines
7.1 KiB

<?php
namespace App\Http\Controllers;
use App\Models\LdapGroupMeta;
use App\Services\LdapGroupService;
use App\Services\LdapMetadataService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use InvalidArgumentException;
use RuntimeException;
use Throwable;
class LdapGroupController extends Controller
{
public function __construct(
private readonly LdapGroupService $groupService,
private readonly LdapMetadataService $metadata
) {
}
public function index(Request $request): View
{
$sort = $request->string('sort', 'name')->toString();
$allowedSort = ['name', 'sam_account_name', 'type', 'members_count', 'description'];
if (! in_array($sort, $allowedSort, true)) {
$sort = 'name';
}
$dir = $request->string('dir', 'asc')->toString() === 'desc' ? 'desc' : 'asc';
$search = $request->string('q')->trim()->toString();
$result = $this->groupService->listGroups($sort, $dir, $search);
$groups = $this->metadata->enrichGroups($result['rows']);
if ($search !== '') {
$existingKeys = array_column($groups, 'route_key');
$metaMatches = LdapGroupMeta::query()
->where('admin_note', 'like', '%'.$search.'%')
->get();
foreach ($metaMatches as $meta) {
if (in_array($meta->group_key, $existingKeys, true)) {
continue;
}
try {
$groupData = $this->groupService->getGroup($meta->group_key);
$groupData['admin_note'] = $meta->admin_note ?? '';
$groups[] = $groupData;
} catch (InvalidArgumentException) {
}
}
}
return view('ldap-groups.index', [
'groups' => $groups,
'meta' => array_merge($result['meta'], ['total' => count($groups)]),
'sort' => $sort,
'dir' => $dir,
'search' => $search,
'error' => $result['error'] ?? null,
]);
}
public function show(string $group): View|RedirectResponse
{
try {
$groupData = $this->groupService->getGroup($group);
$groupData['admin_note'] = $this->metadata->getGroupMeta($groupData['route_key'])['admin_note'];
$usernames = $this->groupService->listUsernamesForSelect();
return view('ldap-groups.show', [
'group' => $groupData,
'usernames' => $usernames,
]);
} catch (InvalidArgumentException $e) {
return redirect()->route('ldap-groups.index')->with('error', $e->getMessage());
}
}
public function updateNote(Request $request, string $group): RedirectResponse
{
$data = $request->validate([
'admin_note' => ['nullable', 'string', 'max:5000'],
]);
try {
$groupData = $this->groupService->getGroup($group);
$this->metadata->saveGroupMeta(
$groupData['route_key'],
$groupData['name'],
$data['admin_note'] ?? null
);
$request->attributes->set('audit_metadata', [
'group' => $groupData['name'],
]);
return redirect()->route('ldap-groups.show', $group)->with('success', 'Group note saved.');
} catch (InvalidArgumentException|RuntimeException $e) {
return back()->with('error', $e->getMessage());
} catch (Throwable) {
return back()->with('error', 'Failed to save group note.');
}
}
public function store(Request $request): RedirectResponse
{
$data = $request->validate([
'name' => ['required', 'string', 'max:64', 'regex:/^[a-zA-Z0-9 _.-]+$/'],
'description' => ['nullable', 'string', 'max:255'],
'confirm_create' => ['required', 'accepted'],
]);
try {
$this->groupService->createGroup($data['name'], $data['description'] ?? null);
$request->attributes->set('audit_metadata', [
'group' => $data['name'],
'description' => $data['description'] ?? null,
]);
return redirect()->route('ldap-groups.index')->with('success', "Group [{$data['name']}] created.");
} catch (InvalidArgumentException|RuntimeException $e) {
return back()->withInput()->with('error', $e->getMessage());
} catch (Throwable) {
return back()->withInput()->with('error', 'Failed to create group.');
}
}
public function destroy(Request $request, string $group): RedirectResponse
{
$data = $request->validate([
'confirm_delete' => ['required', 'accepted'],
'confirm_group_name' => ['required', 'string'],
]);
try {
$groupData = $this->groupService->getGroup($group);
if (mb_strtolower($data['confirm_group_name']) !== mb_strtolower($groupData['name'])) {
return back()->with('error', 'Group name confirmation does not match.');
}
$this->groupService->deleteGroup($group);
$request->attributes->set('audit_metadata', ['group' => $groupData['name']]);
return redirect()->route('ldap-groups.index')->with('success', "Group [{$groupData['name']}] deleted.");
} catch (InvalidArgumentException|RuntimeException $e) {
return back()->with('error', $e->getMessage());
} catch (Throwable) {
return back()->with('error', 'Failed to delete group.');
}
}
public function addMember(Request $request, string $group): RedirectResponse
{
$data = $request->validate([
'username' => ['required', 'string', 'max:100'],
]);
try {
$this->groupService->addMember($group, $data['username']);
$request->attributes->set('audit_metadata', [
'group' => $group,
'username' => $data['username'],
]);
return redirect()->route('ldap-groups.show', $group)->with('success', "User [{$data['username']}] added to group.");
} catch (InvalidArgumentException|RuntimeException $e) {
return back()->with('error', $e->getMessage());
} catch (Throwable) {
return back()->with('error', 'Failed to add member.');
}
}
public function removeMember(Request $request, string $group, string $username): RedirectResponse
{
$request->validate(['confirm' => ['required', 'accepted']]);
try {
$this->groupService->removeMember($group, $username);
$request->attributes->set('audit_metadata', [
'group' => $group,
'username' => $username,
]);
return redirect()->route('ldap-groups.show', $group)->with('success', "User [{$username}] removed from group.");
} catch (InvalidArgumentException|RuntimeException $e) {
return back()->with('error', $e->getMessage());
} catch (Throwable) {
return back()->with('error', 'Failed to remove member.');
}
}
}