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); }
/// <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); }
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); }
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); }
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()); }
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); }
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)); }
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)); }
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)); }
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"); } }
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); } }
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); }
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); }
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); }
internal static bool HasMediaRootAccess(this IUser user, IEntityService entityService, AppCaches appCaches) => ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia);
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)); }