public static XDoc GetInstanceSettingsAsDoc(SiteSettingsRetrievalSettings retrieve) { var instance = DekiContext.Current.Instance; string cachekey = retrieve.IncludeHidden ? CACHE_SETTINGSDOC_WITHHIDDEN : CACHE_SETTINGSDOC; XDoc result = instance.Cache.Get <XDoc>(cachekey, null); if (result == null) { Dictionary <string, ConfigValue> config = GetInstanceSettings(); List <KeyValuePair <string, string> > items = new List <KeyValuePair <string, string> >(); lock (config) { foreach (KeyValuePair <string, ConfigValue> entry in config) { if (entry.Value.IsHidden && !retrieve.IncludeHidden) { continue; } // check if overwritten setting was an element int index = entry.Key.LastIndexOf('/'); bool isElement = ((index + 1) < entry.Key.Length) && (entry.Key[index + 1] != '@'); items.Add(new KeyValuePair <string, string>(entry.Key, entry.Value.Value)); if (isElement) { if (entry.Value.IsReadOnly) { // we need to add a 'readonly' attribute items.Add(new KeyValuePair <string, string>(entry.Key + READONLY_SUFFIX, "true")); } if (entry.Value.IsHidden) { // we need to add a 'hidden' attribute items.Add(new KeyValuePair <string, string>(entry.Key + HIDDEN_SUFFIX, "true")); } } } } //Ensure that attributes are after their associated elements to ensure that the #text and the @attribute are part of the same element rather than creating a new element with just the #text //after the attribute. Consider moving this to Dream XDocFactory.From items.Sort((left, right) => StringUtil.CompareInvariant(left.Key, right.Key)); result = XDocFactory.From(items, "config"); var u = DbUtils.CurrentSession.Users_GetByName(UserBL.ANON_USERNAME); var anonDoc = UserBL.GetUserXmlVerbose(u, null, Utils.ShowPrivateUserInfo(u), true, true); result.InsertValueAt(ANONYMOUS_USER, anonDoc.ToJson()); // Add license information var licenseManager = DekiContext.Current.LicenseManager; var licenseDoc = licenseManager.GetLicenseDocument(false).Clone(); licenseDoc.Elem("type", licenseDoc["@type"].Contents); _log.Debug("Added private information."); licenseDoc["support-agreement"].Remove(); licenseDoc["source-license"].Remove(); licenseDoc["license.public"].Remove(); licenseDoc["grants/service-license"].RemoveAll(); var now = DateTime.UtcNow; foreach (var capability in licenseDoc["grants/*[@date.expire]"]) { if (capability["@date.expire"].AsDate < now) { capability.Remove(); } } XDoc originalLicenseElems = result["license"]; XDoc clonedOriginalLicenseElems = XDoc.Empty; if (!originalLicenseElems.IsEmpty) { clonedOriginalLicenseElems = originalLicenseElems.Clone(); originalLicenseElems.Remove(); licenseDoc.AddNodes(clonedOriginalLicenseElems); } result.Start(LICENSE).AddNodes(licenseDoc).End(); AddVersionInfo(result); instance.Cache.Set(cachekey, result.Clone(), DateTime.UtcNow.AddSeconds(60)); } else { // TODO: remove the clone once cached settings come out of IKeyValueCache (i.e. are serialized) // NOTE(cesarn): We need to clone it because we are stripping and adding // elements depending on permissions and what is requested, but we do not // want to change the cached version that contains everything. result = result.Clone(); } if (!retrieve.IncludeAnonymousUser) { result[ANONYMOUS_USER].Remove(); _log.Debug("Removing anonymous's user information."); } if (!retrieve.IncludeLicense) { var mandatoryLicenseInfo = new XDoc(LICENSE).Start("state").Attr("readonly", "true").Value(result[LICENSE_STATE].Contents).End(); if (DekiContext.Current.LicenseManager.LicenseExpiration != DateTime.MaxValue) { mandatoryLicenseInfo.Start("expiration").Attr("readonly", "true").Value(result[LICENSE_EXPIRATION].Contents).End(); } var productKey = LicenseBL.Instance.BuildProductKey(); if (!String.IsNullOrEmpty(productKey)) { mandatoryLicenseInfo.Start("productkey").Attr("readonly", "true").Value(result[LICENSE_PRODUCTKEY].Contents).End(); } result[LICENSE].Remove(); _log.Debug("Removing private information elements"); result.Start(LICENSE).AddNodes(mandatoryLicenseInfo).End(); } result.InsertValueAt("api/@href", DekiContext.Current.Deki.Self.Uri.AsPublicUri().ToString()); return(result); }