示例#1
0
        public void Access_Allowed_By_Path()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(9);
            userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List <string>()) });
            var user        = userMock.Object;
            var contentMock = new Mock <IContent>();

            contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
            var content            = contentMock.Object;
            var contentServiceMock = new Mock <IContentService>();

            contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
            var contentService    = contentServiceMock.Object;
            var entityServiceMock = new Mock <IEntityService>();
            var entityService     = entityServiceMock.Object;
            var userServiceMock   = new Mock <IUserService>();
            var userService       = userServiceMock.Object;

            //act
            var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
        }
示例#2
0
        /// <summary>
        /// Returns a <see cref="TreeNode"/> for the <see cref="IUmbracoEntity"/> and
        /// attaches some meta data to the node if the user doesn't have start node access to it when in dialog mode
        /// </summary>
        /// <param name="e"></param>
        /// <param name="parentId"></param>
        /// <param name="queryStrings"></param>
        /// <returns></returns>
        internal TreeNode GetSingleTreeNodeWithAccessCheck(IEntitySlim e, string parentId, FormDataCollection queryStrings,
                                                           int[] startNodeIds, string[] startNodePaths)
        {
            var entityIsAncestorOfStartNodes = ContentPermissionsHelper.IsInBranchOfStartNode(e.Path, startNodeIds, startNodePaths, out var hasPathAccess);
            var ignoreUserStartNodes         = IgnoreUserStartNodes(queryStrings);

            if (ignoreUserStartNodes == false && entityIsAncestorOfStartNodes == false)
            {
                return(null);
            }

            var treeNode = GetSingleTreeNode(e, parentId, queryStrings);

            if (treeNode == null)
            {
                //this means that the user has NO access to this node via permissions! They at least need to have browse permissions to see
                //the node so we need to return null;
                return(null);
            }
            if (!ignoreUserStartNodes && !hasPathAccess)
            {
                treeNode.AdditionalData["noAccess"] = true;
            }
            return(treeNode);
        }
示例#3
0
        public void No_Access_To_Recycle_Bin_By_Permission()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(0);
            var user = userMock.Object;

            var userServiceMock = new Mock <IUserService>();
            var permissions     = new EntityPermissionCollection
            {
                new EntityPermission(9876, 1234, new string[] { "A" })
            };
            var permissionSet = new EntityPermissionSet(1234, permissions);

            userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-20")).Returns(permissionSet);
            var userService        = userServiceMock.Object;
            var entityServiceMock  = new Mock <IEntityService>();
            var entityService      = entityServiceMock.Object;
            var contentServiceMock = new Mock <IContentService>();
            var contentService     = contentServiceMock.Object;

            //act
            var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'B' });

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
        }
示例#4
0
        public void No_Content_Found()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(9);
            var user        = userMock.Object;
            var contentMock = new Mock <IContent>();

            contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
            var content            = contentMock.Object;
            var contentServiceMock = new Mock <IContentService>();

            contentServiceMock.Setup(x => x.GetById(0)).Returns(content);
            var contentService  = contentServiceMock.Object;
            var userServiceMock = new Mock <IUserService>();
            var permissions     = new EntityPermissionCollection();
            var permissionSet   = new EntityPermissionSet(1234, permissions);

            userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234,5678")).Returns(permissionSet);
            var userService       = userServiceMock.Object;
            var entityServiceMock = new Mock <IEntityService>();
            var entityService     = entityServiceMock.Object;

            //act
            var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'F' });

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.NotFound, result);
        }
        public void Access_Allowed_By_Permission()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(9);
            userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List <string>()) });
            var user        = userMock.Object;
            var contentMock = new Mock <IContent>();

            contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
            var content            = contentMock.Object;
            var contentServiceMock = new Mock <IContentService>();

            contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
            var contentService = contentServiceMock.Object;
            var permissions    = new EntityPermissionCollection
            {
                new EntityPermission(9876, 1234, new string[] { "A", "F", "C" })
            };
            var permissionSet   = new EntityPermissionSet(1234, permissions);
            var userServiceMock = new Mock <IUserService>();

            userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234,5678")).Returns(permissionSet);
            var userService       = userServiceMock.Object;
            var entityServiceMock = new Mock <IEntityService>();
            var entityService     = entityServiceMock.Object;

            //act
            var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, out var foundContent, new[] { 'F' });

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
        }
示例#6
0
        public void No_Access_By_Path()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(9);
            userMock.Setup(u => u.StartContentIds).Returns(new[] { 9876 });
            var user        = userMock.Object;
            var contentMock = new Mock <IContent>();

            contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
            var content            = contentMock.Object;
            var contentServiceMock = new Mock <IContentService>();

            contentServiceMock.Setup(x => x.GetById(1234)).Returns(content);
            var contentService  = contentServiceMock.Object;
            var userServiceMock = new Mock <IUserService>();
            var permissions     = new EntityPermissionCollection();
            var permissionSet   = new EntityPermissionSet(1234, permissions);

            userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234")).Returns(permissionSet);
            var userService       = userServiceMock.Object;
            var entityServiceMock = new Mock <IEntityService>();

            entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny <UmbracoObjectTypes>(), It.IsAny <int[]>()))
            .Returns(new[] { Mock.Of <TreeEntityPath>(entity => entity.Id == 9876 && entity.Path == "-1,9876") });
            var entityService = entityServiceMock.Object;

            //act
            var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'F' });

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
        }
        private Attempt <string> AuthorizePath(IUser currentUser, IEnumerable <int> startContentIds, IEnumerable <int> startMediaIds)
        {
            if (startContentIds != null)
            {
                foreach (var contentId in startContentIds)
                {
                    if (contentId == Constants.System.Root)
                    {
                        var hasAccess = ContentPermissionsHelper.HasPathAccess("-1", currentUser.CalculateContentStartNodeIds(_entityService, _appCaches), Constants.System.RecycleBinContent);
                        if (hasAccess == false)
                        {
                            return(Attempt.Fail("The current user does not have access to the content root"));
                        }
                    }
                    else
                    {
                        var content = _contentService.GetById(contentId);
                        if (content == null)
                        {
                            continue;
                        }
                        var hasAccess = currentUser.HasPathAccess(content, _entityService, _appCaches);
                        if (hasAccess == false)
                        {
                            return(Attempt.Fail("The current user does not have access to the content path " + content.Path));
                        }
                    }
                }
            }

            if (startMediaIds != null)
            {
                foreach (var mediaId in startMediaIds)
                {
                    if (mediaId == Constants.System.Root)
                    {
                        var hasAccess = ContentPermissionsHelper.HasPathAccess("-1", currentUser.CalculateMediaStartNodeIds(_entityService, _appCaches), Constants.System.RecycleBinMedia);
                        if (hasAccess == false)
                        {
                            return(Attempt.Fail("The current user does not have access to the media root"));
                        }
                    }
                    else
                    {
                        var media = _mediaService.GetById(mediaId);
                        if (media == null)
                        {
                            continue;
                        }
                        var hasAccess = currentUser.HasPathAccess(media, _entityService, _appCaches);
                        if (hasAccess == false)
                        {
                            return(Attempt.Fail("The current user does not have access to the media path " + media.Path));
                        }
                    }
                }
            }

            return(Attempt <string> .Succeed());
        }
示例#8
0
        public void Access_To_Root_By_Permission()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(0);
            userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List <string>()) });
            var user = userMock.Object;

            var userServiceMock = new Mock <IUserService>();
            var permissions     = new EntityPermissionCollection
            {
                new EntityPermission(9876, 1234, new string[] { "A" })
            };
            var permissionSet = new EntityPermissionSet(1234, permissions);

            userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1")).Returns(permissionSet);
            var contentServiceMock = new Mock <IContentService>();
            var contentService     = contentServiceMock.Object;
            var userService        = userServiceMock.Object;
            var entityServiceMock  = new Mock <IEntityService>();
            var entityService      = entityServiceMock.Object;


            //act
            var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'A' });

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
        }
示例#9
0
 internal static bool HasPathAccess(this IUser user, IContent content, IEntityService entityService)
 {
     if (content == null)
     {
         throw new ArgumentNullException(nameof(content));
     }
     return(ContentPermissionsHelper.HasPathAccess(content.Path, user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent));
 }
示例#10
0
 internal static bool HasPathAccess(this IUser user, IMedia media, IEntityService entityService, AppCaches appCaches)
 {
     if (media == null)
     {
         throw new ArgumentNullException(nameof(media));
     }
     return(ContentPermissionsHelper.HasPathAccess(media.Path, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia));
 }
示例#11
0
 internal static bool HasMediaPathAccess(this IUser user, IUmbracoEntity entity, IEntityService entityService)
 {
     if (entity == null)
     {
         throw new ArgumentNullException(nameof(entity));
     }
     return(ContentPermissionsHelper.HasPathAccess(entity.Path, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia));
 }
示例#12
0
        internal static bool IsInBranchOfStartNode(this IUser user, IUmbracoEntity entity, IEntityService entityService, int recycleBinId, out bool hasPathAccess)
        {
            switch (recycleBinId)
            {
            case Constants.System.RecycleBinMedia:
                return(ContentPermissionsHelper.IsInBranchOfStartNode(entity.Path, user.CalculateMediaStartNodeIds(entityService), user.GetMediaStartNodePaths(entityService), out hasPathAccess));

            case Constants.System.RecycleBinContent:
                return(ContentPermissionsHelper.IsInBranchOfStartNode(entity.Path, user.CalculateContentStartNodeIds(entityService), user.GetContentStartNodePaths(entityService), out hasPathAccess));

            default:
                throw new NotSupportedException("Path access is only determined on content or media");
            }
        }
示例#13
0
        internal void FilterBasedOnStartNode(IList items, IUser user)
        {
            var toRemove = new List <dynamic>();

            foreach (dynamic item in items)
            {
                var hasPathAccess = (item != null && ContentPermissionsHelper.HasPathAccess(item.Path, GetUserStartNodes(user), RecycleBinId));
                if (hasPathAccess == false)
                {
                    toRemove.Add(item);
                }
            }

            foreach (var item in toRemove)
            {
                items.Remove(item);
            }
        }
示例#14
0
        public void Access_To_Recycle_Bin_By_Path()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(0);
            userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List <string>()) });
            var user = userMock.Object;
            var contentServiceMock = new Mock <IContentService>();
            var contentService     = contentServiceMock.Object;
            var userServiceMock    = new Mock <IUserService>();
            var userService        = userServiceMock.Object;
            var entityServiceMock  = new Mock <IEntityService>();
            var entityService      = entityServiceMock.Object;

            //act
            var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
        }
示例#15
0
        public void No_Access_To_Root_By_Path()
        {
            //arrange
            var userMock = new Mock <IUser>();

            userMock.Setup(u => u.Id).Returns(0);
            userMock.Setup(u => u.StartContentIds).Returns(new[] { 1234 });
            var user = userMock.Object;
            var contentServiceMock = new Mock <IContentService>();
            var contentService     = contentServiceMock.Object;
            var userServiceMock    = new Mock <IUserService>();
            var userService        = userServiceMock.Object;
            var entityServiceMock  = new Mock <IEntityService>();

            entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny <UmbracoObjectTypes>(), It.IsAny <int[]>()))
            .Returns(new[] { Mock.Of <TreeEntityPath>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
            var entityService = entityServiceMock.Object;

            //act
            var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);

            //assert
            Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
        }
示例#16
0
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (UmbracoContext.Current.Security.CurrentUser == null)
            {
                //not logged in
                throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
            }

            int nodeId;

            if (_nodeId.HasValue == false)
            {
                var parts = _paramName.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

                if (actionContext.ActionArguments[parts[0]] == null)
                {
                    throw new InvalidOperationException("No argument found for the current action with the name: " + _paramName);
                }

                if (parts.Length == 1)
                {
                    var argument = actionContext.ActionArguments[parts[0]].ToString();
                    // if the argument is an int, it will parse and can be assigned to nodeId
                    // if might be a udi, so check that next
                    // otherwise treat it as a guid - unlikely we ever get here
                    if (int.TryParse(argument, out int parsedId))
                    {
                        nodeId = parsedId;
                    }
                    else if (Udi.TryParse(argument, true, out Udi udi))
                    {
                        //fixme: inject? we can't because this is an attribute but we could provide ctors and empty ctors that pass in the required services
                        nodeId = Current.Services.EntityService.GetId(udi).Result;
                    }
                    else
                    {
                        Guid.TryParse(argument, out Guid key);
                        //fixme: inject? we can't because this is an attribute but we could provide ctors and empty ctors that pass in the required services
                        nodeId = Current.Services.EntityService.GetId(key, UmbracoObjectTypes.Document).Result;
                    }
                }
                else
                {
                    //now we need to see if we can get the property of whatever object it is
                    var pType = actionContext.ActionArguments[parts[0]].GetType();
                    var prop  = pType.GetProperty(parts[1]);
                    if (prop == null)
                    {
                        throw new InvalidOperationException("No argument found for the current action with the name: " + _paramName);
                    }
                    nodeId = (int)prop.GetValue(actionContext.ActionArguments[parts[0]]);
                }
            }
            else
            {
                nodeId = _nodeId.Value;
            }

            var permissionResult = ContentPermissionsHelper.CheckPermissions(nodeId,
                                                                             Current.UmbracoContext.Security.CurrentUser,
                                                                             Current.Services.UserService,
                                                                             Current.Services.ContentService,
                                                                             Current.Services.EntityService,
                                                                             out var contentItem,
                                                                             _permissionToCheck.HasValue ? new[] { _permissionToCheck.Value } : null);

            if (permissionResult == ContentPermissionsHelper.ContentAccess.NotFound)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            if (permissionResult == ContentPermissionsHelper.ContentAccess.Denied)
            {
                throw new HttpResponseException(actionContext.Request.CreateUserNoAccessResponse());
            }

            if (contentItem != null)
            {
                //store the content item in request cache so it can be resolved in the controller without re-looking it up
                actionContext.Request.Properties[typeof(IContent).ToString()] = contentItem;
            }

            base.OnActionExecuting(actionContext);
        }
        /// <summary>
        /// Checks if the user has access to post a content item based on whether it's being created or saved.
        /// </summary>
        /// <param name="actionContext"></param>
        /// <param name="contentItem"></param>
        private bool ValidateUserAccess(ContentItemSave contentItem, HttpActionContext actionContext)
        {
            //We now need to validate that the user is allowed to be doing what they are doing.
            //Based on the action we need to check different permissions.
            //Then if it is new, we need to lookup those permissions on the parent!

            var      permissionToCheck = new List <char>();
            IContent contentToCheck    = null;
            int      contentIdToCheck;

            switch (contentItem.Action)
            {
            case ContentSaveAction.Save:
                permissionToCheck.Add(ActionUpdate.ActionLetter);
                contentToCheck   = contentItem.PersistedContent;
                contentIdToCheck = contentToCheck.Id;
                break;

            case ContentSaveAction.Publish:
            case ContentSaveAction.PublishWithDescendants:
            case ContentSaveAction.PublishWithDescendantsForce:
                permissionToCheck.Add(ActionPublish.ActionLetter);
                contentToCheck   = contentItem.PersistedContent;
                contentIdToCheck = contentToCheck.Id;
                break;

            case ContentSaveAction.SendPublish:
                permissionToCheck.Add(ActionToPublish.ActionLetter);
                contentToCheck   = contentItem.PersistedContent;
                contentIdToCheck = contentToCheck.Id;
                break;

            case ContentSaveAction.Schedule:
                permissionToCheck.Add(ActionUpdate.ActionLetter);
                permissionToCheck.Add(ActionToPublish.ActionLetter);
                contentToCheck   = contentItem.PersistedContent;
                contentIdToCheck = contentToCheck.Id;
                break;

            case ContentSaveAction.SaveNew:
                //Save new requires ActionNew

                permissionToCheck.Add(ActionNew.ActionLetter);

                if (contentItem.ParentId != Constants.System.Root)
                {
                    contentToCheck   = _contentService.GetById(contentItem.ParentId);
                    contentIdToCheck = contentToCheck.Id;
                }
                else
                {
                    contentIdToCheck = contentItem.ParentId;
                }
                break;

            case ContentSaveAction.SendPublishNew:
                //Send new requires both ActionToPublish AND ActionNew

                permissionToCheck.Add(ActionNew.ActionLetter);
                permissionToCheck.Add(ActionToPublish.ActionLetter);
                if (contentItem.ParentId != Constants.System.Root)
                {
                    contentToCheck   = _contentService.GetById(contentItem.ParentId);
                    contentIdToCheck = contentToCheck.Id;
                }
                else
                {
                    contentIdToCheck = contentItem.ParentId;
                }
                break;

            case ContentSaveAction.PublishNew:
            case ContentSaveAction.PublishWithDescendantsNew:
            case ContentSaveAction.PublishWithDescendantsForceNew:
                //Publish new requires both ActionNew AND ActionPublish
                //TODO: Shoudn't publish also require ActionUpdate since it will definitely perform an update to publish but maybe that's just implied

                permissionToCheck.Add(ActionNew.ActionLetter);
                permissionToCheck.Add(ActionPublish.ActionLetter);

                if (contentItem.ParentId != Constants.System.Root)
                {
                    contentToCheck   = _contentService.GetById(contentItem.ParentId);
                    contentIdToCheck = contentToCheck.Id;
                }
                else
                {
                    contentIdToCheck = contentItem.ParentId;
                }
                break;

            case ContentSaveAction.ScheduleNew:

                permissionToCheck.Add(ActionNew.ActionLetter);
                permissionToCheck.Add(ActionUpdate.ActionLetter);
                permissionToCheck.Add(ActionPublish.ActionLetter);

                if (contentItem.ParentId != Constants.System.Root)
                {
                    contentToCheck   = _contentService.GetById(contentItem.ParentId);
                    contentIdToCheck = contentToCheck.Id;
                }
                else
                {
                    contentIdToCheck = contentItem.ParentId;
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            ContentPermissionsHelper.ContentAccess accessResult;
            if (contentToCheck != null)
            {
                //store the content item in request cache so it can be resolved in the controller without re-looking it up
                actionContext.Request.Properties[typeof(IContent).ToString()] = contentItem;

                accessResult = ContentPermissionsHelper.CheckPermissions(
                    contentToCheck, _security.CurrentUser,
                    _userService, _entityService, permissionToCheck.ToArray());
            }
            else
            {
                accessResult = ContentPermissionsHelper.CheckPermissions(
                    contentIdToCheck, _security.CurrentUser,
                    _userService, _contentService, _entityService,
                    out contentToCheck,
                    permissionToCheck.ToArray());
                if (contentToCheck != null)
                {
                    //store the content item in request cache so it can be resolved in the controller without re-looking it up
                    actionContext.Request.Properties[typeof(IContent).ToString()] = contentToCheck;
                }
            }

            if (accessResult == ContentPermissionsHelper.ContentAccess.NotFound)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return(accessResult == ContentPermissionsHelper.ContentAccess.Granted);
        }
示例#18
0
 internal static bool HasMediaRootAccess(this IUser user, IEntityService entityService, AppCaches appCaches)
 => ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia);
示例#19
0
 internal static bool HasMediaBinAccess(this IUser user, IEntityService entityService)
 {
     return(ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinMediaString, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia));
 }
 internal static bool HasContentBinAccess(this IUser user, IEntityService entityService)
 {
     return(ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinContent.ToInvariantString(), user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent));
 }