/// <summary> /// Should a create menu item be kept or removed? /// </summary> /// <remarks> /// Create menu items should be shown when the user has /// <see cref="Permissions.Create"/> on the target /// entity (which must be a type). /// </remarks> /// <param name="menuItem"> /// The menu item to check. /// </param> /// <returns> /// True if it should be kept, false if it should be removed. /// </returns> /// <exception cref="ArgumentNullException"> /// No argument can be null. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="menuItem"/> should be a create menu item /// and must have a target entity. /// </exception> private bool KeepCreateMenuItem(ActionMenuItemInfo menuItem) { if (menuItem == null) { throw new ArgumentNullException("menuItem"); } if (!menuItem.IsNew) { throw new ArgumentException("Not a create menu item", "menuItem"); } if (!HasTargetEntity(menuItem)) { throw new ArgumentException("Lacks a target entity Id"); } EntityType entityType; entityType = Entity.Get <EntityType>(menuItem.EntityId); if (entityType == null) { throw new ArgumentException("Not an entity type", "menuItem"); } return(Service.CanCreate(entityType)); }
/// <summary> /// Should this entity be removed, assuming it the action is a system based targeted action with /// some custom required permissions. /// </summary> /// <param name="menuItem">The menu item to check.</param> /// <returns>True if it should be kept, false if it should be removed.</returns> private bool KeepTargetedEntityMenuItem(ActionMenuItemInfo menuItem) { if (!menuItem.IsSystem) { // this is a system feature. just for us. return(false); } if (string.IsNullOrEmpty(menuItem.HtmlActionTarget)) { // this action hasn't been targeted return(false); } IList <EntityRef> requiredPermissions = new List <EntityRef>(); var result = true; // // The target will alter what the permissions should be checked against // if (menuItem.RequiresPermissions.Count > 0) { requiredPermissions.AddRange(menuItem.RequiresPermissions.Select(p => new EntityRef(p.Id))); if (requiredPermissions.Any(p => p.Id == Permissions.Create.Id)) { var entityType = Entity.Get <EntityType>(menuItem.EntityId); // Create permission on a non-EntityType = access denied result = entityType != null && Service.CanCreate(entityType); // Remove in prep for extra checks below requiredPermissions.Remove(Permissions.Create); } if (result) { // Bare minimum access required is "View" if (requiredPermissions.All(p => p.Id != Permissions.Read.Id)) { requiredPermissions.Add(Permissions.Read); } result = Service.Check(menuItem.EntityId, requiredPermissions); } // Add to cache? I don't think this applies if it's not against the selected items? } return(result); }
/// <summary> /// Should an entity menu item be kept or removed? /// </summary> /// <remarks> /// Entity menu items are ones created from an <see cref="ActionMenuItem"/> /// entity. Users require read access to the target entity and any /// additional permissions referenced by the /// <see cref="ActionMenuItem.ActionRequiresPermission" /> relationship. /// </remarks> /// <param name="menuItem"> /// The menu item to check. /// </param> /// <param name="selectedResourceIds"> /// The IDs of the resources to check. Ths cannot be null. /// </param> /// <param name="checkedPermissions"> /// Set of permissions that have already been checked. /// </param> /// <returns> /// True if it should be kept, false if it should be removed. /// </returns> /// <exception cref="ArgumentNullException"> /// No argument can be null. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="menuItem"/> should be an entity menu item /// and must have a target entity. /// </exception> private bool KeepEntityMenuItem(ActionMenuItemInfo menuItem, IList <long> selectedResourceIds, IDictionary <long, bool> checkedPermissions) { if (menuItem == null) { throw new ArgumentNullException("menuItem"); } if (selectedResourceIds == null) { throw new ArgumentNullException("selectedResourceIds"); } if (!IsEntityMenuItem(menuItem)) { throw new ArgumentException(@"Not an entity menu item", "menuItem"); } IList <EntityRef> requiredPermissions = new List <EntityRef>(); bool result = true; // // There are some cases where we allow for very specific security on custom system actions (namely 'New Workflow') // if (menuItem.IsSystem && !string.IsNullOrEmpty(menuItem.HtmlActionTarget)) { return(KeepTargetedEntityMenuItem(menuItem)); } using (new SecurityBypassContext()) { foreach (var ct in Entity.GetRelationships(new EntityRef(menuItem.Id), new EntityRef("console:actionRequiresPermission"), Direction.Forward)) { if (!checkedPermissions.ContainsKey(ct.Key)) { requiredPermissions.Add(new EntityRef(ct.Key)); } else { result &= checkedPermissions[ct.Key]; } } if (!checkedPermissions.ContainsKey(Permissions.Read.Id)) { requiredPermissions.Add(Permissions.Read); } else { result &= checkedPermissions [Permissions.Read.Id]; } // Filter actionRequiresRole foreach (var ct in Entity.GetRelationships(new EntityRef(menuItem.Id), new EntityRef("actionRequiresRole"), Direction.Forward)) { long roleId = ct.Key; var userRoles = UserRoleRepository.GetUserRoles(RequestContext.UserId); if (!userRoles.Contains(roleId)) { return(false); } } } if (requiredPermissions.Count > 0 && result) { IDictionary <long, bool> checkResults = Service.Check(selectedResourceIds.Select(id => new EntityRef(id)).ToList( ), requiredPermissions.ToList( )); foreach (KeyValuePair <long, bool> pair in checkResults) { if (pair.Value) { foreach (var requiredPermission in requiredPermissions) { checkedPermissions[requiredPermission.Id] = true; } } else { ///// // Check failed. If multiple permissions were requested don't update the checkedPermissions cache. ///// if (requiredPermissions.Count == 1) { checkedPermissions[requiredPermissions[0].Id] = false; } result = false; } } } return(result); }
/// <summary> /// Does the given <paramref name="menuItem"/> have a /// target entity? /// </summary> /// <param name="menuItem"> /// The menu item to check. /// </param> /// <returns> /// True if it has a target entity, false if not. /// </returns> private bool HasTargetEntity(ActionMenuItemInfo menuItem) { return(menuItem.EntityId > 0); }
/// <summary> /// Determines whether the menu item is the new holder menu item. /// </summary> /// <param name="menuItem">The menu item.</param> /// <returns></returns> private bool IsNewHolderMenuItem(ActionMenuItemInfo menuItem) { return(menuItem.HtmlActionState == ActionService.NewHolderMenuItemActionState); }
/// <summary> /// Is the given <paramref name="menuItem"/> created /// from an <see cref="ActionMenuItem"/> entity? /// </summary> /// <param name="menuItem"> /// The menu item to check. /// </param> /// <returns> /// True if the menu item was created from an entity, false otherwise. /// </returns> private bool IsEntityMenuItem(ActionMenuItemInfo menuItem) { return(menuItem.Id > 0); }