107 lines
3.2 KiB
C#
107 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Linq;
|
|
|
|
namespace StellaOps.Scheduler.WebService.EventWebhooks;
|
|
|
|
public sealed record ConselierExportEventRequest(
|
|
string ExportId,
|
|
IReadOnlyList<string> ChangedProductKeys,
|
|
IReadOnlyList<string>? Kev,
|
|
WebhookEventWindow? Window)
|
|
{
|
|
public string ExportId { get; } = ExportId?.Trim() ?? throw new ArgumentNullException(nameof(ExportId));
|
|
|
|
public IReadOnlyList<string> ChangedProductKeys { get; } = NormalizeList(ChangedProductKeys, nameof(ChangedProductKeys));
|
|
|
|
public IReadOnlyList<string> Kev { get; } = NormalizeList(Kev, nameof(Kev), allowEmpty: true);
|
|
|
|
public WebhookEventWindow? Window { get; } = Window;
|
|
|
|
private static IReadOnlyList<string> NormalizeList(IReadOnlyList<string>? source, string propertyName, bool allowEmpty = false)
|
|
{
|
|
if (source is null)
|
|
{
|
|
if (allowEmpty)
|
|
{
|
|
return ImmutableArray<string>.Empty;
|
|
}
|
|
|
|
throw new ValidationException($"{propertyName} must be specified.");
|
|
}
|
|
|
|
var cleaned = source
|
|
.Where(item => !string.IsNullOrWhiteSpace(item))
|
|
.Select(item => item.Trim())
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
.ToArray();
|
|
|
|
if (!allowEmpty && cleaned.Length == 0)
|
|
{
|
|
throw new ValidationException($"{propertyName} must contain at least one value.");
|
|
}
|
|
|
|
return cleaned;
|
|
}
|
|
}
|
|
|
|
public sealed record ExcitorExportEventRequest(
|
|
string ExportId,
|
|
IReadOnlyList<ExcitorClaimChange> ChangedClaims,
|
|
WebhookEventWindow? Window)
|
|
{
|
|
public string ExportId { get; } = ExportId?.Trim() ?? throw new ArgumentNullException(nameof(ExportId));
|
|
|
|
public IReadOnlyList<ExcitorClaimChange> ChangedClaims { get; } = NormalizeClaims(ChangedClaims);
|
|
|
|
public WebhookEventWindow? Window { get; } = Window;
|
|
|
|
private static IReadOnlyList<ExcitorClaimChange> NormalizeClaims(IReadOnlyList<ExcitorClaimChange>? claims)
|
|
{
|
|
if (claims is null || claims.Count == 0)
|
|
{
|
|
throw new ValidationException("changedClaims must contain at least one entry.");
|
|
}
|
|
|
|
foreach (var claim in claims)
|
|
{
|
|
claim.Validate();
|
|
}
|
|
|
|
return claims;
|
|
}
|
|
}
|
|
|
|
public sealed record ExcitorClaimChange(
|
|
string ProductKey,
|
|
string VulnerabilityId,
|
|
string Status)
|
|
{
|
|
public string ProductKey { get; } = Normalize(ProductKey, nameof(ProductKey));
|
|
|
|
public string VulnerabilityId { get; } = Normalize(VulnerabilityId, nameof(VulnerabilityId));
|
|
|
|
public string Status { get; } = Normalize(Status, nameof(Status));
|
|
|
|
internal void Validate()
|
|
{
|
|
_ = ProductKey;
|
|
_ = VulnerabilityId;
|
|
_ = Status;
|
|
}
|
|
|
|
private static string Normalize(string value, string propertyName)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
throw new ValidationException($"{propertyName} must be provided.");
|
|
}
|
|
|
|
return value.Trim();
|
|
}
|
|
}
|
|
|
|
public sealed record WebhookEventWindow(DateTimeOffset? From, DateTimeOffset? To);
|