/// <summary>
        /// Calls the function as the owner of the object
        /// </summary>
        /// <param name="function"></param>
        /// <returns></returns>
        public static object callAsOwner(SubProcess.Callback callback)
        {
            FunctionCallContext functionCallContext = FunctionCallContext.GetCurrentContext();

            ID<IUserOrGroup, Guid>? ownerId = functionCallContext.ScopeWrapper.FileContainer.OwnerId;

            IUser owner;
            if (null != ownerId)
                owner = functionCallContext.ScopeWrapper.FileHandlerFactoryLocator.UserManagerHandler.GetUser(ownerId.Value);
            else
                owner = functionCallContext.WebConnection.WebServer.FileHandlerFactoryLocator.UserFactory.AnonymousUser;

            // When calling as the owner, a shell web connection is pushed that impersonates the owner
            IWebConnection shellConnection = functionCallContext.WebConnection.CreateShellConnection(owner);
            FunctionCaller.WebConnectionStack.Push(shellConnection);

            try
            {
                return callback.Call(new object[0]);
            }
            finally
            {
                FunctionCaller.WebConnectionStack.Pop();
            }
        }
        /// <summary>
        /// Creates a Javascript execution environment
        /// </summary>
        /// <param name="fileContainer">The object that will be accessed through Javascript</param>
        /// <param name="javascriptContainer">The text file that contains the javascript</param>
        public ExecutionEnvironment(
            FileHandlerFactoryLocator fileHandlerFactoryLocator,
            IFileContainer javascriptContainer,
            IFileContainer fileContainer,
            SubProcess subProcess,
            ParentScope parentScope)
        {
            _FileHandlerFactoryLocator = fileHandlerFactoryLocator;
            _JavascriptContainer = javascriptContainer;
            _JavascriptLastModified = javascriptContainer.LastModified;

            parentScope.WebHandlersWithThisAsParent.Enqueue(fileContainer.WebHandler);

            object toDiscard;

            ISession ownerSession = FileHandlerFactoryLocator.SessionManagerHandler.CreateSession();

            try
            {
                if (null != fileContainer.Owner)
                    ownerSession.Login(fileContainer.Owner);

                IWebConnection ownerWebConnection = new BlockingShellWebConnection(
                    FileHandlerFactoryLocator.WebServer,
                    ownerSession,
                    fileContainer.FullPath,
                    null,
                    null,
                    new CookiesFromBrowser(),
                    CallingFrom.Web,
                    WebMethod.GET);

                ScopeWrapper = new ScopeWrapper(
                    fileHandlerFactoryLocator,
                    subProcess,
                    fileContainer,
                    parentScope,
                    ownerWebConnection,
                    out toDiscard);
            }
            catch (Exception e)
            {
                // If the Javascript has an error in it, it must be ignored.  If an error were returned, then malformed Javascript could hose the system!
                this._ExecutionEnvironmentErrors = e.ToString();
                log.Error("Error creating scope", e);
            }
            finally
            {
                FileHandlerFactoryLocator.SessionManagerHandler.EndSession(ownerSession.SessionId);
            }
        }
        /// <summary>
        /// Disables server-side JavaScript while calling the passed-in function
        /// </summary>
        /// <param name="function"></param>
        /// <param name="callingFrom"></param>
        /// <returns></returns>
        public static object bypassJavascript(SubProcess.Callback callback)
        {
            bool oldBypassJavascript = FunctionCaller.BypassJavascript;
            FunctionCaller.BypassJavascript = true;

            try
            {
                return callback.Call(new object[0]);
            }
            finally
            {
                FunctionCaller.BypassJavascript = oldBypassJavascript;
            }
        }
Example #4
0
        /// <summary>
        /// Creates a scope wrapper
        /// </summary>
        /// <param name="fileHandlerFactoryLocator"></param>
        /// <param name="webConnection"></param>
        /// <param name="javascript"></param>
        /// <param name="fileContainer"></param>
        /// <param name="constructScopeResults"></param>
        public ScopeWrapper(
            FileHandlerFactoryLocator fileHandlerFactoryLocator,
            SubProcess subProcess,
            IFileContainer fileContainer,
            ParentScope parentScope,
            IWebConnection constructWebConnection,
            out object constructScopeResults)
        {
            _FileContainer = fileContainer;
            _SubProcess = subProcess;
            _ParentScope = parentScope;

            _ScopeId = GetScopeID();

            _FileHandlerFactoryLocator = fileHandlerFactoryLocator;

            constructScopeResults = ConstructScope(constructWebConnection);
        }
        /// <summary>
        /// Returns all of the script IDs for the class
        /// </summary>
        /// <param name="javascriptClass">The text handler that has the class's javascript</param>
        /// <param name="subProcess">The process that must have the given script loaded</param>
        /// <returns></returns>
        public ScopeInfo GetScopeInfoForClass(ITextHandler javascriptClass, SubProcess subProcess)
        {
            DateTime javascriptLastModified = javascriptClass.FileContainer.LastModified;

            ScopeInfo toReturn = null;
            using (TimedLock.Lock(ScopeInfoCache))
                ScopeInfoCache.TryGetValue(javascriptClass.FileContainer.FileId, out toReturn);

            if (null != toReturn)
                if (toReturn.JavascriptLastModified == javascriptLastModified)
                {
                    using (TimedLock.Lock(PrecompiledScriptDataByID))
                        foreach (int scriptID in toReturn.ScriptsAndIDsToBuildScope)
                            subProcess.LoadCompiled(
                                Thread.CurrentThread.ManagedThreadId,
                                PrecompiledScriptDataByID[scriptID],
                                scriptID);

                    return toReturn;
                }

            string javascript = javascriptClass.ReadAll();
            string fileType = null;
            List<int> scriptIDsToBuildScope = new List<int>();

            ISession ownerSession = FileHandlerFactoryLocator.SessionManagerHandler.CreateSession();

            try
            {
                ownerSession.Login(javascriptClass.FileContainer.Owner);

                IWebConnection ownerWebConnection = new BlockingShellWebConnection(
                    FileHandlerFactoryLocator.WebServer,
                    ownerSession,
                    javascriptClass.FileContainer.FullPath,
                    null,
                    null,
                    new CookiesFromBrowser(),
                    CallingFrom.Web,
                    WebMethod.GET);

                IEnumerable<ScriptAndMD5> dependantScriptsAndMD5s = FileHandlerFactoryLocator.WebServer.WebComponentResolver.DetermineDependantScripts(
                    GetRequiredScriptURLs(javascriptClass, out fileType),
                    ownerWebConnection);

                // Load static methods that are passed into the Javascript environment as-is
                Dictionary<string, MethodInfo> functionsInScope = SubProcessFactory.GetFunctionsForFileType(fileType);

                // Load all dependant scripts
                foreach (ScriptAndMD5 dependantScript in dependantScriptsAndMD5s)
                {
                    int scriptID = GetScriptID(
                        dependantScript.ScriptName + "___" + ownerSession.User.Identity,
                        dependantScript.MD5,
                        dependantScript.Script,
                        subProcess);

                    scriptIDsToBuildScope.Add(scriptID);
                }

                // Construct Javascript to shell to the "base" webHandler
                Set<Type> webHandlerTypes = new Set<Type>(FileHandlerFactoryLocator.WebHandlerPlugins);
                if (null != fileType)
                    webHandlerTypes.Add(FileHandlerFactoryLocator.WebHandlerClasses[fileType]);

                string baseWrapper = GetJavascriptWrapperForBase("base", webHandlerTypes);
                scriptIDsToBuildScope.Add(
                    GetScriptID(
                        javascriptClass.FileContainer.FullPath + "___" + "serversideBaseWrapper",
                        StringParser.GenerateMD5String(baseWrapper),
                        baseWrapper,
                        subProcess));

                // Get the ID for the actual javascript
                scriptIDsToBuildScope.Add(
                    GetScriptID(
                        javascriptClass.FileContainer.FullPath,
                        StringParser.GenerateMD5String(javascript),
                        javascript,
                        subProcess));

                // Add a little shunt to return information about the options
                scriptIDsToBuildScope.Add(
                    GetScriptID(
                        "____scopeshunt",
                        "xxx",
                        "\nif (this.options) options; else null;",
                        subProcess));

                toReturn = new ScopeInfo(
                    javascriptLastModified,
                    functionsInScope,
                    scriptIDsToBuildScope);

                using (TimedLock.Lock(ScopeInfoCache))
                    ScopeInfoCache[javascriptClass.FileContainer.FileId] = toReturn;

                return toReturn;
            }
            finally
            {
                FileHandlerFactoryLocator.SessionManagerHandler.EndSession(ownerSession.SessionId);
            }
        }
 public ParentScopeFactory(FileHandlerFactoryLocator fileHandlerFactoryLocator, SubProcess subProcess)
 {
     FileHandlerFactoryLocator = fileHandlerFactoryLocator;
     _SubProcess = subProcess;
 }
Example #7
0
        /// <summary>
        /// Returns the corresponding sub process for the given class.  Creates it if it isn't running, restarts if the class was modified
        /// </summary>
        /// <param name="javascriptContainer"></param>
        /// <returns></returns>
        public SubProcess GetOrCreateSubProcess(IFileContainer javascriptContainer)
        {
            SubProcess toReturn = null;

            using (TimedLock.Lock(javascriptContainer))
            {
                using (TimedLock.Lock(SubProcessesByClass))
                {
                    if (SubProcessesByClass.TryGetValue(javascriptContainer.FullPath, out toReturn))
                    {
                        DateTime classLastModified;
                        if (ClassLastModified.TryGetValue(javascriptContainer.FullPath, out classLastModified))
                            if (javascriptContainer.LastModified == classLastModified)
                                if (toReturn.Alive)
                                    return toReturn;
                    }

                    if (null != toReturn)
                        toReturn.Dispose();

                    ClassLastModified[javascriptContainer.FullPath] = javascriptContainer.LastModified;
                }

                toReturn = new SubProcess(javascriptContainer, FileHandlerFactoryLocator);

                using (TimedLock.Lock(SubProcessesByClass))
                    SubProcessesByClass[javascriptContainer.FullPath] = toReturn;

                return toReturn;
            }
        }
 /// <summary>
 /// Calls the given function in an de-elevated cecurity context
 /// </summary>
 /// <param name="function"></param>
 /// <returns></returns>
 public static object deElevate(SubProcess.Callback callback)
 {
     return SetTempCallingFrom(callback, CallingFrom.Web);
 }
        /// <summary>
        /// Calls a function within the context of a CallingFrom
        /// </summary>
        /// <param name="function"></param>
        /// <param name="callingFrom"></param>
        /// <returns></returns>
        private static object SetTempCallingFrom(SubProcess.Callback callback, CallingFrom callingFrom)
        {
            CallingFrom priorCallingFrom = FunctionCaller.CallingFrom;
            FunctionCaller.CallingFrom = callingFrom;

            try
            {
                return callback.Call(new object[0]);
            }
            finally
            {
                FunctionCaller.CallingFrom = priorCallingFrom;
            }
        }
        /// <summary>
        /// Ugly hack that hacks around permission issues by changing the current user to root
        /// </summary>
        /// <param name="function"></param>
        /// <returns></returns>
        public static object sudo(SubProcess.Callback callback)
        {
            FunctionCallContext functionCallContext = FunctionCallContext.GetCurrentContext();

            // When calling as the owner, a shell web connection is pushed that impersonates the owner
            IWebConnection shellConnection = functionCallContext.WebConnection.CreateShellConnection(
                functionCallContext.WebConnection.WebServer.FileHandlerFactoryLocator.UserFactory.RootUser);

            FunctionCaller.WebConnectionStack.Push(shellConnection);

            try
            {
                return callback.Call(new object[0]);
            }
            finally
            {
                FunctionCaller.WebConnectionStack.Pop();
            }
        }
        /// <summary>
        /// Locks the owning object so that the passed in function has exclusive access to it
        /// </summary>
        /// <param name="function"></param>
        /// <returns></returns>
        public static object lockMe(SubProcess.Callback callback)
        {
            FunctionCallContext functionCallContext = FunctionCallContext.GetCurrentContext();

            using (TimedLock.Lock(functionCallContext.ScopeWrapper.FileContainer.FileHandler))
            {
                return callback.Call(new object[0]);
            }
        }
 /// <summary>
 /// Calls the given function in an elevated cecurity context
 /// </summary>
 /// <param name="function"></param>
 /// <returns></returns>
 public static object elevate(SubProcess.Callback callback)
 {
     return SetTempCallingFrom(callback, CallingFrom.Local);
 }
Example #13
0
 public Callback(SubProcess subProcess, int scopeId, object threadId, object callbackId)
 {
     _SubProcess = subProcess;
     _ScopeId = scopeId;
     _ThreadId = threadId;
     _CallbackId = callbackId;
 }