diff --git a/src/ScadaLink.CentralUI/Components/Pages/Admin/ApiKeyForm.razor b/src/ScadaLink.CentralUI/Components/Pages/Admin/ApiKeyForm.razor
index 3e2dbd6..b47872d 100644
--- a/src/ScadaLink.CentralUI/Components/Pages/Admin/ApiKeyForm.razor
+++ b/src/ScadaLink.CentralUI/Components/Pages/Admin/ApiKeyForm.razor
@@ -57,6 +57,37 @@
+ @if (IsEditMode)
+ {
+
+
+ @if (_allMethods.Count == 0)
+ {
+
+ No API methods configured.
+
Create one to grant access.
+
+ }
+ else
+ {
+
+ @foreach (var method in _allMethods.OrderBy(m => m.Name))
+ {
+ var checkboxId = $"method-access-{method.Id}";
+
+ ToggleMethod(method.Id, (bool)e.Value!)" />
+
+
+ }
+
+
+ Callers using this key can invoke any checked method.
+
+ }
+
+ }
@if (_formError != null)
{
@_formError
@@ -81,6 +112,10 @@
private bool _loading = true;
private bool _saved;
+ private List _allMethods = new();
+ private HashSet _initialMethodIds = new();
+ private HashSet _selectedMethodIds = new();
+
private ToastNotification _toast = default!;
protected override async Task OnInitializedAsync()
@@ -97,6 +132,12 @@
else
{
_formName = _editingKey.Name;
+ _allMethods = (await InboundApiRepository.GetAllApiMethodsAsync()).ToList();
+ _initialMethodIds = _allMethods
+ .Where(m => ParseApprovedKeyIds(m.ApprovedApiKeyIds).Contains(_editingKey.Id))
+ .Select(m => m.Id)
+ .ToHashSet();
+ _selectedMethodIds = new HashSet(_initialMethodIds);
}
}
}
@@ -118,6 +159,22 @@
{
_editingKey.Name = _formName.Trim();
await InboundApiRepository.UpdateApiKeyAsync(_editingKey);
+
+ var changedIds = _selectedMethodIds
+ .Except(_initialMethodIds)
+ .Concat(_initialMethodIds.Except(_selectedMethodIds))
+ .ToHashSet();
+ foreach (var method in _allMethods.Where(m => changedIds.Contains(m.Id)))
+ {
+ var ids = ParseApprovedKeyIds(method.ApprovedApiKeyIds);
+ if (_selectedMethodIds.Contains(method.Id)) ids.Add(_editingKey.Id);
+ else ids.Remove(_editingKey.Id);
+ method.ApprovedApiKeyIds = ids.Count == 0
+ ? null
+ : string.Join(",", ids.OrderBy(x => x));
+ await InboundApiRepository.UpdateApiMethodAsync(method);
+ }
+
await InboundApiRepository.SaveChangesAsync();
NavigationManager.NavigateTo("/admin/api-keys");
}
@@ -139,6 +196,22 @@
private void GoBack() => NavigationManager.NavigateTo("/admin/api-keys");
+ private void ToggleMethod(int methodId, bool isChecked)
+ {
+ if (isChecked) _selectedMethodIds.Add(methodId);
+ else _selectedMethodIds.Remove(methodId);
+ }
+
+ private static HashSet ParseApprovedKeyIds(string? value)
+ {
+ if (string.IsNullOrWhiteSpace(value))
+ return new HashSet();
+ return value.Split(',', StringSplitOptions.RemoveEmptyEntries)
+ .Select(s => int.TryParse(s.Trim(), out var id) ? id : -1)
+ .Where(id => id > 0)
+ .ToHashSet();
+ }
+
private async Task CopyKeyToClipboard()
{
if (_newlyCreatedKeyValue == null) return;