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
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.'); |
|
} |
|
} |
|
}
|
|
|