Exemple #1
0
        private bool HandleResponseForClientCache(HttpHeaderTools headerTools)
        {
            if (RequestedNodeHead == null)
            {
                return(false);
            }

            var cacheSetting = GetCacheHeaderSetting(headerTools);

            if (!cacheSetting.HasValue)
            {
                return(false);
            }

            // cache header (public or private) depends on whether the content is available for anyone
            var accessibleForVisitor = SystemAccount.Execute(() =>
                                                             Providers.Instance.SecurityHandler.HasPermission(User.Visitor, RequestedNodeHead.Id, PermissionType.Open));

            // set MaxAge by type or extension or a global value as a fallback
            headerTools.SetCacheControlHeaders(cacheSetting.Value,
                                               accessibleForVisitor ? HttpCacheability.Public : HttpCacheability.Private);

            // in case of preview images do NOT return 304, because _undetectable_ permission changes
            // (on the image or on one of its parents) may change the preview image (e.g. display redaction or not).
            if (DocumentPreviewProvider.Current?.IsPreviewOrThumbnailImage(RequestedNodeHead) ?? false)
            {
                return(false);
            }

            // Handle If-Modified-Since and Last-Modified headers: end the response
            // if the content has not changed since the value posted by the client.
            var endResponse = headerTools.EndResponseForClientCache(RequestedNodeHead.ModificationDate);

            return(endResponse);
        }
        /// <summary>
        /// Executes the boot sequence of the Repository by the passed <see cref="RepositoryStartSettings"/>.
        /// </summary>
        /// <example>
        /// Use the following code in your tool or other outer application:
        /// <code>
        /// var startSettings = new RepositoryStartSettings
        /// {
        ///     PluginsPath = pluginsPath, // Local directory path of plugins if it is different from your tool's path.
        ///     Console = Console.Out      // Startup sequence will be traced to given writer.
        /// };
        /// using (SenseNet.ContentRepository.Repository.Start(startSettings))
        /// {
        ///     // your code
        /// }
        /// </code>
        /// </example>
        /// <remarks>
        /// Repository will be stopped if the returned <see cref="RepositoryStartSettings"/> instance is disposed.
        /// </remarks>
        /// <returns>A new IDisposable <see cref="RepositoryInstance"/> instance.</returns>
        /// <returns></returns>
        public static RepositoryInstance Start(RepositoryStartSettings settings)
        {
            var instance = RepositoryInstance.Start(settings);

            SystemAccount.Execute(() => Root);
            return(instance);
        }
Exemple #3
0
        public static string GetAvatarUrl(Node node, int?width = null, int?height = null)
        {
            if (node == null)
            {
                return(string.Empty);
            }

            // Reload in elevated mode because we do not know how the provided
            // node has been loaded and we need its avatar url.
            var fullNode = SystemAccount.Execute(() => Node.LoadNode(node.Id));
            var group    = fullNode as Group;
            var user     = fullNode as User;

            if (group != null)
            {
                var url = GetDefaultGroupAvatarPath();
                url = AddWidthHeightParam(url, width, height);
                return(url);
            }
            if (user != null)
            {
                var avatarUrl = user.AvatarUrl;
                var url       = string.IsNullOrEmpty(avatarUrl) ? GetDefaultUserAvatarPath() : avatarUrl;
                url = AddWidthHeightParam(url, width, height);
                return(url);
            }
            return(string.Empty);
        }
Exemple #4
0
        public static IApplicationBuilder UseSenseNetUser(this IApplicationBuilder app)
        {
            app.Use(async(context, next) =>
            {
                // At this point the user is already authenticated, which means
                // we can trust the information in the identity: we load the
                // user in elevated mode (using system account).

                var identity = context?.User?.Identity;
                if (!string.IsNullOrEmpty(identity?.Name))
                {
                    // Currently we look for users by their login name. In the future we may add
                    // a more flexible user discovery algorithm here.

                    var user = SystemAccount.Execute(() => User.Load(identity.Name));
                    if (user != null)
                    {
                        User.Current = user;
                    }
                    else
                    {
                        SnTrace.Security.Write("Unknown user: {0}", identity.Name);
                    }
                }

                await next.Invoke();
            });

            return(app);
        }
 private static ServiceQueryContext GetQueryContext(SnQuery query, IQueryContext context)
 {
     return(new ServiceQueryContext
     {
         UserId = context.UserId,
         FieldLevel = PermissionFilter.GetFieldLevel(query).ToString(),
         DynamicGroups = SystemAccount.Execute(() => Node.Load <User>(context.UserId)?.GetDynamicGroups(0)?.ToArray() ?? new int[0])
     });
 }
Exemple #6
0
        private Stream GetConvertedStream(out string contentType, out BinaryFileName fileName)
        {
            // We have to treat images differently: the image handler takes care
            // of putting redactions on the preview image if permissions require that.
            if (RequestedNode is Image img)
            {
                var parameters = new Dictionary <string, object>();
                if (Width.HasValue)
                {
                    parameters.Add("width", Width.Value);
                }
                if (Height.HasValue)
                {
                    parameters.Add("height", Height.Value);
                }
                if (Watermark != null)
                {
                    parameters.Add("watermark", Watermark);
                }

                // At this point we are certain that the user can have the binary.
                // If the user does not have Open permission, it is still possible for them
                // to access a preview image. In this case we have to reload the image
                // to clear the headonly flag and let the user access the binary.
                if (img.IsPreviewOnly)
                {
                    // ReSharper disable once AccessToModifiedClosure
                    img = SystemAccount.Execute(() => Node.Load <Image>(img.Id));
                }

                return(img.GetImageStream(PropertyName, parameters, out contentType, out fileName));
            }

            // Get the stream through our provider to let 3rd party developers serve custom data.
            var stream = DocumentBinaryProvider.Instance.GetStream(RequestedNode, PropertyName, _context,
                                                                   out contentType, out fileName);

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

            // try to treat the binary value as an image and resize it
            if (Width.HasValue && Height.HasValue)
            {
                return(Image.CreateResizedImageFile(stream, string.Empty, Width.Value, Height.Value, 0,
                                                    contentType));
            }

            return(stream);
        }
Exemple #7
0
        private static void AssertCommentFeature(Content content)
        {
            if (!(content?.ContentHandler is File))
            {
                throw new SnNotSupportedException("Cannot comment on this type of content.");
            }

            var latestContent = content.IsLatestVersion
                ? content
                : SystemAccount.Execute(() => Content.Load(content.Id));

            if (latestContent.ContentHandler.Locked && latestContent.ContentHandler.LockedById != User.Current.Id)
            {
                throw new InvalidOperationException("Content is locked by someone else.");
            }
        }
Exemple #8
0
        /// <summary>
        /// Executes the boot sequence of the Repository by the passed <see cref="RepositoryStartSettings"/>.
        /// </summary>
        /// <example>
        /// Use the following code in your tool or other outer application:
        /// <code>
        /// var startSettings = new RepositoryStartSettings
        /// {
        ///     PluginsPath = pluginsPath, // Local directory path of plugins if it is different from your tool's path.
        ///     Console = Console.Out      // Startup sequence will be traced to given writer.
        /// };
        /// using (SenseNet.ContentRepository.Repository.Start(startSettings))
        /// {
        ///     // your code
        /// }
        /// </code>
        /// </example>
        /// <remarks>
        /// Repository will be stopped if the returned <see cref="RepositoryStartSettings"/> instance is disposed.
        /// </remarks>
        /// <returns>A new IDisposable <see cref="RepositoryInstance"/> instance.</returns>
        /// <returns></returns>
        public static RepositoryInstance Start(RepositoryStartSettings settings)
        {
            if (!settings.ExecutingPatches)
            {
                // Switch ON this flag so that inner repository start operations
                // do not try to execute patches again recursively.
                settings.ExecutingPatches = true;

                //TODO: [auto-patch] this feature is not released yet
                //PackageManager.ExecuteAssemblyPatches(settings);
            }

            var instance = RepositoryInstance.Start(settings);
            SystemAccount.Execute(() => Root);
            return instance;
        }
Exemple #9
0
        public override MembershipExtension GetExtension(IUser user)
        {
            var context = HttpContext.Current;

            if (context != null && user != null)
            {
                //TODO: handle multiple group ids in context
                var cookieValue = context.Request.Cookies[Constants.SharingTokenKey]?.Value;

                var extension        = SystemAccount.Execute(() => GetSharingExtension(context.Request.Params, cookieValue));
                var extensionGroupId = extension.ExtensionIds.FirstOrDefault();
                if (extensionGroupId > 0)
                {
                    // the url value takes precedence
                    var currentValue = context.Request.Params[Constants.SharingUrlParameterName];
                    if (string.IsNullOrEmpty(currentValue))
                    {
                        currentValue = cookieValue;
                    }

                    // set cookie only if it is different from the current value
                    if (currentValue != cookieValue)
                    {
                        SnTrace.Security.Write($"SharingMembershipExtender: setting sharing cookie containing group id {extensionGroupId}.");

                        context.Response.Cookies.Set(new HttpCookie(Constants.SharingTokenKey, currentValue)
                        {
                            Expires = DateTime.UtcNow.AddDays(1)
                        });
                    }
                }
                else if (cookieValue != null)
                {
                    // No sharing group or invalid group or content: clear cookie
                    // (only if there was a cookie before).
                    context.Response.Cookies.Set(new HttpCookie(Constants.SharingTokenKey, string.Empty)
                    {
                        Expires = DateTime.UtcNow.AddDays(-1)
                    });
                }

                return(extension);
            }

            return(base.GetExtension(user));
        }
        public MembershipExtension GetExtension(IUser user)
        {
            if (_httpContext == null || user == null)
            {
                return(MembershipExtension.Placeholder);
            }

            //TODO: handle multiple group ids in context
            var cookieValue = _httpContext.Request.Cookies[Constants.SharingTokenKey];

            var extension        = SystemAccount.Execute(() => GetSharingExtension(cookieValue));
            var extensionGroupId = extension.ExtensionIds.FirstOrDefault();

            if (extensionGroupId > 0)
            {
                // the url value takes precedence
                var currentValue = _httpContext.Request.Query[Constants.SharingUrlParameterName];
                if (string.IsNullOrEmpty(currentValue))
                {
                    currentValue = cookieValue;
                }

                // set cookie only if it is different from the current value
                if (currentValue != cookieValue)
                {
                    SnTrace.Security.Write($"SharingMembershipExtender: setting sharing cookie containing group id {extensionGroupId}.");

                    _httpContext.Response.Cookies.Append(Constants.SharingTokenKey, currentValue, new CookieOptions
                    {
                        Expires  = DateTime.UtcNow.AddDays(1),
                        HttpOnly = true,
                        Secure   = true
                    });
                }
            }
            else if (cookieValue != null)
            {
                // No sharing group or invalid group or content: clear cookie
                // (only if there was a cookie before).
                _httpContext.Response.Cookies.Delete(Constants.SharingTokenKey);
            }

            return(extension);
        }
Exemple #11
0
        private void ResetContent(Content content)
        {
            // Create "dummy" content
            var newContent = SystemAccount.Execute(() => { return(Content.CreateNew(content.ContentType.Name, content.ContentHandler.Parent, null)); });

            Aspect[] aspects = null;
            if (content.ContentHandler.HasProperty(GenericContent.ASPECTS))
            {
                // Get aspects
                aspects = content.ContentHandler.GetReferences(GenericContent.ASPECTS).Cast <Aspect>().ToArray();

                // Reset aspect fields
                var gc = content.ContentHandler as GenericContent;
                if (gc != null)
                {
                    content.RemoveAllAspects();
                    gc.AspectData = null;
                    gc.ClearReference(GenericContent.ASPECTS);
                }
            }

            // Reset regular fields
            foreach (var field in content.Fields.Values)
            {
                var fieldName = field.Name;
                if (newContent.Fields.Any(f => f.Value.Name == fieldName) && !field.ReadOnly && !SafeFieldsInReset.Contains(fieldName))
                {
                    content[fieldName] = newContent[fieldName];
                }
            }

            if (content.ContentHandler.HasProperty(GenericContent.ASPECTS))
            {
                // Re-add all the aspects
                content.AddAspects(aspects);
            }
        }
        private bool ContentTypeIsValid()
        {
            // The content type is valid if the parent content has an empty ContentTypes list (any type is allowed),
            // or the type of the content to be created is among the allowed content types (or is a derived type).

            if (_currentContent == null)
            {
                return(true);
            }

            var parent = SystemAccount.Execute(() => { return(_currentContent.ContentHandler.Parent as GenericContent); });

            if (parent == null)
            {
                return(true);
            }

            if (_currentContent.ContentType.IsInstaceOfOrDerivedFrom("FieldSettingContent") && parent is ContentList)
            {
                return(true);
            }

            return(parent.GetAllowedChildTypeNames().Any(ctn => ctn == _currentContent.ContentType.Name));
        }
Exemple #13
0
        private static void EnsureIndex(RepositoryBuilder builder)
        {
            var logger = builder.Services?.GetService <ILogger <RepositoryInstance> >();

            logger?.LogInformation("Checking the index...");

            // execute a query that should return multiple items if the index is not empty
            var indexDocExist = SystemAccount.Execute(() => ContentQuery.Query(SafeQueries.ContentTypes, QuerySettings.AdminSettings).Count > 10);

            if (indexDocExist)
            {
                return;
            }

            // This scenario auto-generates the whole index from the database. The most common case is
            // when a new web app domain (usually a container) is started in a load balanced environment.

            var populator  = Providers.Instance.SearchManager.GetIndexPopulator();
            var indexCount = 0;

            populator.IndexingError += (sender, eventArgs) =>
            {
                logger?.LogWarning($"Error during building app start index for {eventArgs.Path}. " +
                                   $"(id: {eventArgs.NodeId}). {eventArgs.Exception?.Message}");
            };
            populator.NodeIndexed += (sender, eventArgs) =>
            {
                Interlocked.Increment(ref indexCount);
            };

            logger?.LogInformation("Rebuilding the index...");

            populator.ClearAndPopulateAllAsync(CancellationToken.None, builder.Console ?? new LoggerConsole(logger)).GetAwaiter().GetResult();

            logger?.LogInformation($"Indexing of {indexCount} nodes finished.");
        }
        public PreviewComment(PreviewCommentData data)
        {
            Data = data;

            // Workaround: we only have a domain\username information here that cannot be used
            // to load a node head. We have to try to load the whole user node in elevated mode
            // and check for permissions after.
            var caller = AccessProvider.Current.GetOriginalUser();
            var user   = SystemAccount.Execute(() => string.IsNullOrEmpty(data.CreatedBy) ? null : User.Load(data.CreatedBy));

            if (user == null || !SecurityHandler.HasPermission(caller, user.Id, PermissionType.Open))
            {
                user = User.Somebody;
            }

            CreatedBy = new PreviewCommentUser
            {
                Id          = user.Id,
                Path        = user.Path,
                Username    = user.Username,
                DisplayName = user.DisplayName,
                AvatarUrl   = user.AvatarUrl
            };
        }
Exemple #15
0
        internal static ODataRequest Parse(string path, PortalContext portalContext)
        {
            if (!portalContext.IsOdataRequest)
            {
                throw new InvalidOperationException("The Request is not an OData request.");
            }

            var req = new ODataRequest();

            try
            {
                var relPath =
                    path.Substring(path.IndexOf(Configuration.Services.ODataServiceToken, StringComparison.OrdinalIgnoreCase) +
                                   Configuration.Services.ODataServiceToken.Length);

                req.IsServiceDocumentRequest = relPath.Length == 0;

                var segments    = relPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                var resSegments = new List <string>();
                var prmSegments = new List <string>();
                req.IsCollection = true;
                for (var i = 0; i < segments.Length; i++)
                {
                    if (String.Compare(segments[i], "$metadata", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        req.IsMetadataRequest = true;
                        break;
                    }
                    if (String.Compare(segments[i], "$value", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        req.IsRawValueRequest = true;
                        break;
                    }
                    if (String.Compare(segments[i], "$count", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        req.CountOnly = true;
                        break;
                    }

                    if (!req.IsCollection)
                    {
                        prmSegments.Add(segments[i]);
                        continue;
                    }

                    var segment = segments[i];
                    if (i == 0 && segment.StartsWith("content(", StringComparison.OrdinalIgnoreCase) &&
                        segment.EndsWith(")"))
                    {
                        var idStr = segment.Substring(8).Trim('(', ')');
                        if (idStr[0] != '\'' && idStr[idStr.Length - 1] != '\'')
                        {
                            int id;
                            if (!int.TryParse(idStr, out id))
                            {
                                throw new ODataException(SNSR.Exceptions.OData.InvalidId, ODataExceptionCode.InvalidId);
                            }
                            req.IsCollection       = false;
                            req.RequestedContentId = id;
                            resSegments.Add(segment);
                            continue;
                        }
                    }
                    if (!segment.EndsWith("')"))
                    {
                        resSegments.Add(segment);
                    }
                    else
                    {
                        req.IsCollection = false;

                        var ii         = segment.IndexOf("('");
                        var entityName = segment.Substring(ii).Trim('(', ')').Trim('\'');
                        segment = segment.Substring(0, ii);
                        if (segment.Length > 0)
                        {
                            resSegments.Add(segment);
                        }
                        resSegments.Add(entityName);
                    }
                }

                var pathIsRelative = true;
                if (resSegments.Count == 0)
                {
                    req.RepositoryPath = portalContext.Site?.Path;
                    if (req.RepositoryPath == null)
                    {
                        pathIsRelative = false;
                    }
                    req.IsCollection = true;
                }
                else
                {
                    pathIsRelative = String.Compare(resSegments[0], "root", StringComparison.OrdinalIgnoreCase) != 0;
                    if (pathIsRelative)
                    {
                        pathIsRelative = !resSegments[0].StartsWith("root(", StringComparison.OrdinalIgnoreCase);
                    }

                    if (prmSegments.Count > 0)
                    {
                        req.IsMemberRequest = true;
                        req.PropertyName    = prmSegments[0];
                    }
                }

                Content content;
                if (req.RequestedContentId > 0 && (content = SystemAccount.Execute(() => Content.Load(req.RequestedContentId))) != null)
                {
                    req.RepositoryPath = content.Path;
                }
                else
                {
                    var newPath = String.Concat("/", String.Join("/", resSegments));
                    if (pathIsRelative)
                    {
                        if (portalContext.Site == null)
                        {
                            newPath = "/";
                        }
                        else
                        {
                            newPath = newPath == "/"
                                ? portalContext.Site.Path
                                : string.Concat(portalContext.Site.Path, newPath);
                        }
                    }
                    req.RepositoryPath = newPath;
                }

                req.ParseQuery(path, portalContext);
            }
            catch (Exception e)
            {
                req.RequestError = e;
            }
            return(req);
        }
Exemple #16
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      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
                SecurityHandler.CreateAclEditor()
                .Allow(bag.Id, node.OwnerId, false, PermissionType.Delete)
                .Apply();
            }

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

                bag.Destroy();

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

            return(bag);
        }
        protected virtual void BuildSearchForm()
        {
            if (string.IsNullOrEmpty(SearchFormCtd))
            {
                return;
            }
            var nt = (from t in ActiveSchema.NodeTypes
                      where t.NodeTypePath.Equals(SearchFormCtd.Remove(0, 33))
                      select t).FirstOrDefault();

            if (nt == null)
            {
                return;
            }

            var parent = SystemAccount.Execute(() => Repository.SystemFolder);
            var c      = Content.CreateNew(nt.Name, parent, null);

            var s = State;

            if (_state != null && !string.IsNullOrWhiteSpace(_state.ExportQueryFields))
            {
                var xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(_state.ExportQueryFields);
                XmlNodeList allFields = xmlDoc.SelectNodes("/ContentMetaData/Fields/*");

                // do this in elevated mode to avoid errors related to non-writable fields, like CreationDate
                using (new SystemAccount())
                {
                    var transferringContext = new ImportContext(allFields, "", c.Id == 0, true, false);
                    // import flat properties
                    c.ImportFieldData(transferringContext, false);
                    // update references
                    transferringContext.UpdateReferences = true;
                    c.ImportFieldData(transferringContext, false);
                }
            }

            // override content filed from url parameters
            foreach (KeyValuePair <string, Field> keyValuePair in c.Fields)
            {
                var portletSpecKey = GetPortletSpecificParamName(keyValuePair.Key);
                var requestValue   = GetValueFromRequest(portletSpecKey);

                if (!string.IsNullOrEmpty(requestValue) && c.Fields.ContainsKey(keyValuePair.Key))
                {
                    c.Fields[keyValuePair.Key].Parse(requestValue);
                }
            }

            var cv = string.IsNullOrEmpty(SearchFormRenderer)
                         ? ContentView.Create(c, this.Page, ViewMode.InlineNew)
                         : ContentView.Create(c, this.Page, ViewMode.InlineNew, SearchFormRenderer);

            // Attach search event
            var iCsView = cv as IContentSearchView;

            if (iCsView != null)
            {
                iCsView.Search += new EventHandler(ContentSearchView_Search_OnClick);
            }
            else
            {
                var btn = cv.FindControl(SearchBtnId) as Button;
                if (btn == null)
                {
                    btn = new Button {
                        ID = SearchBtnId, Text = SenseNetResourceManager.Current.GetString(ResourceClassName, "SearchBtnText"), CssClass = "sn-submit"
                    };
                    cv.Controls.Add(btn);
                }
                btn.Click += new EventHandler(ContentSearchView_Search_OnClick);
            }
            SearchForm = cv;
        }
Exemple #18
0
 private static bool IsAdmin()
 {
     return(SystemAccount.Execute(() =>
                                  AccessProvider.Current.GetOriginalUser().IsInGroup(Group.Administrators)));
 }
Exemple #19
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();
        }
Exemple #20
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.
                Providers.Instance.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);
        }