diff --git a/src/ScadaLink.CentralUI/Components/Pages/Design/ApiMethodForm.razor b/src/ScadaLink.CentralUI/Components/Pages/Design/ApiMethodForm.razor index 039f253..414ee97 100644 --- a/src/ScadaLink.CentralUI/Components/Pages/Design/ApiMethodForm.razor +++ b/src/ScadaLink.CentralUI/Components/Pages/Design/ApiMethodForm.razor @@ -28,6 +28,40 @@ +
+ + @if (_allKeys.Count == 0) + { +
+ No API keys configured. + Create one to authorize callers for this method. +
+ } + else + { +
+ @foreach (var key in _allKeys) + { + var checkboxId = $"approved-key-{key.Id}"; +
+ + +
+ } +
+
+ Callers must present a checked key in the X-API-Key header to invoke this method. +
+ } +
(); private ApiMethod? _existing; + private List _allKeys = new(); + private HashSet _selectedKeyIds = new(); protected override async Task OnInitializedAsync() { + try + { + _allKeys = (await InboundApiRepository.GetAllApiKeysAsync()).ToList(); + } + catch (Exception ex) { _formError = ex.Message; } + if (Id.HasValue) { try @@ -92,6 +134,7 @@ _timeoutSeconds = _existing.TimeoutSeconds; _params = _existing.ParameterDefinitions; _returns = _existing.ReturnDefinition; + _selectedKeyIds = ParseApprovedKeyIds(_existing.ApprovedApiKeyIds); } } catch (Exception ex) { _formError = ex.Message; } @@ -99,6 +142,25 @@ _loading = false; } + 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 void ToggleKey(int keyId, bool isChecked) + { + if (isChecked) _selectedKeyIds.Add(keyId); + else _selectedKeyIds.Remove(keyId); + } + + private string? SerializeApprovedKeyIds() => + _selectedKeyIds.Count == 0 ? null : string.Join(",", _selectedKeyIds.OrderBy(id => id)); + private async Task Save() { _formError = null; @@ -110,12 +172,14 @@ try { + var approvedKeyIds = SerializeApprovedKeyIds(); if (_existing != null) { _existing.Script = _script; _existing.TimeoutSeconds = _timeoutSeconds; _existing.ParameterDefinitions = _params?.Trim(); _existing.ReturnDefinition = _returns?.Trim(); + _existing.ApprovedApiKeyIds = approvedKeyIds; await InboundApiRepository.UpdateApiMethodAsync(_existing); } else @@ -124,7 +188,8 @@ { TimeoutSeconds = _timeoutSeconds, ParameterDefinitions = _params?.Trim(), - ReturnDefinition = _returns?.Trim() + ReturnDefinition = _returns?.Trim(), + ApprovedApiKeyIds = approvedKeyIds }; await InboundApiRepository.AddApiMethodAsync(m); }