namespace PrivaPub.Api.Mastodon.Auth { public static class MastodonScopes { public static readonly string[] All = { "read", "write", "follow", "push", "profile", "read:accounts", "read:blocks", "read:bookmarks", "read:favourites", "read:filters", "read:follows", "read:lists", "read:mutes", "read:notifications", "read:search", "read:statuses", "write:accounts", "write:blocks", "write:bookmarks", "write:conversations", "write:favourites", "write:filters", "write:follows", "write:lists", "write:media", "write:mutes", "write:notifications", "write:reports", "write:statuses" }; public static IReadOnlyList Parse(string scopes) { var parsed = (scopes ?? string.Empty).Split(new[] { ' ', '+', ',' }, StringSplitOptions.RemoveEmptyEntries) .Where(s => All.Contains(s)) .Distinct() .ToList(); return parsed.Count == 0 ? new[] { "read" } : parsed; } public static bool Grants(IEnumerable granted, string required) { var scopes = granted as ICollection ?? granted.ToList(); if (scopes.Contains(required)) return true; var colon = required.IndexOf(':'); if (colon > 0 && scopes.Contains(required[..colon])) return true; return required.StartsWith("read:follows") || required.StartsWith("write:follows") || required.StartsWith("write:blocks") || required.StartsWith("read:blocks") || required.StartsWith("write:mutes") || required.StartsWith("read:mutes") ? scopes.Contains("follow") : false; } } }