public static SqlPreCommand?ImportRulesScript(XDocument doc, bool interactive) { Replacements replacements = new Replacements { Interactive = interactive }; Dictionary <string, Lite <RoleEntity> > rolesDic = roles.Value.ToDictionary(a => a.ToString()); Dictionary <string, XElement> rolesXml = doc.Root.Element("Roles").Elements("Role").ToDictionary(x => x.Attribute("Name").Value); replacements.AskForReplacements(rolesXml.Keys.ToHashSet(), rolesDic.Keys.ToHashSet(), "Roles"); rolesDic = replacements.ApplyReplacementsToNew(rolesDic, "Roles"); try { var xmlOnly = rolesXml.Keys.Except(rolesDic.Keys).ToList(); if (xmlOnly.Any()) { throw new InvalidOperationException("roles {0} not found on the database".FormatWith(xmlOnly.ToString(", "))); } foreach (var kvp in rolesXml) { var r = rolesDic[kvp.Key]; var current = GetMergeStrategy(r); var should = kvp.Value.Attribute("MergeStrategy")?.Let(t => t.Value.ToEnum <MergeStrategy>()) ?? MergeStrategy.Union; if (current != should) { throw new InvalidOperationException("Merge strategy of {0} is {1} in the database but is {2} in the file".FormatWith(r, current, should)); } EnumerableExtensions.JoinStrict( roles.Value.RelatedTo(r), kvp.Value.Attribute("Contains").Value.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries), sr => sr.ToString(), s => rolesDic[s].ToString(), (sr, s) => 0, "subRoles of {0}".FormatWith(r)); } } catch (InvalidOperationException ex) { throw new InvalidRoleGraphException("The role graph does not match:\r\n" + ex.Message); } var dbOnlyWarnings = rolesDic.Keys.Except(rolesXml.Keys).Select(n => new SqlPreCommandSimple("-- Alien role {0} not configured!!".FormatWith(n)) ).Combine(Spacing.Simple); SqlPreCommand?result = ImportFromXml.GetInvocationListTyped() .Select(inv => inv(doc.Root, rolesDic, replacements)).Combine(Spacing.Triple); if (replacements.Values.Any(a => a.Any())) { SafeConsole.WriteLineColor(ConsoleColor.Red, "There are renames! Remember to export after executing the script"); } if (result == null && dbOnlyWarnings == null) { return(null); } return(SqlPreCommand.Combine(Spacing.Triple, new SqlPreCommandSimple("-- BEGIN AUTH SYNC SCRIPT"), new SqlPreCommandSimple("use {0}".FormatWith(Connector.Current.DatabaseName())), dbOnlyWarnings, result, new SqlPreCommandSimple("-- END AUTH SYNC SCRIPT"))); }
public static SqlPreCommand ImportRulesScript(XDocument doc, bool interactive) { Replacements replacements = new Replacements { Interactive = interactive }; Dictionary<string, Lite<RoleEntity>> rolesDic = roles.Value.ToDictionary(a => a.ToString()); Dictionary<string, XElement> rolesXml = doc.Root.Element("Roles").Elements("Role").ToDictionary(x => x.Attribute("Name").Value); replacements.AskForReplacements(rolesXml.Keys.ToHashSet(), rolesDic.Keys.ToHashSet(), "Roles"); rolesDic = replacements.ApplyReplacementsToNew(rolesDic, "Roles"); try { var xmlOnly = rolesXml.Keys.Except(rolesDic.Keys).ToList(); if (xmlOnly.Any()) throw new InvalidOperationException("roles {0} not found on the database".FormatWith(xmlOnly.ToString(", "))); foreach (var kvp in rolesXml) { var r = rolesDic[kvp.Key]; var current = GetMergeStrategy(r); var should = kvp.Value.Attribute("MergeStrategy")?.Let(t => t.Value.ToEnum<MergeStrategy>()) ?? MergeStrategy.Union; if (current != should) throw new InvalidOperationException("Merge strategy of {0} is {1} in the database but is {2} in the file".FormatWith(r, current, should)); EnumerableExtensions.JoinStrict( roles.Value.RelatedTo(r), kvp.Value.Attribute("Contains").Value.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries), sr => sr.ToString(), s => rolesDic[s].ToString(), (sr, s) => 0, "subRoles of {0}".FormatWith(r)); } } catch (InvalidOperationException ex) { throw new InvalidRoleGraphException("The role graph does not match:\r\n" + ex.Message); } var dbOnlyWarnings = rolesDic.Keys.Except(rolesXml.Keys).Select(n => new SqlPreCommandSimple("-- Alien role {0} not configured!!".FormatWith(n)) ).Combine(Spacing.Simple); SqlPreCommand result = ImportFromXml.GetInvocationListTyped() .Select(inv => inv(doc.Root, rolesDic, replacements)).Combine(Spacing.Triple); result = SqlPreCommand.Combine(Spacing.Triple, result, UpdateLastAuthRules(doc.Root.Element("Exported"))); if (replacements.Values.Any(a => a.Any())) SafeConsole.WriteLineColor(ConsoleColor.Red, "There are renames! Remember to export after executing the script"); if (result == null && dbOnlyWarnings == null) return null; return SqlPreCommand.Combine(Spacing.Triple, new SqlPreCommandSimple("-- BEGIN AUTH SYNC SCRIPT"), new SqlPreCommandSimple("use {0}".FormatWith(Connector.Current.DatabaseName())), dbOnlyWarnings, result, new SqlPreCommandSimple("-- END AUTH SYNC SCRIPT")); }