private static bool ProcessNode(RightsRule rule, ExecuteContext ctx) { // check if node matches if (!rule.HasMatcher() || (ctx.Host != null && rule.MatchHost.Contains(ctx.Host)) || (ctx.ClientUid != null && rule.MatchClientUid.Contains(ctx.ClientUid)) || (ctx.AvailableGroups.Length > 0 && rule.MatchClientGroupId.Overlaps(ctx.AvailableGroups)) || (ctx.ChannelGroupId.HasValue && rule.MatchChannelGroupId.Contains(ctx.ChannelGroupId.Value)) || (ctx.ApiToken != null && rule.MatchToken.Contains(ctx.ApiToken)) || (ctx.IsApi == rule.MatchIsApi) || (ctx.Visibiliy.HasValue && rule.MatchVisibility.Contains(ctx.Visibiliy.Value))) { bool hasMatchingChild = false; foreach (var child in rule.ChildrenRules) { hasMatchingChild |= ProcessNode(child, ctx); } if (!hasMatchingChild) { ctx.MatchingRules.Add(rule); } return(true); } return(false); }
public ParseContext(ISet <string> registeredRights) { Declarations = new List <RightsDecl>(); RootRule = new RightsRule(); Errors = new List <string>(); Warnings = new List <string>(); RegisteredRights = registeredRights; }
public ParseContext(ISet <string> registeredRights) { Declarations = new List <RightsDecl>(); RootRule = new RightsRule(); Errors = new List <string>(); Warnings = new List <string>(); RegisteredRights = registeredRights; Groups = Array.Empty <RightsGroup>(); Rules = Array.Empty <RightsRule>(); }
/// <summary> /// Sums up all includes and parent rule declarations for each rule and includes them /// directly into the <see cref="RightsDecl.DeclAdd"/> and <see cref="RightsDecl.DeclDeny"/>. /// </summary> /// <param name="root">The root element of the hierarchy tree.</param> private static void FlattenRules(RightsRule root) { if (root.Parent != null) { root.MergeGroups(root.Parent); } root.MergeGroups(root.Includes); root.Includes = null; foreach (var child in root.ChildrenRules) { FlattenRules(child); } }
private static bool ProcessNode(RightsRule rule, ExecuteContext ctx) { // check if node matches if (rule.Matches(ctx)) { bool hasMatchingChild = false; foreach (var child in rule.ChildrenRules) { hasMatchingChild |= ProcessNode(child, ctx); } if (!hasMatchingChild) { ctx.MatchingRules.Add(rule); } return(true); } return(false); }
private void RecalculateRights(TomlTable table, ParseContext parseCtx) { rules = Array.Empty <RightsRule>(); rootRule = new RightsRule(); if (!rootRule.ParseChilden(table, parseCtx)) { return; } parseCtx.SplitDeclarations(); if (!ValidateUniqueGroupNames(parseCtx)) { return; } if (!ResolveIncludes(parseCtx)) { return; } if (!CheckCyclicGroupDependencies(parseCtx)) { return; } BuildLevel(rootRule); LintDeclarations(parseCtx); if (!NormalizeRule(parseCtx)) { return; } FlattenGroups(parseCtx); FlattenRules(rootRule); rules = parseCtx.Rules; }
private RightsRule TryGetRootSafe() { var localRootRule = rootRule; if (localRootRule != null && !needsRecalculation) { return(localRootRule); } lock (rootRuleLock) { if (rootRule != null && !needsRecalculation) { return(rootRule); } rootRule = ReadFile(); return(rootRule); } }
private void RecalculateRights(TomlTable table, ParseContext parseCtx) { Rules = new RightsRule[0]; RootRule = new RightsRule(); if (!RootRule.ParseChilden(table, parseCtx)) { return; } parseCtx.SplitDeclarations(); if (!ValidateUniqueGroupNames(parseCtx)) { return; } if (!ResolveIncludes(parseCtx)) { return; } if (!CheckCyclicGroupDependencies(parseCtx)) { return; } BuildLevel(RootRule); LintDeclarations(parseCtx); SanitizeRules(parseCtx); FlattenGroups(parseCtx); FlattenRules(RootRule); Rules = parseCtx.Rules; }
public override bool ParseKey(string key, TomlObject tomlObj, ParseContext ctx) { if (base.ParseKey(key, tomlObj, ctx)) { return(true); } switch (key) { case "host": var host = TomlTools.GetValues <string>(tomlObj); if (host == null) { ctx.Errors.Add("<host> Field has invalid data."); } else { MatchHost = new HashSet <string>(host); } return(true); case "groupid": var groupid = TomlTools.GetValues <ulong>(tomlObj); if (groupid == null) { ctx.Errors.Add("<groupid> Field has invalid data."); } else { MatchClientGroupId = new HashSet <ulong>(groupid); } return(true); case "channelgroupid": var cgroupid = TomlTools.GetValues <ulong>(tomlObj); if (cgroupid == null) { ctx.Errors.Add("<channelgroupid> Field has invalid data."); } else { MatchChannelGroupId = new HashSet <ulong>(cgroupid); } return(true); case "useruid": var useruid = TomlTools.GetValues <string>(tomlObj); if (useruid == null) { ctx.Errors.Add("<useruid> Field has invalid data."); } else { MatchClientUid = new HashSet <string>(useruid); } return(true); case "perm": var perm = TomlTools.GetValues <string>(tomlObj); if (perm == null) { ctx.Errors.Add("<perm> Field has invalid data."); } else { MatchPermission = new HashSet <string>(perm); } return(true); case "visibility": var visibility = TomlTools.GetValues <TextMessageTargetMode>(tomlObj); if (visibility == null) { ctx.Errors.Add("<visibility> Field has invalid data."); } else { MatchVisibility = visibility; } return(true); case "rule": if (tomlObj.TomlType == TomlObjectType.ArrayOfTables) { var childTables = (TomlTableArray)tomlObj; foreach (var childTable in childTables.Items) { var rule = new RightsRule(); Children.Add(rule); rule.Parent = this; rule.ParseChilden(childTable, ctx); } return(true); } else { ctx.Errors.Add("Misused key with reserved name \"rule\"."); return(false); } default: // group if (key.StartsWith("$")) { if (tomlObj.TomlType == TomlObjectType.Table) { var childTable = (TomlTable)tomlObj; var group = new RightsGroup(key); Children.Add(group); group.Parent = this; group.ParseChilden(childTable, ctx); return(true); } else { ctx.Errors.Add($"Misused key for group declaration: {key}."); } } return(false); } }
public override bool ParseKey(string key, TomlObject tomlObj, ParseContext ctx) { if (base.ParseKey(key, tomlObj, ctx)) { return(true); } switch (key) { case "host": if (tomlObj.TryGetValueArray <string>(out var host)) { Matcher.Add(new MatchHost(host)); } else { ctx.Errors.Add("<host> Field has invalid data."); } return(true); case "groupid": if (tomlObj.TryGetValueArray <ulong>(out var servergroupid)) { Matcher.Add(new MatchServerGroupId(servergroupid.Select(ServerGroupId.To))); } else { ctx.Errors.Add("<groupid> Field has invalid data."); } return(true); case "channelgroupid": if (tomlObj.TryGetValueArray <ulong>(out var channelgroupid)) { Matcher.Add(new MatchChannelGroupId(channelgroupid.Select(ChannelGroupId.To))); } else { ctx.Errors.Add("<channelgroupid> Field has invalid data."); } return(true); case "useruid": if (tomlObj.TryGetValueArray <string>(out var useruid)) { Matcher.Add(new MatchClientUid(useruid.Select(Uid.To))); } else { ctx.Errors.Add("<useruid> Field has invalid data."); } return(true); case "perm": if (tomlObj.TryGetValueArray <string>(out var perm)) { Matcher.Add(new MatchPermission(perm, ctx)); } else { ctx.Errors.Add("<perm> Field has invalid data."); } return(true); case "apitoken": if (tomlObj.TryGetValueArray <string>(out var apitoken)) { Matcher.Add(new MatchToken(apitoken)); } else { ctx.Errors.Add("<apitoken> Field has invalid data."); } return(true); case "bot": if (tomlObj.TryGetValueArray <string>(out var bot)) { Matcher.Add(new MatchBot(bot)); } else { ctx.Errors.Add("<bot> Field has invalid data."); } return(true); case "isapi": if (tomlObj.TryGetValue <bool>(out var isapi)) { Matcher.Add(new MatchIsApi(isapi)); } else { ctx.Errors.Add("<isapi> Field has invalid data."); } return(true); case "ip": if (tomlObj.TryGetValueArray <string>(out var ip)) { Matcher.Add(new MatchApiCallerIp(ip.Select(x => { if (IPAddress.TryParse(x, out var ipa)) { return(ipa); } ctx.Errors.Add($"<ip> Field value '{x}' could not be parsed."); return(null !); }).Where(x => x != null))); } else { ctx.Errors.Add("<ip> Field has invalid data."); } return(true); case "visibility": if (tomlObj.TryGetValueArray <TextMessageTargetMode>(out var visibility)) { Matcher.Add(new MatchVisibility(visibility)); } else { ctx.Errors.Add("<visibility> Field has invalid data."); } return(true); case "rule": if (tomlObj.TomlType == TomlObjectType.ArrayOfTables) { var childTables = (TomlTableArray)tomlObj; foreach (var childTable in childTables.Items) { var rule = new RightsRule(); Children.Add(rule); rule.Parent = this; rule.ParseChilden(childTable, ctx); } return(true); } else { ctx.Errors.Add("Misused key with reserved name \"rule\"."); return(false); } default: // group if (key.StartsWith("$")) { if (tomlObj.TomlType == TomlObjectType.Table) { var childTable = (TomlTable)tomlObj; var group = new RightsGroup(key); Children.Add(group); group.Parent = this; group.ParseChilden(childTable, ctx); return(true); } else { ctx.Errors.Add($"Misused key for group declaration: {key}."); } } return(false); } }