using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net; using System.Net.Http.Formatting; using System.Web.Http; using Umbraco.Core; using Umbraco.Core.Models; using umbraco.BusinessLogic.Actions; using umbraco.businesslogic; using umbraco.interfaces; namespace Umbraco.Web.Trees { public abstract class ContentTreeControllerBase : TreeApiController { /// /// Based on the allowed actions, this will filter the ones that the current user is allowed /// /// /// /// protected MenuItemCollection GetUserAllowedMenuItems(IEnumerable allMenuItems, IEnumerable userAllowedMenuItems) { var userAllowedActions = userAllowedMenuItems.Where(x => x.Action != null).Select(x => x.Action).ToArray(); return new MenuItemCollection(allMenuItems.Where( a => (a.Action == null || a.Action.CanBePermissionAssigned == false || (a.Action.CanBePermissionAssigned && userAllowedActions.Contains(a.Action))))); } internal MenuItemCollection GetUserMenuItemsForNode(UmbracoEntity dd) { var actions = global::umbraco.BusinessLogic.Actions.Action.FromString(UmbracoUser.GetPermissions(dd.Path)); // A user is allowed to delete their own stuff if (dd.CreatorId == UmbracoUser.Id && actions.Contains(ActionDelete.Instance) == false) actions.Add(ActionDelete.Instance); return new MenuItemCollection(actions.Select(x => new MenuItem(x))); } } [Tree(Constants.Applications.Content, Constants.Trees.Content, "Content")] public class ContentTreeController : ContentTreeControllerBase { protected override TreeNode CreateRootNode(FormDataCollection queryStrings) { //TODO: We need to implement security checks here and the user's start node! return base.CreateRootNode(queryStrings); } protected override TreeNodeCollection GetTreeData(string id, FormDataCollection queryStrings) { int iid; if (int.TryParse(id, out iid) == false) { throw new InvalidCastException("The id for the content tree must be an integer"); } var nodes = new TreeNodeCollection(); var entities = Services.EntityService.GetChildren(iid, UmbracoObjectTypes.Document).ToArray(); foreach (var entity in entities) { //TODO: We need to implement security checks here! var e = (UmbracoEntity)entity; nodes.Add( CreateTreeNode( e.Id.ToInvariantString(), queryStrings, e.Name, e.ContentTypeIcon, e.HasChildren)); } return nodes; } protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) { var menu = new MenuItemCollection(); if (id == Constants.System.Root.ToInvariantString()) { // we need to get the default permissions as you can't set permissions on the very root node var nodeActions = global::umbraco.BusinessLogic.Actions.Action.FromString( UmbracoUser.GetPermissions(Constants.System.Root.ToInvariantString())) .Select(x => new MenuItem(x)); menu.AddMenuItem(); menu.AddMenuItem(); var allowedMenu = GetUserAllowedMenuItems(menu, nodeActions); if (allowedMenu.Any()) { allowedMenu.Last().SeperatorBefore = true; } // default actions for all users allowedMenu.AddMenuItem(); allowedMenu.AddMenuItem(true); return allowedMenu; } //return a normal node menu: int iid; if (int.TryParse(id, out iid) == false) { throw new InvalidOperationException("The Id for a content item must be an integer"); } var item = Services.EntityService.Get(iid, UmbracoObjectTypes.Document); if (item == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } return GetUserAllowedMenuItems( CreateAllowedActions(), GetUserMenuItemsForNode((UmbracoEntity) item)); } protected IEnumerable CreateAllowedActions() { var menu = new MenuItemCollection(); menu.AddMenuItem(); menu.AddMenuItem(true); menu.AddMenuItem(true); menu.AddMenuItem(); menu.AddMenuItem(true); menu.AddMenuItem(); menu.AddMenuItem(true); menu.AddMenuItem(); menu.AddMenuItem(); menu.AddMenuItem(); menu.AddMenuItem(true); menu.AddMenuItem(true); menu.AddMenuItem(true); menu.AddMenuItem(); menu.AddMenuItem(true); return menu; } } }