예제 #1
0
        public static bool HasRequiredPermissions(Application app, NodeHead contextHead)
        {
            if (app == null)
            {
                return(true);
            }

            var perms = GetRequiredPermissions(app);

            return(perms.All(permType => SecurityHandler.HasPermission(contextHead, permType) &&
                             (!app.DeepPermissionCheck || SecurityHandler.HasSubTreePermission(contextHead, permType))));
        }
예제 #2
0
        public override void AssertPermissions()
        {
            var isOwner = TargetNode.CreatorId == User.Current.Id;

            if (!SecurityHandler.HasPermission(TargetNode, PermissionType.See))
            {
                base.ThrowNotFound();
            }
            if (!SecurityHandler.HasPermission(TargetNode, PermissionType.Open))
            {
                base.ThrowForbidden();
            }
        }
        public static string[] GetProtectedPaths(Content content)
        {
            var permitted = ContentProtector.GetProtectedPaths()
                            .Where(x =>
            {
                var head = NodeHead.Get(x);
                return(head != null && SecurityHandler.HasPermission(
                           User.Current, head.Id, PermissionType.See));
            })
                            .ToArray();

            return(permitted);
        }
예제 #4
0
        protected override Node GetContextNode()
        {
            if (!string.IsNullOrEmpty(this.KPIDataSource))
            {
                var sourcePath = RepositoryPath.Combine(kpiSourcePath, this.KPIDataSource);
                var sourceHead = NodeHead.Get(sourcePath);

                return(!SecurityHandler.HasPermission(sourceHead, PermissionType.See)
                    ? null
                    : Node.LoadNode(sourceHead));
            }
            return(null);
        }
예제 #5
0
        public static SnIdentity Create(int nodeId)
        {
            Node node = null;

            using (new SystemAccount())
                node = Node.LoadNode(nodeId);

            if (node == null || !SecurityHandler.HasPermission(node, PermissionType.See))
            {
                node = Node.LoadNode(Identifiers.SomebodyUserId);
            }

            string         name       = node.Name;
            SnIdentityKind kind       = SnIdentityKind.User;
            var            nodeAsUser = node as IUser;

            if (nodeAsUser != null)
            {
                name = nodeAsUser.FullName;
                kind = SnIdentityKind.User;
            }
            else
            {
                var nodeAsGroup = node as IGroup;
                if (nodeAsGroup != null)
                {
                    kind = SnIdentityKind.Group;
                }
                else
                {
                    var nodeAsOrgUnit = node as IOrganizationalUnit;
                    if (nodeAsOrgUnit != null)
                    {
                        kind = SnIdentityKind.OrganizationalUnit;
                    }
                    else
                    {
                        throw new ApplicationException(String.Concat("Cannot create SnIdentity from NodeType ",
                                                                     Providers.Instance.StorageSchema.NodeTypes.GetItemById(node.NodeTypeId).Name, ". Path: ", node.Path));
                    }
                }
            }

            return(new SnIdentity
            {
                NodeId = node.Id,
                Path = node.Path,
                Name = name,
                Kind = kind
            });
        }
예제 #6
0
        private Control CreateViewControl(string path)
        {
            if (!string.IsNullOrEmpty(path))
            {
                // only display the view if the user has permissions for it
                var viewHead = NodeHead.Get(path);
                if (viewHead != null && SecurityHandler.HasPermission(viewHead, PermissionType.RunApplication))
                {
                    return(Page.LoadControl(path));
                }
            }

            return(new Control());
        }
예제 #7
0
        private void SetActualParent(Node actualNode, int index)
        {
            _actualNodeLevel = index;

            switch (StartBindTarget)
            {
            case Portlets.StartBindTarget.CurrentSite:
                if (actualNode.NodeType.IsInstaceOfOrDerivedFrom("Site"))
                {
                    return;
                }
                break;

            case Portlets.StartBindTarget.CurrentList:
                if (PortalContext.Current.ContentList != null && actualNode.Path == PortalContext.Current.ContentList.Path)
                {
                    return;
                }
                break;

            case Portlets.StartBindTarget.CurrentWorkspace:
                if (PortalContext.Current.ContextWorkspace != null && actualNode.Path == PortalContext.Current.ContextWorkspace.Path)
                {
                    return;
                }
                break;

            default:
                break;
            }

            var parentHead = NodeHead.Get(actualNode.ParentId);
            var parent     = parentHead == null
                             ? null
                             : SecurityHandler.HasPermission(parentHead, PermissionType.See, PermissionType.Open)
                                   ? actualNode.Parent
                                   : null;

            if (parent != null)
            {
                index++;
                _pathNodeList.Add(parent);
                SetActualParent(parent, index);
            }
            else
            {
                return;
            }
        }
예제 #8
0
 private bool IsPermitted(int?contentId)
 {
     if (contentId == null)
     {
         return(true);
     }
     try
     {
         return(SecurityHandler.HasPermission(User.Current, contentId.Value, PermissionType.Open));
     }
     catch (EntityNotFoundException)
     {
         return(false);
     }
 }
예제 #9
0
 public override bool CheckPermission()
 {
     if (!base.CheckPermission())
     {
         return(false);
     }
     if (HttpHandlerNode != null)
     {
         if (!SecurityHandler.HasPermission(HttpHandlerNode, PermissionType.RunApplication))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #10
0
        internal static File LoadViewWithPermissions(string viewPath)
        {
            var viewHead = NodeHead.Get(viewPath);

            if (viewHead != null && SecurityHandler.HasPermission(viewHead, PermissionType.RunApplication))
            {
                // elevation: we have to serve the view, if the user has run
                // application for it, even if no Open permission is given
                using (new SystemAccount())
                {
                    return(Node.LoadNode(viewHead) as File);
                }
            }

            return(null);
        }
예제 #11
0
        public override bool CheckPermission()
        {
            if (!base.CheckPermission())
            {
                return(false);
            }

            //content that serve themselves as IHttpHandlers - e.g. images - do not require a Run application permission
            if (HttpHandlerNode != null && (TargetNode != null && TargetNode.Id != HttpHandlerNode.Id))
            {
                if (!SecurityHandler.HasPermission(HttpHandlerNode, PermissionType.RunApplication))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #12
0
        public void InitialData_FW_Permissions_Apply()
        {
            var initialData = new InitialData
            {
                Permissions = new List <string>
                {
                    "+6|Normal|-6:_______________________________________________________________+",
                    "-1000|Normal|+6:_______________________________________________________________+",
                }
            };

            InitialSecurityDataTest(() =>
            {
                var mask = PermissionType.GetPermissionMask(PermissionType.BuiltInPermissionTypes);
                SecurityHandler.CreateAclEditor()
                .RemoveExplicitEntries(2)
                .RemoveExplicitEntries(6)
                .RemoveExplicitEntries(1000)
                .Set(2, 7, false, mask, 0UL)
                .Apply();

                // PRECHECKS
                // Administrators group has 1 entry on the Root.
                Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count);
                // Visitor has no any permission.
                Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See));
                Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 1000, PermissionType.See));
                // There is no break.
                Assert.IsTrue(SecurityHandler.IsEntityInherited(6));
                Assert.IsTrue(SecurityHandler.IsEntityInherited(1000));

                // ACTION
                SecurityHandler.SecurityInstaller.InstallDefaultSecurityStructure(initialData);

                // ASSERT
                // Administrators group has an entry on the Root.
                Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count);
                // Visitor has See permission on both contents.
                Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See));
                Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 1000, PermissionType.See));
                // The second content is not inherited.
                Assert.IsTrue(SecurityHandler.IsEntityInherited(6));
                Assert.IsFalse(SecurityHandler.IsEntityInherited(1000));
            });
        }
예제 #13
0
        protected override bool UserAuthorized(IPrincipal user)
        {
            var princ = user as PortalPrincipal;

            if (princ?.Identity == null)
            {
                return(false);
            }

            if (!princ.Identity.IsAuthenticated)
            {
                return(false);
            }

            var permissionHead = NodeHead.Get(PermissionPlaceholderPath + HubType.Name);

            return(permissionHead != null && SecurityHandler.HasPermission(permissionHead, PermissionType.RunApplication));
        }
예제 #14
0
        public static void TakeOwnership(Content content, string userOrGroup)
        {
            if (content == null)
            {
                throw new ArgumentNullException("content");
            }

            Content target = null;

            if (!String.IsNullOrEmpty(userOrGroup))
            {
                target = Content.LoadByIdOrPath(userOrGroup);
                if (target == null)
                {
                    throw new ArgumentException("The parameter cannot be recognized as a path or an Id: " + userOrGroup);
                }
            }

            if (SecurityHandler.HasPermission(content.Id, PermissionType.TakeOwnership))
            {
                if (target == null)
                {
                    // if the input string was null or empty
                    content["Owner"] = User.Current;
                }
                else
                {
                    if (target.ContentHandler is Group)
                    {
                        content["Owner"] = target.ContentHandler as Group;
                    }
                    else if (target.ContentHandler is User)
                    {
                        content["Owner"] = target.ContentHandler as User;
                    }
                    else
                    {
                        throw new ArgumentException("The parameter cannot be recognized as a User or a Group: " + userOrGroup);
                    }
                }

                content.Save();
            }
        }
예제 #15
0
        /// <summary>
        /// Gets the model.
        /// </summary>
        /// <returns></returns>
        protected override object GetModel()
        {
            var managerHead = NodeHead.Get(FirstManager);

            if (managerHead == null)
            {
                throw new NotSupportedException(ResourceManager.Current.GetString("OrganizationChart", "NoSuchManagerError"));
            }

            var resultXml = new XmlDocument();

            if (!SecurityHandler.HasPermission(managerHead, PermissionType.Open))
            {
                return(resultXml);
            }

            var manager = Content.Load(FirstManager);

            if (manager == null)
            {
                throw new NotSupportedException(ResourceManager.Current.GetString("OrganizationChart", "NoSuchManagerError"));
            }

            var managerStream = manager.GetXml(true);

            resultXml.Load(managerStream);

            _usedNodeId = new List <int> {
                manager.Id
            };

            try
            {
                GetEmployees(manager, resultXml.SelectSingleNode("/Content"), 1);
            }
            catch (Exception ex)
            {
                Logger.WriteException(ex);
                throw new NotSupportedException(ex.Message);
            }

            return(resultXml);
        }
예제 #16
0
        public static SnIdentity Create(int nodeId)
        {
            Node node;

            using (new SystemAccount())
                node = Node.LoadNode(nodeId);

            if (node == null || !SecurityHandler.HasPermission(node, PermissionType.See))
            {
                node = User.Somebody;
            }

            string         name = node.Name;
            SnIdentityKind kind;

            switch (node)
            {
            case IUser nodeAsUser:
                name = nodeAsUser.FullName;
                kind = SnIdentityKind.User;
                break;

            case IGroup _:
                kind = SnIdentityKind.Group;
                break;

            case IOrganizationalUnit _:
                kind = SnIdentityKind.OrganizationalUnit;
                break;

            default:
                throw new ApplicationException(string.Concat("Cannot create SnIdentity from NodeType ",
                                                             Providers.Instance.StorageSchema.NodeTypes.GetItemById(node.NodeTypeId).Name, ". Path: ", node.Path));
            }

            return(new SnIdentity
            {
                NodeId = node.Id,
                Path = node.Path,
                Name = name,
                Kind = kind
            });
        }
예제 #17
0
        public int GetPermittedCount()
        {
            var userId = SenseNet.ContentRepository.Storage.Security.AccessProvider.Current.GetCurrentUser().Id;

            if (userId < 0)
            {
                return(IdCount);
            }

            int count = 0;

            foreach (var head in new NodeHeadResolver(RawData))
            {
                if (SecurityHandler.HasPermission(head, PermissionType.See))
                {
                    count++;
                }
            }
            return(count);
        }
예제 #18
0
        private static object[] GetNodeInternal(string parentPath, bool simpleContent = false)
        {
            Node node = null;

            if (parentPath == Repository.RootPath || parentPath == RepositoryStructure.ImsFolderPath)
            {
                // Elevation: Root and IMS should be accessible through this service
                // (the user already passed the feature permission check).
                using (new SystemAccount())
                {
                    node = Node.LoadNode(parentPath);
                }
            }
            else
            {
                var head = NodeHead.Get(parentPath);
                if (head != null && SecurityHandler.HasPermission(head, PermissionType.Open))
                {
                    node = Node.LoadNode(head);
                }
            }

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

            if (simpleContent)
            {
                return(new List <cs.SimpleServiceContent> {
                    new cs.SimpleServiceContent(node)
                }.ToArray());
            }
            else
            {
                return(new List <cs.Content> {
                    new cs.Content(node, true, false, false, false, 0, 0)
                }.ToArray());
            }
        }
예제 #19
0
        private void SetControls()
        {
            var contextNode = PortalContext.Current.ContextNode;

            foreach (var templateName in templateNames)
            {
                var templateNode = contextNode.GetReference <Node>(string.Concat(templateName, "Page"));
                if (templateNode == null)
                {
                    continue;
                }

                var templateContent = ContentRepository.Content.Create(templateNode);

                var placeHolder     = this.FindControlRecursive(string.Concat("ph", templateName));
                var pageContentView = contextNode.GetReference <Node>("PageContentView").Path;
                var contentView     = ContentView.Create(templateContent, this.Page, ViewMode.Browse, pageContentView);

                if (placeHolder == null || contentView == null)
                {
                    continue;
                }

                placeHolder.Controls.Clear();
                placeHolder.Controls.Add(contentView);

                var btnEdit = this.FindControlRecursive(string.Concat("btnEdit", templateName)) as Button;

                if (btnEdit == null)
                {
                    continue;
                }

                if (SecurityHandler.HasPermission(contextNode, new[] { PermissionType.AddNew, PermissionType.Save }) &&
                    SecurityHandler.HasPermission(templateNode, PermissionType.Save))
                {
                    btnEdit.Visible = true;
                }
            }
        }
예제 #20
0
        public static List <string> GetGetContentPickerRootPathList(string path)
        {
            var pathList    = new List <string>();
            var contentHead = NodeHead.Get(path);
            var parentPath  = string.Empty;

            // add the highest reachable parent
            while (contentHead != null)
            {
                var parent = NodeHead.Get(contentHead.ParentId);

                if (parent == null || !SecurityHandler.HasPermission(parent, PermissionType.See))
                {
                    parentPath = contentHead.Path;
                    break;
                }

                contentHead = parent;
            }

            if (!string.IsNullOrEmpty(parentPath) && !pathList.Contains(parentPath))
            {
                pathList.Add(parentPath);
            }

            // add site path
            //var site = PortalContext.GetSiteByNodePath(path);
            //if (site != null && !pathList.Contains(site.Path))
            //    pathList.Add(site.Path);

            // add root
            if (!pathList.Contains(Repository.RootPath))
            {
                pathList.Add(Repository.RootPath);
            }

            return(pathList);
        }
예제 #21
0
        protected override bool UserAuthorized(System.Security.Principal.IPrincipal user)
        {
            var princ = user as PortalPrincipal;

            if (princ == null || princ.Identity == null)
            {
                throw new ArgumentNullException("user");
            }

            if (!princ.Identity.IsAuthenticated)
            {
                return(false);
            }

            var permissionHead = NodeHead.Get(PermissionPlaceholderPath + HubType.Name);

            if (permissionHead != null && SecurityHandler.HasPermission(permissionHead, PermissionType.RunApplication))
            {
                return(true);
            }

            return(false);
        }
예제 #22
0
        void VotingItemNewContentViewUserAction(object sender, UserActionEventArgs e)
        {
            // If the button's action is not Save
            if (e.ActionName != "Save")
            {
                return;
            }

            if (!SecurityHandler.HasPermission(e.ContentView.ContentHandler, PermissionType.AddNew))
            {
                e.ContentView.ContentException = new Exception("You do not have the appropriate permissions to answer this question.");
                return;
            }

            e.ContentView.UpdateContent();
            if (e.ContentView.Content.IsValid)
            {
                e.ContentView.Content.Save();
                Controls.Clear();
                ChildControlsCreated = false;
                _myState             = "ThankYouView";
            }
        }
예제 #23
0
        private static bool HasPermission(Subscription subscription, Event @event)
        {
            if (@event == null || string.IsNullOrEmpty(@event.ContentPath) || subscription == null || subscription.User == null)
            {
                return(false);
            }

            var head = NodeHead.Get(@event.ContentPath);

            if (head == null)
            {
                return(false);
            }

            if (@event.NotificationType == NotificationType.MinorVersionModified)
            {
                return(SecurityHandler.HasPermission(subscription.User, head.Id, PermissionType.OpenMinor));
            }
            else
            {
                return(SecurityHandler.HasPermission(subscription.User, head.Id, PermissionType.Open));
            }
        }
예제 #24
0
        public void InitialData_Permissions_Apply()
        {
            var initialData = new InitialData
            {
                Permissions = new List <string>
                {
                    "+6|Normal|-6:_______________________________________________________________+",
                    "-1113|Normal|+6:_______________________________________________________________+",
                }
            };

            InitialSecurityDataTest(() =>
            {
                // PRECHECKS
                // Administrators group has 1 entry on the Root.
                Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count);
                // Visitor has no any permission.
                Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See));
                Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 1113, PermissionType.See));
                // There is no break.
                Assert.IsTrue(SecurityHandler.IsEntityInherited(6));
                Assert.IsTrue(SecurityHandler.IsEntityInherited(1113));

                // ACTION
                SecurityHandler.SecurityInstaller.InstallDefaultSecurityStructure(initialData);

                // ASSERT
                // Administrators group has an entry on the Root.
                Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count);
                // Visitor has See permission on both contents.
                Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See));
                Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 1113, PermissionType.See));
                // The second content is not inherited.
                Assert.IsTrue(SecurityHandler.IsEntityInherited(6));
                Assert.IsFalse(SecurityHandler.IsEntityInherited(1113));
            });
        }
        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
            };
        }
        public async Task OD_Security_HasPermission_Administrator()
        {
            await IsolatedODataTestAsync(async() =>
            {
                SecurityHandler.CreateAclEditor()
                .Allow(Repository.Root.Id, Group.Administrators.Id, false, PermissionType.Open)
                .Allow(Repository.Root.Id, Group.Administrators.Id, false, PermissionType.Save)
                .Apply();

                var hasPermission = SecurityHandler.HasPermission(
                    User.Administrator, Group.Administrators, PermissionType.Open, PermissionType.Save);
                Assert.IsTrue(hasPermission);

                // ACTION
                var response = await ODataPostAsync(
                    "/OData.svc/Root/IMS/BuiltIn/Portal('Administrators')/HasPermission",
                    "",
                    $"{{user:\"{User.Administrator.Path}\", permissions:[\"Open\",\"Save\"] }}")
                               .ConfigureAwait(false);

                // ASSERT
                Assert.AreEqual("true", response.Result);
            }).ConfigureAwait(false);
        }
예제 #27
0
        private bool IsReachedEndpoint(Node current)
        {
            if (current.ParentId == 0)
            {
                return(true);
            }
            if (!SecurityHandler.HasPermission(current.ParentId, PermissionType.See))
            {
                return(true);
            }

            var endPoint = GetStartBindingRoot();

            if (endPoint != null)
            {
                if ((!ShowFirstElement && current.Parent.Id == endPoint.Id) ||
                    (ShowFirstElement && endPoint.Id == current.Id))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #28
0
        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;

                Exception requestError = null;
                try
                {
                    odataReq          = ODataRequest.Parse(portalContext.RequestedUri.GetComponents(UriComponents.Path, UriFormat.Unescaped), portalContext);
                    this.ODataRequest = odataReq;
                }
                catch (Exception e)
                {
                    requestError = e;
                }

                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 == null ? ODataExceptionCode.RequestError : innerOdataError.ODataExceptionCode;
                    throw new ODataException(message, code, requestError);
                }

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

                // Cross-Origin Resource Sharing (CORS)
                // Do this after the formatter was initialized to be able to provide a proper error message.
                HttpHeaderTools.AssertOriginHeader();

                var exists = Node.Exists(odataReq.RepositoryPath);
                if (httpMethod != "POST" && !exists)
                {
                    ContentNotFound(context, odataReq.RepositoryPath);
                    return;
                }

                JObject model = null;
                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);
                        }
                        if (odataReq.HasContentQuery)
                        {
                            formatter.WriteQueryResult(portalContext, odataReq);
                        }
                        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 = Content.Load(odataReq.RepositoryPath);
                        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 = Content.Load(odataReq.RepositoryPath);
                        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
                    {
                        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
                    {
                        //model = Read(inputStream);
                        Content.Delete(odataReq.RepositoryPath);
                    }
                    break;
                }
            }
            catch (ContentNotFoundException e)
            {
                var oe = new ODataException(ODataExceptionCode.ResourceNotFound, e);

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

                formatter.WriteErrorResponse(context, e);
            }
            catch (SecurityException 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);

                Logger.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
                //Logger.WriteException(oe);

                formatter.WriteErrorResponse(context, oe);
            }
            catch (Exception ex)
            {
                var oe = new ODataException(ODataExceptionCode.NotSpecified, ex);

                Logger.WriteException(oe);

                formatter.WriteErrorResponse(context, oe);
            }
            finally
            {
                context.Response.End();
            }
        }
예제 #29
0
        internal void AuthorizeRequest(HttpContext context)
        {
            PortalContext currentPortalContext = PortalContext.Current;

            if (currentPortalContext == null)
            {
                return;
            }
            var currentUser = context?.User.Identity as User;

            // deny access for visitors in case of webdav or office protocol requests, if they have no See access to the content
            if (currentUser != null && currentUser.Id == Identifiers.VisitorUserId && (currentPortalContext.IsOfficeProtocolRequest || currentPortalContext.IsWebdavRequest))
            {
                if (!currentPortalContext.IsRequestedResourceExistInRepository ||
                    currentPortalContext.ContextNodeHead == null ||
                    !SecurityHandler.HasPermission(currentPortalContext.ContextNodeHead, PermissionType.See))
                {
                    AuthenticationHelper.ForceBasicAuthentication(HttpContext.Current);
                }
            }

            if (context == null)
            {
                return;
            }

            if (currentPortalContext.IsRequestedResourceExistInRepository)
            {
                var authMode = currentPortalContext.AuthenticationMode;
                if (string.IsNullOrEmpty(authMode))
                {
                    authMode = WebApplication.DefaultAuthenticationMode;
                }

                bool appPerm;
                if (authMode == "Forms")
                {
                    appPerm = currentPortalContext.CurrentAction.CheckPermission();
                }
                else if (authMode == "Windows")
                {
                    currentPortalContext.CurrentAction.AssertPermissions();
                    appPerm = true;
                }
                else
                {
                    throw new NotSupportedException("None authentication is not supported");
                }

                var path            = currentPortalContext.RepositoryPath;
                var nodeHead        = NodeHead.Get(path);
                var permissionValue = SecurityHandler.GetPermission(nodeHead, PermissionType.Open);

                if (permissionValue == PermissionValue.Allowed && DocumentPreviewProvider.Current.IsPreviewOrThumbnailImage(nodeHead))
                {
                    // In case of preview images we need to make sure that they belong to a content version that
                    // is accessible by the user (e.g. must not serve images for minor versions if the user has
                    // access only to major versions of the content).
                    if (!DocumentPreviewProvider.Current.IsPreviewAccessible(nodeHead))
                    {
                        permissionValue = PermissionValue.Denied;
                    }
                }
                else if (permissionValue != PermissionValue.Allowed && appPerm && DocumentPreviewProvider.Current.HasPreviewPermission(nodeHead))
                {
                    // In case Open permission is missing: check for Preview permissions. If the current Document
                    // Preview Provider allows access to a preview, we should allow the user to access the content.
                    permissionValue = PermissionValue.Allowed;
                }

                if (permissionValue != PermissionValue.Allowed)
                {
                    if (nodeHead.Id == Identifiers.PortalRootId)
                    {
                        if (currentPortalContext.IsOdataRequest)
                        {
                            if (currentPortalContext.ODataRequest.IsMemberRequest)
                            {
                                permissionValue = PermissionValue.Allowed;
                            }
                        }
                    }
                }

                if (permissionValue != PermissionValue.Allowed || !appPerm)
                {
                    if (currentPortalContext.IsOdataRequest)
                    {
                        AuthenticationHelper.ThrowForbidden();
                    }
                    switch (authMode)
                    {
                    case "Forms":
                        if (User.Current.IsAuthenticated)
                        {
                            // user is authenticated, but has no permissions: return 403
                            context.Response.StatusCode = 403;
                            context.Response.Flush();
                            context.Response.Close();
                        }
                        else
                        {
                            // let webdav and office protocol handle authentication - in these cases redirecting to a login page makes no sense
                            if (PortalContext.Current.IsWebdavRequest || PortalContext.Current.IsOfficeProtocolRequest)
                            {
                                return;
                            }

                            // user is not authenticated and visitor has no permissions: redirect to login page
                            // Get the login page Url (eg. http://localhost:1315/home/login)
                            string loginPageUrl = currentPortalContext.GetLoginPageUrl();
                            // Append trailing slash
                            if (loginPageUrl != null && !loginPageUrl.EndsWith("/"))
                            {
                                loginPageUrl = loginPageUrl + "/";
                            }

                            // Cut down the querystring (eg. drop ?Param1=value1@Param2=value2)
                            string currentRequestUrlWithoutQueryString = currentPortalContext.RequestedUri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.Unescaped);

                            // Append trailing slash
                            if (!currentRequestUrlWithoutQueryString.EndsWith("/"))
                            {
                                currentRequestUrlWithoutQueryString = currentRequestUrlWithoutQueryString + "/";
                            }

                            // Redirect to the login page, if neccessary.
                            if (currentRequestUrlWithoutQueryString != loginPageUrl)
                            {
                                context.Response.Redirect(loginPageUrl + "?OriginalUrl=" + System.Web.HttpUtility.UrlEncode(currentPortalContext.RequestedUri.ToString()), true);
                            }
                        }
                        break;

                    default:
                        AuthenticationHelper.DenyAccess(context);
                        break;
                    }
                }
            }
        }
예제 #30
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 == Identifiers.VisitorUserId)
                {
                    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();
            }
        }