286 lines
11 KiB
C#
286 lines
11 KiB
C#
using System;
|
|
using System.Data;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Configuration;
|
|
using System.Web;
|
|
using System.Web.Security;
|
|
using System.Web.UI;
|
|
using System.Reflection;
|
|
using System.Collections.Specialized;
|
|
using System.Xml;
|
|
using umbraco;
|
|
using umbraco.cms.businesslogic.member;
|
|
|
|
namespace presentation.umbracoBase
|
|
{
|
|
public class requestModule : IHttpModule
|
|
{
|
|
#region IHttpModule Members
|
|
public void Dispose()
|
|
{
|
|
throw new Exception("The method or operation is not implemented.");
|
|
}
|
|
|
|
public void Init(HttpApplication httpApp)
|
|
{
|
|
httpApp.BeginRequest += new EventHandler(OnBeginRequest);
|
|
}
|
|
|
|
|
|
public void OnBeginRequest(Object sender, EventArgs e)
|
|
{
|
|
HttpApplication httpApp = (HttpApplication)sender;
|
|
|
|
//remove extension and split the url
|
|
object[] urlArray = httpApp.Context.Request.RawUrl.Replace(".aspx", "").Split('/');
|
|
|
|
if (urlArray[1].ToString() == "base")
|
|
{
|
|
//There has to be minimum 4 parts in the url for this to work... /base/library/method/[parameter].aspx
|
|
if (urlArray.Length >= 4)
|
|
{
|
|
string extensionAlias = urlArray[2].ToString();
|
|
string methodName = urlArray[3].ToString();
|
|
|
|
httpApp.Response.ContentType = "text/xml";
|
|
MyMethodStruct myMMS = getMethod(extensionAlias, methodName);
|
|
|
|
if (myMMS.isAllowed)
|
|
{
|
|
httpApp.Response.Output.Write(invokeMethod(myMMS, urlArray));
|
|
}
|
|
else
|
|
{
|
|
//Very static error msg...
|
|
httpApp.Response.Output.Write("<error>Extension not found or permission denied</error>");
|
|
}
|
|
//end the resposne
|
|
httpApp.Response.End();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
private string invokeMethod(MyMethodStruct myMethod, object[] paras)
|
|
{
|
|
try
|
|
{
|
|
//So method is either not found or not valid... this should probably be moved...
|
|
if (!myMethod.method.IsPublic || !myMethod.method.IsStatic)
|
|
return "<error>Method has to be public and static</error>";
|
|
else //And if it is lets continue trying to invoke it...
|
|
{
|
|
//lets check if we have parameters enough in the url..
|
|
if (myMethod.method.GetParameters().Length > (paras.Length - 4)) //Too few
|
|
return "<error>Not Enough parameters in url</error>";
|
|
else
|
|
{
|
|
|
|
//We have enough parameters... lets invoke..
|
|
//Create an instance of the type we need to invoke the method from.
|
|
Object obj = Activator.CreateInstance(myMethod.type);
|
|
Object response;
|
|
|
|
//umbracoBase.baseBinder bBinder = new baseBinder();
|
|
|
|
if (myMethod.method.GetParameters().Length == 0)
|
|
{
|
|
//response = myMethod.method.Invoke(obj, BindingFlags.Public | BindingFlags.Instance, bBinder, null, System.Globalization.CultureInfo.CurrentCulture);
|
|
response = myMethod.method.Invoke(obj, null); //Invoke with null as parameters as there are none
|
|
}
|
|
|
|
else
|
|
{
|
|
//We only need the parts of the url above the number 4 so we'll
|
|
//recast those to objects and add them to the object[]
|
|
|
|
//Getting the right lenght.. 4 is the magic number dum di dum..
|
|
object[] methodParams = new object[(paras.Length - 4)];
|
|
|
|
int i = 0;
|
|
|
|
foreach (ParameterInfo pInfo in myMethod.method.GetParameters())
|
|
{
|
|
Type myType = Type.GetType(pInfo.ParameterType.ToString());
|
|
methodParams[(i)] = Convert.ChangeType(paras[i + 4], myType);
|
|
i++;
|
|
}
|
|
|
|
//Invoke with methodParams
|
|
//response = myMethod.method.Invoke(obj, BindingFlags.Public | BindingFlags.Instance, bBinder, methodParams, System.Globalization.CultureInfo.CurrentCulture);
|
|
response = myMethod.method.Invoke(obj, methodParams);
|
|
}
|
|
|
|
/*TODO - SOMETHING ALITTLE BETTER THEN ONLY CHECK FOR XPATHNODEITERATOR OR ELSE do ToString() */
|
|
if (response != null)
|
|
{
|
|
if (myMethod.method.ReturnType.ToString() == "System.Xml.XPath.XPathNodeIterator")
|
|
return ((System.Xml.XPath.XPathNodeIterator)response).Current.OuterXml;
|
|
else
|
|
{
|
|
string strResponse = ((string)response.ToString());
|
|
|
|
//do a quick "is this html?" check... if it is add CDATA...
|
|
if (strResponse.Contains("<") || strResponse.Contains(">"))
|
|
strResponse = "<![CDATA[" + strResponse + "]]>";
|
|
return "<value>" + strResponse + "</value>";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Error msg...
|
|
return "<error>Null value returned</error>";
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
catch (Exception ex)
|
|
{
|
|
//Overall exception handling...
|
|
return "<error><![CDATA[MESSAGE:" + ex.Message + " STACKTRACE: " + ex.StackTrace + " ]]></error>";
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private struct MyMethodStruct
|
|
{
|
|
public Type type;
|
|
public MethodInfo method;
|
|
public Assembly assembly;
|
|
public string alias;
|
|
public bool isAllowed;
|
|
}
|
|
|
|
|
|
private static MyMethodStruct getMethod(string extensionAlias, string methodName)
|
|
{
|
|
|
|
bool allowed = false;
|
|
|
|
XmlDocument baseDoc = new XmlDocument(); //RESTExtension document...
|
|
baseDoc.Load(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../config/restExtensions.xml"));
|
|
|
|
XmlNode baseExt = baseDoc.SelectSingleNode("/RestExtensions/ext [@alias='" + extensionAlias + "']/permission [@method='" + methodName + "']");
|
|
|
|
//basicly - if not there.. it's not allowed...
|
|
if (baseExt != null)
|
|
{
|
|
//Access for all ?
|
|
if (baseExt.Attributes["allowAll"] != null)
|
|
{
|
|
if (baseExt.Attributes["allowAll"].Value.ToString().ToLower() == "true")
|
|
allowed = true;
|
|
}
|
|
|
|
if (!allowed)
|
|
{
|
|
//Member Based permissions.. check for group, type and ID...
|
|
Member currentMem = library.library.GetCurrentMember(); // <-- /TODO/ uses bases own member class as umbracos doesn't work yet...
|
|
|
|
//not basic.. and not logged in? - out..
|
|
if (currentMem == null)
|
|
{
|
|
allowed = false;
|
|
}
|
|
else //do member authentication stuff...
|
|
allowed = memberAuthentication(baseExt, currentMem);
|
|
}
|
|
}
|
|
|
|
if (allowed)
|
|
{
|
|
XmlNode extNode = baseDoc.SelectSingleNode("/RestExtensions/ext [@alias='" + extensionAlias + "']");
|
|
string asml = extNode.Attributes["assembly"].Value;
|
|
string assemblyPath = System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/.." + asml + ".dll");
|
|
Assembly returnAssembly = System.Reflection.Assembly.LoadFrom(assemblyPath);
|
|
|
|
string returnTypeName = extNode.Attributes["type"].Value;
|
|
Type returnType = returnAssembly.GetType(returnTypeName);
|
|
|
|
|
|
MyMethodStruct mms = new MyMethodStruct();
|
|
mms.alias = extensionAlias;
|
|
mms.assembly = returnAssembly;
|
|
mms.method = returnType.GetMethod(methodName);
|
|
mms.type = returnType;
|
|
mms.isAllowed = true;
|
|
return mms;
|
|
}
|
|
else
|
|
{
|
|
MyMethodStruct noMms = new MyMethodStruct();
|
|
noMms.isAllowed = false;
|
|
return noMms;
|
|
}
|
|
}
|
|
|
|
|
|
private static bool memberAuthentication(XmlNode baseExt, Member currentMem)
|
|
{
|
|
//Check group, type and ID
|
|
bool memberAccess = false;
|
|
|
|
if (baseExt.Attributes["allowGroup"] != null)
|
|
{
|
|
if (baseExt.Attributes["allowGroup"].Value != "")
|
|
{
|
|
//Groups array
|
|
string[] groupArray = baseExt.Attributes["allowGroup"].Value.Split(',');
|
|
|
|
foreach (MemberGroup mg in currentMem.Groups.Values)
|
|
{
|
|
foreach (string group in groupArray)
|
|
{
|
|
if (group == mg.Text)
|
|
memberAccess = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Membertype allowed?
|
|
if (baseExt.Attributes["allowType"] != null && !memberAccess)
|
|
{
|
|
if (baseExt.Attributes["allowType"].Value != "")
|
|
{
|
|
//Types array
|
|
string[] typeArray = baseExt.Attributes["allowType"].Value.Split(',');
|
|
|
|
foreach (string type in typeArray)
|
|
{
|
|
if (type == currentMem.ContentType.Alias)
|
|
memberAccess = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//Member ID allowed? should this work with loginName instead?
|
|
if (baseExt.Attributes["allowMember"] != null && !memberAccess)
|
|
{
|
|
if (baseExt.Attributes["allowMember"].Value != "")
|
|
{
|
|
if (int.Parse((string)baseExt.Attributes["allowMember"].Value.Trim()) == currentMem.Id)
|
|
memberAccess = true;
|
|
}
|
|
}
|
|
return memberAccess;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|