Add 33 new management message records, ManagementActor handlers, and CLI commands to close all functionality gaps between the Central UI and the Management CLI. New capabilities include: - Template member CRUD (attributes, alarms, scripts, compositions) - Shared script CRUD - Database connection definition CRUD - Inbound API method CRUD - LDAP scope rule management - API key enable/disable - Area update - Remote event log and parked message queries - Missing get/update commands for templates, sites, instances, data connections, external systems, notifications, and SMTP config Includes 12 new ManagementActor unit tests covering authorization, happy-path queries, and error handling. Updates CLI README and component design documents (Component-CLI.md, Component-ManagementService.md).
173 lines
7.9 KiB
C#
173 lines
7.9 KiB
C#
using System.CommandLine;
|
|
using System.CommandLine.Parsing;
|
|
using ScadaLink.Commons.Messages.Management;
|
|
|
|
namespace ScadaLink.CLI.Commands;
|
|
|
|
public static class SecurityCommands
|
|
{
|
|
public static Command Build(Option<string> contactPointsOption, Option<string> formatOption)
|
|
{
|
|
var command = new Command("security") { Description = "Manage security settings" };
|
|
|
|
command.Add(BuildApiKey(contactPointsOption, formatOption));
|
|
command.Add(BuildRoleMapping(contactPointsOption, formatOption));
|
|
command.Add(BuildScopeRule(contactPointsOption, formatOption));
|
|
|
|
return command;
|
|
}
|
|
|
|
private static Command BuildApiKey(Option<string> contactPointsOption, Option<string> formatOption)
|
|
{
|
|
var group = new Command("api-key") { Description = "Manage API keys" };
|
|
|
|
var listCmd = new Command("list") { Description = "List all API keys" };
|
|
listCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new ListApiKeysCommand());
|
|
});
|
|
group.Add(listCmd);
|
|
|
|
var nameOption = new Option<string>("--name") { Description = "API key name", Required = true };
|
|
var createCmd = new Command("create") { Description = "Create an API key" };
|
|
createCmd.Add(nameOption);
|
|
createCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var name = result.GetValue(nameOption)!;
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new CreateApiKeyCommand(name));
|
|
});
|
|
group.Add(createCmd);
|
|
|
|
var idOption = new Option<int>("--id") { Description = "API key ID", Required = true };
|
|
var deleteCmd = new Command("delete") { Description = "Delete an API key" };
|
|
deleteCmd.Add(idOption);
|
|
deleteCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(idOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new DeleteApiKeyCommand(id));
|
|
});
|
|
group.Add(deleteCmd);
|
|
|
|
var updateIdOption = new Option<int>("--id") { Description = "API key ID", Required = true };
|
|
var enabledOption = new Option<bool>("--enabled") { Description = "Enable or disable", Required = true };
|
|
var updateCmd = new Command("update") { Description = "Enable or disable an API key" };
|
|
updateCmd.Add(updateIdOption);
|
|
updateCmd.Add(enabledOption);
|
|
updateCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(updateIdOption);
|
|
var enabled = result.GetValue(enabledOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new UpdateApiKeyCommand(id, enabled));
|
|
});
|
|
group.Add(updateCmd);
|
|
|
|
return group;
|
|
}
|
|
|
|
private static Command BuildRoleMapping(Option<string> contactPointsOption, Option<string> formatOption)
|
|
{
|
|
var group = new Command("role-mapping") { Description = "Manage LDAP role mappings" };
|
|
|
|
var listCmd = new Command("list") { Description = "List all role mappings" };
|
|
listCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new ListRoleMappingsCommand());
|
|
});
|
|
group.Add(listCmd);
|
|
|
|
var ldapGroupOption = new Option<string>("--ldap-group") { Description = "LDAP group name", Required = true };
|
|
var roleOption = new Option<string>("--role") { Description = "Role name", Required = true };
|
|
var createCmd = new Command("create") { Description = "Create a role mapping" };
|
|
createCmd.Add(ldapGroupOption);
|
|
createCmd.Add(roleOption);
|
|
createCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var ldapGroup = result.GetValue(ldapGroupOption)!;
|
|
var role = result.GetValue(roleOption)!;
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption,
|
|
new CreateRoleMappingCommand(ldapGroup, role));
|
|
});
|
|
group.Add(createCmd);
|
|
|
|
var idOption = new Option<int>("--id") { Description = "Mapping ID", Required = true };
|
|
var deleteCmd = new Command("delete") { Description = "Delete a role mapping" };
|
|
deleteCmd.Add(idOption);
|
|
deleteCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(idOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new DeleteRoleMappingCommand(id));
|
|
});
|
|
group.Add(deleteCmd);
|
|
|
|
var updateIdOption = new Option<int>("--id") { Description = "Mapping ID", Required = true };
|
|
var updateLdapGroupOption = new Option<string>("--ldap-group") { Description = "LDAP group name", Required = true };
|
|
var updateRoleOption = new Option<string>("--role") { Description = "Role name", Required = true };
|
|
var updateCmd = new Command("update") { Description = "Update a role mapping" };
|
|
updateCmd.Add(updateIdOption);
|
|
updateCmd.Add(updateLdapGroupOption);
|
|
updateCmd.Add(updateRoleOption);
|
|
updateCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(updateIdOption);
|
|
var ldapGroup = result.GetValue(updateLdapGroupOption)!;
|
|
var role = result.GetValue(updateRoleOption)!;
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption,
|
|
new UpdateRoleMappingCommand(id, ldapGroup, role));
|
|
});
|
|
group.Add(updateCmd);
|
|
|
|
return group;
|
|
}
|
|
|
|
private static Command BuildScopeRule(Option<string> contactPointsOption, Option<string> formatOption)
|
|
{
|
|
var group = new Command("scope-rule") { Description = "Manage LDAP scope rules" };
|
|
|
|
var mappingIdOption = new Option<int>("--mapping-id") { Description = "Role mapping ID", Required = true };
|
|
var listCmd = new Command("list") { Description = "List scope rules for a mapping" };
|
|
listCmd.Add(mappingIdOption);
|
|
listCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var mappingId = result.GetValue(mappingIdOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new ListScopeRulesCommand(mappingId));
|
|
});
|
|
group.Add(listCmd);
|
|
|
|
var addMappingIdOption = new Option<int>("--mapping-id") { Description = "Role mapping ID", Required = true };
|
|
var siteIdOption = new Option<int>("--site-id") { Description = "Site ID", Required = true };
|
|
var addCmd = new Command("add") { Description = "Add a scope rule" };
|
|
addCmd.Add(addMappingIdOption);
|
|
addCmd.Add(siteIdOption);
|
|
addCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var mappingId = result.GetValue(addMappingIdOption);
|
|
var siteId = result.GetValue(siteIdOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new AddScopeRuleCommand(mappingId, siteId));
|
|
});
|
|
group.Add(addCmd);
|
|
|
|
var deleteIdOption = new Option<int>("--id") { Description = "Scope rule ID", Required = true };
|
|
var deleteCmd = new Command("delete") { Description = "Delete a scope rule" };
|
|
deleteCmd.Add(deleteIdOption);
|
|
deleteCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(deleteIdOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, new DeleteScopeRuleCommand(id));
|
|
});
|
|
group.Add(deleteCmd);
|
|
|
|
return group;
|
|
}
|
|
}
|