namespace ScadaLink.Security;
public class SecurityOptions
{
public string LdapServer { get; set; } = string.Empty;
public int LdapPort { get; set; } = 389;
///
/// Transport security mode for the LDAP connection. Defaults to LDAPS.
/// Use to connect on the plaintext port
/// and upgrade the session before binding.
///
public LdapTransport LdapTransport { get; set; } = LdapTransport.Ldaps;
///
/// True when the configured transport provides encryption (LDAPS or StartTLS).
/// Retained for backward compatibility: assigning a value maps onto
/// (true => LDAPS, false => None).
///
public bool LdapUseTls
{
get => LdapTransport != LdapTransport.None;
set => LdapTransport = value ? LdapTransport.Ldaps : LdapTransport.None;
}
///
/// Allow insecure (non-TLS) LDAP connections. ONLY for dev/test with GLAuth.
/// Must be false in production.
///
public bool AllowInsecureLdap { get; set; } = false;
///
/// Base DN for LDAP searches (e.g., "dc=example,dc=com").
///
public string LdapSearchBase { get; set; } = string.Empty;
///
/// Service account DN for LDAP user searches (e.g., "cn=admin,dc=example,dc=com").
/// Required for search-then-bind authentication. If empty, direct bind with
/// {LdapUserIdAttribute}={username},{LdapSearchBase} is attempted instead.
///
public string LdapServiceAccountDn { get; set; } = string.Empty;
///
/// LDAP attribute that identifies a user. Used both for the search-then-bind
/// filter (({LdapUserIdAttribute}={username})) and for constructing the
/// fallback bind DN when no service account is configured, so the two
/// authentication modes are interchangeable. Common values: uid (OpenLDAP),
/// sAMAccountName (Active Directory).
///
public string LdapUserIdAttribute { get; set; } = "uid";
///
/// Service account password for LDAP user searches.
///
public string LdapServiceAccountPassword { get; set; } = string.Empty;
///
/// LDAP attribute that contains the user's display name.
///
public string LdapDisplayNameAttribute { get; set; } = "cn";
///
/// LDAP attribute that contains group membership.
///
public string LdapGroupAttribute { get; set; } = "memberOf";
///
/// Network timeout, in milliseconds, applied to the LDAP socket connect and to
/// LDAP operations (bind/search). The synchronous Novell LDAP calls are wrapped
/// in Task.Run, where the CancellationToken only guards work-item
/// scheduling — it cannot interrupt an in-progress blocking call. This timeout is
/// the real safeguard: it bounds how long a hung LDAP server can pin a thread-pool
/// thread (Security-009). Default 10 seconds.
///
public int LdapConnectionTimeoutMs { get; set; } = 10_000;
///
/// Symmetric HMAC-SHA256 signing key for cookie-embedded JWTs. Must be at least
/// 32 bytes (256 bits) — validated at construction.
///
public string JwtSigningKey { get; set; } = string.Empty;
///
/// Minimum signing-key length in bytes required for HMAC-SHA256 (256 bits).
///
public const int MinJwtSigningKeyBytes = 32;
public int JwtExpiryMinutes { get; set; } = 15;
public int IdleTimeoutMinutes { get; set; } = 30;
///
/// Minutes before token expiry to trigger refresh.
///
public int JwtRefreshThresholdMinutes { get; set; } = 5;
}