Ejemplo n.º 1
0
        private static string[] PurgeUrlFromProxy(string url, bool async)
        {
            // PURGE /contentem/maicontent.jpg HTTP/1.1
            // Host: myhost.hu

            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }

            if (WebApplication.ProxyIPs.Count == 0)
            {
                return(null);
            }

            string contentPath;
            string host;

            var slashIndex = url.IndexOf("/");

            if (slashIndex >= 0)
            {
                contentPath = url.Substring(slashIndex);
                host        = url.Substring(0, slashIndex);
            }
            else
            {
                contentPath = "/";
                host        = url;
            }

            if (string.IsNullOrEmpty(host) && HttpContext.Current != null)
            {
                host = HttpContext.Current.Request.Url.Host;
            }

            string[] result = null;
            if (!async)
            {
                result = new string[WebApplication.ProxyIPs.Count];
            }

            var proxyIndex = 0;

            foreach (var proxyIP in WebApplication.ProxyIPs)
            {
                var proxyUrl = string.Concat("http://", proxyIP, contentPath);

                try
                {
                    var request = WebRequest.Create(proxyUrl) as HttpWebRequest;
                    if (request == null)
                    {
                        break;
                    }

                    request.Method = "PURGE";
                    request.Host   = host;

                    if (!async)
                    {
                        using (request.GetResponse())
                        {
                            // we do not need to read the request here, just the status code
                            result[proxyIndex] = "OK";
                        }
                    }
                    else
                    {
                        request.BeginGetResponse(null, null);
                    }
                }
                catch (WebException wex)
                {
                    var wr = wex.Response as HttpWebResponse;
                    if (wr != null && !async)
                    {
                        switch (wr.StatusCode)
                        {
                        case HttpStatusCode.NotFound:
                            result[proxyIndex] = "MISS";
                            break;

                        case HttpStatusCode.OK:
                            result[proxyIndex] = "OK";
                            break;

                        default:
                            SnLog.WriteException(wex);
                            result[proxyIndex] = wex.Message;
                            break;
                        }
                    }
                    else
                    {
                        SnLog.WriteException(wex);
                        if (!async)
                        {
                            result[proxyIndex] = wex.Message;
                        }
                    }
                }

                proxyIndex++;
            }

            return(result);
        }
Ejemplo n.º 2
0
        protected void BtnSave_Click(object sender, EventArgs args)
        {
            _contentView.UpdateContent();
            var content = _contentView.Content;

            if (!_contentView.IsUserInputValid || !content.IsValid)
            {
                return;
            }

            if (!this.HasPermission)
            {
                _contentView.ContentException = new SenseNetSecurityException(HttpContext.GetGlobalResourceObject("Notification", "NotEnoughPermissions") as string);
                return;
            }

            Subscription subscription;

            if (IsSubscriptionNew)
            {
                subscription = new Subscription
                {
                    IsActive    = true,
                    ContentPath = (string)content["ContentPath"],
                    Frequency   = (NotificationFrequency)Enum.Parse(typeof(NotificationFrequency),
                                                                    (content["Frequency"] as List <String>)[0]),
                    UserEmail = (string)content["UserEmail"],
                    UserId    = (int)(decimal)content["UserId"],
                    UserName  = (string)content["UserName"],
                    UserPath  = (string)content["UserPath"],
                    Language  = (content["Language"] as List <String>)[0],
                    SitePath  = PortalContext.Current.Site.Path,
                    SiteUrl   = PortalContext.Current.SiteUrl
                };
            }
            else
            {
                subscription = new Subscription
                {
                    IsActive    = (bool)content["IsActive"],
                    ContentPath = (string)content["ContentPath"],
                    Frequency   = (NotificationFrequency)Enum.Parse(typeof(NotificationFrequency),
                                                                    (content["Frequency"] as List <String>)[0]),
                    UserEmail = (string)content["UserEmail"],
                    UserId    = (int)(decimal)content["UserId"],
                    UserName  = (string)content["UserName"],
                    UserPath  = (string)content["UserPath"],
                    Language  = (content["Language"] as List <String>)[0],
                    SitePath  = PortalContext.Current.Site.Path,
                    SiteUrl   = PortalContext.Current.SiteUrl
                };
            }

            try
            {
                subscription.Save();

                CallDone(false);
            }
            catch (Exception ex) // logged
            {
                SnLog.WriteException(ex);
                _contentView.ContentException = ex;
            }
        }
Ejemplo n.º 3
0
        public override object Execute(Content content, params object[] parameters)
        {
            var targetPath = (string)parameters[0];
            var targetNode = Node.LoadNode(targetPath);

            if (targetNode == null)
            {
                throw new ContentNotFoundException(targetPath);
            }

            if (!(parameters[1] is object[] ids))
            {
                throw new InvalidOperationException("No content identifiers provided.");
            }

            var results          = new List <object>();
            var errors           = new List <ErrorContent>();
            var identifiers      = ids.Select(NodeIdentifier.Get).ToList();
            var foundIdentifiers = new List <NodeIdentifier>();
            var nodes            = Node.LoadNodes(identifiers);

            foreach (var node in nodes)
            {
                try
                {
                    // Collect already found identifiers in a separate list otherwise the error list
                    // would contain multiple errors for the same content.
                    foundIdentifiers.Add(NodeIdentifier.Get(node));

                    node.MoveTo(targetNode);
                    results.Add(new { node.Id, node.Path, node.Name });
                }
                catch (Exception e)
                {
                    //TODO: we should log only relevant exceptions here and skip
                    // business logic-related errors, e.g. lack of permissions or
                    // existing target content path.
                    SnLog.WriteException(e);

                    errors.Add(new ErrorContent
                    {
                        Content = new { node?.Id, node?.Path, node?.Name },
                        Error   = new Error
                        {
                            Code          = "NotSpecified",
                            ExceptionType = e.GetType().FullName,
                            InnerError    = new StackInfo {
                                Trace = e.StackTrace
                            },
                            Message = new ErrorMessage
                            {
                                Lang  = System.Globalization.CultureInfo.CurrentUICulture.Name.ToLower(),
                                Value = e.Message
                            }
                        }
                    });
                }
            }

            // iterating through the missing identifiers and making error items for them
            errors.AddRange(identifiers.Where(id => !foundIdentifiers.Exists(f => f.Id == id.Id || f.Path == id.Path))
                            .Select(missing => new ErrorContent
            {
                Content = new { missing?.Id, missing?.Path },
                Error   = new Error
                {
                    Code          = "ResourceNotFound",
                    ExceptionType = "ContentNotFoundException",
                    InnerError    = null,
                    Message       = new ErrorMessage
                    {
                        Lang  = System.Globalization.CultureInfo.CurrentUICulture.Name.ToLower(),
                        Value = string.Format(SNSR.GetString(SNSR.Exceptions.OData.ErrorContentNotFound),
                                              missing?.Path)
                    }
                }
            }));

            return(BatchActionResponse.Create(results, errors, results.Count + errors.Count));
        }
Ejemplo n.º 4
0
        protected virtual void Application_Error(object sender, EventArgs e, HttpApplication application)
        {
            int?originalHttpCode = null;
            var ex = application.Server.GetLastError();

            var httpException = ex as HttpException;

            if (httpException != null)
            {
                originalHttpCode = httpException.GetHttpCode();
            }

            var unknownActionException = ex as UnknownActionException;

            if (unknownActionException != null)
            {
                SnTrace.Web.Write("UnknownActionException: " + unknownActionException.Message);
                originalHttpCode = 404;
            }

            // if httpcode is contained in the dontcare list (like 404), don't log the exception
            var skipLogException = originalHttpCode.HasValue && dontCareErrorCodes.Contains(originalHttpCode.Value);

            if (!skipLogException)
            {
                try
                {
                    SnLog.WriteException(ex);
                }
                catch
                {
                    // if logging failed, cannot do much at this point
                }
            }

            if (ex.InnerException?.StackTrace != null &&
                (ex.InnerException.StackTrace.IndexOf("System.Web.UI.PageParser.GetCompiledPageInstanceInternal", StringComparison.InvariantCulture) != -1))
            {
                return;
            }

            if (HttpContext.Current == null)
            {
                return;
            }

            HttpResponse response;

            try
            {
                response = HttpContext.Current.Response;
            }
            catch (Exception)
            {
                response = null;
            }

            response?.Headers.Remove("Content-Disposition");

            // HACK: HttpAction.cs (and possibly StaticFileHandler) throws 404 and 403 HttpExceptions.
            // These are not exceptions to be displayed, but "fake" exceptions to handle 404 and 403 requests.
            // Therefore, here we set the statuscode and return, no further logic is executed.
            if (originalHttpCode.HasValue && (originalHttpCode == 404 || originalHttpCode == 403))
            {
                if (response != null)
                {
                    response.StatusCode = originalHttpCode.Value;
                }

                HttpContext.Current.ClearError();
                HttpContext.Current.ApplicationInstance.CompleteRequest();
                return;
            }


            var errorPageHtml = string.Empty;

            var exception = ex;

            if (exception.InnerException != null)
            {
                exception = exception.InnerException;
            }

            var statusCode = GetStatusCode(exception);

            if (response != null)
            {
                if (!HttpContext.Current.Request.Url.AbsoluteUri.StartsWith("http://localhost"))
                {
                    if (originalHttpCode.HasValue)
                    {
                        response.StatusCode = originalHttpCode.Value;
                    }

                    // If there is a specified status code in statusCodeString then set Response.StatusCode to it.
                    // Otherwise go on to global error page.
                    if (statusCode != null)
                    {
                        application.Response.StatusCode    = statusCode.StatusCode;
                        application.Response.SubStatusCode = statusCode.SubStatusCode;
                        response.Clear();
                        HttpContext.Current.ClearError();
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        return;
                    }

                    application.Response.TrySkipIisCustomErrors = true; // keeps our custom error page defined below instead of using the page of IIS - works in IIS7 only

                    if (application.Response.StatusCode == 200)
                    {
                        application.Response.StatusCode = 500;
                    }

                    Node globalErrorNode = null;
                    var  site            = Site.Current;

                    if (site != null)
                    {
                        var path = string.Concat("/Root/System/ErrorMessages/", site.Name, "/UserGlobal.html");
                        globalErrorNode = SystemAccount.Execute(() => Node.LoadNode(path));
                    }

                    if (globalErrorNode != null)
                    {
                        var globalBinary = globalErrorNode.GetBinary("Binary");
                        var stream       = globalBinary.GetStream();
                        if (stream != null)
                        {
                            var str = new StreamReader(stream);
                            errorPageHtml = str.ReadToEnd();
                        }
                    }
                    else
                    {
                        errorPageHtml = GetDefaultUserErrorPageHtml(application.Server.MapPath("/"), true);
                    }
                }
                else
                {
                    // if the page is requested from localhost
                    errorPageHtml = GetDefaultLocalErrorPageHtml(application.Server.MapPath("/"), true);
                }
            }
            else
            {
                // TODO: SQL Error handling
            }

            errorPageHtml = InsertErrorMessagesIntoHtml(exception, errorPageHtml);

            application.Response.TrySkipIisCustomErrors = true;

            // If there is a specified status code in statusCodeString then set Response.StatusCode to it.
            // Otherwise go on to global error page.
            if (statusCode != null)
            {
                application.Response.StatusCode    = statusCode.StatusCode;
                application.Response.SubStatusCode = statusCode.SubStatusCode;
                response?.Clear();

                HttpContext.Current.ClearError();
                HttpContext.Current.ApplicationInstance.CompleteRequest();
            }
            else
            {
                if (application.Response.StatusCode == 200)
                {
                    application.Response.StatusCode = 500;
                }
            }

            if (response != null)
            {
                response.Clear();
                response.Write(errorPageHtml);
            }

            HttpContext.Current.ClearError();
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Add or edit a saved content query.
        /// </summary>
        /// <param name="content">A query content to modify, a user, or any content under a workspace.</param>
        /// <param name="query">Query text.</param>
        /// <param name="displayName">Display name for the saved query.</param>
        /// <param name="queryType">Type of the query.</param>
        /// <param name="uiFilters">Technical data containing filter information.</param>
        /// <returns></returns>
        public static object SaveQuery(Content content, string query, string displayName,
                                       QueryType queryType, string uiFilters = null)
        {
            if (content == null)
            {
                throw new ArgumentNullException("content");
            }

            if (query == null)
            {
                throw new ArgumentNullException("query");
            }

            try
            {
                // replace @@ templates, because they cannot be parsed
                var replacedQuery = TemplateManager.Replace(typeof(ContentQueryTemplateReplacer), query);

                // We need to validate the query to avoid saving unknown texts.
                SnQuery.Parse(replacedQuery, new SnQueryContext(QuerySettings.Default, User.Current.Id));
            }
            catch (Exception ex)
            {
                SnLog.WriteWarning("Content query parse error during query save.", EventId.Querying,
                                   properties: new Dictionary <string, object>
                {
                    { "User", User.Current.Name },
                    { "Query text", query },
                    { "Error", ex.Message }
                });

                throw new InvalidOperationException("Cannot save an invalid content query: " + query);
            }

            ContentList queryContainer = null;
            Content     queryContent   = null;

            switch (queryType)
            {
            case QueryType.Private:

                // load the user and his profile
                var user = content.ContentHandler as User ?? (User)User.Current;
                if (!user.IsProfileExist())
                {
                    user.CreateProfile();
                }

                var profile = user.Profile;
                if (profile == null)
                {
                    throw new InvalidOperationException("User profile could not be created.");
                }

                queryContainer = GetQueryContainer(profile);
                break;

            case QueryType.Public:
                // store the query under the current workspace
                queryContainer = GetQueryContainer(((GenericContent)content.ContentHandler).Workspace);
                if (queryContainer == null)
                {
                    throw new InvalidOperationException("Query container could not be created for a public query. Content: " + content.Path);
                }
                break;

            case QueryType.NonDefined:
                if (!content.ContentType.IsInstaceOfOrDerivedFrom(QueryTypeName))
                {
                    throw new InvalidOperationException("If the query type is nondefined, the content must be a query to save.");
                }
                queryContent = content;
                break;

            default:
                throw new InvalidOperationException("Unknown query type: " + queryType);
            }

            if (queryContainer != null)
            {
                // create a new query under the previously found container
                queryContent = Content.CreateNew(QueryTypeName, queryContainer, null);
            }

            if (queryContent == null)
            {
                throw new InvalidOperationException("No query content to save.");
            }

            // Elevation: a simple user does not necessarily have
            // 'Add' permission for the public queries folder.
            using (new SystemAccount())
            {
                if (!string.IsNullOrEmpty(displayName))
                {
                    queryContent.DisplayName = displayName;
                }

                queryContent["Query"]     = query;
                queryContent["UiFilters"] = uiFilters;
                queryContent.Save();
            }

            return(queryContent);
        }
Ejemplo n.º 6
0
        private static void StartUpdaterAndExit()
        {
            // this switch is monitored by the Work method because it
            // must not ask for a new task if an update has started
            _updateStarted = true;

            SnLog.WriteInformation($"Task#Starting update process on agent {AgentName}.", EventId.TaskManagement.General);

            var updaterToolName       = AgentManager.UPDATER_PROCESSNAME + ".exe";
            var updaterToolPath       = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), updaterToolName);
            var updaterAlreadyRunning = false;

            // the tool should be next to the agent executable
            if (File.Exists(updaterToolPath))
            {
                var startInfo = new ProcessStartInfo(updaterToolName)
                {
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    ErrorDialog            = false,
                    WindowStyle            = ProcessWindowStyle.Hidden,
                    RedirectStandardInput  = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                };

                var updaterProcess = new Process
                {
                    EnableRaisingEvents = true,
                    StartInfo           = startInfo
                };

                // listen to what the updater tool writes to the Console
                updaterProcess.OutputDataReceived += delegate(object sender, DataReceivedEventArgs args)
                {
                    if (args == null || args.Data == null)
                    {
                        return;
                    }

                    // the updater notified us that he won
                    if (string.CompareOrdinal(args.Data, "WINNER") == 0)
                    {
                        _updateWinner = true;
                    }
                };

                try
                {
                    updaterProcess.Start();
                    updaterProcess.BeginOutputReadLine();

                    SnLog.WriteInformation($"Task#Updater tool STARTED on agent {Agent.AgentName}",
                                           EventId.TaskManagement.General);

                    // Wait while the updater process exits (because another updater is already running)
                    // or it notifies us that he is the winner and will do the actual update soon.
                    do
                    {
                        updaterProcess.WaitForExit(1000);
                    } while (!updaterProcess.HasExited && !_updateWinner);

                    if (updaterProcess.HasExited)
                    {
                        if (updaterProcess.ExitCode == AgentManager.UPDATER_STATUSCODE_STARTED)
                        {
                            updaterAlreadyRunning = true;

                            // another agent already started the updater tool, simply exit
                            SnLog.WriteInformation($"Task#Updater tool EXITED on agent {AgentName} because another updater is already running.",
                                                   EventId.TaskManagement.General);
                        }
                        else
                        {
                            // unknown error code
                            SnLog.WriteWarning($"Task#Updater tool EXITED on agent {AgentName} with an unexpected code: {updaterProcess.ExitCode}.",
                                               EventId.TaskManagement.General);
                        }
                    }
                    else if (_updateWinner)
                    {
                        // Download the package only if we started the one
                        // and only true updater exe - that has not exited.
                        DownloadUpdatePackage();
                    }
                }
                catch (Exception ex)
                {
                    SnLog.WriteException(ex, "Agent update error.", EventId.TaskManagement.General);
                }
            }
            else
            {
                // the updater tool is missing
                SnLog.WriteError(string.Format("Task#Updater tool not found ({0}), but there is a new version on the server. Please update the TaskManagement folder manually.", updaterToolPath),
                                 EventId.TaskManagement.General);

                // no update will be performed: switch back to working mode
                _updateStarted = false;

                // do not exit if there is no updater: the operator must handle
                // this use-case manually (stop the service and copy the files)
                return;
            }

            // wait for the last task executor to finish
            while (_working)
            {
                Thread.Sleep(1000);
            }

            SnLog.WriteInformation(string.Format(updaterAlreadyRunning
                    ? "Task#Agent {0} exits before updating."
                    : "Task#Agent {0} exits before updating. This is Ripley, last survivor of the Nostromo, signing off.", AgentName), EventId.TaskManagement.General);

            // shut down this agent
            Environment.Exit(0);
        }
Ejemplo n.º 7
0
            /// <summary>
            /// MUST BE SYNCHRON
            /// GAPS MUST BE ORDERED
            /// </summary>
            internal static void Start(int lastDatabaseId, int lastExecutedId, int[] gaps, System.IO.TextWriter consoleOut)
            {
                if (consoleOut != null)
                {
                    consoleOut.WriteLine("Executing unprocessed activities. {0}-{1} {2}", lastExecutedId, lastDatabaseId, CompletionState.GapsToString(gaps, 5, 3));
                }

                SnLog.WriteInformation("Executing unprocessed activities.",
                                       EventId.RepositoryRuntime,
                                       properties: new Dictionary <string, object> {
                    { "LastDatabaseId", lastDatabaseId },
                    { "LastExecutedId", lastExecutedId },
                    { "CountOfGaps", gaps.Length },
                    { "Gaps", String.Join(", ", gaps) }
                });

                DependencyManager.Start();

                var count = 0;

                if (gaps.Any())
                {
                    var loadedActivities = new IndexingActivityLoader(gaps, true);
                    foreach (LuceneIndexingActivity loadedActivity in loadedActivities)
                    {
                        // wait and start processing loaded activities in the meantime
                        WaitIfOverloaded(true);

                        SnTrace.IndexQueue.Write("IAQ: Startup: A{0} enqueued from db.", loadedActivity.Id);

                        IndexingActivityHistory.Arrive(loadedActivity);
                        _arrivalQueue.Enqueue(loadedActivity);
                        _lastQueued = loadedActivity.Id;
                        count++;
                    }
                }
                if (lastExecutedId < lastDatabaseId)
                {
                    var loadedActivities = new IndexingActivityLoader(lastExecutedId + 1, lastDatabaseId, true);
                    foreach (LuceneIndexingActivity loadedActivity in loadedActivities)
                    {
                        // wait and start processing loaded activities in the meantime
                        WaitIfOverloaded(true);

                        SnTrace.IndexQueue.Write("IAQ: Startup: A{0} enqueued from db.", loadedActivity.Id);

                        IndexingActivityHistory.Arrive(loadedActivity);
                        _arrivalQueue.Enqueue(loadedActivity);
                        _lastQueued = loadedActivity.Id;
                        count++;
                    }
                }

                if (_lastQueued < lastExecutedId)
                {
                    _lastQueued = lastExecutedId;
                }

                // ensure that the arrival activity queue is not empty at this pont.
                DependencyManager.ActivityEnqueued();

                if (lastDatabaseId != 0 || lastExecutedId != 0 || gaps.Any())
                {
                    while (IsWorking())
                    {
                        Thread.Sleep(200);
                    }
                }

                // At this point we know for sure that the original gap is not there anymore.
                // In case there is a false gap (e.g. because there are missing activity ids
                // in the db) we have to remove these ids manually from the in-memory gap.
                if (gaps.Any())
                {
                    TerminationHistory.RemoveGaps(gaps);

                    // Commit is necessary because otherwise the gap is removed only in memory, but
                    // the index is not updated in the file system.
                    LuceneManager.Commit();
                }

                SnLog.WriteInformation($"Executing unprocessed activities ({count}) finished.", EventId.RepositoryLifecycle);
            }
Ejemplo n.º 8
0
        /// <summary>
        /// Initializes a RabbitMQ service connection based on the provided service url.
        /// Declares the exchange and binds a consumer queue.
        /// Opens a receiver channel and creates a consumer for receiving messages.
        /// </summary>
        public override void Initialize()
        {
            if (_initialized)
            {
                return;
            }

            base.Initialize();

            Connection = OpenConnection(ServiceUrl);

            string queueName;

            try
            {
                // declare an exchange and bind a queue unique for this application
                using (var initChannel = OpenChannel(Connection))
                {
                    initChannel.ExchangeDeclare(MessageExchange, "fanout");

                    // let the server generate a unique queue name
                    queueName = initChannel.QueueDeclare().QueueName;
                    SnTrace.Messaging.Write($"RMQ: RabbitMQ Security queue declared: {queueName}");

                    initChannel.QueueBind(queueName, MessageExchange, string.Empty);

                    SnTrace.Messaging.Write($"RMQ: RabbitMQ Security queue {queueName} is bound to exchange {MessageExchange}.");
                }
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex, $"RabbitMQ Security message provider connection error. Service url: {ServiceUrl}");
                throw;
            }

            // use a single channel for receiving messages
            ReceiverChannel = OpenChannel(Connection);

            var consumer = new EventingBasicConsumer(ReceiverChannel);

            consumer.Shutdown          += (sender, args) => { SnTrace.Messaging.Write("RMQ: RabbitMQ Security consumer shutdown."); };
            consumer.ConsumerCancelled += (sender, args) => { SnTrace.Messaging.Write("RMQ: RabbitMQ Security consumer cancelled."); };
            consumer.Received          += (model, args) =>
            {
                // this is the main entry point for receiving messages
                using (var ms = new MemoryStream(args.Body))
                {
                    OnMessageReceived(ms);
                }
            };

            ReceiverChannel.BasicConsume(queueName, true, consumer);

            SnLog.WriteInformation($"RabbitMQ Security message provider connected to {ServiceUrl}",
                                   properties: new Dictionary <string, object>
            {
                { "Exchange", MessageExchange },
                { "QueueName", queueName }
            });

            _initialized = true;
        }
Ejemplo n.º 9
0
        public void ResizeImage(HttpContext context)
        {
            Stream imageStream   = null;
            var    imageNodePath = HttpContext.Current.Request.FilePath;

            var content     = Content.Create(PortalContext.Current.ContextNode);
            var contentPath = "";

            var contentFileName = "";
            var contentId       = -1;

            CheckCacheFolder();

            if (!string.IsNullOrEmpty(imageNodePath))
            {
                if (ImageType == "Binary")
                {
                    var contentBinary = content.Fields["Binary"].GetData() as BinaryData;

                    if (contentBinary == null)
                    {
                        throw new Exception("Can not read Binary field from the given Content. Doesn't exists?");
                    }

                    imageStream     = contentBinary.GetStream();
                    contentFileName = content.Name;
                    contentId       = content.Id;
                }
                else if (ImageType == "ImageData")
                {
                    if (!String.IsNullOrEmpty(ImageFieldName))
                    {
                        try
                        {
                            var contentImageFieldData = content.Fields[ImageFieldName].GetData() as SenseNet.ContentRepository.Fields.ImageField.ImageFieldData;

                            if (contentImageFieldData.ImgData.Size > 0)
                            {
                                imageStream     = contentImageFieldData.ImgData.GetStream();
                                contentFileName = new FileInfo(contentImageFieldData.ImgData.FileName.FullFileName).Name;
                                contentId       = contentImageFieldData.ImgData.Id;
                            }
                            else
                            {
                                imageStream     = contentImageFieldData.ImgRef.Binary.GetStream();
                                contentFileName = new FileInfo(contentImageFieldData.ImgRef.Path).Name;
                                contentId       = contentImageFieldData.ImgRef.Id;
                            }
                        }
                        catch (Exception)
                        {
                            throw new Exception("Invalid Image Field Name was given in the application.");
                        }
                    }
                    else
                    {
                        throw new Exception("There was no ImageFieldName specified when using ImageData as ImageType.");
                    }
                }
                else if (ImageType == "Reference")
                {
                    if (!String.IsNullOrEmpty(ImageFieldName))
                    {
                        try
                        {
                            //TODO: GetData can return with null, a Node or a List<node>
                            var referenceField   = content.Fields[ImageFieldName].GetData() as List <Node>;
                            var refContent       = Content.Create(referenceField[0]);
                            var refContentBinary = refContent.Fields["Binary"].GetData() as BinaryData;
                            imageStream     = refContentBinary.GetStream();
                            contentFileName = refContent.Name;
                            contentId       = refContent.Id;
                        }
                        catch (Exception)
                        {
                            //TODO: empty catch block
                        }
                    }
                    else
                    {
                        throw new Exception("There was no ImageFieldName specified when using ImageData as ImageType.");
                    }
                }
                else if (ImageType == "Attachment")
                {
                    if (!String.IsNullOrEmpty(ImageFieldName))
                    {
                        try
                        {
                            var binary = content.Fields[ImageFieldName].GetData() as BinaryData;
                            imageStream     = binary.GetStream();
                            contentFileName = new FileInfo(binary.FileName.FullFileName).Name;
                            contentId       = binary.Id;
                        }
                        catch (Exception)
                        {
                            throw new Exception(
                                      String.Format("The given image field field '{0}' is not a valid binary field of an image.", ImageFieldName));
                        }
                    }
                }

                // generating contentPath
                int lastDotIndex = contentFileName.LastIndexOf('.');
                contentPath = lastDotIndex != -1
                                  ? contentFileName.Insert(lastDotIndex, String.Format("_{1}{0}", contentId.ToString(), ResizeType == ResizeTypeList.Resize ? "R_" : "C_"))
                                  : String.Format("{0}_{2}{1}", contentFileName, contentId.ToString(), ResizeType == ResizeTypeList.Resize ? "R_" : "C_");

                if (IsCached(contentPath))
                {
                    FlushCachedFile(contentPath, context);
                    return;
                }

                if (ResizeType == ResizeTypeList.Resize)
                {
                    // Resize image
                    imageStream = ImageResizer.CreateResizedImageFile(imageStream, Width, Height, 0, Stretch,
                                                                      IsAutoOutputFormat ? GetImageFormat(GetMimeType(contentPath)) : this.ResizeOutputFormat,
                                                                      this.ResizeSmoothingMode,
                                                                      this.ResizeInterpolationMode,
                                                                      this.ResizePixelOffsetMode);
                }
                else
                {
                    double verticalDiff;
                    double horizontalDiff;

                    switch (CropVAlign.ToLower())
                    {
                    case "top":
                        verticalDiff = 0;
                        break;

                    case "center":
                        verticalDiff = -1;
                        break;

                    case "bottom":
                        verticalDiff = double.MaxValue;
                        break;

                    default:
                        try
                        {
                            verticalDiff = Convert.ToDouble(CropVAlign);
                        }
                        catch (Exception ex)
                        {
                            SnLog.WriteException(ex);
                            verticalDiff = 0;
                        }
                        break;
                    }

                    switch (CropHAlign.ToLower())
                    {
                    case "left":
                        horizontalDiff = 0;
                        break;

                    case "center":
                        horizontalDiff = -1;
                        break;

                    case "right":
                        horizontalDiff = double.MaxValue;
                        break;

                    default:
                        try
                        {
                            horizontalDiff = Convert.ToDouble(CropHAlign);
                        }
                        catch (Exception ex)
                        {
                            SnLog.WriteException(ex);
                            horizontalDiff = 0;
                        }
                        break;
                    }
                    // Crop image
                    imageStream = ImageResizer.CreateCropedImageFile(imageStream, Width, Height, 0,
                                                                     IsAutoOutputFormat ? GetImageFormat(GetMimeType(contentPath)) : this.ResizeOutputFormat,
                                                                     this.ResizeSmoothingMode,
                                                                     this.ResizeInterpolationMode,
                                                                     this.ResizePixelOffsetMode, verticalDiff, horizontalDiff);
                }

                Cache(imageStream, GetImageCachePath(contentPath));
                FlushStream(imageStream, context, GetMimeType(contentPath));
                return;
            }
            else
            {
                throw new Exception("There was no image in the requested file path.");
            }
        }
Ejemplo n.º 10
0
        private void StartManagers()
        {
            object          dummy;
            IClusterChannel channel = null;

            try
            {
                ConsoleWrite("Initializing cache ... ");
                dummy = Cache.Count;

                // Log this, because logging is switched off when creating the cache provider
                // to avoid circular reference.
                SnLog.WriteInformation($"CacheProvider created: {Cache.Instance?.GetType().FullName}");
                ConsoleWriteLine("ok.");

                ConsoleWrite("Starting message channel ... ");
                channel = DistributedApplication.ClusterChannel;
                channel.StartAsync(CancellationToken.None).GetAwaiter().GetResult();

                ConsoleWriteLine("ok.");
                SnLog.WriteInformation($"Message channel {channel.GetType().FullName} started." +
                                       $"Instance id: {channel.ClusterMemberInfo.InstanceID}");

                ConsoleWrite("Sending greeting message ... ");
                new PingMessage(new string[0]).SendAsync(CancellationToken.None).GetAwaiter().GetResult();
                ConsoleWriteLine("ok.");

                ConsoleWrite("Starting NodeType system ... ");
                dummy = Providers.Instance.StorageSchema.NodeTypes[0];
                ConsoleWriteLine("ok.");

                ConsoleWrite("Starting ContentType system ... ");
                dummy = ContentType.GetByName("GenericContent");
                ConsoleWriteLine("ok.");

                ConsoleWrite("Starting AccessProvider ... ");
                dummy = User.Current;
                ConsoleWriteLine("ok.");

                SnQuery.SetPermissionFilterFactory(Providers.Instance.PermissionFilterFactory);

                if (_settings.StartIndexingEngine)
                {
                    StartIndexingEngine();
                }
                else
                {
                    ConsoleWriteLine("IndexingEngine is not started.");
                }

                // switch on message processing after IndexingEngine was started.
                channel.AllowMessageProcessing = true;

                if (_settings.StartWorkflowEngine)
                {
                    StartWorkflowEngine();
                }
                else
                {
                    ConsoleWriteLine("Workflow subsystem is not started.");
                }

                ConsoleWrite("Loading string resources ... ");
                dummy = SenseNetResourceManager.Current;
                ConsoleWriteLine("ok.");

                _serviceInstances = new List <ISnService>();
                foreach (var serviceType in TypeResolver.GetTypesByInterface(typeof(ISnService)))
                {
                    var service = (ISnService)Activator.CreateInstance(serviceType);
                    service.Start();
                    ConsoleWriteLine("Service started: ", serviceType.Name);
                    _serviceInstances.Add(service);
                }

                // register this application in the task management component
                SnTaskManager.RegisterApplication();
            }
            catch
            {
                // If an error occoured, shut down the cluster channel.
                channel?.ShutDownAsync(CancellationToken.None).GetAwaiter().GetResult();

                throw;
            }
        }
Ejemplo n.º 11
0
        public override Stream Open()
        {
            if (_node == null)
            {
                try
                {
                    var allowCompiledContent = AllowCompiledContent(_repositoryPath);

                    // http://localhost/TestDoc.docx?action=RestoreVersion&version=2.0A
                    // When there are 'action' and 'version' parameters in the requested URL the portal is trying to load the desired version of the node of the requested action.
                    // This leads to an exception when the action doesn't have that version.
                    // _repositoryPath will point to the node of action and ContextNode will be the document
                    // if paths are not equal then we will return the last version of the requested action.
                    // We also have to ignore the version request parameter in case of binary handler, because that
                    // ashx must not have multiple versions.
                    if (PortalContext.Current == null || PortalContext.Current.BinaryHandlerRequestedNodeHead != null || string.IsNullOrEmpty(PortalContext.Current.VersionRequest) || _repositoryPath != PortalContext.Current.ContextNodePath)
                    {
                        if (allowCompiledContent)
                        {
                            // elevated mode: pages, ascx files, etc.
                            using (new SystemAccount())
                            {
                                _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                            }
                        }
                        else
                        {
                            _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                        }
                    }
                    else
                    {
                        VersionNumber version;
                        if (VersionNumber.TryParse(PortalContext.Current.VersionRequest, out version))
                        {
                            Node node;

                            if (allowCompiledContent)
                            {
                                // elevated mode: pages, ascx files, etc.
                                using (new SystemAccount())
                                {
                                    node = Node.LoadNode(_repositoryPath, version);
                                }
                            }
                            else
                            {
                                node = Node.LoadNode(_repositoryPath, version);
                            }

                            if (node != null && node.SavingState == ContentSavingState.Finalized)
                            {
                                _node = node;
                            }
                        }
                    }

                    // we cannot serve the binary if the user has only See or Preview permissions for the content
                    if (_node != null && (_node.IsHeadOnly || _node.IsPreviewOnly) && HttpContext.Current != null)
                    {
                        AuthenticationHelper.ThrowForbidden(_node.Name);
                    }
                }
                catch (SenseNetSecurityException ex) // logged
                {
                    SnLog.WriteException(ex);

                    if (HttpContext.Current == null || (_repositoryPath != null && _repositoryPath.ToLower().EndsWith(".ascx")))
                    {
                        throw;
                    }

                    AuthenticationHelper.DenyAccess(HttpContext.Current.ApplicationInstance);
                }
            }

            if (_node == null)
            {
                throw new ApplicationException(string.Format("{0} not found. RepositoryFile cannot be served.", _repositoryPath));
            }

            string propertyName = string.Empty;

            if (PortalContext.Current != null)
            {
                propertyName = PortalContext.Current.QueryStringNodePropertyName;
            }

            if (string.IsNullOrEmpty(propertyName))
            {
                propertyName = PortalContext.DefaultNodePropertyName;
            }

            var propType = _node.PropertyTypes[propertyName];

            if (propType == null)
            {
                throw new ApplicationException("Property not found: " + propertyName);
            }

            var    propertyDataType = propType.DataType;
            Stream stream;

            switch (propertyDataType)
            {
            case DataType.Binary:
                string         contentType;
                BinaryFileName fileName;
                stream = DocumentBinaryProvider.Current.GetStream(_node, propertyName, out contentType, out fileName);

                if (stream == null)
                {
                    throw new ApplicationException(string.Format("BinaryProperty.Value.GetStream() returned null. RepositoryPath={0}, OriginalUri={1}, AppDomainFriendlyName={2} ", this._repositoryPath, ((PortalContext.Current != null) ? PortalContext.Current.RequestedUri.ToString() : "PortalContext.Current is null"), AppDomain.CurrentDomain.FriendlyName));
                }

                // Set MIME type only if this is the main content (skip asp controls and pages,
                // page templates and other repository files opened during the request).
                // We need this in case of special images, fonts, etc, and handle the variable
                // at the end of the request (PortalContextModule.EndRequest method).
                if (HttpContext.Current != null &&
                    PortalContext.Current != null &&
                    string.Equals(PortalContext.Current.RepositoryPath, _repositoryPath, StringComparison.InvariantCultureIgnoreCase) &&
                    (string.IsNullOrEmpty(PortalContext.Current.ActionName) || string.Equals(PortalContext.Current.ActionName, "Browse", StringComparison.InvariantCultureIgnoreCase)) &&
                    !string.IsNullOrEmpty(contentType) &&
                    contentType != "text/asp")
                {
                    if (!HttpContext.Current.Items.Contains(RESPONSECONTENTTYPEKEY))
                    {
                        HttpContext.Current.Items.Add(RESPONSECONTENTTYPEKEY, contentType);
                    }

                    // set the value anyway as it may be useful in case of our custom file handler (SenseNetStaticFileHandler)
                    HttpContext.Current.Response.ContentType = contentType;

                    // add the necessary header for the css font-face rule
                    if (MimeTable.IsFontType(fileName.Extension))
                    {
                        HttpHeaderTools.SetAccessControlHeaders();
                    }
                }

                // set compressed encoding if necessary
                if (HttpContext.Current != null && MimeTable.IsCompressedType(fileName.Extension))
                {
                    HttpContext.Current.Response.Headers.Add("Content-Encoding", "gzip");
                }

                // let the client code log file downloads
                var file = _node as ContentRepository.File;
                if (file != null)
                {
                    ContentRepository.File.Downloaded(file.Id);
                }
                break;

            case DataType.String:
            case DataType.Text:
            case DataType.Int:
            case DataType.DateTime:
                stream = new MemoryStream(Encoding.UTF8.GetBytes(_node[propertyName].ToString()));
                break;

            default:
                throw new NotSupportedException(string.Format("The {0} property cannot be served because that's datatype is {1}.", propertyName, propertyDataType));
            }

            return(stream);
        }
Ejemplo n.º 12
0
        internal void DoStart()
        {
            ConsoleWriteLine();
            ConsoleWriteLine("Starting Repository...");
            ConsoleWriteLine();

            if (_settings.TraceCategories != null)
            {
                LoggingSettings.SnTraceConfigurator.UpdateCategories(_settings.TraceCategories);
            }
            else
            {
                LoggingSettings.SnTraceConfigurator.UpdateStartupCategories();
            }

            InitializeLogger();

            RegisterAppdomainEventHandlers();

            if (_settings.IndexPath != null)
            {
                Providers.Instance.SearchManager.IndexDirectoryPath = _settings.IndexPath;
            }

            LoadAssemblies(_settings.IsWebContext);

            _settings.Services.GetRequiredService <SecurityHandler>().StartSecurity(_settings.IsWebContext, _settings.Services);

            //UNDONE: modernize TemplateManager
            // Set legacy collection from the new services collection and reset the
            // current singleton list to force the system to regenerate it.
            TemplateManager.TemplateReplacerInstances =
                _settings.Services.GetService <IEnumerable <TemplateReplacerBase> >()?.ToArray() ??
                Array.Empty <TemplateReplacerBase>();
            TemplateManager.Clear();

            SnQueryVisitor.VisitorExtensionTypes = new[] { typeof(Sharing.SharingVisitor) };

            // We have to log the access provider here because it cannot be logged
            // during creation as it would lead to a circular reference.
            SnLog.WriteInformation($"AccessProvider created: {AccessProvider.Current?.GetType().FullName}");

            using (new SystemAccount())
                StartManagers();

            if (_settings.TraceCategories != null)
            {
                LoggingSettings.SnTraceConfigurator.UpdateCategories(_settings.TraceCategories);
            }
            else
            {
                LoggingSettings.SnTraceConfigurator.UpdateCategories();
            }

            InitializeOAuthProviders();

            ConsoleWriteLine();
            ConsoleWriteLine("Repository has started.");
            ConsoleWriteLine();

            _startupInfo.Started = DateTime.UtcNow;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Executes all modifications.
        /// Current user must have SetPermissions permission on any modified entity.
        /// An Auditlog record with changed data will be writen.
        /// OnPermissionChanging and OnPermissionChanged events are fired on any active NodeObserver that is not in the exclusion list (see "disabledObservers" parameter).
        /// </summary>
        /// <param name="disabledObservers">NodeObserver exclusion list.</param>
        public void Apply(List <Type> disabledObservers)
        {
            foreach (var entityId in this._acls.Keys)
            {
                this.Context.AssertPermission(entityId, PermissionType.SetPermissions);
            }
            using (var audit = new AuditBlock(AuditEvent.PermissionChanged, "Trying to execute permission modifications",
                                              new Dictionary <string, object>
            {
                { "Entities", this._acls.Count },
                { "Breaks", this._breaks.Count },
                { "Unbreaks", this._unbreaks.Count }
            }))
            {
                using (var op = SnTrace.Security.StartOperation("AclEditor.Apply (acl count: {0})", _acls.Count))
                {
                    string msg = null;
                    if ((msg = Validate(this._acls)) != null)
                    {
                        // Log the error, but allow the operation to continue, because acl editor
                        // may contain many different operations that we do not want to lose.
                        SnLog.WriteWarning("Invalid ACL: " + msg, EventId.Security);
                    }

                    var relatedEntities = new List <int>();
                    // collect related aces
                    var originalAces = new List <string>();
                    // changed acls
                    foreach (var entityId in this._acls.Keys)
                    {
                        relatedEntities.Add(entityId);
                        originalAces.Add(AcesToString(entityId, this.Context.GetExplicitEntries(entityId)));
                    }
                    // breaks that are not in changed aces
                    foreach (var entityId in this._breaks)
                    {
                        if (!this._acls.ContainsKey(entityId))
                        {
                            relatedEntities.Add(entityId);
                            originalAces.Add(AcesToString(entityId, this.Context.GetExplicitEntries(entityId)));
                        }
                    }
                    // unbreaks that are not in changed aces
                    foreach (var entityId in this._unbreaks)
                    {
                        if (!this._acls.ContainsKey(entityId))
                        {
                            relatedEntities.Add(entityId);
                            originalAces.Add(AcesToString(entityId, this.Context.GetExplicitEntries(entityId)));
                        }
                    }

                    var relatedNodeHeads = relatedEntities.Select(NodeHead.Get).ToArray();
                    var changedData      = new[] { new ChangedData {
                                                       Name = "SetPermissions", Original = originalAces
                                                   } };

                    // fire "before" event
                    var args1 = new CancellablePermissionChangingEventArgs(relatedNodeHeads, changedData);
                    using (var op1 = SnTrace.Security.StartOperation("AclEditor.Apply / FireOnPermissionChanging"))
                    {
                        NodeObserver.FireOnPermissionChanging(null, null, args1, disabledObservers);
                        if (args1.Cancel)
                        {
                            throw new CancelNodeEventException(args1.CancelMessage, args1.EventType, null);
                        }
                        op1.Successful = true;
                    }

                    var customData = args1.GetCustomData();

                    // main operation
                    base.Apply();

                    // collect new values
                    changedData[0].Value = relatedEntities.Select(x => AcesToString(x, this.Context.GetExplicitEntries(x))).ToList();

                    // fire "after" event
                    var args2 = new PermissionChangedEventArgs(relatedNodeHeads, customData, changedData);
                    using (var op2 = SnTrace.Security.StartOperation("AclEditor.Apply / FireOnPermissionChanged"))
                    {
                        NodeObserver.FireOnPermissionChanged(null, null, args2, disabledObservers);
                        op2.Successful = true;
                    }

                    // iterate through all edited entities and log changes one by one
                    for (var i = 0; i < relatedEntities.Count; i++)
                    {
                        var entity = relatedNodeHeads[i];
                        SnLog.WriteAudit(AuditEvent.PermissionChanged, new Dictionary <string, object>
                        {
                            { "Id", entity != null ? entity.Id : 0 },
                            { "Path", entity != null ? entity.Path : string.Empty },
                            { "Type", changedData[0].Name },
                            { "OldAcl", (changedData[0].Original as List <string>)[i] }, // changed data lists are in the same order as relatedentities
                            { "NewAcl", (changedData[0].Value as List <string>)[i] }
                        });
                    }
                    op.Successful = true;
                }
                audit.Successful = true;
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Processes the OData web request. Designed for test purposes.
        /// </summary>
        /// <param name="context">An <see cref="HttpContext" /> object that provides references to the intrinsic server objects (for example, <see langword="Request" />, <see langword="Response" />, <see langword="Session" />, and <see langword="Server" />) used to service HTTP requests. </param>
        /// <param name="httpMethod">HTTP protocol method.</param>
        /// <param name="inputStream">Request stream containing the posted JSON object.</param>
        public void ProcessRequest(HttpContext context, string httpMethod, Stream inputStream)
        {
            ODataRequest   odataReq      = null;
            ODataFormatter formatter     = null;
            var            portalContext = (PortalContext)context.Items[PortalContext.CONTEXT_ITEM_KEY];

            try
            {
                Content content;

                odataReq = portalContext.ODataRequest;
                if (odataReq == null)
                {
                    formatter = ODataFormatter.Create("json", portalContext);
                    throw new ODataException("The Request is not an OData request.", ODataExceptionCode.RequestError);
                }

                this.ODataRequest = portalContext.ODataRequest;
                Exception requestError = this.ODataRequest.RequestError;

                formatter = ODataFormatter.Create(portalContext, odataReq);
                if (formatter == null)
                {
                    formatter = ODataFormatter.Create("json", portalContext);
                    throw new ODataException(ODataExceptionCode.InvalidFormatParameter);
                }

                if (requestError != null)
                {
                    var innerOdataError = requestError as ODataException;
                    var message         = "An error occured during request parsing. " + requestError.Message +
                                          " See inner exception for details.";
                    var code = innerOdataError?.ODataExceptionCode ?? ODataExceptionCode.RequestError;
                    throw new ODataException(message, code, requestError);
                }

                odataReq.Format = formatter.FormatName;
                formatter.Initialize(odataReq);

                var exists = Node.Exists(odataReq.RepositoryPath);
                if (!exists && !odataReq.IsServiceDocumentRequest && !odataReq.IsMetadataRequest && !AllowedMethodNamesWithoutContent.Contains(httpMethod))
                {
                    ContentNotFound(context, odataReq.RepositoryPath);
                    return;
                }

                JObject model;
                switch (httpMethod)
                {
                case "GET":
                    if (odataReq.IsServiceDocumentRequest)
                    {
                        formatter.WriteServiceDocument(portalContext, odataReq);
                    }
                    else if (odataReq.IsMetadataRequest)
                    {
                        formatter.WriteMetadata(context, odataReq);
                    }
                    else
                    {
                        if (!Node.Exists(odataReq.RepositoryPath))
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                        }
                        else if (odataReq.IsCollection)
                        {
                            formatter.WriteChildrenCollection(odataReq.RepositoryPath, portalContext, odataReq);
                        }
                        else if (odataReq.IsMemberRequest)
                        {
                            formatter.WriteContentProperty(odataReq.RepositoryPath, odataReq.PropertyName,
                                                           odataReq.IsRawValueRequest, portalContext, odataReq);
                        }
                        else
                        {
                            formatter.WriteSingleContent(odataReq.RepositoryPath, portalContext);
                        }
                    }
                    break;

                case "PUT":     // update
                    if (odataReq.IsMemberRequest)
                    {
                        throw new ODataException("Cannot access a member with HTTP PUT.",
                                                 ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        model   = Read(inputStream);
                        content = LoadContentOrVirtualChild(odataReq);
                        if (content == null)
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                            return;
                        }

                        ResetContent(content);
                        UpdateContent(content, model, odataReq);
                        formatter.WriteSingleContent(content, portalContext);
                    }
                    break;

                case "MERGE":
                case "PATCH":     // update
                    if (odataReq.IsMemberRequest)
                    {
                        throw new ODataException(
                                  String.Concat("Cannot access a member with HTTP ", httpMethod, "."),
                                  ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        model   = Read(inputStream);
                        content = LoadContentOrVirtualChild(odataReq);
                        if (content == null)
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                            return;
                        }

                        UpdateContent(content, model, odataReq);
                        formatter.WriteSingleContent(content, portalContext);
                    }
                    break;

                case "POST":     // invoke an action, create content
                    if (odataReq.IsMemberRequest)
                    {
                        formatter.WriteOperationResult(inputStream, portalContext, odataReq);
                    }
                    else
                    {
                        // parent must exist
                        if (!Node.Exists(odataReq.RepositoryPath))
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                            return;
                        }
                        model   = Read(inputStream);
                        content = CreateContent(model, odataReq);
                        formatter.WriteSingleContent(content, portalContext);
                    }
                    break;

                case "DELETE":
                    if (odataReq.IsMemberRequest)
                    {
                        throw new ODataException(
                                  String.Concat("Cannot access a member with HTTP ", httpMethod, "."),
                                  ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        content = LoadContentOrVirtualChild(odataReq);
                        content?.Delete();
                    }
                    break;
                }
            }
            catch (ContentNotFoundException e)
            {
                var oe = new ODataException(ODataExceptionCode.ResourceNotFound, e);

                formatter?.WriteErrorResponse(context, oe);
            }
            catch (ODataException e)
            {
                if (e.HttpStatusCode == 500)
                {
                    SnLog.WriteException(e);
                }

                formatter?.WriteErrorResponse(context, e);
            }
            catch (SenseNetSecurityException e)
            {
                // In case of a visitor we should not expose the information that this content actually exists. We return
                // a simple 404 instead to provide exactly the same response as the regular 404, where the content
                // really does not exist. But do this only if the visitor really does not have permission for the
                // requested content (because security exception could be thrown by an action or something else too).
                if (odataReq != null && User.Current.Id == User.Visitor.Id)
                {
                    var head = NodeHead.Get(odataReq.RepositoryPath);
                    if (head != null && !SecurityHandler.HasPermission(head, PermissionType.Open))
                    {
                        ContentNotFound(context, odataReq.RepositoryPath);
                        return;
                    }
                }

                var oe = new ODataException(ODataExceptionCode.NotSpecified, e);

                SnLog.WriteException(oe);

                formatter?.WriteErrorResponse(context, oe);
            }
            catch (InvalidContentActionException ex)
            {
                var oe = new ODataException(ODataExceptionCode.NotSpecified, ex);
                if (ex.Reason != InvalidContentActionReason.NotSpecified)
                {
                    oe.ErrorCode = Enum.GetName(typeof(InvalidContentActionReason), ex.Reason);
                }

                // it is unnecessary to log this exception as this is not a real error
                formatter?.WriteErrorResponse(context, oe);
            }
            catch (ContentRepository.Storage.Data.NodeAlreadyExistsException nae)
            {
                var oe = new ODataException(ODataExceptionCode.ContentAlreadyExists, nae);

                formatter?.WriteErrorResponse(context, oe);
            }
            catch (System.Threading.ThreadAbortException tae)
            {
                if (!context.Response.IsRequestBeingRedirected)
                {
                    var oe = new ODataException(ODataExceptionCode.RequestError, tae);
                    formatter?.WriteErrorResponse(context, oe);
                }
                // specific redirect response so do nothing
            }
            catch (Exception ex)
            {
                var oe = new ODataException(ODataExceptionCode.NotSpecified, ex);

                SnLog.WriteException(oe);

                formatter?.WriteErrorResponse(context, oe);
            }
            finally
            {
                context.Response.End();
            }
        }
Ejemplo n.º 15
0
 static void Connection_Reconnected()
 {
     SnLog.WriteInformation($"Agent {AgentName}: connection reconnected.", EventId.TaskManagement.Communication);
 }
Ejemplo n.º 16
0
        private int ExecuteInner(SnTask task)
        {
            var workerExe = GetWorkerExePath(task);

            if (string.IsNullOrEmpty(workerExe) || !File.Exists(workerExe))
            {
                throw new TaskManagementException("Task executor command was not found", task.AppId, task.Id, task.Type);
            }

            var user              = Configuration.GetUserCredentials(task.AppId);
            var userParameter     = "USERNAME:\"" + (user != null ? user.UserName : string.Empty) + "\"";
            var passwordParameter = "PASSWORD:\"" + (user != null ? user.Password : string.Empty) + "\"";
            var dataParameter     = "DATA:\"" + EscapeArgument(task.TaskData) + "\"";

            var prms = new List <string> {
                userParameter, passwordParameter, dataParameter
            };

            var processArgs = string.Join(" ", prms);
            var startInfo   = new ProcessStartInfo(workerExe, processArgs)
            {
                UseShellExecute        = false,
                WorkingDirectory       = Path.GetDirectoryName(workerExe),
                CreateNoWindow         = true,
                ErrorDialog            = false,
                WindowStyle            = ProcessWindowStyle.Hidden,
                RedirectStandardInput  = true,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
            };

            //_process = Process.Start(startInfo);
            _process = new Process();
            _process.EnableRaisingEvents = true;
            _process.StartInfo           = startInfo;
            _process.OutputDataReceived += process_OutputDataReceived;

            SnLog.WriteInformation(string.Format(
                                       "Task#{1} execution STARTED on agent {0}:\r\n    id: {1},\r\n    type: {2},\r\n    hash: {3},\r\n    order: {4},\r\n    registered: {5},\r\n    key: {6},\r\n    data: {7}"
                                       , Agent.AgentName, task.Id, task.Type, task.Hash, task.Order, task.RegisteredAt, task.TaskKey, task.TaskData), EventId.TaskManagement.Lifecycle);

            _process.Start();
            _process.BeginOutputReadLine();
            _process.WaitForExit();

            _process.OutputDataReceived -= process_OutputDataReceived;
            var result = _process.ExitCode;

            if (result != 0)
            {
                SnLog.WriteWarning($"Task#{task.Id} execution TERMINATED with error. Result:{result}, task type: {task.Type}, agent: {Agent.AgentName}",
                                   EventId.TaskManagement.General);
            }
            else
            {
                SnLog.WriteInformation($"Task#{task.Id} execution FINISHED: type: {task.Type}, agent: {Agent.AgentName}",
                                       EventId.TaskManagement.Lifecycle);
            }

            _process.Dispose();
            _process = null;
            return(result);
        }
Ejemplo n.º 17
0
 static void Connection_Closed()
 {
     SnLog.WriteWarning($"Agent {AgentName}: connection is closed.", EventId.TaskManagement.Communication);
 }
        // ================================================================================ Notification

        protected virtual void SendMail()
        {
            if (!(LoadContentList() is SurveyList parentForm))
            {
                return;
            }

            var smtpClient = new SmtpClient();

            if (string.IsNullOrEmpty(smtpClient.Host))
            {
                return;
            }

            var itemContent    = Content.Create(this);
            var fromEmail      = parentForm.GetSenderEmail();
            var adminEmailList = string.Empty;

            if (!string.IsNullOrEmpty(parentForm.EmailList))
            {
                adminEmailList = parentForm.EmailList.Trim(' ', ';', ',')
                                 .Replace(";", ",")
                                 .Replace("\n", " ")
                                 .Replace("\t", " ")
                                 .Replace("\r", " ");
            }

            // send mail to administrator
            if (!string.IsNullOrEmpty(adminEmailList))
            {
                var ms = new MailMessage(fromEmail, adminEmailList)
                {
                    Subject = string.IsNullOrEmpty(parentForm.DisplayName)
                                               ? parentForm.Name
                                               : ReplaceField(parentForm.DisplayName, false, itemContent),
                    Body = string.IsNullOrEmpty(parentForm.AdminEmailTemplate)
                                            ? CreateEmailText()
                                            : ReplaceField(parentForm.AdminEmailTemplate, false, itemContent),
                    IsBodyHtml = !string.IsNullOrEmpty(parentForm.AdminEmailTemplate)
                };

                if (Attachments.Count > 0)
                {
                    foreach (var a in Attachments)
                    {
                        ms.Attachments.Add(a);
                    }
                }

                try
                {
                    smtpClient.Send(ms);
                }
                catch (Exception ex)
                {
                    SnLog.WriteException(ex,
                                         $"Error during sending notification email to {ms.To} after a user completed the following form: {parentForm.Path}.");
                }
            }

            // send mail to submitter
            var submitterAddress = GetSubmitterAddress(itemContent, parentForm.EmailField);

            if (!string.IsNullOrEmpty(submitterAddress))
            {
                var ms = new MailMessage(fromEmail, submitterAddress)
                {
                    Subject = string.IsNullOrEmpty(parentForm.MailSubject)
                                               ? parentForm.Name
                                               : ReplaceField(parentForm.MailSubject, true, itemContent),
                    Body = string.IsNullOrEmpty(parentForm.SubmitterEmailTemplate)
                                            ? CreateEmailText()
                                            : ReplaceField(parentForm.SubmitterEmailTemplate, true, itemContent),
                    IsBodyHtml = !string.IsNullOrEmpty(parentForm.SubmitterEmailTemplate)
                };

                if (Attachments.Count > 0)
                {
                    foreach (var a in Attachments)
                    {
                        ms.Attachments.Add(a);
                    }
                }

                try
                {
                    smtpClient.Send(ms);
                }
                catch (Exception ex)
                {
                    SnLog.WriteException(ex,
                                         $"Error during sending notification email to {ms.To} after completing the following form: {parentForm.Path}.");
                }
            }

            try
            {
                // dispose attachment streams
                if (Streams != null)
                {
                    foreach (var stream in Streams.Where(stream => stream != null))
                    {
                        stream.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex, $"Error when disposing attachments for {Path} (id: {Id}).");
            }
        }
Ejemplo n.º 19
0
        private DocumentOpenLevel GetDocumentLevel(int nodeId)
        {
            var userId = _userId;

            if (userId == -1)
            {
                return(DocumentOpenLevel.OpenMinor);
            }
            if (userId < -1)
            {
                return(DocumentOpenLevel.Denied);
            }

            List <int> identities;

            try
            {
                identities = SecurityHandler.GetIdentitiesByMembership(_user, nodeId);
            }
            catch (EntityNotFoundException)
            {
                return(DocumentOpenLevel.Denied);
            }

            List <AceInfo> entries;

            try
            {
                using (new SystemAccount())
                    entries = SecurityHandler.GetEffectiveEntries(nodeId);
            }
            catch (Exception ex) // LOGGED
            {
                //TODO: collect aggregated errors per query instead of logging every error
                SnLog.WriteWarning($"GetEffectiveEntries threw an exception for id {nodeId}. Error: {ex}");
                return(DocumentOpenLevel.Denied);
            }

            var allowBits = 0UL;
            var denyBits  = 0UL;

            foreach (var entry in entries)
            {
                if (identities.Contains(entry.IdentityId))
                {
                    allowBits |= entry.AllowBits;
                    denyBits  |= entry.DenyBits;
                }
            }
            allowBits = allowBits & ~denyBits;
            var docLevel = DocumentOpenLevel.Denied;

            if ((allowBits & PermissionType.See.Mask) > 0)
            {
                docLevel = DocumentOpenLevel.See;
            }
            if ((allowBits & PermissionType.Preview.Mask) > 0)
            {
                docLevel = DocumentOpenLevel.Preview;
            }
            if ((allowBits & PermissionType.PreviewWithoutRedaction.Mask) > 0)
            {
                docLevel = DocumentOpenLevel.Open;
            }
            if ((allowBits & PermissionType.OpenMinor.Mask) > 0)
            {
                docLevel = DocumentOpenLevel.OpenMinor;
            }
            return(docLevel);
        }
Ejemplo n.º 20
0
        internal async Task ProcessRequestAsync(HttpContext httpContext, ODataRequest odataRequest)
        {
            httpContext.SetODataRequest(odataRequest);

            var         request     = httpContext.Request;
            var         httpMethod  = request.Method;
            var         inputStream = request.Body;
            ODataWriter odataWriter = null;

            try
            {
                Content content;
                if (odataRequest == null)
                {
                    odataWriter = new ODataJsonWriter();
                    throw new ODataException("The Request is not an OData request.", ODataExceptionCode.RequestError);
                }

                odataWriter = ODataWriter.Create(httpContext, odataRequest);
                if (odataWriter == null)
                {
                    odataWriter = new ODataJsonWriter();
                    odataWriter.Initialize(odataRequest);
                    throw new ODataException(ODataExceptionCode.InvalidFormatParameter);
                }

                odataWriter.Initialize(odataRequest);

                var requestError = odataRequest.RequestError;
                if (requestError != null)
                {
                    var innerOdataError = requestError as ODataException;
                    var message         = "An error occured during request parsing. " + requestError.Message +
                                          " See inner exception for details.";
                    var code = innerOdataError?.ODataExceptionCode ?? ODataExceptionCode.RequestError;
                    throw new ODataException(message, code, requestError);
                }

                odataRequest.Format = odataWriter.FormatName;

                var requestedContent = LoadContentByVersionRequest(odataRequest.RepositoryPath, httpContext);

                var exists = requestedContent != null;
                if (!exists && !odataRequest.IsServiceDocumentRequest && !odataRequest.IsMetadataRequest &&
                    !AllowedMethodNamesWithoutContent.Contains(httpMethod))
                {
                    ContentNotFound(httpContext);
                    return;
                }

                JObject model;
                switch (httpMethod)
                {
                case "GET":
                    if (odataRequest.IsServiceDocumentRequest)
                    {
                        await odataWriter.WriteServiceDocumentAsync(httpContext, odataRequest)
                        .ConfigureAwait(false);
                    }
                    else if (odataRequest.IsMetadataRequest)
                    {
                        await odataWriter.WriteMetadataAsync(httpContext, odataRequest)
                        .ConfigureAwait(false);
                    }
                    else
                    {
                        if (!Node.Exists(odataRequest.RepositoryPath))
                        {
                            ContentNotFound(httpContext);
                        }
                        else if (odataRequest.IsCollection)
                        {
                            await odataWriter.WriteChildrenCollectionAsync(odataRequest.RepositoryPath, httpContext,
                                                                           odataRequest)
                            .ConfigureAwait(false);
                        }
                        else if (odataRequest.IsMemberRequest)
                        {
                            await odataWriter.WriteContentPropertyAsync(
                                odataRequest.RepositoryPath, odataRequest.PropertyName,
                                odataRequest.IsRawValueRequest, httpContext, odataRequest, _appConfig)
                            .ConfigureAwait(false);
                        }
                        else
                        {
                            await odataWriter.WriteSingleContentAsync(requestedContent, httpContext)
                            .ConfigureAwait(false);
                        }
                    }

                    break;

                case "PUT":     // update
                    if (odataRequest.IsMemberRequest)
                    {
                        throw new ODataException("Cannot access a member with HTTP PUT.",
                                                 ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        model = await ReadToJsonAsync(httpContext).ConfigureAwait(false);

                        content = LoadContentOrVirtualChild(odataRequest);
                        if (content == null)
                        {
                            ContentNotFound(httpContext);
                            return;
                        }

                        ResetContent(content);
                        UpdateContent(content, model, odataRequest);
                        await odataWriter.WriteSingleContentAsync(content, httpContext)
                        .ConfigureAwait(false);
                    }

                    break;

                case "MERGE":
                case "PATCH":     // update
                    if (odataRequest.IsMemberRequest)
                    {
                        throw new ODataException(
                                  String.Concat("Cannot access a member with HTTP ", httpMethod, "."),
                                  ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        model = await ReadToJsonAsync(httpContext).ConfigureAwait(false);

                        content = LoadContentOrVirtualChild(odataRequest);
                        if (content == null)
                        {
                            ContentNotFound(httpContext);
                            return;
                        }

                        UpdateContent(content, model, odataRequest);
                        await odataWriter.WriteSingleContentAsync(content, httpContext)
                        .ConfigureAwait(false);
                    }

                    break;

                case "POST":     // invoke an action, create content
                    if (odataRequest.IsMemberRequest)
                    {
                        // MEMBER REQUEST
                        await odataWriter.WritePostOperationResultAsync(httpContext, odataRequest, _appConfig)
                        .ConfigureAwait(false);
                    }
                    else
                    {
                        // CREATION
                        if (!Node.Exists(odataRequest.RepositoryPath))
                        {
                            // parent does not exist
                            ContentNotFound(httpContext);
                            return;
                        }

                        model = await ReadToJsonAsync(httpContext).ConfigureAwait(false);

                        var newContent = CreateNewContent(model, odataRequest);
                        await odataWriter.WriteSingleContentAsync(newContent, httpContext)
                        .ConfigureAwait(false);
                    }

                    break;

                case "DELETE":
                    if (odataRequest.IsMemberRequest)
                    {
                        throw new ODataException(
                                  String.Concat("Cannot access a member with HTTP ", httpMethod, "."),
                                  ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        content = LoadContentOrVirtualChild(odataRequest);
                        if (content != null)
                        {
                            var x = httpContext.Request.Query["permanent"].ToString();
                            if (x.Equals("true", StringComparison.OrdinalIgnoreCase))
                            {
                                content.DeletePhysical();
                            }
                            else
                            {
                                content.Delete();
                            }
                        }
                    }

                    break;
                }
            }
            catch (ContentNotFoundException e)
            {
                var oe = new ODataException(ODataExceptionCode.ResourceNotFound, e);
                await odataWriter.WriteErrorResponseAsync(httpContext, oe)
                .ConfigureAwait(false);
            }
            catch (ODataException e)
            {
                if (e.HttpStatusCode == 500)
                {
                    SnLog.WriteException(e);
                }
                await odataWriter.WriteErrorResponseAsync(httpContext, e)
                .ConfigureAwait(false);
            }
            catch (AccessDeniedException e)
            {
                var oe = new ODataException(ODataExceptionCode.Forbidden, e);
                await odataWriter.WriteErrorResponseAsync(httpContext, oe)
                .ConfigureAwait(false);
            }
            catch (UnauthorizedAccessException e)
            {
                var oe = new ODataException(ODataExceptionCode.Unauthorized, e);
                await odataWriter.WriteErrorResponseAsync(httpContext, oe)
                .ConfigureAwait(false);
            }
            catch (SenseNetSecurityException e)
            {
                // In case of a visitor we should not expose the information that this content actually exists. We return
                // a simple 404 instead to provide exactly the same response as the regular 404, where the content
                // really does not exist. But do this only if the visitor really does not have permission for the
                // requested content (because security exception could be thrown by an action or something else too).
                if (odataRequest != null && User.Current.Id == Identifiers.VisitorUserId)
                {
                    var head = NodeHead.Get(odataRequest.RepositoryPath);
                    if (head != null && !SecurityHandler.HasPermission(head, PermissionType.Open))
                    {
                        ContentNotFound(httpContext);
                        return;
                    }
                }

                var oe = new ODataException(ODataExceptionCode.NotSpecified, e);

                SnLog.WriteException(oe);

                await odataWriter.WriteErrorResponseAsync(httpContext, oe)
                .ConfigureAwait(false);
            }
            catch (InvalidContentActionException ex)
            {
                var oe = new ODataException(ODataExceptionCode.NotSpecified, ex);
                if (ex.Reason != InvalidContentActionReason.NotSpecified)
                {
                    oe.ErrorCode = Enum.GetName(typeof(InvalidContentActionReason), ex.Reason);
                }

                // it is unnecessary to log this exception as this is not a real error
                await odataWriter.WriteErrorResponseAsync(httpContext, oe)
                .ConfigureAwait(false);
            }
            catch (ContentRepository.Storage.Data.NodeAlreadyExistsException nae)
            {
                var oe = new ODataException(ODataExceptionCode.ContentAlreadyExists, nae);

                await odataWriter.WriteErrorResponseAsync(httpContext, oe)
                .ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                var oe = new ODataException(ODataExceptionCode.NotSpecified, ex);

                SnLog.WriteException(oe);

                await odataWriter.WriteErrorResponseAsync(httpContext, oe)
                .ConfigureAwait(false);
            }
        }
Ejemplo n.º 21
0
        internal static void Shutdown()
        {
            if (_instance == null)
            {
                SnLog.WriteWarning("Repository shutdown has already completed.");
                return;
            }

            lock (_shutDownSync)
            {
                if (_instance == null)
                {
                    SnLog.WriteWarning("Repository shutdown has already completed.");
                    return;
                }

                SnTrace.Repository.Write("Sending a goodbye message.");

                _instance.ConsoleWriteLine();

                _instance.ConsoleWriteLine("Sending a goodbye message...");
                DistributedApplication.ClusterChannel.ClusterMemberInfo.NeedToRecover = false;
                var pingMessage = new PingMessage();
                pingMessage.Send();

                foreach (var svc in _instance.serviceInstances)
                {
                    SnTrace.Repository.Write("Shutting down {0}", svc.GetType().Name);
                    svc.Shutdown();
                }

                SnTrace.Repository.Write("Shutting down {0}", DistributedApplication.ClusterChannel.GetType().Name);
                DistributedApplication.ClusterChannel.ShutDown();

                if (Instance.BackupIndexAtTheEnd)
                {
                    SnTrace.Repository.Write("Backing up the index.");
                    if (LuceneManagerIsRunning)
                    {
                        _instance.ConsoleWriteLine("Backing up the index...");
                        SenseNet.Search.Indexing.BackupTools.SynchronousBackupIndex();
                        _instance.ConsoleWriteLine("The backup of index is finished.");
                    }
                    else
                    {
                        _instance.ConsoleWriteLine("Backing up index is skipped because Lucene was not started.");
                    }
                }

                if (LuceneManagerIsRunning)
                {
                    SnTrace.Repository.Write("Shutting down LuceneManager.");
                    SenseNet.Search.Indexing.LuceneManager.ShutDown();
                }

                SnTrace.Repository.Write("Waiting for writer lock file is released.");
                WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd);

                var t   = DateTime.UtcNow - _instance._startupInfo.Starting;
                var msg = String.Format("Repository has stopped. Running time: {0}.{1:d2}:{2:d2}:{3:d2}", t.Days,
                                        t.Hours, t.Minutes, t.Seconds);

                SnTrace.Repository.Write(msg);
                SnTrace.Flush();

                _instance.ConsoleWriteLine(msg);
                _instance.ConsoleWriteLine();
                SnLog.WriteInformation(msg);
                _instance = null;
            }
        }
Ejemplo n.º 22
0
        internal static Dictionary <Version, PackagingResult> ExecuteAssemblyPatches(SnComponentInfo assemblyComponent,
                                                                                     RepositoryStartSettings settings = null)
        {
            var patchResults = new Dictionary <Version, PackagingResult>();

            // If there is no installed component for this id, skip patching.
            var installedComponent = RepositoryVersionInfo.Instance.Components.FirstOrDefault(c => c.ComponentId == assemblyComponent.ComponentId);

            if (installedComponent == null)
            {
                return(patchResults);
            }

            // check which db version is supported by the assembly
            if (assemblyComponent.SupportedVersion == null ||
                assemblyComponent.SupportedVersion <= installedComponent.Version)
            {
                return(patchResults);
            }

            // Supported version in the assembly is higher than
            // the physical version: there should be a patch.
            if (!(assemblyComponent.Patches?.Any() ?? false))
            {
                throw new InvalidOperationException($"Missing patch for component {installedComponent.ComponentId}. " +
                                                    $"Installed version is {installedComponent.Version}. " +
                                                    $"The assembly requires at least version {assemblyComponent.SupportedVersion}.");
            }

            foreach (var patch in assemblyComponent.Patches)
            {
                // this variable is refreshed in every cycle
                if (installedComponent == null)
                {
                    break;
                }

                if (patch.MinVersion > patch.MaxVersion ||
                    patch.MaxVersion > patch.Version)
                {
                    // the patch version numbers are the responsibility of the developer of the component
                    SnLog.WriteWarning(
                        $"Patch {patch.Version} for component {assemblyComponent.ComponentId} cannot be executed because it contains invalid version numbers.",
                        properties: new Dictionary <string, object>
                    {
                        { "MinVersion", patch.MinVersion },
                        { "MaxVersion", patch.MaxVersion }
                    });

                    continue;
                }

                if (!string.IsNullOrEmpty(patch.Contents) && patch.Execute != null)
                {
                    // ambigous patch definition
                    SnLog.WriteWarning(
                        $"Patch {patch.Version} for component {assemblyComponent.ComponentId} cannot be executed because it contains multiple patch definitions.");

                    continue;
                }

                // check if the patch is relevant for the currently installed component version
                if (patch.MinVersion > installedComponent.Version ||
                    patch.MinVersionIsExclusive && patch.MinVersion == installedComponent.Version ||
                    patch.MaxVersion < installedComponent.Version ||
                    patch.MaxVersionIsExclusive && patch.MaxVersion == installedComponent.Version)
                {
                    continue;
                }

                PackagingResult patchResult;

                try
                {
                    if (patch.Contents?.StartsWith("<?xml", StringComparison.InvariantCultureIgnoreCase) ?? false)
                    {
                        // execute manifest patch
                        patchResult = ExecutePatch(patch.Contents, settings);
                    }
                    else if (patch.Execute != null)
                    {
                        // execute code patch
                        patch.Execute(new PatchContext
                        {
                            Settings = settings
                        });

                        // save the new package info manually based on the patch version number
                        Storage.SavePackage(new Package
                        {
                            ComponentId      = assemblyComponent.ComponentId,
                            ComponentVersion = patch.Version,
                            ExecutionResult  = ExecutionResult.Successful,
                            PackageType      = PackageType.Patch
                        });

                        patchResult = new PackagingResult
                        {
                            NeedRestart = false,
                            Successful  = true,
                            Terminated  = false,
                            Errors      = 0
                        };
                    }
                    else
                    {
                        //TODO: handle other patch formats (resource or filesystem path)

                        // unknown patch format
                        patchResult = new PackagingResult
                        {
                            NeedRestart = false,
                            Successful  = false,
                            Terminated  = false,
                            Errors      = 0
                        };
                    }
                }
                catch (Exception ex)
                {
                    SnLog.WriteException(ex,
                                         $"Error during patch execution for component {assemblyComponent.ComponentId}. Patch target version: {patch.Version}.");

                    throw;
                }

                patchResults[patch.Version] = patchResult;

                // reload
                installedComponent = RepositoryVersionInfo.Instance.Components.FirstOrDefault(c =>
                                                                                              c.ComponentId == assemblyComponent.ComponentId);
            }

            return(patchResults);
        }
Ejemplo n.º 23
0
        /* ============================================================================== Receive */

        private void ReceiveMessages()
        {
            while (true)
            {
                try
                {
                    var message = _receiveQueue.Receive(TimeSpan.FromSeconds(1));
                    if (message == null)
                    {
                        return;
                    }

                    if (Shutdown)
                    {
                        return;
                    }

                    OnMessageReceived(message.Body as Stream);
                }
                catch (ThreadAbortException tex)
                {
                    // suppress threadabortexception on shutdown
                    if (Shutdown)
                    {
                        return;
                    }

                    SnLog.WriteException(tex, $"An error occurred when receiving from the queue ({_receiveQueue.Path}).",
                                         EventId.Messaging);
                }
                catch (MessageQueueException mex)
                {
                    // check if receive timed out: this is not a problem
                    if (mex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    {
                        if (Shutdown)
                        {
                            return;
                        }
                        continue;
                    }

                    SnLog.WriteException(mex, $"An error occurred when receiving from the queue ({_receiveQueue.Path}).",
                                         EventId.Messaging);
                    OnReceiveException(mex);

                    try
                    {
                        _receiveQueue = RecoverQueue(_receiveQueue);
                        SnLog.WriteInformation("Receiver queue has been repaired.", EventId.Messaging);
                    }
                    catch (Exception ex)
                    {
                        SnLog.WriteException(ex, EventMessage.Errors.RepairError, EventId.Messaging);
                    }
                    var thread = new Thread(ReceiveMessages);
                    thread.Start();
                    return;
                }
                catch (Exception e)
                {
                    SnLog.WriteException(e, $"An error occurred when receiving from the queue ({_receiveQueue.Path}).",
                                         EventId.Messaging);
                    OnReceiveException(e);
                }
            }
        }
Ejemplo n.º 24
0
        public static BatchActionResponse DeleteBatch(Content content, bool permanent, object[] paths)
        {
            // no need to throw an exception if no ids are provided: we simply do not have to delete anything
            if (paths == null || paths.Length == 0)
            {
                return(null);
            }

            var results          = new List <object>();
            var errors           = new List <ErrorContent>();
            var identifiers      = paths.Select(NodeIdentifier.Get).ToList();
            var foundIdentifiers = new List <NodeIdentifier>();
            var nodes            = Node.LoadNodes(identifiers);

            foreach (var node in nodes)
            {
                try
                {
                    // Collect already found identifiers in a separate list otherwise the error list
                    // would contain multiple errors for the same content.
                    foundIdentifiers.Add(NodeIdentifier.Get(node));

                    switch (node)
                    {
                    case GenericContent gc:
                        gc.Delete(permanent);
                        break;

                    case ContentType ct:
                        ct.Delete();
                        break;
                    }

                    results.Add(new { node.Id, node.Path, node.Name });
                }
                catch (Exception e)
                {
                    //TODO: we should log only relevant exceptions here and skip
                    // business logic-related errors, e.g. lack of permissions or
                    // existing target content path.
                    SnLog.WriteException(e);

                    errors.Add(new ErrorContent
                    {
                        Content = new { node?.Id, node?.Path },
                        Error   = new Error
                        {
                            Code          = "NotSpecified",
                            ExceptionType = e.GetType().FullName,
                            InnerError    = new StackInfo {
                                Trace = e.StackTrace
                            },
                            Message = new ErrorMessage
                            {
                                Lang  = System.Globalization.CultureInfo.CurrentUICulture.Name.ToLower(),
                                Value = e.Message
                            }
                        }
                    });
                }
            }

            // iterating through the missing identifiers and making error items for them
            errors.AddRange(identifiers.Where(id => !foundIdentifiers.Exists(f => f.Id == id.Id || f.Path == id.Path))
                            .Select(missing => new ErrorContent
            {
                Content = new { missing?.Id, missing?.Path },
                Error   = new Error
                {
                    Code          = "ResourceNotFound",
                    ExceptionType = "ContentNotFoundException",
                    InnerError    = null,
                    Message       = new ErrorMessage
                    {
                        Lang  = System.Globalization.CultureInfo.CurrentUICulture.Name.ToLower(),
                        Value = string.Format(SNSR.GetString(SNSR.Exceptions.OData.ErrorContentNotFound),
                                              missing?.Path)
                    }
                }
            }));

            return(BatchActionResponse.Create(results, errors, results.Count + errors.Count));
        }
Ejemplo n.º 25
0
        public async Task TaskFinished(SnTaskResult taskResult)
        {
            SnTrace.TaskManagement.Write("AgentHub TaskFinished called. Agent: {0} / {1}, taskId: {2}, code: {3}, error: {4}",
                                         taskResult.MachineName, taskResult.AgentName, taskResult.Task.Id, taskResult.ResultCode,
                                         taskResult.Error == null ? "" : taskResult.Error.Message);
            try
            {
                if (string.IsNullOrEmpty(taskResult.Task.AppId))
                {
                    SnLog.WriteWarning($"AppId is empty for task #{taskResult.Task.Id}.",
                                       EventId.TaskManagement.Lifecycle);
                    return;
                }

                var app = _applicationHandler.GetApplication(taskResult.Task.AppId);
                var doesApplicationNeedNotification = !string.IsNullOrWhiteSpace(taskResult.Task.GetFinalizeUrl(app));

                // first we make sure that the app is accessible by sending a ping request
                if (doesApplicationNeedNotification && !(await _applicationHandler.SendPingRequestAsync(taskResult.Task.AppId, Context.ConnectionAborted)
                                                         .ConfigureAwait(false)))
                {
                    SnLog.WriteError($"Ping request to application {taskResult.Task.AppId} " +
                                     $"({(app == null ? "unknown app" : app.ApplicationUrl)}) " +
                                     $"failed when finalizing task #{taskResult.Task.Id}. " +
                                     $"Task success: {taskResult.Successful}, " +
                                     $"error: {(taskResult.Error == null ? "-" : taskResult.Error.ToString())}",
                                     EventId.TaskManagement.Communication);

                    doesApplicationNeedNotification = false;
                }

                // remove the task from the database first
                await _dataHandler.FinalizeTaskAsync(taskResult, Context.ConnectionAborted).ConfigureAwait(false);

                SnTrace.TaskManagement.Write("AgentHub TaskFinished: task {0} has been deleted.", taskResult.Task.Id);

                if (doesApplicationNeedNotification)
                {
                    // This method does not need to be awaited, because we do not want to do anything
                    // with the result, only notify the app that the task has been finished.
#pragma warning disable 4014
                    _applicationHandler.SendFinalizeNotificationAsync(taskResult, CancellationToken.None);
#pragma warning restore 4014
                }

                // notify monitors
                var te = taskResult.Successful
                    ? SnTaskEvent.CreateDoneEvent(taskResult.Task.Id, taskResult.Task.Title,
                                                  taskResult.ResultData, taskResult.Task.AppId, taskResult.Task.Tag,
                                                  taskResult.MachineName, taskResult.AgentName)
                    : SnTaskEvent.CreateFailedEvent(taskResult.Task.Id, taskResult.Task.Title,
                                                    taskResult.ResultData, taskResult.Task.AppId, taskResult.Task.Tag,
                                                    taskResult.MachineName, taskResult.AgentName);

                await _monitorHub.OnTaskEvent(te).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex, "AgentHub TaskFinished failed.", EventId.TaskManagement.General);
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Returns a new <see cref="TrashBag"/> instance that packages the
        /// given <see cref="GenericContent"/> instance.
        /// </summary>
        /// <param name="node">The <see cref="GenericContent"/> instance that will be wrapped.</param>
        public static TrashBag BagThis(GenericContent node)
        {
            var bin = TrashBin.Instance;

            if (bin == null)
            {
                return(null);
            }

            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            // creating a bag has nothing to do with user permissions: Move will handle that
            TrashBag bag            = null;
            var      currentUserId  = User.Current.Id;
            var      wsId           = 0;
            var      wsRelativePath = string.Empty;
            var      ws             = SystemAccount.Execute(() => node.Workspace);

            if (ws != null)
            {
                wsId           = ws.Id;
                wsRelativePath = node.Path.Substring(ws.Path.Length);
            }

            using (new SystemAccount())
            {
                bag = new TrashBag(bin)
                {
                    KeepUntil             = DateTime.UtcNow.AddDays(bin.MinRetentionTime),
                    OriginalPath          = RepositoryPath.GetParentPath(node.Path),
                    WorkspaceRelativePath = wsRelativePath,
                    WorkspaceId           = wsId,
                    DisplayName           = node.DisplayName,
                    Link  = node,
                    Owner = node.Owner
                };
                bag.Save();

                CopyPermissions(node, bag);

                // Add Delete permission for the owner to let them remove it later and also
                // AddNew permission to let the move operation below actually move
                // the content into the TrashBag.
                SecurityHandler.CreateAclEditor()
                .Allow(bag.Id, node.OwnerId, false, PermissionType.Delete, PermissionType.AddNew)
                .Allow(bag.Id, currentUserId, true, PermissionType.Delete, PermissionType.AddNew)
                .Apply();
            }

            try
            {
                Node.Move(node.Path, bag.Path);
            }
            catch (SenseNetSecurityException ex)
            {
                SnLog.WriteException(ex);

                bag.Destroy();

                if (ex.Data.Contains("PermissionType") && (string)ex.Data["PermissionType"] == "Delete")
                {
                    throw new InvalidOperationException("You do not have enough permissions to delete this content to the Trash.", ex);
                }

                throw new InvalidOperationException("Error moving item to the trash", ex);
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex);

                bag.Destroy();

                throw new InvalidOperationException("Error moving item to the trash", ex);
            }

            return(bag);
        }
Ejemplo n.º 27
0
        protected virtual void BuildResultView()
        {
            Content   rootContent      = null;
            Exception controlException = null;

            try
            {
                // Elevation: it should be possible to search for content
                // under a folder where the user does not have explicit
                // permissions but on one of the child content may have.
                using (new SystemAccount())
                {
                    rootContent = GetModel() as Content;
                }

                if (rootContent != null)
                {
                    rootContent.ChildrenDefinition.AllChildren = AllChildren;
                }
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex);
                controlException = ex;
            }

            var model = new ContentCollectionViewModel {
                State = this.State
            };

            var childCount = 0;

            if (rootContent != null)
            {
                try
                {
                    childCount = rootContent.Children.Count();
                }
                catch (Exception ex)
                {
                    SnLog.WriteException(ex);
                    if (controlException == null)
                    {
                        controlException = ex;
                    }
                }
            }

            try
            {
                model.Pager   = GetPagerModel(childCount, State, string.Empty);
                model.Content = rootContent;
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex);
                if (controlException == null)
                {
                    controlException = ex;
                }

                // in case of error, set dummy pager model
                model.Pager = new PagerModel(0, State, string.Empty);
            }

            try
            {
                if (RenderingMode == RenderMode.Xslt)
                {
                    XmlModelData = model.ToXPathNavigator();
                }
                else
                {
                    // the Renderer property may contain a skin-relative path
                    var viewPath = RenderingMode == RenderMode.Native
                                       ? "/root/Global/Renderers/ContentCollectionView.ascx"
                                       : SkinManager.Resolve(Renderer);

                    Control presenter = null;

                    try
                    {
                        presenter = Page.LoadControl(viewPath);
                    }
                    catch (Exception ex)
                    {
                        SnLog.WriteException(ex);
                        if (controlException == null)
                        {
                            controlException = ex;
                        }
                    }

                    if (presenter != null)
                    {
                        Controls.Add(presenter);
                        PresenterClientId = presenter.ClientID;

                        var ccView = presenter as ContentCollectionView;
                        if (ccView != null)
                        {
                            ccView.Model = model;
                        }

                        if (rootContent != null)
                        {
                            var itemlist = presenter.FindControl(ContentListID);
                            if (itemlist != null)
                            {
                                try
                                {
                                    ContentQueryPresenterPortlet.DataBindingHelper.SetDataSourceAndBind(itemlist,
                                                                                                        rootContent.
                                                                                                        Children);
                                }
                                catch (Exception ex)
                                {
                                    SnLog.WriteException(ex);
                                    if (controlException == null)
                                    {
                                        controlException = ex;
                                    }
                                }
                            }
                            itemlist = presenter.FindControl("ViewDatasource");
                            if (itemlist != null)
                            {
                                try
                                {
                                    ContentQueryPresenterPortlet.DataBindingHelper.SetDataSourceAndBind(itemlist,
                                                                                                        rootContent.Children);
                                }
                                catch (Exception ex)
                                {
                                    SnLog.WriteException(ex);
                                    if (controlException == null)
                                    {
                                        controlException = ex;
                                    }
                                }
                            }
                        }

                        var itemPager = presenter.FindControl("ContentListPager");
                        if (itemPager != null)
                        {
                            try
                            {
                                ContentQueryPresenterPortlet.DataBindingHelper.SetDataSourceAndBind(itemPager,
                                                                                                    model.Pager.PagerActions);
                            }
                            catch (Exception ex)
                            {
                                SnLog.WriteException(ex);
                                if (controlException == null)
                                {
                                    controlException = ex;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex);
                if (controlException == null)
                {
                    controlException = ex;
                }
            }

            try
            {
                if (controlException != null)
                {
                    BuildErrorMessage(controlException);
                }
            }
            catch (Exception ex)
            {
                var errorText = SR.GetString(SR.Portlets.ContentCollection.ErrorLoadingContentView, HttpUtility.HtmlEncode(ex.Message));

                this.Controls.Clear();
                this.Controls.Add(new LiteralControl(errorText));
            }
        }
Ejemplo n.º 28
0
        protected override void CreateChildControls()
        {
            if (Cacheable && CanCache && IsInCache)
            {
                return;
            }

            Controls.Clear();

            var node = GetContextNode();

            if (node == null)
            {
                if (this.RenderException != null)
                {
                    Controls.Clear();
                    Controls.Add(new System.Web.UI.WebControls.Label()
                    {
                        Text = string.Format("Error loading content view: {0}", this.RenderException.Message)
                    });
                }
                else
                {
                    Controls.Clear();
                    Controls.Add(new System.Web.UI.WebControls.Label()
                    {
                        Text = "Content could not be loaded"
                    });
                }
                ChildControlsCreated = true;
                return;
            }

            var content = Content.Create(node);

            var contentView = String.IsNullOrEmpty(ContentViewPath) ?
                              ContentView.Create(content, Page, ViewMode.InlineEdit) :
                              ContentView.Create(content, Page, ViewMode.InlineEdit, ContentViewPath);

            if (contentView == null)
            {
                this.Controls.Clear();
                this.Controls.Add(new System.Web.UI.WebControls.Label {
                    Text = SR.GetString(SR.Exceptions.ContentView.NotFound)
                });

                return;
            }

            contentView.CommandButtonsAction += new EventHandler <CommandButtonsEventArgs>(contentView_CommandButtonsAction);

            // backward compatibility: use eventhandler for contentviews using defaultbuttons and not commandbuttons
            contentView.UserAction += new EventHandler <UserActionEventArgs>(contentView_UserAction);

            try
            {
                Controls.Add(contentView);
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex);

                this.Controls.Clear();

                var message = ex.Message.Contains("does not contain Field")
                                  ? string.Format("Content and view mismatch: {0}", ex.Message)
                                  : string.Format("Error: {0}", ex.Message);

                Controls.Add(new LiteralControl(message));
            }

            ChildControlsCreated = true;
        }
Ejemplo n.º 29
0
        public static void Restore(TrashBag trashBag, string targetPath, bool addNewName)
        {
            if (trashBag == null || string.IsNullOrEmpty(targetPath))
            {
                throw new RestoreException(RestoreResultType.Nonedefined);
            }

            targetPath = targetPath.TrimEnd(new [] { '/' });

            var node = trashBag.DeletedContent;

            if (node == null)
            {
                throw new InvalidOperationException("TrashBag is empty");
            }

            var targetContentPath = RepositoryPath.Combine(targetPath, node.Name);
            var targetParent      = Node.Load <GenericContent>(targetPath);

            if (targetParent == null)
            {
                throw new RestoreException(RestoreResultType.NoParent,
                                           RepositoryPath.GetParentPath(targetPath));
            }

            // assert permissions
            if (!targetParent.Security.HasPermission(PermissionType.Open))
            {
                throw new RestoreException(RestoreResultType.PermissionError, targetContentPath);
            }

            // target type check: ContentTypes field
            AssertRestoreContentType(targetParent, node);

            if (Node.Exists(targetContentPath))
            {
                var newName = ContentNamingProvider.IncrementNameSuffixToLastName(node.Name, targetParent.Id);
                targetContentPath = RepositoryPath.Combine(targetPath, newName);

                if (addNewName)
                {
                    try
                    {
                        // there is no other way right now (rename and move cannot be done at the same time)
                        node.Name = newName;
                        node.Save();
                    }
                    catch (SenseNetSecurityException ex)
                    {
                        SnLog.WriteException(ex);
                        throw new RestoreException(RestoreResultType.PermissionError,
                                                   targetContentPath, ex);
                    }
                    catch (Exception ex)
                    {
                        SnLog.WriteException(ex);
                        throw new RestoreException(RestoreResultType.UnknownError,
                                                   targetContentPath, ex);
                    }
                }
                else
                {
                    throw new RestoreException(RestoreResultType.ExistingName,
                                               targetContentPath);
                }
            }

            var originalUser = User.Current;

            try
            {
                node.MoveTo(targetParent);

                AccessProvider.Current.SetCurrentUser(User.Administrator);

                trashBag.KeepUntil = DateTime.Today.AddDays(-1);
                trashBag.ForceDelete();
            }
            catch (SenseNetSecurityException ex)
            {
                SnLog.WriteException(ex);
                throw new RestoreException(RestoreResultType.PermissionError,
                                           targetContentPath, ex);
            }
            catch (Exception ex)
            {
                SnLog.WriteException(ex);
                throw new RestoreException(RestoreResultType.UnknownError,
                                           targetContentPath, ex);
            }
            finally
            {
                AccessProvider.Current.SetCurrentUser(originalUser);
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Check if the origin header sent by the client is a known domain. It has to be the
        /// same that the request was sent to, OR it has to be among the whitelisted external
        /// domains that are allowed to access the Content Repository.
        /// </summary>
        public static bool TrySetAllowedOriginHeader()
        {
            if (HttpContext.Current == null)
            {
                return(true);
            }

            // Get the Origin header from the request, if it was sent by the browser.
            // Command-line tools or local html files will not send this.
            var originHeader = HttpContext.Current.Request.Headers[HEADER_ACESSCONTROL_ORIGIN_NAME];

            if (string.IsNullOrEmpty(originHeader) || string.Compare(originHeader, "null", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                SetAccessControlHeaders();
                return(true);
            }

            // We compare only the domain parts of the two urls, because interim servers
            // may change the scheme and port of the url (e.g. from https to http).
            var currentDomain = HttpContext.Current.Request.Url.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped);
            var originDomain  = string.Empty;
            var error         = false;

            try
            {
                var origin = new Uri(originHeader.Trim(' '));
                originDomain = origin.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped);
            }
            catch (Exception)
            {
                SnLog.WriteWarning("Unknown or incorrectly formatted origin header: " + originHeader, EventId.Portal);
                error = true;
            }

            if (!error)
            {
                // check if the request arrived from an external domain
                if (string.Compare(currentDomain, originDomain, StringComparison.InvariantCultureIgnoreCase) != 0)
                {
                    // We allow requests from external domains only if they are registered in this whitelist.
                    var corsDomains = Settings.GetValue <IEnumerable <string> >(PortalSettings.SETTINGSNAME, PortalSettings.SETTINGS_ALLOWEDORIGINDOMAINS,
                                                                                PortalContext.Current.ContextNodePath, new string[0]);

                    // try to find the domain in the whitelist (or the '*')
                    var externalDomain = corsDomains.FirstOrDefault(d => d == HEADER_ACESSCONTROL_ALLOWCREDENTIALS_ALL ||
                                                                    string.Compare(d, originDomain, StringComparison.InvariantCultureIgnoreCase) == 0);

                    if (!string.IsNullOrEmpty(externalDomain))
                    {
                        // Set the desired domain as allowed (or '*' if it is among the whitelisted domains). We cannot use
                        // the value from the whitelist (e.g. 'example.com'), because the browser expects the full origin
                        // (with schema and port, e.g. 'http://example.com:80').
                        SetAccessControlHeaders(externalDomain == HEADER_ACESSCONTROL_ALLOWCREDENTIALS_ALL ? HEADER_ACESSCONTROL_ALLOWCREDENTIALS_ALL : originHeader);
                        return(true);
                    }

                    // not found in the whitelist
                    error = true;
                }
            }

            SetAccessControlHeaders();

            return(!error);
        }