示例#1
0
        private void Add(DekiExtFunctionAttribute ext, MethodInfo method, XDoc script)
        {
            // convert DekiExtParamAttribute into DekiScriptNativeInvocationTarget.Parameter
            var parameters = from param in method.GetParameters()
                             let attr = (DekiExtParamAttribute[])param.GetCustomAttributes(typeof(DekiExtParamAttribute), false)
                                        select((attr != null) && (attr.Length > 0)) ? new DekiScriptNativeInvocationTarget.Parameter(attr[0].Hint, attr[0].Optional) : null;

            // create native target invocation
            var target = new DekiScriptNativeInvocationTarget(this, method, parameters.ToArray());
            DekiScriptInvocationTargetDescriptor function;

            // check if implementation is provided by a script instead
            if (script != null)
            {
                var scriptTarget = new DekiScriptExpressionInvocationTarget(target.Access, target.Parameters, DekiScriptParser.Parse(script));
                function = new DekiScriptInvocationTargetDescriptor(target.Access, ext.IsProperty, false, ext.Name ?? method.Name, target.Parameters, target.ReturnType, ext.Description, ext.Transform, scriptTarget);
            }
            else
            {
                function = new DekiScriptInvocationTargetDescriptor(target.Access, ext.IsProperty, false, ext.Name ?? method.Name, target.Parameters, target.ReturnType, ext.Description, ext.Transform, target);
            }
            _functions[Self.At(function.SystemName)] = function;
        }
示例#2
0
        public Yield PostExtensionFunction(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            var  name = context.GetParam("function");
            XUri uri  = Self.At(name);

            // check if deki server is permitted to invoke this function
            if (this is IDreamServiceLicense)
            {
                string deki;
                if (context.ServiceLicense.TryGetValue("deki", out deki) && !deki.EqualsInvariant(request.Headers[DEKI_HEADER] ?? string.Empty))
                {
                    throw new DreamAbortException(DreamMessage.Forbidden("deki server is not licensed for this service"));
                }
            }

            // check if any functions were found
            DekiScriptInvocationTargetDescriptor descriptor;

            if (!_functions.TryGetValue(uri, out descriptor))
            {
                response.Return(DreamMessage.NotFound(string.Format("function {0} not found", context.GetParam("function"))));
                yield break;
            }

            // check if invoker has access to function
            if ((descriptor.Access != DreamAccess.Public) && (descriptor.Access > DetermineAccess(context, request)))
            {
                response.Return(DreamMessage.Forbidden("insufficient access privileges"));
                yield break;
            }

            // check if request has a requested culture
            context.Culture = HttpUtil.GetCultureInfoFromHeader(request.Headers.AcceptLanguage, context.Culture);

            // check for implicit arguments
            context.SetState(GetImplicitEnvironment(request, _publicDigitalSignature));

            // create custom environment
            DekiScriptEnv env = CreateEnvironment();

            // create custom target for custom environment
            var target = descriptor.Target as DekiScriptExpressionInvocationTarget;

            if (target != null)
            {
                // TODO (steveb): re-initializing the invocation target works for the first call, but not if the function calls another function in the same extension!

                target = new DekiScriptExpressionInvocationTarget(target.Access, target.Parameters, target.Expression, env);
            }

            // invoke target
            DekiScriptLiteral eval;

            if (target != null)
            {
                eval = target.Invoke(ScriptRuntime, DekiScriptLiteral.FromXml(request.ToDocument()));
            }
            else
            {
                eval = descriptor.Target.Invoke(ScriptRuntime, DekiScriptLiteral.FromXml(request.ToDocument()));
            }

            // invoke function
            response.Return(DreamMessage.Ok(new DekiScriptList().Add(eval).ToXml()));
            yield break;
        }