//--- Methods --- protected override IEnumerator <IYield> Start(XDoc config, Result result) { yield return(Coroutine.Invoke(base.Start, config, new Result())); _processingQueue = new ProcessingQueue <XDoc>(CallUpdate); _instances = new ExpiringDictionary <string, PackageUpdater>(TimerFactory, true); _apikey = config["apikey"].AsText; _instanceTtl = TimeSpan.FromSeconds(config["instance-ttl"].AsInt ?? 10 * 60); _packagePath = config["package-path"].AsText; if (string.IsNullOrEmpty(_packagePath)) { throw new ArgumentException("No value was provided for configuration key 'package-path'"); } try { _packagePath = PhpUtil.ConvertToFormatString(_packagePath); // Note (arnec): _packagePath may contain a {0} for injecting wikiid, so we want to make sure the // path string can be formatted without an exception string.Format(_packagePath, "dummy"); } catch { throw new ArgumentException(string.Format("The package path '{0}' contains an illegal formmating directive", _packagePath)); } // set up subscription for pubsub yield return(Coroutine.Invoke(SubscribeInstanceEvents, PubSub, new Result())); result.Return(); }
public Stream Format(XDoc doc) { var stream = new MemoryStream(); PhpUtil.WritePhp(doc, stream, MimeType.PHP.CharSet); stream.Position = 0; return(stream); }
public string BuildBindDn(string username) { if (string.IsNullOrEmpty(username)) { return(null); } return (string.Format(PhpUtil.ConvertToFormatString(_config.BindingDn), username)); }
public void PhpSerialization3() { XDoc doc = new XDoc("test"); doc.Value("<tag>ö</tag>"); Encoding encoding = Encoding.GetEncoding("ISO-8859-1"); MemoryStream stream = new MemoryStream(); PhpUtil.WritePhp(doc, stream, encoding); byte[] text = stream.ToArray(); Assert.IsTrue(ArrayUtil.Compare(encoding.GetBytes("a:1:{s:4:\"test\";s:12:\"<tag>ö</tag>\";}"), text) == 0); }
/// <summary> /// Retrieves group information from ldap /// </summary> /// <param name="retrieveGroupMembers">true to return users in each group. This may hurt performance</param> /// <param name="optionalGroupName">Group to lookup by name. Null for all groups</param> /// <returns></returns> public XDoc GetGroupInfo(bool retrieveGroupMembers, string optionalGroupName) { LdapConnection conn = null; XDoc resultXml = null; try { //Confirm a query bind has been established conn = Bind(); string searchFilter; //Build the searchfilter based on if a group name is given. if (!string.IsNullOrEmpty(optionalGroupName)) { optionalGroupName = EscapeLdapString(optionalGroupName); //Looking up group by name searchFilter = string.Format(PhpUtil.ConvertToFormatString(_config.GroupQuery), optionalGroupName); } else { //Looking up all groups searchFilter = _config.GroupQueryAll; } //Build interesting attribute list List <string> attrs = new List <string>(); attrs.AddRange(new string[] { "whenCreated", "name", "sAMAccountName", "cn" }); if (retrieveGroupMembers) { attrs.Add("member"); } if (!string.IsNullOrEmpty(_config.GroupNameAttribute) && !attrs.Contains(_config.GroupNameAttribute)) { attrs.Add(_config.GroupNameAttribute); } LdapSearchConstraints cons = new LdapSearchConstraints(new LdapConstraints(_timeLimit, true, null, 0)); cons.BatchSize = 0; LdapSearchResults results = conn.Search(_config.LdapSearchBase, LdapConnection.SCOPE_SUB, searchFilter, attrs.ToArray(), false, cons); //Create outer groups collection if multiple groups are being looked up or none provided if (string.IsNullOrEmpty(optionalGroupName)) { resultXml = new XDoc("groups"); } while (results.hasMore()) { LdapEntry nextEntry = null; try { nextEntry = results.next(); } catch (LdapException x) { HandleLdapException(x); continue; } //Create xml from search entry if (resultXml == null) { resultXml = new XDoc("group"); } else { resultXml.Start("group"); } string name = string.Empty; //If a groupnameattribute is configured, use that. Otherwise try the common ones. if (!string.IsNullOrEmpty(_config.GroupNameAttribute)) { name = GetAttributeSafe(nextEntry, _config.GroupNameAttribute); } else { name = GetAttributeSafe(nextEntry, "sAMAccountName"); //MS Active Directory if (string.IsNullOrEmpty(name)) { name = GetAttributeSafe(nextEntry, "uid"); //OpenLDAP } if (string.IsNullOrEmpty(name)) { name = GetAttributeSafe(nextEntry, "name"); //OpenLDAP } if (string.IsNullOrEmpty(name)) { name = GetAttributeSafe(nextEntry, "cn"); //Novell eDirectory } } resultXml.Attr("name", name); resultXml.Start("ldap-dn").Value(nextEntry.DN).End(); resultXml.Start("date.created").Value(ldapStringToDate(GetAttributeSafe(nextEntry, "whenCreated"))).End(); //Retrieve and write group membership to xml LdapAttributeSet memberAttrSet = nextEntry.getAttributeSet(); LdapAttribute memberAttr = memberAttrSet.getAttribute("member"); // TODO MaxM: This currently does not differentiate between user and group // members. if (memberAttr != null) { foreach (string member in memberAttr.StringValueArray) { resultXml.Start("member"); resultXml.Attr("name", GetNameFromDn(member)); resultXml.Start("ldap-dn").Value(member).End(); resultXml.End(); } } if (string.IsNullOrEmpty(optionalGroupName)) { resultXml.End(); } } } finally { UnBind(conn); } return(resultXml); }
//--- Methods --- public IDictionaryEnumerator GetEnumerator() { Dictionary <String, String> resources = new Dictionary <String, String>(); if (System.IO.File.Exists(_filename)) { char[] brackets = new char[] { ']' }; char[] equals = new char[] { '=' }; string[] parts; // read the file into the hashtable using (StreamReader sr = new StreamReader(_filename, System.Text.Encoding.UTF8, true)) { int count = 0; string section = null; for (string line = sr.ReadLine(); line != null; line = sr.ReadLine()) { line = line.TrimStart(); ++count; // check if line is a comment if (line.StartsWith(";")) { continue; } // check if line is a new section if (line.StartsWith("[")) { parts = line.Substring(1).Split(brackets, 2); if (!string.IsNullOrEmpty(parts[0])) { section = parts[0].Trim(); } else { section = null; _log.WarnMethodCall("missing namespace name", _filename, count); } continue; } // parse the line as key=value parts = line.Split(equals, 2); if (parts.Length == 2) { if (!string.IsNullOrEmpty(parts[0])) { string key; // check if a section is defined if (section != null) { key = section + "." + parts[0]; } else { key = parts[0]; _log.WarnMethodCall("missing namespace prefix", _filename, count, parts[0]); } // check if key already exists if (resources.ContainsKey(key)) { _log.WarnMethodCall("duplicate key", _filename, count, key); } resources[key] = PhpUtil.ConvertToFormatString(parts[1]); } else { _log.WarnMethodCall("empty key", _filename, count, line); } } else if (line != string.Empty) { _log.WarnMethodCall("bad key/value pair", _filename, count, line); } } sr.Close(); } } return(resources.GetEnumerator()); }
/// <summary> /// Calls methods to perform initial init of a wiki instance including db updates, etc /// </summary> public void Startup(DekiContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (_status != DekiInstanceStatus.CREATED) { throw new InvalidOperationException("bad state"); } _status = DekiInstanceStatus.INITIALIZING; // run startup code try { // have to initialize the event sink first since because license checking might trigger a license transition event _eventSink = new DekiChangeSink(Id, DekiContext.Current.ApiUri, DekiContext.Current.Deki.PubSub.At("publish").WithCookieJar(DekiContext.Current.Deki.Cookies)); // create the IDekiDataSessionFactory for this instance Type typeMySql = Type.GetType("MindTouch.Deki.Data.MySql.MySqlDekiDataSessionFactory, mindtouch.deki.data.mysql", true); Type typeCaching = null; try { typeCaching = Type.GetType("MindTouch.Deki.Data.Caching.CachingDekiDataSessionFactory, mindtouch.data.caching", false); } catch (Exception x) { Log.Warn("The caching library was found but could not be loaded. Check that its version matches the version of your MindTouch API", x); } // FUN FACT: DekiInstanceSettings is a proxy for the static calls in ConfigBL, which expects to access DbUtils.CurrentSession, // which has to be initialized by the session factory.. Yes, the very session factory that takes DekiInstanceSettings as part // of its initialization call. I call it the M.C.Escher Design Pattern. var sessionFactory = (IDekiDataSessionFactory)typeMySql.GetConstructor(Type.EmptyTypes).Invoke(null); sessionFactory = new LoggingDekiDataSessionFactory(sessionFactory); sessionFactory = new DekiDataSessionProfilerFactory(sessionFactory); if (typeCaching != null) { sessionFactory = (IDekiDataSessionFactory)typeCaching.GetConstructor(new[] { typeof(IDekiDataSessionFactory) }).Invoke(new object[] { sessionFactory }); } _sessionFactory = sessionFactory; _sessionFactory.Initialize(Config ?? _deki.Config, _licenseController.LicenseDoc, new DekiInstanceSettings()); var state = context.LicenseManager.LicenseState; if (state == LicenseStateType.UNDEFINED) { throw new MindTouchInvalidLicenseStateException(); } // set deki license token _token = context.LicenseManager.LicenseDocument["licensee/deki"].AsText; if (string.IsNullOrEmpty(_token)) { // compute deki license token var tokenKey = _apiKey ?? _deki.MasterApiKey; ulong folded_productkey_md5 = 0; byte[] md5_bytes = StringUtil.ComputeHash(tokenKey, Encoding.UTF8); for (int i = 0; i < md5_bytes.Length; ++i) { folded_productkey_md5 ^= (ulong)md5_bytes[i] << (i & 7) * 8; } _token = folded_productkey_md5.ToString("X"); } // check if a storage config section was provided (default storage is filesystem provider) XDoc storageConfig; switch (ConfigBL.GetInstanceSettingsValue("storage/@type", ConfigBL.GetInstanceSettingsValue("storage/type", "default"))) { case "default": string defaultAttachPath = Path.Combine(_deki.DekiPath, "attachments"); storageConfig = new XDoc("config") .Elem("path", defaultAttachPath) .Elem("cache-path", Path.Combine(defaultAttachPath, ".cache")); _storage = new FSStorage(storageConfig); break; case "fs": string fsPath = ConfigBL.GetInstanceSettingsValue("storage/fs/path", null); //Replace a $1 with the wiki name fsPath = string.Format(PhpUtil.ConvertToFormatString(fsPath ?? string.Empty), Id); storageConfig = new XDoc("config") .Elem("path", fsPath) .Elem("cache-path", ConfigBL.GetInstanceSettingsValue("storage/fs/cache-path", null)); _storage = new FSStorage(storageConfig); break; case "s3": storageConfig = new XDoc("config") .Elem("publickey", ConfigBL.GetInstanceSettingsValue("storage/s3/publickey", null)) .Elem("privatekey", ConfigBL.GetInstanceSettingsValue("storage/s3/privatekey", null)) .Elem("bucket", ConfigBL.GetInstanceSettingsValue("storage/s3/bucket", null)) .Elem("prefix", string.Format(PhpUtil.ConvertToFormatString(ConfigBL.GetInstanceSettingsValue("storage/s3/prefix", string.Empty)), DekiContext.Current.Instance.Id)) .Elem("timeout", ConfigBL.GetInstanceSettingsValue("storage/s3/timeout", null)) .Elem("allowredirects", ConfigBL.GetInstanceSettingsValue("storage/s3/allowredirects", null)) .Elem("redirecttimeout", ConfigBL.GetInstanceSettingsValue("storage/s3/redirecttimeout", null)); _storage = new S3Storage(storageConfig, _loggerRepository.Get <S3Storage>()); break; default: throw new ArgumentException("Storage provider unknown or not defined (key: storage/type)", "storage/type"); } HomePageId = DbUtils.CurrentSession.Pages_HomePageId; _eventSink.InstanceStarting(DekiContext.Current.Now); } catch { // we failed to initialize _status = DekiInstanceStatus.ABANDONED; throw; } // set state to initializing _status = DekiInstanceStatus.INITIALIZING; }