public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { AuthLogic.AssertStarted(sb); OperationLogic.AssertStarted(sb); OperationLogic.AllowOperation += OperationLogic_AllowOperation; cache = new AuthCache <RuleOperationEntity, OperationAllowedRule, OperationSymbol, OperationSymbol, OperationAllowed>(sb, s => s, s => s, merger: new OperationMerger(), invalidateWithTypes: true, coercer: OperationCoercer.Instance); AuthLogic.ExportToXml += exportAll => cache.ExportXml("Operations", "Operation", s => s.Key, b => b.ToString(), exportAll ? OperationLogic.RegisteredOperations.ToList() : null); AuthLogic.ImportFromXml += (x, roles, replacements) => { string replacementKey = "AuthRules:" + typeof(OperationSymbol).Name; replacements.AskForReplacements( x.Element("Operations").Elements("Role").SelectMany(r => r.Elements("Operation")).Select(p => p.Attribute("Resource").Value).ToHashSet(), SymbolLogic <OperationSymbol> .AllUniqueKeys(), replacementKey); return(cache.ImportXml(x, "Operations", "Operation", roles, s => SymbolLogic <OperationSymbol> .TryToSymbol(replacements.Apply(replacementKey, s)), EnumExtensions.ToEnum <OperationAllowed>)); }; } }
internal SqlPreCommand?ImportXml(XElement element, Dictionary <string, Lite <RoleEntity> > roles, Replacements replacements) { var current = Database.RetrieveAll <RuleTypeEntity>().GroupToDictionary(a => a.Role); var xRoles = (element.Element("Types")?.Elements("Role")).EmptyIfNull(); var should = xRoles.ToDictionary(x => roles.GetOrThrow(x.Attribute("Name").Value)); Table table = Schema.Current.Table(typeof(RuleTypeEntity)); replacements.AskForReplacements( xRoles.SelectMany(x => x.Elements("Type")).Select(x => x.Attribute("Resource").Value).ToHashSet(), TypeLogic.NameToType.Where(a => !a.Value.IsEnumEntity()).Select(a => a.Key).ToHashSet(), typeReplacementKey); replacements.AskForReplacements( xRoles.SelectMany(x => x.Elements("Type")).SelectMany(t => t.Elements("Condition")).Select(x => x.Attribute("Name").Value).ToHashSet(), SymbolLogic <TypeConditionSymbol> .AllUniqueKeys(), typeConditionReplacementKey); Func <string, TypeEntity?> getResource = s => { Type?type = TypeLogic.NameToType.TryGetC(replacements.Apply(typeReplacementKey, s)); if (type == null) { return(null); } return(TypeLogic.TypeToEntity.GetOrThrow(type)); }; return(Synchronizer.SynchronizeScript(Spacing.Double, should, current, createNew: (role, x) => { var dic = (from xr in x.Elements("Type") let t = getResource(xr.Attribute("Resource").Value) where t != null select KVP.Create(t, new { Allowed = xr.Attribute("Allowed").Value.ToEnum <TypeAllowed>(), Condition = Conditions(xr, replacements) })).ToDictionaryEx("Type rules for {0}".FormatWith(role)); SqlPreCommand?restSql = dic.Select(kvp => table.InsertSqlSync(new RuleTypeEntity { Resource = kvp.Key, Role = role, Allowed = kvp.Value.Allowed, Conditions = kvp.Value.Condition ! /*CSBUG*/ }, comment: Comment(role, kvp.Key, kvp.Value.Allowed))).Combine(Spacing.Simple)?.Do(p => p.GoBefore = true);
static string SynchronizeContent(string content, Replacements r, SyncData data) { if (content == null) { return(null); } return(WikiMarkup.WikiParserExtensions.TokenRegex.Replace(content, m => { var m2 = HelpLinkRegex.Match(m.Groups["content"].Value); if (!m2.Success) { return m.Value; } string letter = m2.Groups["letter"].Value; string link = m2.Groups["link"].Value; string text = m2.Groups["text"].Value; switch (letter) { case WikiFormat.EntityLink: { string type = r.SelectInteractive(link, TypeLogic.NameToType.Keys, "Type", data.StringDistance); if (type == null) { return Link(letter + "-error", link, text); } return Link(letter, type, text); } case WikiFormat.PropertyLink: { string type = r.SelectInteractive(link.Before("."), TypeLogic.NameToType.Keys, "Type", data.StringDistance); if (type == null) { return Link(letter + "-error", link, text); } var routes = PropertyRoute.GenerateRoutes(TypeLogic.GetType(type)).Select(a => a.PropertyString()).ToList(); string pr = r.SelectInteractive(link.After('.'), routes, "PropertyRoutes-" + type, data.StringDistance); if (pr == null) { return Link(letter + "-error", link, text); } return Link(letter, type + "." + pr, text); } case WikiFormat.QueryLink: { string query = r.SelectInteractive(link, QueryLogic.QueryNames.Keys, "Query", data.StringDistance); if (query == null) { return Link(letter + "-error", link, text); } return Link(letter, query, text); } case WikiFormat.OperationLink: { string operation = r.SelectInteractive(link, SymbolLogic <OperationSymbol> .AllUniqueKeys(), "Operation", data.StringDistance); if (operation == null) { return Link(letter + "-error", link, text); } return Link(letter, operation, text); } case WikiFormat.Hyperlink: return m.Value; case WikiFormat.NamespaceLink: { string @namespace = r.SelectInteractive(link, data.Namespaces, "Namespace", data.StringDistance); if (@namespace == null) { return Link(letter + "-error", link, text); } return Link(letter, @namespace, text); } case WikiFormat.AppendixLink: { string appendix = r.SelectInteractive(link, data.Appendices, "Appendices", data.StringDistance); if (appendix == null) { return Link(letter + "-error", link, text); } return Link(letter, appendix, text); } default: break; } return m.Value; })); }
internal SqlPreCommand ImportXml(XElement element, Dictionary <string, Lite <RoleEntity> > roles, Replacements replacements) { var current = Database.RetrieveAll <RuleTypeEntity>().GroupToDictionary(a => a.Role); var xRoles = (element.Element("Types")?.Elements("Role")).EmptyIfNull(); var should = xRoles.ToDictionary(x => roles[x.Attribute("Name").Value]); Table table = Schema.Current.Table(typeof(RuleTypeEntity)); replacements.AskForReplacements( xRoles.SelectMany(x => x.Elements("Type")).Select(x => x.Attribute("Resource").Value).ToHashSet(), TypeLogic.NameToType.Where(a => !a.Value.IsEnumEntity()).Select(a => a.Key).ToHashSet(), typeReplacementKey); replacements.AskForReplacements( xRoles.SelectMany(x => x.Elements("Type")).SelectMany(t => t.Elements("Condition")).Select(x => x.Attribute("Name").Value).ToHashSet(), SymbolLogic <TypeConditionSymbol> .AllUniqueKeys(), typeConditionReplacementKey); Func <string, TypeEntity> getResource = s => { Type type = TypeLogic.NameToType.TryGetC(replacements.Apply(typeReplacementKey, s)); if (type == null) { return(null); } return(TypeLogic.TypeToEntity[type]); }; return(Synchronizer.SynchronizeScript(Spacing.Double, should, current, createNew: (role, x) => { var dic = (from xr in x.Elements("Type") let t = getResource(xr.Attribute("Resource").Value) where t != null select KVP.Create(t, new { Allowed = xr.Attribute("Allowed").Value.ToEnum <TypeAllowed>(), Condition = Conditions(xr, replacements) })).ToDictionaryEx("Type rules for {0}".FormatWith(role)); SqlPreCommand restSql = dic.Select(kvp => table.InsertSqlSync(new RuleTypeEntity { Resource = kvp.Key, Role = role, Allowed = kvp.Value.Allowed, Conditions = kvp.Value.Condition }, comment: Comment(role, kvp.Key, kvp.Value.Allowed))).Combine(Spacing.Simple)?.Do(p => p.GoBefore = true); return restSql; }, removeOld: (role, list) => list.Select(rt => table.DeleteSqlSync(rt)).Combine(Spacing.Simple)?.Do(p => p.GoBefore = true), mergeBoth: (role, x, list) => { var dic = (from xr in x.Elements("Type") let t = getResource(xr.Attribute("Resource").Value) where t != null && !t.ToType().IsEnumEntity() select KVP.Create(t, xr)).ToDictionaryEx("Type rules for {0}".FormatWith(role)); SqlPreCommand restSql = Synchronizer.SynchronizeScript( Spacing.Simple, dic, list.Where(a => a.Resource != null).ToDictionary(a => a.Resource), createNew: (r, xr) => { var a = xr.Attribute("Allowed").Value.ToEnum <TypeAllowed>(); var conditions = Conditions(xr, replacements); return table.InsertSqlSync(new RuleTypeEntity { Resource = r, Role = role, Allowed = a, Conditions = conditions }, comment: Comment(role, r, a)); }, removeOld: (r, rt) => table.DeleteSqlSync(rt, Comment(role, r, rt.Allowed)), mergeBoth: (r, xr, pr) => { var oldA = pr.Allowed; pr.Allowed = xr.Attribute("Allowed").Value.ToEnum <TypeAllowed>(); var conditions = Conditions(xr, replacements); if (!pr.Conditions.SequenceEqual(conditions)) { pr.Conditions = conditions; } return table.UpdateSqlSync(pr, comment: Comment(role, r, oldA, pr.Allowed)); })?.Do(p => p.GoBefore = true); return restSql; })); }