/************************************************************************* * ModernUO * * Copyright 2019-2026 - ModernUO Development Team * * Email: hi@modernuo.com * * File: CrowdSecAlert.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ using System.Text.Json.Serialization; namespace Server.Network.Bans.CrowdSec; /// One CrowdSec alert (POST /v1/alerts takes an array of these). public sealed class CrowdSecAlert { [JsonPropertyName("scenario")] public string Scenario { get; set; } /// /// Required by LAPI. It dereferences the field unconditionally when persisting the alert, so /// omitting it answers 500 rather than a validation error. Empty is the accepted value for a /// watcher that isn't shipping a hub scenario. /// [JsonPropertyName("scenario_hash")] public string ScenarioHash { get; set; } = ""; /// Required alongside ; same 500-on-missing behavior. [JsonPropertyName("scenario_version")] public string ScenarioVersion { get; set; } = "1.0"; [JsonPropertyName("message")] public string Message { get; set; } [JsonPropertyName("events_count")] public int EventsCount { get; set; } = 1; [JsonPropertyName("start_at")] public string StartAt { get; set; } [JsonPropertyName("stop_at")] public string StopAt { get; set; } /// Bucket capacity. One decision per alert, so 1 — a leaky-bucket capacity of 0 is nonsense. [JsonPropertyName("capacity")] public int Capacity { get; set; } = 1; [JsonPropertyName("leakspeed")] public string LeakSpeed { get; set; } = "0s"; [JsonPropertyName("simulated")] public bool Simulated { get; set; } [JsonPropertyName("events")] public object[] Events { get; set; } = []; [JsonPropertyName("remediation")] public bool Remediation { get; set; } = true; [JsonPropertyName("source")] public CrowdSecSource Source { get; set; } [JsonPropertyName("decisions")] public CrowdSecDecisionDto[] Decisions { get; set; } } public sealed class CrowdSecSource { [JsonPropertyName("scope")] public string Scope { get; set; } = "Ip"; [JsonPropertyName("value")] public string Value { get; set; } } public sealed class CrowdSecDecisionDto { [JsonPropertyName("origin")] public string Origin { get; set; } [JsonPropertyName("type")] public string Type { get; set; } = "ban"; [JsonPropertyName("scope")] public string Scope { get; set; } = "Ip"; [JsonPropertyName("value")] public string Value { get; set; } [JsonPropertyName("duration")] public string Duration { get; set; } [JsonPropertyName("scenario")] public string Scenario { get; set; } } /// Watcher login request/response for POST /v1/watchers/login. public sealed class CrowdSecLoginRequest { [JsonPropertyName("machine_id")] public string MachineId { get; set; } [JsonPropertyName("password")] public string Password { get; set; } } public sealed class CrowdSecLoginResponse { [JsonPropertyName("code")] public int Code { get; set; } [JsonPropertyName("token")] public string Token { get; set; } [JsonPropertyName("expire")] public string Expire { get; set; } }