using System; using System.Text.RegularExpressions; namespace BulkArchiveMailer.Core { /// /// Which kind of archive ssh-access-tui produced. See /// internal/keymgr/pack.go (BuildUserArchive -> "_ssh_access.7z") and /// internal/keymgr/configonly.go (BuildConfigOnlyArchive -> /// "_config_update.7z") in the main repo for the producing side. /// public enum ArchiveKind { SshAccess, ConfigUpdate } /// Result of successfully parsing an archive file name. public sealed class ParsedFilename { public ParsedFilename(string login, ArchiveKind kind) { Login = login; Kind = kind; } /// Lower-cased login exactly as it appears in the file name (hyphens intact). public string Login { get; } public ArchiveKind Kind { get; } } /// /// Parses the two file name shapes ssh-access-tui ever produces: /// "{login}_ssh_access.7z" and "{login}_config_update.7z". Anything /// else (wrong extension, extra suffix, typo'd kind, stray file dropped /// in the export folder by a human) simply fails to parse - the caller /// (ArchiveScanner) is responsible for routing that into the /// "unrecognized" bucket instead of blocking the batch. /// public static class FilenameParser { // Matches the login part ssh-access-tui itself accepts for a Linux // username: lowercase alnum segments joined by single hyphens (no // leading/trailing/double hyphens). Case-insensitive purely as a // defensive measure in case a file was renamed by hand on a // case-insensitive filesystem; the captured login is normalized to // lower case before use. private static readonly Regex Pattern = new Regex( @"^(?[a-z0-9]+(?:-[a-z0-9]+)*)_(?ssh_access|config_update)\.7z$", RegexOptions.IgnoreCase | RegexOptions.Compiled); public static bool TryParse(string fileName, out ParsedFilename parsed) { parsed = null; if (string.IsNullOrEmpty(fileName)) { return false; } var match = Pattern.Match(fileName); if (!match.Success) { return false; } var login = match.Groups["login"].Value.ToLowerInvariant(); var kindText = match.Groups["kind"].Value.ToLowerInvariant(); var kind = kindText == "ssh_access" ? ArchiveKind.SshAccess : ArchiveKind.ConfigUpdate; parsed = new ParsedFilename(login, kind); return true; } } }