Some checks failed
Build Test Deploy / build-test (push) Has been cancelled
Build Test Deploy / authority-container (push) Has been cancelled
Build Test Deploy / docs (push) Has been cancelled
Build Test Deploy / deploy (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
55 lines
1.8 KiB
C#
55 lines
1.8 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace StellaOps.Concelier.Connector.Acsc.Configuration;
|
|
|
|
/// <summary>
|
|
/// Defines a single ACSC RSS feed endpoint.
|
|
/// </summary>
|
|
public sealed class AcscFeedOptions
|
|
{
|
|
private static readonly Regex SlugPattern = new("^[a-z0-9][a-z0-9\\-]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
|
|
|
/// <summary>
|
|
/// Logical slug for the feed (alerts, advisories, threats, etc.).
|
|
/// </summary>
|
|
public string Slug { get; set; } = "alerts";
|
|
|
|
/// <summary>
|
|
/// Relative path (under <see cref="AcscOptions.BaseEndpoint"/>) for the RSS feed.
|
|
/// </summary>
|
|
public string RelativePath { get; set; } = "/acsc/view-all-content/alerts/rss";
|
|
|
|
/// <summary>
|
|
/// Indicates whether the feed is active.
|
|
/// </summary>
|
|
public bool Enabled { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// Optional display name for logging.
|
|
/// </summary>
|
|
public string? DisplayName { get; set; }
|
|
|
|
internal void Validate(int index)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(Slug))
|
|
{
|
|
throw new InvalidOperationException($"ACSC feed entry #{index} must define a slug.");
|
|
}
|
|
|
|
if (!SlugPattern.IsMatch(Slug))
|
|
{
|
|
throw new InvalidOperationException($"ACSC feed slug '{Slug}' is invalid. Slugs must be lower-case alphanumeric with optional hyphen separators.");
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(RelativePath))
|
|
{
|
|
throw new InvalidOperationException($"ACSC feed '{Slug}' must specify a relative path.");
|
|
}
|
|
|
|
if (!RelativePath.StartsWith("/", StringComparison.Ordinal))
|
|
{
|
|
throw new InvalidOperationException($"ACSC feed '{Slug}' relative path must begin with '/' (value: '{RelativePath}').");
|
|
}
|
|
}
|
|
}
|