// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking at the legacy configuration file // returns null if not found // static RestExtensionMethodInfo GetFromLegacyConfiguration(string extensionAlias, string methodName) { const string ExtensionXPath = "/RestExtensions/ext [@alias='{0}']"; const string MethodXPath = "./permission [@method='{0}']"; var config = (Configuration.BaseRestSection)System.Configuration.ConfigurationManager.GetSection("BaseRestExtensions"); if (config == null) { return(null); // does not exist } // fixme - at the moment we reload the config file each time // we have to support live edits of the config file for backward compatibility reason // so if we want to cache, we'd also need to implement a watcher on the config file... var doc = new XmlDocument(); doc.Load(IOHelper.MapPath(SystemFiles.RestextensionsConfig)); var eNode = doc.SelectSingleNode(string.Format(ExtensionXPath, extensionAlias)); if (eNode == null) { return(null); // does not exist } var mNode = eNode.SelectSingleNode(string.Format(MethodXPath, methodName)); if (mNode == null) { return(null); // does not exist } string assemblyName = eNode.Attributes["assembly"].Value; var assembly = Assembly.Load(assemblyName); string typeName = eNode.Attributes["type"].Value; Type type = assembly.GetType(typeName); if (type == null) { return(null); // does not exist } var method = type.GetMethod(methodName); if (method == null) { return(null); // does not exist } var allowAll = GetAttribute(mNode, "allowAll"); var returnXml = GetAttribute(mNode, "returnXml"); var info = new RestExtensionMethodInfo(allowAll != null && allowAll.ToLower() == "true", GetAttribute(mNode, "allowGroup"), GetAttribute(mNode, "allowType"), GetAttribute(mNode, "allowMember"), returnXml == null || returnXml.ToLower() != "false", method); return(info); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the attributes // returns null if not found // static RestExtensionMethodInfo GetFromAttribute(string extensionAlias, string methodName) { // here we can cache because any change would trigger an app restart string cacheKey = extensionAlias + "." + methodName; lock (_cache) { // if it's in the cache, return if (_cache.ContainsKey(cacheKey)) { return(_cache[cacheKey]); } } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo // // note: the extension may be implemented by more than one class var extensions = PluginManager.Current.ResolveRestExtensions() .Where(type => type.GetCustomAttribute <RestExtensionAttribute>(false).Alias == extensionAlias); RestExtensionMethodInfo info = null; foreach (var extension in extensions) // foreach classes with extension alias { var method = extension.GetMethod(methodName); if (method == null) { continue; // not implementing the method = ignore } var attribute = method.GetCustomAttributes(typeof(RestExtensionMethodAttribute), false).Cast <RestExtensionMethodAttribute>().SingleOrDefault(); if (attribute == null) { continue; // method has not attribute = ignore } // got it! info = new RestExtensionMethodInfo(attribute.AllowAll, attribute.AllowGroup, attribute.AllowType, attribute.AllowMember, attribute.ReturnXml, method); // cache lock (_cache) { _cache[cacheKey] = info; } // got it, no need to look any further break; } return(info); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the attributes // returns null if not found // static RestExtensionMethodInfo GetFromAttribute(string extensionAlias, string methodName) { // here we can cache because any change would trigger an app restart string cacheKey = extensionAlias + "." + methodName; lock (_cache) { // if it's in the cache, return if (_cache.ContainsKey(cacheKey)) { return(_cache[cacheKey]); } } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo var extensions = PluginManager.Current.ResolveRestExtensions(); var extension = extensions .SingleOrDefault(type => type.GetCustomAttribute <RestExtensionAttribute>(false).Alias == extensionAlias); RestExtensionMethodInfo info = null; if (extension != null) { var method = extension.GetMethod(methodName); if (method != null) { var attribute = method.GetCustomAttributes(typeof(RestExtensionMethodAttribute), false).Cast <RestExtensionMethodAttribute>().SingleOrDefault(); if (attribute != null) { info = new RestExtensionMethodInfo(attribute.AllowAll, attribute.AllowGroup, attribute.AllowType, attribute.AllowMember, attribute.ReturnXml, method); // looks good, cache lock (_cache) { _cache[cacheKey] = info; } } } } return(info); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking at the configuration file // returns null if not found // static RestExtensionMethodInfo GetFromConfiguration(string extensionAlias, string methodName) { var config = (Configuration.BaseRestSection)System.Configuration.ConfigurationManager.GetSection("BaseRestExtensions"); if (config == null) { return(null); // does not exist } Configuration.ExtensionElement configExtension = config.Items[extensionAlias]; if (configExtension == null) { return(null); // does not exist } Configuration.MethodElement configMethod = configExtension[methodName]; if (configMethod == null) { return(null); // does not exist } MethodInfo method; try { var parts = configExtension.Type.Split(','); if (parts.Length > 2) { throw new Exception(string.Format("Failed to load extension '{0}', invalid type.")); } var assembly = parts.Length == 1 ? Assembly.GetExecutingAssembly() : Assembly.Load(parts[1]); var type = assembly.GetType(parts[0]); method = type.GetMethod(methodName); } catch (Exception e) { throw new Exception(string.Format("Failed to load extension '{0}', see inner exception.", configExtension.Type), e); } if (method == null) { return(null); // does not exist } var info = new RestExtensionMethodInfo(configMethod.AllowAll, configMethod.AllowGroup, configMethod.AllowType, configMethod.AllowMember, configMethod.ReturnXml, method); return(info); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the attributes // returns null if not found // static RestExtensionMethodInfo GetFromAttribute(string extensionAlias, string methodName, int paramsCount) { // here we can cache because any change would trigger an app restart var cacheKey = string.Format("{0}.{1}[{2}]", extensionAlias, methodName, paramsCount); lock (Cache) { // if it's in the cache, return if (Cache.ContainsKey(cacheKey)) { return(Cache[cacheKey]); } } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo // // note: the extension may be implemented by more than one class var extensions = PluginManager.Current.ResolveRestExtensions() .Where(type => type.GetCustomAttribute <RestExtensionAttribute>(false).Alias == extensionAlias); RestExtensionMethodInfo info = null; foreach (var extension in extensions) // foreach classes with extension alias { var methods = extension.GetMethods() .Where(m => m.Name == methodName) .Where(m => m.GetParameters().Count() == paramsCount) .ToArray(); if (methods.Length == 0) { continue; // not implementing the method = ignore } if (methods.Length > 1) { throw new Exception(string.Format("Method \"{0}\" has many overloads with same number of parameters.", methodName)); } var method = methods[0]; if (!method.IsPublic || !method.IsStatic) { throw new Exception(string.Format("Method \"{0}\" has to be public and static.", methodName)); } var attribute = method.GetCustomAttributes(typeof(RestExtensionMethodAttribute), false).Cast <RestExtensionMethodAttribute>().SingleOrDefault(); if (attribute == null) { continue; // method has not attribute = ignore } // got it! info = new RestExtensionMethodInfo(attribute.AllowAll, attribute.AllowGroup, attribute.AllowType, attribute.AllowMember, attribute.ReturnXml, method); // cache lock (Cache) { Cache[cacheKey] = info; } // got it, no need to look any further break; } return(info); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the legacy attributes // returns null if not found // static RestExtensionMethodInfo GetFromLegacyAttribute(string extensionAlias, string methodName) { // here we can cache because any change would trigger an app restart anyway var cacheKey = extensionAlias + "." + methodName; lock (Cache) { // if it's in the cache, return if (Cache.ContainsKey(cacheKey)) { return(Cache[cacheKey]); } } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo // note: add #pragma - yes it's obsolete but we still want to support it for the time being var extensions = PluginManager.Current.ResolveLegacyRestExtensions() #pragma warning disable 612,618 .Where(type => type.GetCustomAttribute <global::umbraco.presentation.umbracobase.RestExtension>(false).GetAlias() == extensionAlias); #pragma warning restore 612,618 RestExtensionMethodInfo info = null; foreach (var extension in extensions) // foreach classes with extension alias { var method = extension.GetMethod(methodName); if (method == null) { continue; // not implementing the method = ignore } #pragma warning disable 612,618 var attribute = method.GetCustomAttributes(typeof(global::umbraco.presentation.umbracobase.RestExtensionMethod), false).Cast <global::umbraco.presentation.umbracobase.RestExtensionMethod>().SingleOrDefault(); #pragma warning restore 612,618 if (attribute == null) { continue; // method has not attribute = ignore } // got it! info = new RestExtensionMethodInfo(attribute.GetAllowAll(), attribute.GetAllowGroup(), attribute.GetAllowType(), attribute.GetAllowMember(), attribute.returnXml, method); // cache lock (Cache) { Cache[cacheKey] = info; } // got it, no need to look any further break; } return(info); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking at the configuration file // returns null if not found // static RestExtensionMethodInfo GetFromConfiguration(string extensionAlias, string methodName, int paramsCount) { var config = Core.Configuration.UmbracoSettings.For <Configuration.BaseRestSection>(); var configExtension = config.Items[extensionAlias]; if (configExtension == null) { return(null); // does not exist } var configMethod = configExtension[methodName]; if (configMethod == null) { return(null); // does not exist } MethodInfo method = null; try { var parts = configExtension.Type.Split(','); if (parts.Length > 2) { throw new Exception(string.Format("Failed to load extension '{0}', invalid type.", configExtension.Type)); } var assembly = parts.Length == 1 ? Assembly.GetExecutingAssembly() : Assembly.Load(parts[1]); var type = assembly.GetType(parts[0]); if (type == null) { throw new Exception(string.Format("Could not get type \"{0}\".", parts[0])); } var methods = type.GetMethods() .Where(m => m.Name == methodName) .Where(m => m.GetParameters().Count() == paramsCount) .ToArray(); if (methods.Length > 1) { throw new Exception(string.Format("Method \"{0}\" has many overloads with same number of parameters.", methodName)); } if (methods.Length > 0) { method = methods[0]; if (!method.IsPublic || !method.IsStatic) { throw new Exception(string.Format("Method \"{0}\" has to be public and static.", methodName)); } } } catch (Exception e) { throw new Exception(string.Format("Failed to load extension '{0}', see inner exception.", configExtension.Type), e); } if (method == null) { return(null); // does not exist } var info = new RestExtensionMethodInfo(configMethod.AllowAll, configMethod.AllowGroup, configMethod.AllowType, configMethod.AllowMember, configMethod.ReturnXml, method); return(info); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking at the legacy configuration file // returns null if not found // static RestExtensionMethodInfo GetFromLegacyConfiguration(string extensionAlias, string methodName) { const string extensionXPath = "/RestExtensions/ext [@alias='{0}']"; const string methodXPath = "./permission [@method='{0}']"; var config = (Configuration.BaseRestSection)System.Configuration.ConfigurationManager.GetSection("BaseRestExtensions"); if (config == null) return null; // does not exist // note - at the moment we reload the config file each time // we have to support live edits of the config file for backward compatibility reason // so if we want to cache, we'd also need to implement a watcher on the config file... var doc = new XmlDocument(); doc.Load(IOHelper.MapPath(SystemFiles.RestextensionsConfig)); var eNode = doc.SelectSingleNode(string.Format(extensionXPath, extensionAlias)); if (eNode == null) return null; // does not exist var mNode = eNode.SelectSingleNode(string.Format(methodXPath, methodName)); if (mNode == null) return null; // does not exist var attributes = eNode.Attributes; if (attributes == null) return null; // has no attributes var assemblyName = attributes["assembly"].Value; var assembly = Assembly.Load(assemblyName); var typeName = attributes["type"].Value; var type = assembly.GetType(typeName); if (type == null) return null; // does not exist var method = type.GetMethod(methodName); if (method == null) return null; // does not exist var allowAll = GetAttribute(mNode, "allowAll"); var returnXml = GetAttribute(mNode, "returnXml"); var info = new RestExtensionMethodInfo(allowAll != null && allowAll.ToLower() == "true", GetAttribute(mNode, "allowGroup"), GetAttribute(mNode, "allowType"), GetAttribute(mNode, "allowMember"), returnXml == null || returnXml.ToLower() != "false", method); return info; }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the attributes // returns null if not found // static RestExtensionMethodInfo GetFromAttribute(string extensionAlias, string methodName, int paramsCount) { // here we can cache because any change would trigger an app restart var cacheKey = string.Format("{0}.{1}[{2}]", extensionAlias, methodName, paramsCount); lock (Cache) { // if it's in the cache, return if (Cache.ContainsKey(cacheKey)) return Cache[cacheKey]; } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo // // note: the extension may be implemented by more than one class var extensions = PluginManager.Current.ResolveRestExtensions() .Where(type => type.GetCustomAttribute<RestExtensionAttribute>(false).Alias == extensionAlias); RestExtensionMethodInfo info = null; foreach (var extension in extensions) // foreach classes with extension alias { var methods = extension.GetMethods() .Where(m => m.Name == methodName) .Where(m => m.GetParameters().Count() == paramsCount) .ToArray(); if (methods.Length == 0) continue; // not implementing the method = ignore if (methods.Length > 1) throw new Exception(string.Format("Method \"{0}\" has many overloads with same number of parameters.", methodName)); var method = methods[0]; if (!method.IsPublic || !method.IsStatic) throw new Exception(string.Format("Method \"{0}\" has to be public and static.", methodName)); var attribute = method.GetCustomAttributes(typeof(RestExtensionMethodAttribute), false).Cast<RestExtensionMethodAttribute>().SingleOrDefault(); if (attribute == null) continue; // method has not attribute = ignore // got it! info = new RestExtensionMethodInfo(attribute.AllowAll, attribute.AllowGroup, attribute.AllowType, attribute.AllowMember, attribute.ReturnXml, method); // cache lock (Cache) { Cache[cacheKey] = info; } // got it, no need to look any further break; } return info; }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the legacy attributes // returns null if not found // static RestExtensionMethodInfo GetFromLegacyAttribute(string extensionAlias, string methodName) { // here we can cache because any change would trigger an app restart anyway var cacheKey = extensionAlias + "." + methodName; lock (Cache) { // if it's in the cache, return if (Cache.ContainsKey(cacheKey)) return Cache[cacheKey]; } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo // note: add #pragma - yes it's obsolete but we still want to support it for the time being var extensions = PluginManager.Current.ResolveLegacyRestExtensions() #pragma warning disable 612,618 .Where(type => type.GetCustomAttribute<global::umbraco.presentation.umbracobase.RestExtension>(false).GetAlias() == extensionAlias); #pragma warning restore 612,618 RestExtensionMethodInfo info = null; foreach (var extension in extensions) // foreach classes with extension alias { var method = extension.GetMethod(methodName); if (method == null) continue; // not implementing the method = ignore #pragma warning disable 612,618 var attribute = method.GetCustomAttributes(typeof(global::umbraco.presentation.umbracobase.RestExtensionMethod), false).Cast<global::umbraco.presentation.umbracobase.RestExtensionMethod>().SingleOrDefault(); #pragma warning restore 612,618 if (attribute == null) continue; // method has not attribute = ignore // got it! info = new RestExtensionMethodInfo(attribute.GetAllowAll(), attribute.GetAllowGroup(), attribute.GetAllowType(), attribute.GetAllowMember(), attribute.returnXml, method); // cache lock (Cache) { Cache[cacheKey] = info; } // got it, no need to look any further break; } return info; }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking at the configuration file // returns null if not found // static RestExtensionMethodInfo GetFromConfiguration(string extensionAlias, string methodName, int paramsCount) { var config = Core.Configuration.UmbracoSettings.For<Configuration.BaseRestSection>(); var configExtension = config.Items[extensionAlias]; if (configExtension == null) return null; // does not exist var configMethod = configExtension[methodName]; if (configMethod == null) return null; // does not exist MethodInfo method = null; try { var parts = configExtension.Type.Split(','); if (parts.Length > 2) throw new Exception(string.Format("Failed to load extension '{0}', invalid type.", configExtension.Type)); var assembly = parts.Length == 1 ? Assembly.GetExecutingAssembly() : Assembly.Load(parts[1]); var type = assembly.GetType(parts[0]); if (type == null) throw new Exception(string.Format("Could not get type \"{0}\".", parts[0])); var methods = type.GetMethods() .Where(m => m.Name == methodName) .Where(m => m.GetParameters().Count() == paramsCount) .ToArray(); if (methods.Length > 1) throw new Exception(string.Format("Method \"{0}\" has many overloads with same number of parameters.", methodName)); if (methods.Length > 0) { method = methods[0]; if (!method.IsPublic || !method.IsStatic) throw new Exception(string.Format("Method \"{0}\" has to be public and static.", methodName)); } } catch (Exception e) { throw new Exception(string.Format("Failed to load extension '{0}', see inner exception.", configExtension.Type), e); } if (method == null) return null; // does not exist var info = new RestExtensionMethodInfo(configMethod.AllowAll, configMethod.AllowGroup, configMethod.AllowType, configMethod.AllowMember, configMethod.ReturnXml, method); return info; }
public void ProcessRequest(HttpContext context) { string url = context.Request.RawUrl; // sanitize and split the url url = url.Substring(BaseUrl.Length); if (url.ToLower().Contains(".aspx")) { url = url.Substring(0, url.IndexOf(".aspx", StringComparison.OrdinalIgnoreCase)); } if (url.ToLower().Contains("?")) { url = url.Substring(0, url.IndexOf("?", StringComparison.OrdinalIgnoreCase)); } var urlParts = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); // by default, return xml content context.Response.ContentType = "text/xml"; // ensure that we have a valid request ie /base/library/method/[parameters].aspx if (urlParts.Length < 2) { context.Response.Write("<error>Invalid request, missing parts.</error>"); context.Response.StatusCode = 400; context.Response.StatusDescription = "Bad Request"; context.Response.End(); return; } var extensionAlias = urlParts[0]; var methodName = urlParts[1]; var paramsCount = urlParts.Length - 2; var method = RestExtensionMethodInfo.GetMethod(extensionAlias, methodName, paramsCount); if (!method.Exists) { context.Response.StatusCode = 500; context.Response.StatusDescription = "Internal Server Error"; context.Response.Output.Write("<error>Extension or method not found.</error>"); } else if (!method.CanBeInvokedByCurrentMember) { context.Response.StatusCode = 500; context.Response.StatusDescription = "Internal Server Error"; context.Response.Output.Write("<error>Permission denied.</error>"); } else { if (!method.ReturnXml) { context.Response.ContentType = "text/html"; } TrySetCulture(); var result = method.Invoke(urlParts.Skip(2).ToArray()); if (result.Length >= 7 && result.Substring(0, 7) == "<error>") { context.Response.StatusCode = 500; context.Response.StatusDescription = "Internal Server Error"; } context.Response.Output.Write(result); } context.Response.End(); }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the attributes // returns null if not found // static RestExtensionMethodInfo GetFromAttribute(string extensionAlias, string methodName) { // here we can cache because any change would trigger an app restart string cacheKey = extensionAlias + "." + methodName; lock (_cache) { // if it's in the cache, return if (_cache.ContainsKey(cacheKey)) return _cache[cacheKey]; } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo // // note: the extension may be implemented by more than one class var extensions = PluginManager.Current.ResolveRestExtensions() .Where(type => type.GetCustomAttribute<RestExtensionAttribute>(false).Alias == extensionAlias); RestExtensionMethodInfo info = null; foreach (var extension in extensions) // foreach classes with extension alias { var method = extension.GetMethod(methodName); if (method == null) continue; // not implementing the method = ignore var attribute = method.GetCustomAttributes(typeof(RestExtensionMethodAttribute), false).Cast<RestExtensionMethodAttribute>().SingleOrDefault(); if (attribute == null) continue; // method has not attribute = ignore // got it! info = new RestExtensionMethodInfo(attribute.AllowAll, attribute.AllowGroup, attribute.AllowType, attribute.AllowMember, attribute.ReturnXml, method); // cache lock (_cache) { _cache[cacheKey] = info; } // got it, no need to look any further break; } return info; }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking at the configuration file // returns null if not found // static RestExtensionMethodInfo GetFromConfiguration(string extensionAlias, string methodName) { var config = (Configuration.BaseRestSection)System.Configuration.ConfigurationManager.GetSection("BaseRestExtensions"); if (config == null) return null; // does not exist Configuration.ExtensionElement configExtension = config.Items[extensionAlias]; if (configExtension == null) return null; // does not exist Configuration.MethodElement configMethod = configExtension[methodName]; if (configMethod == null) return null; // does not exist MethodInfo method; try { var parts = configExtension.Type.Split(','); if (parts.Length > 2) throw new Exception(string.Format("Failed to load extension '{0}', invalid type.")); var assembly = parts.Length == 1 ? Assembly.GetExecutingAssembly() : Assembly.Load(parts[1]); var type = assembly.GetType(parts[0]); method = type.GetMethod(methodName); } catch (Exception e) { throw new Exception(string.Format("Failed to load extension '{0}', see inner exception.", configExtension.Type), e); } if (method == null) return null; // does not exist var info = new RestExtensionMethodInfo(configMethod.AllowAll, configMethod.AllowGroup, configMethod.AllowType, configMethod.AllowMember, configMethod.ReturnXml, method); return info; }
// gets a RestExtensionMethodInfo matching extensionAlias and methodName // by looking for the attributes // returns null if not found // static RestExtensionMethodInfo GetFromAttribute(string extensionAlias, string methodName) { // here we can cache because any change would trigger an app restart string cacheKey = extensionAlias + "." + methodName; lock (_cache) { // if it's in the cache, return if (_cache.ContainsKey(cacheKey)) return _cache[cacheKey]; } // find an extension with that alias, then find a method with that name, // which has been properly marked with the attribute, and use the attribute // properties to setup a RestExtensionMethodInfo var extensions = PluginManager.Current.ResolveRestExtensions(); var extension = extensions .SingleOrDefault(type => type.GetCustomAttribute<RestExtensionAttribute>(false).Alias == extensionAlias); RestExtensionMethodInfo info = null; if (extension != null) { var method = extension.GetMethod(methodName); if (method != null) { var attribute = method.GetCustomAttributes(typeof(RestExtensionMethodAttribute), false).Cast<RestExtensionMethodAttribute>().SingleOrDefault(); if (attribute != null) { info = new RestExtensionMethodInfo(attribute.AllowAll, attribute.AllowGroup, attribute.AllowType, attribute.AllowMember, attribute.ReturnXml, method); // looks good, cache lock (_cache) { _cache[cacheKey] = info; } } } } return info; }