Пример #1
0
        private void WriteToLog(string message, LogLevel level)
        {
            if (!IsOutputLoggingEnabled)
            {
                return;
            }

            switch (level)
            {
            case LogLevel.Debug:
                PowerShellLog.Debug(message);
                break;

            case LogLevel.Error:
                PowerShellLog.Error(message);
                break;

            case LogLevel.Info:
            case LogLevel.Verbose:
                PowerShellLog.Info(message);
                break;

            case LogLevel.Warning:
                PowerShellLog.Warn(message);
                break;
            }
        }
Пример #2
0
        private void LogString(string message)
        {
            switch (Log)
            {
            case LogNotificationLevel.Debug:
                PowerShellLog.Debug(message);
                break;

            case LogNotificationLevel.Error:
                PowerShellLog.Error(message);
                break;

            case LogNotificationLevel.Fatal:
                PowerShellLog.Fatal(message);
                break;

            case LogNotificationLevel.Warning:
                PowerShellLog.Warn(message);
                break;

            default:
                PowerShellLog.Info(message);
                break;
            }

            WriteVerbose(message);
        }
Пример #3
0
        internal List <object> ExecuteScriptPart(string script, bool stringOutput, bool internalScript,
                                                 bool marshalResults)
        {
            if (string.IsNullOrWhiteSpace(script) || State == RunspaceAvailability.Busy)
            {
                return(null);
            }

            if (Runspace.DefaultRunspace == null)
            {
                Runspace.DefaultRunspace = host.Runspace;
            }

            PowerShellLog.Info($"Executing a script in ScriptSession '{Key}'.");
            PowerShellLog.Debug(script);

            // Create a pipeline, and populate it with the script given in the
            // edit box of the form.
            return(SpeTimer.Measure($"script execution in ScriptSession '{Key}'", () =>
            {
                try
                {
                    using (powerShell = NewPowerShell())
                    {
                        powerShell.Commands.AddScript(script);
                        return ExecuteCommand(stringOutput, marshalResults);
                    }
                }
                finally
                {
                    powerShell = null;
                }
            }));
        }
        // Methods
        protected override bool Execute(T ruleContext)
        {
            Assert.ArgumentNotNull(ruleContext, "ruleContext");

            var    measuredLength = MeasuredLengths[MeasuredLength];
            string lengthStr;

            if (measuredLength == Measured.Script)
            {
                lengthStr = ruleContext.Parameters["scriptLength"].ToString();
            }
            else
            {
                lengthStr = ruleContext.Parameters["selectionLength"].ToString();
            }

            if (string.IsNullOrEmpty(lengthStr))
            {
                return(false);
            }

            int length;

            if (!int.TryParse(lengthStr, out length))
            {
                PowerShellLog.Debug("Invalid script length: " + MeasuredLength);
                return(false);
            }

            int desiredLength;

            if (!int.TryParse(DesiredLength, out desiredLength))
            {
                PowerShellLog.Debug("Wrong script length definition: " + DesiredLength);
                return(false);
            }

            switch (GetOperator())
            {
            case ConditionOperator.Equal:
                return(length == desiredLength);

            case ConditionOperator.GreaterThanOrEqual:
                return(length >= desiredLength);

            case ConditionOperator.GreaterThan:
                return(length > desiredLength);

            case ConditionOperator.LessThanOrEqual:
                return(length <= desiredLength);

            case ConditionOperator.LessThan:
                return(length < desiredLength);

            case ConditionOperator.NotEqual:
                return(length >= desiredLength);
            }
            return(false);
        }
Пример #5
0
        /// <summary>
        ///     Not implemented by this example class. The call fails with
        ///     a NotImplementedException exception.
        /// </summary>
        public override void EnterNestedPrompt()
        {
            NestedLevel++;
            UiNestedLevel++;
            var resultSig = Guid.NewGuid().ToString();

            var str = new UrlString(UIUtil.GetUri("control:PowerShellConsole"));

            str.Add("sid", resultSig);
            str.Add("fc", privateData.ForegroundColor.ToString());
            str.Add("bc", privateData.BackgroundColor.ToString());
            str.Add("id", SessionKey);
            str.Add("suspend", "true");

            var currentNesting = NestedLevel;
            var jobManager     = TypeResolver.ResolveFromCache <IJobManager>();
            var job            = jobManager.GetContextJob();

            job.MessageQueue.PutMessage(
                new ShowSuspendDialogMessage(SessionKey, str.ToString(), "900", "600", new Hashtable())
            {
                ReceiveResults = true,
            });

            var scriptSession = ScriptSessionManager.GetSession(SessionKey);

            while (currentNesting <= UiNestedLevel)
            {
                if (currentNesting == UiNestedLevel)
                {
                    if (scriptSession.ImmediateCommand is string commandString)
                    {
                        scriptSession.ImmediateCommand = null;
                        PowerShellLog.Info($"Executing a command in ScriptSession '{SessionKey}'.");
                        PowerShellLog.Debug(commandString);
                        try
                        {
                            var result =
                                scriptSession.InvokeInNewPowerShell(commandString, ScriptSession.OutTarget.OutHost);
                        }
                        catch (Exception ex)
                        {
                            PowerShellLog.Error("Error while executing Debugging command.", ex);
                            UI.WriteErrorLine(ScriptSession.GetExceptionString(ex));
                        }
                    }
                    else
                    {
                        Thread.Sleep(20);
                    }
                }
            }
            job.MessageQueue.GetResult();

            ScriptSessionManager.GetSession(SessionKey).InvokeInNewPowerShell("exit", ScriptSession.OutTarget.OutHost);
        }
 protected override ProviderInfo Start(ProviderInfo providerInfo)
 {
     try
     {
         providerInfo.Description = "Sitecore Content Provider";
         this.providerInfo        = providerInfo;
         PowerShellLog.Debug($"Executing {GetType().Name}.Start(providerInfo='{providerInfo.Name ?? "null"}')");
         return(providerInfo);
     }
     catch (Exception ex)
     {
         PowerShellLog.Info($"Error while executing {GetType().Name}.Start(providerInfo='{providerInfo?.Name ?? "null"}')", ex);
         throw;
     }
 }
Пример #7
0
        private static void ProcessMedia(HttpContext context, bool isUpload, Database scriptDb, string itemParam, bool unpackZip, bool skipExisting)
        {
            var request = context.Request;

            if (isUpload)
            {
                if (ZipUtils.IsZipContent(request.InputStream) && unpackZip)
                {
                    PowerShellLog.Debug("The uploaded asset will be extracted to Media Library.");
                    using (var packageReader = new ZipArchive(request.InputStream))
                    {
                        itemParam = Path.GetDirectoryName(itemParam.TrimEnd('\\', '/'));
                        foreach (var zipEntry in packageReader.Entries)
                        {
                            // ZipEntry does not provide an IsDirectory or IsFile property.
                            if (!(zipEntry.FullName.EndsWith("/") && zipEntry.Name == "") && zipEntry.Length > 0)
                            {
                                ProcessMediaUpload(zipEntry.Open(), scriptDb, $"{itemParam}/{zipEntry.FullName}",
                                                   skipExisting);
                            }
                        }
                    }
                }
                else if (request.Files.AllKeys.Length > 0)
                {
                    foreach (string fileName in request.Files.Keys)
                    {
                        var file = request.Files[fileName];
                        if (file != null)
                        {
                            ProcessMediaUpload(file.InputStream, scriptDb, $"{itemParam}/{file.FileName}",
                                               skipExisting);
                        }
                    }
                }
                else
                {
                    ProcessMediaUpload(request.InputStream, scriptDb, itemParam, skipExisting);
                }
            }
            else
            {
                ProcessMediaDownload(context, scriptDb, itemParam);
            }
        }
Пример #8
0
        public static void RemoveSession(string key)
        {
            lock (sessions)
            {
                if (sessions.Contains(key))
                {
                    sessions.Remove(key);
                }
                if (HttpRuntime.Cache[key] == null)
                {
                    return;
                }

                var session = HttpRuntime.Cache.Remove(key) as ScriptSession;
                session?.Dispose();
                PowerShellLog.Debug($"Script Session '{key}' disposed.");
            }
        }
Пример #9
0
        public static ScriptSession GetSession(string persistentId, string applianceType, bool personalizedSettings)
        {
            // sessions with no persistent ID, are just created new every time
            var autoDispose = string.IsNullOrEmpty(persistentId);

            if (autoDispose)
            {
                persistentId = Guid.NewGuid().ToString();
            }

            var sessionKey = GetSessionKey(persistentId);

            lock (sessions)
            {
                if (SessionExists(persistentId))
                {
                    return(HttpRuntime.Cache[sessionKey] as ScriptSession);
                }

                var session = new ScriptSession(applianceType, personalizedSettings)
                {
                    ID = persistentId,
                };

                PowerShellLog.Debug($"New Script Session with key '{sessionKey}' created.");

                if (autoDispose)
                {
                    // this only should be set if new session has been created - do not change!
                    session.AutoDispose = true;
                }
                var expiration            = Sitecore.Configuration.Settings.GetIntSetting(expirationSetting, 30);
                var preventSessionCleanup = Sitecore.Configuration.Settings.GetBoolSetting(preventSessionCleanupSetting, false);

                HttpRuntime.Cache.Add(sessionKey, session, null, Cache.NoAbsoluteExpiration,
                                      new TimeSpan(0, expiration, 0), preventSessionCleanup ? CacheItemPriority.NotRemovable : CacheItemPriority.Normal, CacheItemRemoved);

                sessions.Add(sessionKey);
                session.ID  = persistentId;
                session.Key = sessionKey;
                session.Initialize();
                return(session);
            }
        }
Пример #10
0
        public static T Measure <T>(string message, bool log, Func <T> action) where T : class
        {
            var stopWatch = new Stopwatch();

            try
            {
                stopWatch.Start();

                var result = action();

                stopWatch.Stop();
                if (log)
                {
                    PowerShellLog.Debug($"The {message} completed in {stopWatch.ElapsedMilliseconds} ms.");
                }
                return(result);
            }
            catch (Exception)
            {
                PowerShellLog.Error($"Error while performing timed '{message}' operation within {stopWatch.ElapsedMilliseconds} ms. Exception logged at operation origin point.");
                throw;
            }
        }
Пример #11
0
        public void ProcessRequest(HttpContext context)
        {
            var request           = HttpContext.Current.Request;
            var userName          = request.Params.Get("user");
            var password          = request.Params.Get("password");
            var itemParam         = request.Params.Get("script");
            var pathParam         = request.Params.Get("path");
            var originParam       = request.Params.Get("scriptDb");
            var apiVersion        = request.Params.Get("apiVersion");
            var serviceMappingKey = request.HttpMethod + "/" + apiVersion;
            var isUpload          = request.HttpMethod.Is("POST") && request.InputStream.Length > 0;
            var unpackZip         = request.Params.Get("skipunpack").IsNot("true");
            var skipExisting      = request.Params.Get("skipexisting").Is("true");
            var scDB = request.Params.Get("sc_database");

            var serviceName = apiVersionToServiceMapping.ContainsKey(serviceMappingKey)
                ? apiVersionToServiceMapping[serviceMappingKey]
                : string.Empty;

            // verify that the service is enabled
            if (!CheckServiceEnabled(apiVersion, request.HttpMethod))
            {
                PowerShellLog.Error($"Attempt to call the {apiVersion} service failed as it is not enabled.");
                return;
            }

            // verify that the user is authorized to access the end point
            var authUserName = string.IsNullOrEmpty(userName) ? Context.User.Name : userName;
            var identity     = new AccountIdentity(authUserName);

            if (!ServiceAuthorizationManager.IsUserAuthorized(serviceName, identity.Name))
            {
                HttpContext.Current.Response.StatusCode = 401;
                PowerShellLog.Error(
                    $"Attempt to call the '{serviceMappingKey}' service failed as user '{userName}' was not authorized.");
                return;
            }

            lock (loginLock)
            {
                // login user if specified explicitly
                if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
                {
                    AuthenticationManager.Login(identity.Name, password, false);
                }
            }

            var isAuthenticated = Context.IsLoggedIn;

            // in some cases we need to set the database as it's still set to web after authentication
            if (!scDB.IsNullOrEmpty())
            {
                Context.Database = Database.GetDatabase(scDB);
            }

            var useContextDatabase = apiVersion.Is("file") || apiVersion.Is("handle") || !isAuthenticated ||
                                     string.IsNullOrEmpty(originParam) || originParam.Is("current");
            var scriptDb = useContextDatabase ? Context.Database : Database.GetDatabase(originParam);
            var dbName   = scriptDb?.Name;

            if (!CheckServiceAuthentication(apiVersion, isAuthenticated))
            {
                PowerShellLog.Error(
                    $"Attempt to call the {serviceMappingKey} service failed as - user not logged in, authentication failed or no credentials provided.");
                return;
            }

            if (scriptDb == null && !apiVersion.Is("file") && !apiVersion.Is("handle"))
            {
                PowerShellLog.Error(
                    $"The '{serviceMappingKey}' service requires a database but none was found in parameters or Context.");
                return;
            }

            PowerShellLog.Info($"'{serviceMappingKey}' called by user: '******'");
            PowerShellLog.Debug($"'{request.Url}'");

            Item scriptItem;

            switch (apiVersion)
            {
            case "1":
                scriptItem = scriptDb.GetItem(itemParam) ??
                             scriptDb.GetItem(ApplicationSettings.ScriptLibraryPath + itemParam);
                break;

            case "media":
                if (isUpload)
                {
                    if (ZipUtils.IsZipContent(request.InputStream) && unpackZip)
                    {
                        PowerShellLog.Debug("The uploaded asset will be extracted to Media Library.");
                        using (var packageReader = new Sitecore.Zip.ZipReader(request.InputStream))
                        {
                            itemParam = Path.GetDirectoryName(itemParam.TrimEnd('\\', '/'));
                            foreach (var zipEntry in packageReader.Entries)
                            {
                                if (!zipEntry.IsDirectory && zipEntry.Size > 0)
                                {
                                    ProcessMediaUpload(zipEntry.GetStream(), scriptDb, $"{itemParam}/{zipEntry.Name}",
                                                       skipExisting);
                                }
                            }
                        }
                    }
                    else if (request.Files?.AllKeys?.Length > 0)
                    {
                        foreach (string fileName in request.Files.Keys)
                        {
                            var file = request.Files[fileName];
                            ProcessMediaUpload(file.InputStream, scriptDb, $"{itemParam}/{file.FileName}",
                                               skipExisting);
                        }
                    }
                    else
                    {
                        ProcessMediaUpload(request.InputStream, scriptDb, itemParam, skipExisting);
                    }
                }
                else
                {
                    ProcessMediaDownload(scriptDb, itemParam);
                }
                return;

            case "file":
                if (isUpload)
                {
                    ProcessFileUpload(request.InputStream, originParam, pathParam);
                }
                else
                {
                    ProcessFileDownload(originParam, pathParam);
                }
                return;

            case "handle":
                ProcessHandle(originParam);
                return;

            case "2":
                UpdateCache(dbName);
                if (!apiScripts.ContainsKey(dbName))
                {
                    HttpContext.Current.Response.StatusCode = 404;
                    return;
                }
                var dbScripts = apiScripts[dbName];
                if (!dbScripts.ContainsKey(itemParam))
                {
                    HttpContext.Current.Response.StatusCode = 404;
                    return;
                }
                scriptItem = scriptDb.GetItem(dbScripts[itemParam].Id);
                apiScripts = null;
                break;

            default:
                PowerShellLog.Error($"Requested API/Version ({serviceMappingKey}) is not supported.");
                return;
            }

            var streams = new Dictionary <string, Stream>();

            if (request.Files?.AllKeys?.Length > 0)
            {
                foreach (string fileName in request.Files.AllKeys)
                {
                    streams.Add(fileName, request.Files[fileName].InputStream);
                }
            }
            else if (request.InputStream != null)
            {
                streams.Add("stream", request.InputStream);
            }

            ProcessScript(context, scriptItem, streams);
        }
Пример #12
0
        private void DebuggerOnDebuggerStop(object sender, DebuggerStopEventArgs args)
        {
            Debugger             debugger     = sender as Debugger;
            DebuggerResumeAction?resumeAction = null;

            DebuggingInBreakpoint = true;
            try
            {
                if (
                    ((ScriptingHostUserInterface)host.UI).CheckSessionCanDoInteractiveAction(
                        nameof(DebuggerOnDebuggerStop), false))
                {
                    var output = new PSDataCollection <PSObject>();
                    output.DataAdded += (dSender, dArgs) =>
                    {
                        foreach (var item in output.ReadAll())
                        {
                            host.UI.WriteLine(item.ToString());
                        }
                    };

                    var message = Message.Parse(this, "ise:breakpointhit");
                    //var position = args.InvocationInfo.DisplayScriptPosition;
                    IScriptExtent position;
                    try
                    {
                        position = args.InvocationInfo.GetType()
                                   .GetProperty("ScriptPosition",
                                                BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty)
                                   .GetValue(args.InvocationInfo) as IScriptExtent;
                    }
                    catch (Exception)
                    {
                        position = args.InvocationInfo.DisplayScriptPosition;
                    }

                    if (position != null)
                    {
                        message.Arguments.Add("Line", (position.StartLineNumber - 1).ToString());
                        message.Arguments.Add("Column", (position.StartColumnNumber - 1).ToString());
                        message.Arguments.Add("EndLine", (position.EndLineNumber - 1).ToString());
                        message.Arguments.Add("EndColumn", (position.EndColumnNumber - 1).ToString());
                    }
                    else
                    {
                        message.Arguments.Add("Line", (args.InvocationInfo.ScriptLineNumber - 1).ToString());
                        message.Arguments.Add("Column", (args.InvocationInfo.OffsetInLine - 1).ToString());
                        message.Arguments.Add("EndLine", (args.InvocationInfo.ScriptLineNumber).ToString());
                        message.Arguments.Add("EndColumn", (0).ToString());
                    }

                    message.Arguments.Add("HitCount",
                                          args.Breakpoints.Count > 0 ? args.Breakpoints[0].HitCount.ToString() : "1");
                    SendUiMessage(message);

                    while (resumeAction == null && !abortRequested)
                    {
                        if (ImmediateCommand is string commandString)
                        {
                            PowerShellLog.Info($"Executing a debug command in ScriptSession '{Key}'.");
                            PowerShellLog.Debug(commandString);
                            DebuggerCommandResults results = null;
                            try
                            {
                                var psCommand     = new PSCommand();
                                var scriptCommand = new Command(commandString, true)
                                {
                                    MergeUnclaimedPreviousCommandResults = PipelineResultTypes.Warning
                                };
                                psCommand.AddCommand(scriptCommand)
                                .AddCommand(OutDefaultCommand);

                                results          = debugger?.ProcessCommand(psCommand, output);
                                ImmediateResults = output;
                                LogErrors(null, output.ToList());
                            }
                            catch (Exception ex)
                            {
                                PowerShellLog.Error("Error while executing Debugging command.", ex);
                                ImmediateCommand = null;
                                host.UI.WriteErrorLine(GetExceptionString(ex, ExceptionStringFormat.Default));
                            }

                            if (results?.ResumeAction != null)
                            {
                                resumeAction = results.ResumeAction;
                            }
                            ImmediateCommand = null;
                        }
                        else
                        {
                            Thread.Sleep(20);
                        }
                    }


                    args.ResumeAction = resumeAction ?? DebuggerResumeAction.Continue;
                }
            }
            finally
            {
                DebuggingInBreakpoint = false;
            }
        }
Пример #13
0
        public void ProcessRequest(HttpContext context)
        {
            var request           = context.Request;
            var requestParameters = request.Params;

            var username   = requestParameters.Get("user");
            var password   = requestParameters.Get("password");
            var authHeader = request.Headers["Authorization"];

            if (string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(authHeader))
            {
                if (authHeader.StartsWith("Basic"))
                {
                    var encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
                    var encoding         = Encoding.GetEncoding("iso-8859-1");
                    var usernamePassword = encoding.GetString(System.Convert.FromBase64String(encodedUsernamePassword));

                    var separatorIndex = usernamePassword.IndexOf(':');

                    username = usernamePassword.Substring(0, separatorIndex);
                    password = usernamePassword.Substring(separatorIndex + 1);
                }
            }

            var itemParam         = requestParameters.Get("script");
            var pathParam         = requestParameters.Get("path");
            var originParam       = requestParameters.Get("scriptDb");
            var sessionId         = requestParameters.Get("sessionId");
            var persistentSession = requestParameters.Get("persistentSession").Is("true");
            var rawOutput         = requestParameters.Get("rawOutput").Is("true");
            var apiVersion        = requestParameters.Get("apiVersion");
            var serviceMappingKey = request.HttpMethod + "/" + apiVersion;
            var isUpload          = request.HttpMethod.Is("POST") && request.InputStream.Length > 0;
            var unpackZip         = requestParameters.Get("skipunpack").IsNot("true");
            var skipExisting      = requestParameters.Get("skipexisting").Is("true");
            var scDb = requestParameters.Get("sc_database");

            var serviceName = ApiVersionToServiceMapping.ContainsKey(serviceMappingKey)
                ? ApiVersionToServiceMapping[serviceMappingKey]
                : string.Empty;

            // verify that the service is enabled
            if (!CheckServiceEnabled(context, apiVersion, request.HttpMethod))
            {
                return;
            }

            // verify that the user is authorized to access the end point
            var authUserName = string.IsNullOrEmpty(username) ? Context.User.Name : username;
            var identity     = new AccountIdentity(authUserName);

            if (!CheckIsUserAuthorized(context, identity.Name, serviceName))
            {
                return;
            }

            lock (LoginLock)
            {
                // login user if specified explicitly
                if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
                {
                    AuthenticationManager.Login(identity.Name, password, false);
                }
            }

            var isAuthenticated = Context.IsLoggedIn;

            if (!CheckServiceAuthentication(context, apiVersion, serviceName, isAuthenticated))
            {
                return;
            }

            // in some cases we need to set the database as it's still set to web after authentication
            if (!scDb.IsNullOrEmpty())
            {
                Context.Database = Database.GetDatabase(scDb);
            }

            var useContextDatabase = apiVersion.Is("file") || apiVersion.Is("handle") || !isAuthenticated ||
                                     string.IsNullOrEmpty(originParam) || originParam.Is("current");
            var scriptDb = useContextDatabase ? Context.Database : Database.GetDatabase(originParam);
            var dbName   = scriptDb?.Name;

            if (scriptDb == null && !apiVersion.Is("file") && !apiVersion.Is("handle"))
            {
                PowerShellLog.Error($"The '{serviceMappingKey}' service requires a database but none was found in parameters or Context.");
                return;
            }

            PowerShellLog.Info($"'{serviceMappingKey}' called by user: '******'");
            PowerShellLog.Debug($"'{request.Url}'");

            Item scriptItem = null;

            switch (apiVersion)
            {
            case "1":
                scriptItem = scriptDb.GetItem(itemParam) ??
                             scriptDb.GetItem(ApplicationSettings.ScriptLibraryPath + itemParam);
                break;

            case "media":
                ProcessMedia(context, isUpload, scriptDb, itemParam, unpackZip, skipExisting);
                return;

            case "file":
                ProcessFile(context, isUpload, originParam, pathParam);
                return;

            case "handle":
                ProcessHandle(context, originParam);
                return;

            case "2":
                var apiScripts = GetApiScripts(dbName);
                if (apiScripts.ContainsKey(dbName))
                {
                    var dbScripts = apiScripts[dbName];
                    if (dbScripts.ContainsKey(itemParam))
                    {
                        scriptItem = scriptDb.GetItem(dbScripts[itemParam].Id);
                    }
                }

                if (scriptItem == null)
                {
                    context.Response.StatusCode        = 404;
                    context.Response.StatusDescription = "The specified script is invalid.";
                    return;
                }
                break;

            case "script":
                ProcessScript(context, request, rawOutput, sessionId, persistentSession);
                return;

            default:
                PowerShellLog.Error($"Requested API/Version ({serviceMappingKey}) is not supported.");
                return;
            }

            ProcessScript(context, scriptItem);
        }
        public void OnEvent(object sender, EventArgs args)
        {
            Item item = null;

            if (!(args is SitecoreEventArgs scArgs) || HttpContext.Current?.Session == null || scArgs.Parameters.Length < 1 ||
                SecurityDisabler.CurrentValue == SecurityState.Disabled)
            {
                // allow jobs to modify scripts as otherwise all kind of things break
                // allow modifying scripts when SecurityDisabler is active - needed for Update Packages to function
                return;
            }

            item = scArgs.Parameters[0] as Item;
            if (item != null && !item.IsPowerShellScript() && !item.IsPowerShellLibrary())
            {
                // not a PowerShell related item
                return;
            }

            var itemCreatingEventArgs = scArgs.Parameters[0] as ItemCreatingEventArgs;

            if (itemCreatingEventArgs?.Parent?.Database != null && itemCreatingEventArgs.TemplateId != (ID)null)
            {
                var template = TemplateManager.GetTemplate(itemCreatingEventArgs.TemplateId,
                                                           itemCreatingEventArgs.Parent.Database);
                if (template == null || (!template.InheritsFrom(Templates.Script.Id) &&
                                         !template.InheritsFrom(Templates.ScriptLibrary.Id)))
                {
                    // not creating Script or Library
                    return;
                }
            }


            if (!SessionElevationManager.IsSessionTokenElevated(ApplicationNames.ItemSave))
            {
                SessionElevationErrors.OperationRequiresElevation();

                if (itemCreatingEventArgs != null)
                {
                    itemCreatingEventArgs.Cancel = true;
                    PowerShellLog.Warn(
                        $"Prevented Script/Library '{itemCreatingEventArgs.Parent?.Paths?.Path}/{itemCreatingEventArgs.ItemName}' creation by '{Context.User?.Name}'.");
                }
                else
                {
                    PowerShellLog.Warn(
                        $"Prevented Script/Library save '{item?.Parent.Paths.Path}' by user '{Context.User?.Name}'.");
                }

                scArgs.Result.Cancel = true;
                scArgs.Result.Messages.Add("Item save prevented");
                return;
            }

            if (itemCreatingEventArgs != null)
            {
                PowerShellLog.Info(
                    $" Script/Library '{itemCreatingEventArgs.Parent?.Paths?.Path}/{itemCreatingEventArgs.ItemName}' created by user '{Context.User?.Name}'");
            }
            else
            {
                PowerShellLog.Info(
                    $" Script/Library saved '{item?.Parent.Paths.Path}' by user '{Context.User?.Name}'");
                if (item.IsPowerShellScript())
                {
                    PowerShellLog.Debug(item[Templates.Script.Fields.ScriptBody]);
                }
            }
        }
Пример #15
0
        public void ProcessRequest(HttpContext context)
        {
            var request           = HttpContext.Current.Request;
            var userName          = request.Params.Get("user");
            var password          = request.Params.Get("password");
            var itemParam         = request.Params.Get("script");
            var pathParam         = request.Params.Get("path");
            var originParam       = request.Params.Get("scriptDb");
            var apiVersion        = request.Params.Get("apiVersion");
            var serviceMappingKey = request.HttpMethod + "/" + apiVersion;
            var isUpload          = request.HttpMethod.Is("POST") && request.InputStream.Length > 0;
            var unpackZip         = request.Params.Get("skipunpack").IsNot("true");
            var skipExisting      = request.Params.Get("skipexisting").Is("true");
            var serviceName       = apiVersionToServiceMapping.ContainsKey(serviceMappingKey)
                ? apiVersionToServiceMapping[serviceMappingKey]
                : string.Empty;

            // verify that the service is enabled
            if (!CheckServiceEnabled(apiVersion, request.HttpMethod))
            {
                PowerShellLog.Error($"Attempt to call the {apiVersion} service failed as it is not enabled.");
                return;
            }

            // verify that the user is authorized to access the end point
            var authUserName = string.IsNullOrEmpty(userName) ? Context.User.Name : userName;

            if (!ServiceAuthorizationManager.IsUserAuthorized(serviceName, authUserName, false))
            {
                HttpContext.Current.Response.StatusCode = 401;
                PowerShellLog.Error($"Attempt to call the '{apiVersion}' service failed as user '{userName}' was not authorized.");
                return;
            }

            // login user if specified explicitly
            if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
            {
                var account = new AccountIdentity(userName);
                AuthenticationManager.Login(account.Name, password, false);
            }

            var isAuthenticated    = Context.IsLoggedIn;
            var useContextDatabase = apiVersion.Is("file") || apiVersion.Is("handle") || !isAuthenticated || string.IsNullOrEmpty(originParam) || originParam.Is("current");
            var scriptDb           = useContextDatabase ? Context.Database : Database.GetDatabase(originParam);
            var dbName             = scriptDb.Name;

            if (!CheckServiceAuthentication(apiVersion, isAuthenticated))
            {
                PowerShellLog.Error($"Attempt to call the {apiVersion} service failed as - user not logged in, authentication failed or no credentials provided.");
                return;
            }

            if (isUpload)
            {
                switch (apiVersion)
                {
                case "media":
                    if (ZipUtils.IsZipContent(request.InputStream) && unpackZip)
                    {
                        PowerShellLog.Debug("The uploaded asset will be extracted to Media Library.");
                        using (var packageReader = new Sitecore.Zip.ZipReader(request.InputStream))
                        {
                            foreach (var zipEntry in packageReader.Entries)
                            {
                                if (!zipEntry.IsDirectory)
                                {
                                    ProcessMediaUpload(zipEntry.GetStream(), scriptDb, itemParam, zipEntry.Name, skipExisting);
                                }
                            }
                        }
                    }
                    else
                    {
                        ProcessMediaUpload(request.InputStream, scriptDb, itemParam, null, skipExisting);
                    }
                    break;

                case "file":
                    ProcessFileUpload(request.InputStream, originParam, pathParam);
                    break;

                default:
                    PowerShellLog.Error($"Requested API/Version ({apiVersion}) is not supported.");
                    break;
                }
                return;
            }

            Item scriptItem;

            switch (apiVersion)
            {
            case "1":
                scriptItem = scriptDb.GetItem(itemParam) ??
                             scriptDb.GetItem(ApplicationSettings.ScriptLibraryPath + itemParam);
                break;

            case "media":
                ProcessMediaDownload(scriptDb, itemParam);
                return;

            case "file":
                ProcessFileDownload(originParam, pathParam);
                return;

            case "handle":
                ProcessHandle(originParam);
                return;

            default:
                UpdateCache(dbName);
                if (!apiScripts.ContainsKey(dbName))
                {
                    HttpContext.Current.Response.StatusCode = 404;
                    return;
                }
                var dbScripts = apiScripts[scriptDb.Name];
                if (!dbScripts.ContainsKey(itemParam))
                {
                    HttpContext.Current.Response.StatusCode = 404;
                    return;
                }
                scriptItem = scriptDb.GetItem(dbScripts[itemParam].Id);
                apiScripts = null;
                break;
            }

            ProcessScript(context, scriptItem);
        }