Exemplo n.º 1
0
        //--- Class Methods ---
        public static DekiScriptMap MakeErrorObject(Exception e, DekiScriptEnv env) {
            DekiScriptMap exception = new DekiScriptMap();

            // add call stack if one is available
            DekiScriptList callstack = null;
            if(env != null) {
                DekiScriptLiteral callstackVar;
                if(env.Vars.TryGetValue(DekiScriptEnv.CALLSTACK, out callstackVar)) {
                    callstack = callstackVar as DekiScriptList;
                }
            }
            while(e is DekiScriptInvokeException) {
                var ex = (DekiScriptInvokeException)e;
                if(callstack == null) {
                    callstack = new DekiScriptList();
                }
                callstack.AddNativeValue(ex.FunctionName);
                e = ex.InnerException;
            }
            if(callstack != null) {
                exception.Add("callstack", callstack);
            }

            // add exception text
            exception.Add("message", DekiScriptExpression.Constant(e.Message));
            exception.Add("stacktrace", DekiScriptExpression.Constant(e.GetCoroutineStackTrace()));
            if(e.InnerException != null) {
                exception.Add("inner", MakeErrorObject(e.InnerException, null));
            }
            if(e is DekiScriptException) {
                exception.Add("source", DekiScriptExpression.Constant(((DekiScriptException)e).Location.Origin));
            }
            return exception;
        }
        public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) {

            // prepare uri for invocation
            Plug plug = Plug.New(_endpoint);
            plug = runtime.PreparePlug(plug);

            // make web-request
            DreamMessage response = plug.Post(args.ToXml(), new Tasking.Result<DreamMessage>()).Wait();
            if(!response.IsSuccessful) {
                if(response.HasDocument) {
                    var error = response.ToDocument();
                    var message = error["message"];
                    if(error.HasName("exception") && !message.IsEmpty) {
                        throw new DekiScriptRemoteException(Location.None, message.Contents);
                    }
                }
                throw new DreamResponseException(response);
            }

            // convert response to literal
            DekiScriptLiteral list;
            try {
                list = DekiScriptLiteral.FromXml(response.ToDocument());
            } catch(ArgumentException) {
                throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name));
            }
            if(list.ScriptType != DekiScriptType.LIST) {
                throw new DekiScriptBadTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST });
            }
            return ((DekiScriptList)list)[0];
        }
Exemplo n.º 3
0
        public static DekiScriptMap ValidateToMap(DekiScriptParameter[] parameters, DekiScriptList args) {
            DekiScriptMap result = new DekiScriptMap();

            // check passed in arguments
            int i = 0;
            var count = Math.Min(args.Value.Count, parameters.Length);
            for(; i < count; ++i) {
                var value = args[i];
                if(value.IsNil) {
                    if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) {
                        throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i));
                    }

                    // set default value for this parameter
                    result.Add(parameters[i].Name, parameters[i].Default);
                } else {
                    result.Add(parameters[i].Name, parameters[i].Convert(value));
                }
            }

            // check that missing arguments are optional
            for(; i < parameters.Length; ++i) {
                if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) {
                    throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i));
                }
                result.Add(parameters[i].Name, parameters[i].Default);
            }
            return result;
        }
Exemplo n.º 4
0
        public static DekiScriptMap ValidateToMap(DekiScriptParameter[] parameters, DekiScriptMap args)
        {
            DekiScriptMap result = new DekiScriptMap();

            // check passed in arguments
            for (int i = 0; i < parameters.Length; ++i)
            {
                var value = args[parameters[i].Name];
                if (value.IsNil)
                {
                    if ((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional)
                    {
                        throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i));
                    }

                    // set default value for this parameter
                    result.Add(parameters[i].Name, parameters[i].Default);
                }
                else
                {
                    result.Add(parameters[i].Name, parameters[i].Convert(value));
                }
            }
            return(result);
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptTryCatchFinally expr, DekiScriptExpressionEvaluationState state)
        {
            int marker = state.Buffer.Marker;

            try {
                expr.Try.VisitWith(this, state);
            } catch (DekiScriptFatalException) {
                throw;
            } catch (DekiScriptControlFlowException) {
                throw;
            } catch (Exception e) {
                state.Buffer.Reset(marker);

                // translate exception to an error object
                DekiScriptMap error = DekiScriptLibrary.MakeErrorObject(e, state.Env);

                // capture error object in a nested environment
                try {
                    state.Env.Vars.Add(expr.Variable, error);
                    expr.Catch.VisitWith(this, state);
                } finally {
                    state.Env.Vars.Add(expr.Variable, DekiScriptNil.Value);
                }
            } finally {
                expr.Finally.VisitWith(this, state);
            }
            return(state.Buffer.Since(marker));
        }
        //--- Class Constructor ---
        static DekiScriptRuntime() {

            // register built-in functions
            _commonFunctions = new Dictionary<XUri, DekiScriptInvocationTargetDescriptor>();
            foreach(MethodInfo method in typeof(DekiScriptLibrary).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)) {

                // check if it has the DekiScriptFunction attribute
                DekiScriptFunctionAttribute functionAttribute = (DekiScriptFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiScriptFunctionAttribute));
                if(functionAttribute != null) {
                    var parameters = from param in method.GetParameters()
                                     let attr = (DekiScriptParamAttribute[])param.GetCustomAttributes(typeof(DekiScriptParamAttribute), false)
                                     select ((attr != null) && (attr.Length > 0)) ? new DekiScriptNativeInvocationTarget.Parameter(attr[0].Hint, attr[0].Optional) : null;
                    var target = new DekiScriptNativeInvocationTarget(null, method, parameters.ToArray());
                    var function = new DekiScriptInvocationTargetDescriptor(target.Access, functionAttribute.IsProperty, functionAttribute.IsIdempotent, functionAttribute.Name ?? method.Name, target.Parameters, target.ReturnType, functionAttribute.Description, functionAttribute.Transform, target);
                    _commonFunctions[new XUri("native:///").At(function.SystemName)] = function;
                }
            }

            // build common env
            DekiScriptMap common = new DekiScriptMap();

            // add global constants
            common.AddNativeValueAt("num.e", Math.E);
            common.AddNativeValueAt("num.pi", Math.PI);
            common.AddNativeValueAt("num.epsilon", double.Epsilon);
            common.AddNativeValueAt("num.positiveinfinity", double.PositiveInfinity);
            common.AddNativeValueAt("num.negativeinfinity", double.NegativeInfinity);
            common.AddNativeValueAt("num.nan", double.NaN);

            // add global functions & properties
            foreach(var function in _commonFunctions) {
                common.AddNativeValueAt(function.Value.Name, function.Key);
            }
            _commonEnv = new DekiScriptEnv(common);
        }
Exemplo n.º 7
0
        public static Hashtable MapFilter(
            [DekiScriptParam("map value")] Hashtable map,
            [DekiScriptParam("condition to execute for each item (use '$' to refer to the key-value pair)")] string condition,
            DekiScriptRuntime runtime
            )
        {
            DekiScriptExpression expr   = DekiScriptParser.Parse(new Location("map.select(condition)"), condition);
            Hashtable            result = new Hashtable(StringComparer.OrdinalIgnoreCase);

            foreach (DictionaryEntry entry in map)
            {
                DekiScriptMap keyvalue = new DekiScriptMap();
                object        value    = Eval(entry.Value, runtime);
                keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key));
                keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(value));
                DekiScriptEnv env = runtime.CreateEnv();
                env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue);
                DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env);
                if (!test.IsNilFalseZero)
                {
                    result.Add(entry.Key, value);
                }
            }
            return(result);
        }
Exemplo n.º 8
0
        public Hashtable PopularPages(
            [DekiExtParam("max results (default: 10)", true)] int?max,
            [DekiExtParam("poll interval (only for js format, default: 30)", true)] int?interval
            )
        {
            int               maxResults  = max ?? 10;
            int               resultCount = 0;
            DekiScriptMap     env         = DreamContext.Current.GetState <DekiScriptMap>();
            DekiScriptLiteral uriLiteral  = env.GetAt("site.uri");
            XUri              deki        = new XUri(uriLiteral.NativeValue.ToString()).At("@api", "deki");
            Hashtable         map         = new Hashtable(StringComparer.OrdinalIgnoreCase);

            map.Add("interval", _ttl.TotalSeconds);
            ArrayList pages = new ArrayList();

            map.Add("pages", pages);
            int total = 0;
            Dictionary <uint, int> rankLookup = new Dictionary <uint, int>();

            lock (_pageViews) {
                foreach (View view in _pageViews)
                {
                    if (rankLookup.ContainsKey(view.PageId))
                    {
                        rankLookup[view.PageId]++;
                    }
                    else
                    {
                        rankLookup[view.PageId] = 1;
                    }
                    total++;
                }
            }
            List <Tuplet <uint, int> > rank = new List <Tuplet <uint, int> >();

            foreach (KeyValuePair <uint, int> kvp in rankLookup)
            {
                rank.Add(new Tuplet <uint, int>(kvp.Key, kvp.Value));
            }
            rank.Sort(delegate(Tuplet <uint, int> a, Tuplet <uint, int> b) {
                return(b.Item2.CompareTo(a.Item2));
            });
            map.Add("total", total);
            foreach (Tuplet <uint, int> page in rank)
            {
                Hashtable pageMap = new Hashtable(StringComparer.OrdinalIgnoreCase);
                pages.Add(pageMap);

                // BUGBUGBUG (arnec): the AsLocalUri should not be required after bug #5964 is resolved
                pageMap.Add("page", DekiScriptExpression.Constant(deki.At("$page").AsLocalUri(), new[] { DekiScriptExpression.Constant(page.Item1), DekiScriptExpression.Constant(true) }));
                pageMap.Add("views", page.Item2);
                resultCount++;
                if (resultCount >= maxResults)
                {
                    break;
                }
            }
            return(map);
        }
        private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) {

            // invoke script
            DekiScriptEnv env = (_env != null) ? _env.NewScope() : runtime.CreateEnv();
            env.Vars.Add("args", args);
            env.Vars.Add("$", args);
            return runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env);
        }
Exemplo n.º 10
0
 public DekiScriptEnv(
     DekiScriptMap vars
 ) {
     if(vars == null) {
         throw new ArgumentNullException("vars");
     }
     this.Vars = vars;
 }
        private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args)
        {
            // invoke script
            DekiScriptEnv env = (_env != null) ? _env.NewScope() : runtime.CreateEnv();

            env.Vars.Add("args", args);
            env.Vars.Add("$", args);
            return(runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env));
        }
Exemplo n.º 12
0
 public DekiScriptEnv(
     DekiScriptMap vars
     )
 {
     if (vars == null)
     {
         throw new ArgumentNullException("vars");
     }
     this.Vars = vars;
 }
Exemplo n.º 13
0
 //--- Constructors ---
 public DekiScriptComparer(DekiScriptRuntime runtime, DekiScriptExpression compare) {
     if(compare == null) {
         throw new ArgumentNullException("compare");
     }
     _runtime = runtime;
     _compare = compare;
     _values = new DekiScriptMap();
     _env = runtime.CreateEnv();
     _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values);
 }
Exemplo n.º 14
0
 //--- Constructors ---
 public DekiScriptComparer(DekiScriptRuntime runtime, DekiScriptExpression compare)
 {
     if (compare == null)
     {
         throw new ArgumentNullException("compare");
     }
     _runtime = runtime;
     _compare = compare;
     _values  = new DekiScriptMap();
     _env     = runtime.CreateEnv();
     _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values);
 }
Exemplo n.º 15
0
            //--- Class Methods ---
            internal static AMedia New(XUri uri, XDoc config)
            {
                // check if the uri is a viddler video
                if (uri.Scheme.EqualsInvariantIgnoreCase("kaltura"))
                {
                    if (uri.Segments.Length >= 1)
                    {
                        string entryID   = uri.Segments[0];
                        string partnerID = config["kaltura/partner-id"].AsText;

                        // check if extension is configured for kaltura integration
                        if (!string.IsNullOrEmpty(partnerID))
                        {
                            bool remix = !(uri.GetParam("edit", null) ?? uri.GetParam("remix", "no")).EqualsInvariantIgnoreCase("no");

                            // verify that user has permission to remix content on current page
                            if (remix)
                            {
                                Plug dekiApi = GetDekiApi(config);
                                if (dekiApi != null)
                                {
                                    try {
                                        DekiScriptMap env    = DreamContext.Current.GetState <DekiScriptMap>();
                                        string        pageid = env.GetAt("page.id").AsString();
                                        string        userid = env.GetAt("user.id").AsString();
                                        XDoc          users  = dekiApi.At("pages", pageid, "allowed").With("permissions", "UPDATE").Post(new XDoc("users").Start("user").Attr("id", userid).End()).ToDocument();
                                        remix = !users[string.Format(".//user[@id='{0}']", userid)].IsEmpty;
                                    } catch (Exception e) {
                                        _log.Error("unable to verify user permission on page", e);
                                    }
                                }
                            }

                            // check if SEO links are explicitly disabled
                            bool seo = !(config["kaltura/seo-links"].AsText ?? "enabled").EqualsInvariantIgnoreCase("disabled");

                            // determin which UI configuration to use based on user's permissions and embed settings for video
                            string uiConfID = remix ? config["kaltura/uiconf/player-mix"].AsText : config["kaltura/uiconf/player-nomix"].AsText;
                            if (!string.IsNullOrEmpty(uiConfID))
                            {
                                uri = config["kaltura/server-uri"].AsUri ?? new XUri("http://www.kaltura.com");
                                uri = uri.At("index.php", "kwidget", "wid", "_" + partnerID, "uiconf_id", uiConfID, "entry_id", entryID);
                                return(new KalturaVideo(uri, remix, seo));
                            }
                        }
                    }
                }
                return(null);
            }
        private static DekiScriptLiteral ToDekiScriptRecurse(XDoc doc)
        {
            XDoc xdoc = doc.Elements;

            switch (xdoc.Name)
            {
            case "nil":
                return(DekiScriptNil.Value);

            case "boolean":
                if (xdoc.Contents.GetType().Equals(typeof(String)))
                {
                    return(DekiScriptExpression.Constant((xdoc.Contents.Contains("1") || xdoc.Contents.Contains("true")) ? true : false));
                }
                return(DekiScriptExpression.Constant(xdoc.AsBool ?? false));

            case "double":
                return(DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0));

            case "int":
            case "i4":
                return(DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0));

            case "string":
                return(DekiScriptExpression.Constant(xdoc.AsText ?? string.Empty));

            case "struct": {
                DekiScriptMap result = new DekiScriptMap();
                foreach (XDoc value in xdoc["member"])
                {
                    result.Add(value["name"].Contents, ToDekiScriptRecurse(value["value"]));
                }
                return(result);
            }

            case "array": {
                DekiScriptList result = new DekiScriptList();
                foreach (XDoc value in xdoc["data/value"])
                {
                    result.Add(ToDekiScriptRecurse(value));
                }
                return(result);
            }

            default:
                throw new ArgumentException("this type does not exist in the XML-RPC standard");
            }
        }
Exemplo n.º 17
0
            private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args)
            {
                // invoke script
                DekiScriptEnv env = _env.NewScope();

                env.Vars.AddRange(DreamContext.Current.GetState <DekiScriptMap>("env.implicit"));
                env.Vars.Add("args", args);
                env.Vars.Add("$", args);
                var result = runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env);

                try {
                    return(result.Convert(_returnType));
                } catch (DekiScriptInvalidCastException) {
                    throw new DekiScriptInvalidReturnCastException(Location.None, result.ScriptType, _returnType);
                }
            }
Exemplo n.º 18
0
        public T EnvAt <T>(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            DekiScriptMap env = DreamContext.Current.GetState <DekiScriptMap>();

            if (env == null)
            {
                return(default(T));
            }
            DekiScriptLiteral value = env.GetAt(path);

            return(SysUtil.ChangeType <T>(value.NativeValue));
        }
Exemplo n.º 19
0
        public DekiScriptLiteral GetMagicId(string id) {
            DekiScriptLiteral result = DekiScriptNil.Value;

            // check if magic IDs map already exists; if not, create one
            if(_magicIds == null) {
                _magicIds = new DekiScriptMap();
            } else {
                result = _magicIds[id];
            }

            // check if a magic ID was found; if not, create one
            if(result.IsNil) {
                result = DekiScriptExpression.Constant(id + "_" + StringUtil.CreateAlphaNumericKey(8));
                _magicIds.Add(id, result);
            }
            return result;
        }
 public static Hashtable MapApply(
     [DekiScriptParam("map value")] Hashtable map,
     [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression,
     DekiScriptRuntime runtime
 ) {
     DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression);
     Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase);
     foreach(DictionaryEntry entry in map) {
         DekiScriptMap keyvalue = new DekiScriptMap();
         keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key));
         keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime)));
         DekiScriptEnv env = runtime.CreateEnv();
         env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue);
         result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env));
     }
     return result;
 }
Exemplo n.º 21
0
        public static ArrayList ListIntersect(
            [DekiScriptParam("first list")] ArrayList first,
            [DekiScriptParam("second list")] ArrayList second,
            [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition,
            DekiScriptRuntime runtime
            )
        {
            ArrayList result = new ArrayList();

            if (condition != null)
            {
                // loop over both lists and keep items from the first list based on the outcome of the condition
                DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition);
                foreach (object left in first)
                {
                    foreach (object right in second)
                    {
                        DekiScriptEnv env      = runtime.CreateEnv();
                        DekiScriptMap keyvalue = new DekiScriptMap();
                        keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left));
                        keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right));
                        env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue);
                        DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env);
                        if (!test.IsNilFalseZero)
                        {
                            result.Add(left);
                            break;
                        }
                    }
                }
            }
            else
            {
                // using simple containment check to keep items
                foreach (object item in first)
                {
                    if (second.Contains(item))
                    {
                        result.Add(item);
                    }
                }
            }
            return(result);
        }
Exemplo n.º 22
0
        //--- Class Methods ---
        public static DekiScriptMap MakeErrorObject(Exception e, DekiScriptEnv env)
        {
            DekiScriptMap exception = new DekiScriptMap();

            // add call stack if one is available
            DekiScriptList callstack = null;

            if (env != null)
            {
                DekiScriptLiteral callstackVar;
                if (env.Vars.TryGetValue(DekiScriptEnv.CALLSTACK, out callstackVar))
                {
                    callstack = callstackVar as DekiScriptList;
                }
            }
            while (e is DekiScriptInvokeException)
            {
                var ex = (DekiScriptInvokeException)e;
                if (callstack == null)
                {
                    callstack = new DekiScriptList();
                }
                callstack.AddNativeValue(ex.FunctionName);
                e = ex.InnerException;
            }
            if (callstack != null)
            {
                exception.Add("callstack", callstack);
            }

            // add exception text
            exception.Add("message", DekiScriptExpression.Constant(e.Message));
            exception.Add("stacktrace", DekiScriptExpression.Constant(e.GetCoroutineStackTrace()));
            if (e.InnerException != null)
            {
                exception.Add("inner", MakeErrorObject(e.InnerException, null));
            }
            if (e is DekiScriptException)
            {
                exception.Add("source", DekiScriptExpression.Constant(((DekiScriptException)e).Location.Origin));
            }
            return(exception);
        }
        public DekiScriptLiteral Visit(DekiScriptVar expr, DekiScriptEnv env)
        {
            if (expr.Name.EqualsInvariant(DekiScriptRuntime.ENV_ID))
            {
                DekiScriptMap vars = new DekiScriptMap();
                vars.AddRange(env.Globals);
                vars.AddRange(env.Locals);
                return(vars);
            }

            // check if variable exists
            DekiScriptLiteral result = env[expr.Name];

            if (result == null)
            {
                throw new DekiScriptUndefinedNameException(expr.Line, expr.Column, expr.Name);
            }
            result = DekiScriptRuntime.EvaluateProperty(result, env);
            return(result);
        }
Exemplo n.º 24
0
        public static Hashtable MapApply(
            [DekiScriptParam("map value")] Hashtable map,
            [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression,
            DekiScriptRuntime runtime
            )
        {
            DekiScriptExpression expr   = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression);
            Hashtable            result = new Hashtable(StringComparer.OrdinalIgnoreCase);

            foreach (DictionaryEntry entry in map)
            {
                DekiScriptMap keyvalue = new DekiScriptMap();
                keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key));
                keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime)));
                DekiScriptEnv env = runtime.CreateEnv();
                env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue);
                result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env));
            }
            return(result);
        }
Exemplo n.º 25
0
        public static object ListReduce(
            [DekiScriptParam("list value")] ArrayList list,
            [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression,
            [DekiScriptParam("starting value (default: nil)", true)] object value,
            DekiScriptRuntime runtime
            )
        {
            DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression);

            foreach (object entry in list)
            {
                DekiScriptEnv env    = runtime.CreateEnv();
                DekiScriptMap values = new DekiScriptMap();
                values.Add("value", DekiScriptLiteral.FromNativeValue(value));
                values.Add("item", DekiScriptLiteral.FromNativeValue(entry));
                env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values);
                value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue;
            }
            return(value);
        }
        public DekiScriptExpression Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state)
        {
            // TODO (steveb): need to figure out how to optimize maps with generators
            if (expr.Generator != null)
            {
                return(expr);
            }

            // optimize each item in the map
            var  fields    = new DekiScriptMapConstructor.FieldConstructor[expr.Fields.Length];
            bool isLiteral = true;

            for (int i = 0; i < expr.Fields.Length; i++)
            {
                var current = expr.Fields[i];
                DekiScriptExpression key   = current.Key.VisitWith(this, state);
                DekiScriptExpression value = current.Value.VisitWith(this, state);
                fields[i] = new DekiScriptMapConstructor.FieldConstructor(current.Location, key, value);
                isLiteral = isLiteral && (key is DekiScriptLiteral) && (value is DekiScriptLiteral);
            }
            if (!isLiteral)
            {
                return(DekiScriptExpression.Map(expr.Location, fields));
            }

            // convert expression to a map
            DekiScriptMap result = new DekiScriptMap();

            foreach (var field in fields)
            {
                DekiScriptLiteral key = (DekiScriptLiteral)field.Key;

                // check that key is a simple type
                string text = key.AsString();
                if (text != null)
                {
                    result.Add(text, (DekiScriptLiteral)field.Value);
                }
            }
            return(result);
        }
        public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) {

            // prepare uri for invocation
            Plug plug = Plug.New(_endpoint);
            plug = runtime.PreparePlug(plug);

            // invoke function
            DreamMessage response = plug.Get();

            // convert response to literal
            DekiScriptLiteral list;
            try {
                list = DekiScriptLiteral.FromXml(response.ToDocument());
            } catch(ArgumentException) {
                throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name));
            }
            if(list.ScriptType != DekiScriptType.LIST) {
                throw new DekiScriptBadReturnTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST });
            }
            return ((DekiScriptList)list)[0];
        }
 public static Hashtable MapFilter(
     [DekiScriptParam("map value")] Hashtable map,
     [DekiScriptParam("condition to execute for each item (use '$' to refer to the key-value pair)")] string condition,
     DekiScriptRuntime runtime
 ) {
     DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.select(condition)"), condition);
     Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase);
     foreach(DictionaryEntry entry in map) {
         DekiScriptMap keyvalue = new DekiScriptMap();
         object value = Eval(entry.Value, runtime);
         keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key));
         keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(value));
         DekiScriptEnv env = runtime.CreateEnv();
         env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue);
         DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env);
         if(!test.IsNilFalseZero) {
             result.Add(entry.Key, value);
         }
     }
     return result;
 }
Exemplo n.º 29
0
        public DekiScriptLiteral GetMagicId(string id)
        {
            DekiScriptLiteral result = DekiScriptNil.Value;

            // check if magic IDs map already exists; if not, create one
            if (_magicIds == null)
            {
                _magicIds = new DekiScriptMap();
            }
            else
            {
                result = _magicIds[id];
            }

            // check if a magic ID was found; if not, create one
            if (result.IsNil)
            {
                result = DekiScriptExpression.Constant(id + "_" + StringUtil.CreateAlphaNumericKey(8));
                _magicIds.Add(id, result);
            }
            return(result);
        }
        public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args)
        {
            // prepare uri for invocation
            Plug plug = Plug.New(_endpoint);

            plug = runtime.PreparePlug(plug);

            // make web-request
            DreamMessage response = plug.Post(args.ToXml(), new Tasking.Result <DreamMessage>()).Wait();

            if (!response.IsSuccessful)
            {
                if (response.HasDocument)
                {
                    var error   = response.ToDocument();
                    var message = error["message"];
                    if (error.HasName("exception") && !message.IsEmpty)
                    {
                        throw new DekiScriptRemoteException(Location.None, message.Contents);
                    }
                }
                throw new DreamResponseException(response);
            }

            // convert response to literal
            DekiScriptLiteral list;

            try {
                list = DekiScriptLiteral.FromXml(response.ToDocument());
            } catch (ArgumentException) {
                throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name));
            }
            if (list.ScriptType != DekiScriptType.LIST)
            {
                throw new DekiScriptBadTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST });
            }
            return(((DekiScriptList)list)[0]);
        }
        public DekiScriptLiteral Visit(DekiScriptMapConstructor expr, DekiScriptEnv env)
        {
            DekiScriptMap result = new DekiScriptMap();

            if (expr.Generator == null)
            {
                foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields)
                {
                    DekiScriptLiteral key = field.Key.VisitWith(this, env);

                    // check that key is a simple type
                    string text = key.AsString();
                    if (text != null)
                    {
                        DekiScriptLiteral value = field.Value.VisitWith(this, env);
                        result.Add(text, value);
                    }
                }
            }
            else
            {
                DekiScriptGeneratorEvaluation.Instance.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) {
                    foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields)
                    {
                        DekiScriptLiteral key = field.Key.VisitWith(this, subEnv);

                        // check that key is a simple type
                        string text = key.AsString();
                        if (text != null)
                        {
                            DekiScriptLiteral value = field.Value.VisitWith(this, subEnv);
                            result.Add(text, value);
                        }
                    }
                }, env.NewLocalScope());
            }
            return(result);
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state)
        {
            DekiScriptMap result = new DekiScriptMap();

            if (expr.Generator == null)
            {
                foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields)
                {
                    DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state));

                    // check that key is a simple type
                    string text = key.AsString();
                    if (text != null)
                    {
                        DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state));
                        result.Add(text, value);
                    }
                }
            }
            else
            {
                DekiScriptGeneratorEvaluation.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) {
                    foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields)
                    {
                        DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state.With(subEnv)));

                        // check that key is a simple type
                        string text = key.AsString();
                        if (text != null)
                        {
                            DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state.With(subEnv)));
                            result.Add(text, value);
                        }
                    }
                }, state);
            }
            return(state.Push(result));
        }
Exemplo n.º 33
0
        //--- Class Constructor ---
        static DekiScriptRuntime()
        {
            // register built-in functions
            _commonFunctions = new Dictionary <XUri, DekiScriptInvocationTargetDescriptor>();
            foreach (MethodInfo method in typeof(DekiScriptLibrary).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
            {
                // check if it has the DekiScriptFunction attribute
                DekiScriptFunctionAttribute functionAttribute = (DekiScriptFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiScriptFunctionAttribute));
                if (functionAttribute != null)
                {
                    var parameters = from param in method.GetParameters()
                                     let attr = (DekiScriptParamAttribute[])param.GetCustomAttributes(typeof(DekiScriptParamAttribute), false)
                                                select((attr != null) && (attr.Length > 0)) ? new DekiScriptNativeInvocationTarget.Parameter(attr[0].Hint, attr[0].Optional) : null;
                    var target   = new DekiScriptNativeInvocationTarget(null, method, parameters.ToArray());
                    var function = new DekiScriptInvocationTargetDescriptor(target.Access, functionAttribute.IsProperty, functionAttribute.IsIdempotent, functionAttribute.Name ?? method.Name, target.Parameters, target.ReturnType, functionAttribute.Description, functionAttribute.Transform, target);
                    _commonFunctions[new XUri("native:///").At(function.SystemName)] = function;
                }
            }

            // build common env
            DekiScriptMap common = new DekiScriptMap();

            // add global constants
            common.AddNativeValueAt("num.e", Math.E);
            common.AddNativeValueAt("num.pi", Math.PI);
            common.AddNativeValueAt("num.epsilon", double.Epsilon);
            common.AddNativeValueAt("num.positiveinfinity", double.PositiveInfinity);
            common.AddNativeValueAt("num.negativeinfinity", double.NegativeInfinity);
            common.AddNativeValueAt("num.nan", double.NaN);

            // add global functions & properties
            foreach (var function in _commonFunctions)
            {
                common.AddNativeValueAt(function.Value.Name, function.Key);
            }
            _commonEnv = new DekiScriptEnv(common);
        }
        public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args)
        {
            // prepare uri for invocation
            Plug plug = Plug.New(_endpoint);

            plug = runtime.PreparePlug(plug);

            // invoke function
            DreamMessage response = plug.Get();

            // convert response to literal
            DekiScriptLiteral list;

            try {
                list = DekiScriptLiteral.FromXml(response.ToDocument());
            } catch (ArgumentException) {
                throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name));
            }
            if (list.ScriptType != DekiScriptType.LIST)
            {
                throw new DekiScriptBadReturnTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST });
            }
            return(((DekiScriptList)list)[0]);
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptVar expr, DekiScriptExpressionEvaluationState state)
        {
            if (expr.Name.EqualsInvariant(DekiScriptRuntime.ENV_ID))
            {
                DekiScriptMap vars = new DekiScriptMap();
                vars.AddRange(state.Env.Vars);
                return(state.Push(vars));
            }

            // check if variable exists
            DekiScriptLiteral result;

            if (!state.Env.Vars.TryGetValue(expr.Name, out result))
            {
                result = state.Runtime.ResolveMissingName(expr.Name);
            }

            if (result == null)
            {
                throw new DekiScriptUndefinedNameException(expr.Location, expr.Name);
            }
            result = state.Runtime.EvaluateProperty(expr.Location, result, state.Env);
            return(state.Push(result));
        }
Exemplo n.º 36
0
        //--- Methods ---
        private DekiScriptEnv ProcessEnvironment() {
            var current = DreamContext.Current;
            DekiScriptEnv env = current.GetState<DekiScriptEnv>("pageenv-" + _basePage.ID);

            // check if we already have an initialized environment
            if(env == null) {

                // create environment
                env = ExtensionBL.CreateEnvironment(_basePage);

                // add request arguments
                DekiScriptMap request = new DekiScriptMap();
                DekiScriptMap queryArgs = new DekiScriptMap();
                DreamContext context = DreamContext.CurrentOrNull;
                if(context != null) {
                    if(context.Uri.Params != null) {
                        foreach(KeyValuePair<string, string> query in context.Uri.Params) {

                            // check that query parameter doesn't have 'dream.' prefix
                            if(!query.Key.StartsWithInvariantIgnoreCase("dream.")) {
                                DekiScriptLiteral value;

                                // check if a query parameter with the same name was alreayd found
                                if(queryArgs.TryGetValue(query.Key, out value)) {
                                    DekiScriptList list = value as DekiScriptList;

                                    // check if the current value is already a list
                                    if(list == null) {
                                        list = new DekiScriptList();
                                        list.Add(value);

                                        // replace current value
                                        queryArgs.Add(query.Key, list);
                                    }

                                    // append new value to list
                                    list.Add(DekiScriptExpression.Constant(query.Value));
                                } else {

                                    // add query parameter
                                    queryArgs.Add(query.Key, DekiScriptExpression.Constant(query.Value));
                                }
                            }
                        }
                    }

                    // show User-Agent, Referer and Host information in __request
                    request.Add("referer", DekiScriptExpression.Constant(context.Request.Headers.Referer));
                    request.Add("useragent", DekiScriptExpression.Constant(context.Request.Headers.UserAgent));
                    request.Add("host", DekiScriptExpression.Constant(context.Request.Headers.Host));

                    // determine the client IP address
                    var clientIPs = current.Request.Headers.DreamClientIP;
                    if(clientIPs.Length > 0) {
                        request.Add("client", DekiScriptExpression.Constant(clientIPs[clientIPs.Length - 1]));
                    } else {
                        request.Add("client", DekiScriptNil.Value);
                    }

                    // parse form fields from a request for requests with a mimetype of application/x-www-form-urlencoded
                    DekiScriptMap postParams;
                    if(context.Request.ContentType.Match(MimeType.FORM_URLENCODED)) {
                        KeyValuePair<string, string>[] formFields = XUri.ParseParamsAsPairs(context.Request.ToText());
                        if(!ArrayUtil.IsNullOrEmpty(formFields)) {
                            postParams = new DekiScriptMap();
                            foreach(KeyValuePair<string, string> kvp in formFields) {
                                postParams.Add(kvp.Key, DekiScriptExpression.Constant(kvp.Value));
                            }
                            request.Add("fields", postParams);
                        }
                    }
                }
                request.Add("args", queryArgs);
                env.Vars.Add("__request", request);

                // store computed environment for subsequent calls
                current.SetState("pageenv-" + _basePage.ID, env);
            }
            env = env.NewScope();

            // global processing variables
            env.Vars.Add("__include", DekiScriptExpression.Constant(_isInclude));
            env.Vars.Add("__mode", DekiScriptExpression.Constant(_mode.ToString().ToLowerInvariant()));
            env.Vars.Add(DekiScriptEnv.SAFEMODE, DekiScriptExpression.Constant(ExtensionRuntime.IsSafeMode(_page)));
            env.Vars.Add("__page", DekiContext.Current.Deki.PropertyAt("$page", _page.ID, true));

            // set processing settings
            DekiScriptMap settings = new DekiScriptMap();
            settings.Add("nofollow", DekiScriptExpression.Constant(DekiContext.Current.Instance.WebLinkNoFollow));
            env.Vars.Add(DekiScriptEnv.SETTINGS, settings);

            // add callstack (specific for each page invocation)
            DekiScriptList callstack = new DekiScriptList();
            ParserState parseState = GetParseState();
            if(parseState != null) {
                foreach(PageBE includingPage in parseState.ProcessingStack) {
                    callstack.Add(DekiScriptExpression.Constant(includingPage.Title.AsPrefixedDbPath()));
                }
                env.Vars.Add(DekiScriptEnv.CALLSTACK, callstack);
            }

            // add arguments environment vars
            env.Vars.Add("args", _args ?? DekiScriptNil.Value);
            env.Vars.Add("$", _args ?? DekiScriptNil.Value);
            return env.NewScope();
        }
Exemplo n.º 37
0
            private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) {

                // invoke script
                DekiScriptEnv env = _env.NewScope();
                env.Vars.AddRange(DreamContext.Current.GetState<DekiScriptMap>("env.implicit"));
                env.Vars.Add("args", args);
                env.Vars.Add("$", args);
                var result = runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env);
                try {
                    return result.Convert(_returnType);
                } catch(DekiScriptInvalidCastException) {
                    throw new DekiScriptInvalidReturnCastException(Location.None, result.ScriptType, _returnType);
                }
            }
Exemplo n.º 38
0
 public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) {
     return InvokeHelper(runtime, DekiScriptParameter.ValidateToMap(Parameters, args));
 }
Exemplo n.º 39
0
        private void LoadScript() {
            _manifestPath = null;
            _resourcesPath = null;
            _manifestUri = null;
            _resourcesUri = null;
            _manifest = null;

            // read manifest
            _manifestPath = Config["manifest"].AsText;
            if(string.IsNullOrEmpty(_manifestPath)) {
                throw new ArgumentNullException("manifest");
            }
            _manifestUri = XUri.TryParse(_manifestPath);
            if(_manifestUri != null) {
                _manifestPath = null;
                _manifest = Plug.New(_manifestUri).Get().ToDocument();
                _resourcesUri = Config["resources"].AsUri ?? _manifestUri.WithoutLastSegment();
            } else {
                _manifest = XDocFactory.LoadFrom(_manifestPath, MimeType.XML);
                _resourcesPath = Config["resources"].AsText ?? Path.GetDirectoryName(_manifestPath);
            }
            if(!_manifest.HasName("extension")) {
                throw new ArgumentException("invalid extension manifest");
            }

            // initilize runtime
            _runtime = new DekiScriptRuntime();

            // read manifest settings
            _title = _manifest["title"].AsText;
            _label = _manifest["label"].AsText;
            _copyright = _manifest["copyright"].AsText;
            _description = _manifest["description"].AsText;
            _help = _manifest["uri.help"].AsText;
            _logo = _manifest["uri.logo"].AsText;
            _namespace = _manifest["namespace"].AsText;

            // initialize evaluation environment
            _commonEnv = _runtime.CreateEnv();

            // read functions
            _functions = new Dictionary<XUri, DekiScriptInvocationTargetDescriptor>();
            foreach(var function in _manifest["function"]) {
                var descriptor = ConvertFunction(function);
                if(descriptor != null) {
                    var uri = Self.At(descriptor.SystemName);
                    DekiScriptInvocationTargetDescriptor old;
                    if(_functions.TryGetValue(uri, out old)) {
                        _log.WarnFormat("duplicate function name {0} in script {1}", descriptor.Name, _manifestUri);
                    }
                    _functions[uri] = descriptor;
                }
            }
            _runtime.RegisterExtensionFunctions(_functions);

            // add extension functions to env
            foreach(var function in _functions) {
                _commonEnv.Vars.AddNativeValueAt(function.Value.Name.ToLowerInvariant(), function.Key);
            }

            // add configuration settings
            DreamContext context = DreamContext.Current;
            DekiScriptMap scriptConfig = new DekiScriptMap();
            foreach(KeyValuePair<string, string> entry in Config.ToKeyValuePairs()) {
                XUri local;
                if(XUri.TryParse(entry.Value, out local)) {
                    local = context.AsPublicUri(local);
                    scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString()));
                } else {
                    scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value));
                }
            }
            _commonEnv.Vars.Add("config", scriptConfig);
        }
 private static DekiScriptLiteral ToDekiScriptRecurse(XDoc doc) {
     XDoc xdoc = doc.Elements;
     switch(xdoc.Name) {
     case "nil":
         return DekiScriptNil.Value;
     case "boolean":
         if(xdoc.Contents.GetType().Equals(typeof(String))) {
             return DekiScriptExpression.Constant((xdoc.Contents.Contains("1") || xdoc.Contents.Contains("true")) ? true : false);
         }
         return DekiScriptExpression.Constant(xdoc.AsBool ?? false);
     case "double":
         return DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0);
     case "int":
     case "i4":
         return DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0);
     case "string":
         return DekiScriptExpression.Constant(xdoc.AsText ?? string.Empty);
     case "struct": {
         DekiScriptMap result = new DekiScriptMap();
         foreach(XDoc value in xdoc["member"]) {
             result.Add(value["name"].Contents, ToDekiScriptRecurse(value["value"]));
         }
         return result;
     }
     case "array": {
         DekiScriptList result = new DekiScriptList();
         foreach(XDoc value in xdoc["data/value"]) {
             result.Add(ToDekiScriptRecurse(value));
         }
         return result;
     }
     default:
         throw new ArgumentException("this type does not exist in the XML-RPC standard");
     }
 }
Exemplo n.º 41
0
        public static void InitializeCustomDekiScriptHeaders(PageBE page)
        {
            var           current = DreamContext.Current;
            DekiScriptMap env     = current.GetState <DekiScriptMap>("pageimplicitenv-" + page.ID);

            // check if we already have an initialized environment
            if (env == null)
            {
                DekiContext  deki     = DekiContext.Current;
                DekiInstance instance = deki.Instance;
                env = new DekiScriptMap();

                // add site fields
                DekiScriptMap siteFields = new DekiScriptMap();
                siteFields.Add("name", DekiScriptExpression.Constant(instance.SiteName));
                siteFields.Add("host", DekiScriptExpression.Constant(deki.UiUri.Uri.Host));
                siteFields.Add("language", DekiScriptExpression.Constant(instance.SiteLanguage));
                siteFields.Add("uri", DekiScriptExpression.Constant(deki.UiUri.Uri.ToString()));
                siteFields.Add("id", DekiScriptExpression.Constant(instance.Id));
                env.Add("site", siteFields);

                // add page fields
                DekiScriptMap pageFields = new DekiScriptMap();
                pageFields.Add("title", DekiScriptExpression.Constant(page.Title.AsUserFriendlyName()));
                pageFields.Add("path", DekiScriptExpression.Constant(page.Title.AsPrefixedDbPath()));
                pageFields.Add("namespace", DekiScriptExpression.Constant(Title.NSToString(page.Title.Namespace)));
                pageFields.Add("id", DekiScriptExpression.Constant(page.ID.ToString()));
                pageFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(page.Title)));
                pageFields.Add("date", DekiScriptExpression.Constant(page.TimeStamp.ToString("R")));
                pageFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(page.Language) ? null : page.Language));
                env.Add("page", pageFields);

                // add user fields
                DekiScriptMap userFields = new DekiScriptMap();
                if (deki.User != null)
                {
                    UserBE user = deki.User;
                    userFields.Add("id", DekiScriptExpression.Constant(user.ID.ToString()));
                    userFields.Add("name", DekiScriptExpression.Constant(user.Name));
                    userFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null))));
                    userFields.Add("emailhash", DekiScriptExpression.Constant(StringUtil.ComputeHashString((user.Email ?? string.Empty).Trim().ToLowerInvariant(), Encoding.UTF8)));
                    userFields.Add("anonymous", DekiScriptExpression.Constant(UserBL.IsAnonymous(user).ToString().ToLowerInvariant()));
                    userFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(user.Language) ? null : user.Language));
                }
                else
                {
                    userFields.Add("id", DekiScriptExpression.Constant("0"));
                    userFields.Add("name", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("uri", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("emailhash", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("anonymous", DekiScriptExpression.Constant("true"));
                    userFields.Add("language", DekiScriptNil.Value);
                }
                env.Add("user", userFields);

                // store env for later
                current.SetState("pageimplicitenv-" + page.ID, env);
            }

            // set implicit environment
            DreamContext.Current.SetState(env);
        }
Exemplo n.º 42
0
        public static DekiScriptMap GetImplicitEnvironment(DreamMessage message, DSACryptoServiceProvider publicDigitalSignature)
        {
            DekiScriptMap env = new DekiScriptMap();

            // retrieve implicit arguments
            string[] headers = message.Headers.GetValues(IMPLICIT_ENVIRONMENT_HEADER);
            if (!ArrayUtil.IsNullOrEmpty(headers))
            {
                env.AddAt("__implicit", new DekiScriptList(new ArrayList(headers)));
                foreach (string implicitArg in headers)
                {
                    foreach (KeyValuePair <string, string> arg in HttpUtil.ParseNameValuePairs(implicitArg))
                    {
                        env.AddNativeValueAt(arg.Key, arg.Value);
                    }
                }
            }
            if (publicDigitalSignature != null)
            {
                bool valid = false;
                try {
                    Dictionary <string, string> values = HttpUtil.ParseNameValuePairs(message.Headers[IMPLICIT_SIGNATURE_HEADER]);

                    // verify date
                    DateTime date  = DateTime.Parse(values["date"]).ToUniversalTime();
                    double   delta = DateTime.UtcNow.Subtract(date).TotalSeconds;
                    if ((delta < -60) || (delta > 60))
                    {
                        throw new DreamAbortException(DreamMessage.Forbidden("date in message signature is too far apart from server date"));
                    }

                    // verify message
                    MemoryStream data  = new MemoryStream();
                    byte[]       bytes = null;

                    // get message bytes
                    bytes = message.AsBytes();
                    data.Write(bytes, 0, bytes.Length);

                    // retrieve headers to verify
                    if (!ArrayUtil.IsNullOrEmpty(headers))
                    {
                        Array.Sort(headers, StringComparer.Ordinal);
                        bytes = Encoding.UTF8.GetBytes(string.Join(",", headers));
                        data.Write(bytes, 0, bytes.Length);
                    }

                    // add request date
                    bytes = Encoding.UTF8.GetBytes(values["date"]);
                    data.Write(bytes, 0, bytes.Length);

                    // verify signature
                    byte[] signature = Convert.FromBase64String(values["dsig"]);
                    valid = publicDigitalSignature.VerifyData(data.GetBuffer(), signature);
                } catch (Exception e) {
                    if (e is DreamAbortException)
                    {
                        throw;
                    }
                }
                if (!valid)
                {
                    throw new DreamAbortException(DreamMessage.Forbidden("invalid or missing digital signature"));
                }
            }
            return(env);
        }
Exemplo n.º 43
0
        protected override Yield Start(XDoc config, Result result)
        {
            yield return(Coroutine.Invoke(base.Start, config, new Result()));

            // loop over all resources
            Type   type     = GetType();
            string assembly = type.Assembly.FullName.Split(new char[] { ',' }, 2)[0];

            foreach (DekiExtLibraryFilesAttribute files in Attribute.GetCustomAttributes(type, typeof(DekiExtLibraryFilesAttribute)))
            {
                string prefix = files.Prefix ?? type.Namespace;
                foreach (string filename in files.Filenames)
                {
                    MimeType mime = MimeType.FromFileExtension(filename);
                    _files[filename] = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, prefix, filename)).With("dream.out.type", mime.FullType);
                }
            }

            // check if a public digital signature key was provided
            string dsaKey = config["deki-signature"].AsText ?? config["dekiwiki-signature"].AsText;

            if (dsaKey != null)
            {
                try {
                    DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
                    dsa.ImportCspBlob(Convert.FromBase64String(dsaKey));
                    _publicDigitalSignature = dsa;
                } catch {
                    throw new ArgumentException("invalid digital signature provided", "deki-signature");
                }
            }

            // loop over all instance methods
            foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                // check if it has the DekiExtFunction attriute
                DekiExtFunctionAttribute ext = (DekiExtFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionAttribute));
                if (ext != null)
                {
                    // check if function has an associated script
                    XDekiScript script = null;
                    DekiExtFunctionScriptAttribute scriptAttr = (DekiExtFunctionScriptAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionScriptAttribute));
                    if (scriptAttr != null)
                    {
                        DreamMessage scriptresource = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, scriptAttr.Prefix ?? type.Namespace, scriptAttr.Scriptname)).With("dream.out.type", MimeType.XML.FullType).GetAsync().Wait();
                        if (scriptresource.IsSuccessful)
                        {
                            script = new XDekiScript(scriptresource.ToDocument());
                        }
                        if (script == null)
                        {
                            throw new InvalidOperationException(string.Format("method '{0}' is declard as script, but script could not be loaded", method.Name));
                        }
                    }

                    // add function
                    Add(ext, method, script);
                }
            }

            // add configuration settings
            var context = DreamContext.Current;

            _scriptConfig = new DekiScriptMap();
            foreach (KeyValuePair <string, string> entry in Config.ToKeyValuePairs())
            {
                XUri local;
                if (XUri.TryParse(entry.Value, out local))
                {
                    local = context.AsPublicUri(local);
                    _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString()));
                }
                else
                {
                    _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value));
                }
            }
            result.Return();
        }
 public abstract DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args);
Exemplo n.º 45
0
        public static ArrayList ListIntersect(
            [DekiScriptParam("first list")] ArrayList first,
            [DekiScriptParam("second list")] ArrayList second,
            [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition,
            DekiScriptRuntime runtime
        ) {
            ArrayList result = new ArrayList();
            if(condition != null) {

                // loop over both lists and keep items from the first list based on the outcome of the condition
                DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition);
                foreach(object left in first) {
                    foreach(object right in second) {
                        DekiScriptEnv env = runtime.CreateEnv();
                        DekiScriptMap keyvalue = new DekiScriptMap();
                        keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left));
                        keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right));
                        env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue);
                        DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env);
                        if(!test.IsNilFalseZero) {
                            result.Add(left);
                            break;
                        }
                    }
                }
            } else {

                // using simple containment check to keep items
                foreach(object item in first) {
                    if(second.Contains(item)) {
                        result.Add(item);
                    }
                }
            }
            return result;
        }
Exemplo n.º 46
0
        public static DekiScriptList ValidateToList(DekiScriptParameter[] parameters, DekiScriptMap args) {
            DekiScriptList result = new DekiScriptList();

            // check passed in arguments
            for(int i = 0; i < parameters.Length; ++i) {
                var value = args[parameters[i].Name];
                if(value.IsNil) {
                    if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) {
                        throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i));
                    }

                    // set default value for this parameter
                    result.Add(parameters[i].Default);
                } else {
                    result.Add(parameters[i].Convert(value));
                }
            }
            return result;
        }
Exemplo n.º 47
0
 public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args)
 {
     return(InvokeHelper(runtime, DekiScriptParameter.ValidateToList(Parameters, args)));
 }
Exemplo n.º 48
0
 public static object ListReduce(
     [DekiScriptParam("list value")] ArrayList list,
     [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression,
     [DekiScriptParam("starting value (default: nil)", true)] object value,
     DekiScriptRuntime runtime
 ) {
     DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression);
     foreach(object entry in list) {
         DekiScriptEnv env = runtime.CreateEnv();
         DekiScriptMap values = new DekiScriptMap();
         values.Add("value", DekiScriptLiteral.FromNativeValue(value));
         values.Add("item", DekiScriptLiteral.FromNativeValue(entry));
         env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values);
         value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue;
     }
     return value;
 }
Exemplo n.º 49
0
        public static void InitializeCustomDekiScriptHeaders(PageBE page) {
            var current = DreamContext.Current;
            DekiScriptMap env = current.GetState<DekiScriptMap>("pageimplicitenv-" + page.ID);

            // check if we already have an initialized environment
            if(env == null) {
                DekiContext deki = DekiContext.Current;
                DekiInstance instance = deki.Instance;
                env = new DekiScriptMap();

                // add site fields
                DekiScriptMap siteFields = new DekiScriptMap();
                siteFields.Add("name", DekiScriptExpression.Constant(instance.SiteName));
                siteFields.Add("host", DekiScriptExpression.Constant(deki.UiUri.Uri.Host));
                siteFields.Add("language", DekiScriptExpression.Constant(instance.SiteLanguage));
                siteFields.Add("uri", DekiScriptExpression.Constant(deki.UiUri.Uri.ToString()));
                siteFields.Add("id", DekiScriptExpression.Constant(instance.Id));
                env.Add("site", siteFields);

                // add page fields
                DekiScriptMap pageFields = new DekiScriptMap();
                pageFields.Add("title", DekiScriptExpression.Constant(page.Title.AsUserFriendlyName()));
                pageFields.Add("path", DekiScriptExpression.Constant(page.Title.AsPrefixedDbPath()));
                pageFields.Add("namespace", DekiScriptExpression.Constant(Title.NSToString(page.Title.Namespace)));
                pageFields.Add("id", DekiScriptExpression.Constant(page.ID.ToString()));
                pageFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(page.Title)));
                pageFields.Add("date", DekiScriptExpression.Constant(page.TimeStamp.ToString("R")));
                pageFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(page.Language) ? null : page.Language));
                env.Add("page", pageFields);

                // add user fields
                DekiScriptMap userFields = new DekiScriptMap();
                if(deki.User != null) {
                    UserBE user = deki.User;
                    userFields.Add("id", DekiScriptExpression.Constant(user.ID.ToString()));
                    userFields.Add("name", DekiScriptExpression.Constant(user.Name));
                    userFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null))));
                    userFields.Add("emailhash", DekiScriptExpression.Constant(StringUtil.ComputeHashString((user.Email ?? string.Empty).Trim().ToLowerInvariant(), Encoding.UTF8)));
                    userFields.Add("anonymous", DekiScriptExpression.Constant(UserBL.IsAnonymous(user).ToString().ToLowerInvariant()));
                    userFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(user.Language) ? null : user.Language));
                } else {
                    userFields.Add("id", DekiScriptExpression.Constant("0"));
                    userFields.Add("name", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("uri", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("emailhash", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("anonymous", DekiScriptExpression.Constant("true"));
                    userFields.Add("language", DekiScriptNil.Value);
                }
                env.Add("user", userFields);

                // store env for later
                current.SetState("pageimplicitenv-" + page.ID, env);
            }

            // set implicit environment
            DreamContext.Current.SetState(env);
        }
 public abstract DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args);
Exemplo n.º 51
0
 //--- Constructors ---
 public DekiScriptEnv() {
     this.Vars = new DekiScriptMap();
 }
 public DekiScriptExpression Visit(DekiScriptMap expr, DekiScriptExpressionEvaluationState state)
 {
     return(expr);
 }
Exemplo n.º 53
0
        public static DekiScriptLiteral FromXml(XDoc doc) {

            // check if response is an HTML document
            if(doc.HasName("html")) {

                // TODO (steveb): this handling seems to be to specific to belong here.

                return new DekiScriptList().Add(new DekiScriptXml(doc));
            }

            // check if response is a DekiScript XML document
            if(!doc.HasName("value") || (doc["@type"].AsText == null)) {
                throw new ArgumentException("doc");
            }
            switch(doc["@type"].AsText) {
            case "nil":
                return DekiScriptNil.Value;
            case "bool":
                return Constant(doc.AsBool ?? false);
            case "num":
                return Constant(doc.AsDouble ?? 0.0);
            case "str":
                return Constant(doc.AsText ?? string.Empty);
            case "uri": {
                return Constant(doc.AsUri);
            }
            case "map": {
                DekiScriptMap result = new DekiScriptMap();
                foreach(XDoc value in doc["value"]) {
                    result.Add(value["@key"].AsText, FromXml(value));
                }
                return result;
            }
            case "list": {
                DekiScriptList result = new DekiScriptList();
                foreach(XDoc value in doc["value"]) {
                    result.Add(FromXml(value));
                }
                return result;
            }
            case "xml":
                if((doc.AsXmlNode.ChildNodes.Count == 1) && (doc.AsXmlNode.ChildNodes[0].NodeType == XmlNodeType.Element)) {
                    return new DekiScriptXml(doc[doc.AsXmlNode.ChildNodes[0]]);
                }
                return DekiScriptNil.Value;
            default:
                throw new ArgumentException("doc");
            }
        }
 public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) {
     throw new DekiScriptBadTypeException(Location.None, args.ScriptType, new[] { DekiScriptType.LIST });
 }