Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8305077
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T17:59:54+00:00 2026-06-08T17:59:54+00:00

I am following this cake php acl model article to create my own acl

  • 0

I am following this cake php acl model article to create my own acl implementation.

I have understood the concepts of ACO ARO and ACO_ARO. I want to implement the Check method which will decide whether the aro has access to the aco. since there are ARO trees and ACO trees, how do i calculate the most effective permissions for a aco to a aro.

Also i have found the below article which has check method implemented but that is in php
acl implementation

In short, what should take precedence Account or group, aco or parent aco.

something like this article

update
uptill now i have reached till here

i have made a accessControlEntry class as follows

public class AccessControlEntry
{
    public BsonObjectId AccessControlEntryId { get; set; }
    public BsonObjectId AccessRequestObjectId { get; set; }
    public BsonObjectId AccessControlObjectId { get; set; }
    public bool CanView { get; set; }
    public bool CanEdit { get; set; }
    public bool CanDelete { get; set; }
    public bool CanAdministrate { get; set; }
}

        public bool Check(Usercontext usercontext, BsonObjectId acoId, string permission)
    {
        //aco id is accessControlObjectId like in cakephp acl
        Account acc = _usercontextService.GetAccountByUserContext(usercontext);

        //getting ACE  eg X account has CanRead=true on Y object
        AccessControlEntry entry = _accessControlEntryRepository.GetAccessControlEntry(acc.AccountId, acoId);
        if (entry != null)
        {
            bool value = (bool)entry.GetType().GetProperty(permission).GetValue(entry, null);
            return value;
        }

        //account entry not found ...search in groups
        bool groupEntryFound = false;
        bool effectiveValue = false;
        Group[] groups = _usercontextService.GetGroupsForAccount(acc.AccountId);
        foreach (Group group in groups)
        {
            AccessControlEntry entryGroup = _accessControlEntryRepository.GetAccessControlEntry(group.GroupId, acoId);
            if (entryGroup != null)
            {
                groupEntryFound = true;
                effectiveValue |= (bool)entryGroup.GetType().GetProperty(permission).GetValue(entryGroup, null);
            }
        }

        //ACE found in group ..return most privilged value
        if (groupEntryFound)
            return effectiveValue;

        //entry not found for account nor for group..return false
        return false;
    }

I call the check method from other services ike this

Check(context,44556,"CanRead")

The check method looks for AccessControlEntry for the account, if it does not find any entry for account then it looks for groups.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T17:59:56+00:00Added an answer on June 8, 2026 at 5:59 pm

    Given the above information we can write some simple tooling, in my case I am working with a content management system so my ACL’s are about page access.

    First I define what my ACL entries look like …

    using System;
    namespace Core.Objects.CMS
    {
        /// <summary>
        /// Represents a record on an access control list
        /// </summary>
        public class PageACLEntry
        {
            /// <summary>
            /// Gets or sets the access control entry id.
            /// </summary>
            /// <value>
            /// The access control entry id.
            /// </value>
            public int PageACLEntryId { get; set; }
            /// <summary>
            /// Gets or sets the page id.
            /// </summary>
            /// <value>
            /// The page id.
            /// </value>
            public int PageId { get; set; }
            /// <summary>
            /// Gets or sets the name of the role.
            /// </summary>
            /// <value>
            /// The name of the role.
            /// </value>
            public string RoleName { get; set; }
            /// <summary>
            /// Gets or sets the read.
            /// </summary>
            /// <value>
            /// The read.
            /// </value>
            public bool? Read { get; set; }
            /// <summary>
            /// Gets or sets the content of the update.
            /// </summary>
            /// <value>
            /// The content of the update.
            /// </value>
            public bool? UpdateContent { get; set; }
            /// <summary>
            /// Gets or sets the update meta.
            /// </summary>
            /// <value>
            /// The update meta.
            /// </value>
            public bool? UpdateMeta { get; set; }
            /// <summary>
            /// Gets or sets the delete.
            /// </summary>
            /// <value>
            /// The delete.
            /// </value>
            public bool? Delete { get; set; }
            /// <summary>
            /// Gets or sets the full control.
            /// </summary>
            /// <value>
            /// The full control.
            /// </value>
            public bool? FullControl { get; set; }
        }
    }
    

    Then I create a helper class to handle the evaluations …

    using System.Collections.Generic;
    using System.Security.Principal;
    using Core.Objects.CMS;
    
    namespace Core.Utilities
    {
        /// <summary>
        /// Tools for permission calculation
        /// </summary>
        public static class PermissionHelper
        {
            /// <summary>
            /// Calculates the page permissions the given user has on the given page.
            /// </summary>
            /// <param name="page">The page.</param>
            /// <param name="user">The user.</param>
            /// <returns>the effective permissions</returns>
            private static PageACLEntry CalculatePagePermissions(Page page, IPrincipal user)
            {
                PageACLEntry result = new PageACLEntry();
                // start with acl for the current page
                List<PageACLEntry> acl = new List<PageACLEntry>(page.AclRules);
                // append all the way up the tree until parent == null
                acl = AppendTreePermissions(acl, page, user);
                // reverse the list so we evaluate root first then work up to here
                acl.Reverse();
                // because of the order in which these are applied the most local rules overrule the less local
                // the wider the scope the less it applies
                acl.ForEach(ace => 
                {
                    // only apply rules that apply to roles that our current user is in
                    if (user.IsInRole(ace.RoleName))
                    {
                        result.Read = Eval(result.Read, ace.Read);
                        result.Delete = Eval(result.Delete, ace.Delete);
                        result.UpdateMeta = Eval(result.UpdateMeta, ace.UpdateMeta);
                        result.UpdateContent = Eval(result.UpdateContent, ace.UpdateContent);
                        result.FullControl = Eval(result.FullControl, ace.FullControl);
                    }
                });
    
                return result;
            }
    
            /// <summary>
            /// Evaluates the specified permission level.
            /// </summary>
            /// <param name="target">The target.</param>
            /// <param name="suggestion">The suggestion.</param>
            /// <returns>evaluation result</returns>
            private static bool? Eval(bool? target, bool? suggestion)
            {
                bool? result = null; 
                switch (target)
                { 
                    case false:
                        result = false;
                        break;
                    case true:
                        result = true;
                        break;
                    case null:
                        break;
                }
    
                return result;
            }
    
            /// <summary>
            /// Appends the tree acl from the tree root up to this point.
            /// </summary>
            /// <param name="acl">The acl.</param>
            /// <param name="page">The page.</param>
            /// <param name="user">The user.</param>
            /// <returns>the complete acl</returns>
            private static List<PageACLEntry> AppendTreePermissions(List<PageACLEntry> acl, Page page, IPrincipal user)
            {
                Page currentPage = page.Parent;
                while (currentPage != null)
                {
                    acl.AddRange(currentPage.AclRules);
                    currentPage = page.Parent;
                }
    
                return acl;
            }
    
            /// <summary>
            /// Determines if the current User can read the given page.
            /// Unless an explicit deny rule is in place the default is to make everything read only.
            /// </summary>
            /// <param name="page">The page.</param>
            /// <param name="user">The user.</param>
            /// <returns>
            /// access right indication as bool
            /// </returns>
            public static bool UserCanRead(Page page, IPrincipal user)
            {
                PageACLEntry permissions = CalculatePagePermissions(page, user);
                if (permissions.Read != false)
                {
                    return true;
                }
    
                return false;
            }
            /// <summary>
            /// Determines if the current User can delete the given page.
            /// </summary>
            /// <param name="page">The page.</param>
            /// <param name="user">The user.</param>
            /// <returns>
            /// access right indication as bool
            /// </returns>
            public static bool UserCanDelete(Page page, IPrincipal user)
            {
                PageACLEntry permissions = CalculatePagePermissions(page, user);
    
                if (permissions.FullControl == true || permissions.Delete == true)
                {
                    return true;
                }
    
                return false;
            }
            /// <summary>
            /// Determines if the current User can update the given page.
            /// </summary>
            /// <param name="page">The page.</param>
            /// <param name="user">The user.</param>
            /// <returns>
            /// access right indication as bool
            /// </returns>
            public static bool UserCanUpdate(Page page, IPrincipal user)
            {
                PageACLEntry permissions = CalculatePagePermissions(page, user);
    
                if (permissions.FullControl == true || permissions.UpdateMeta == true)
                {
                    return true;
                }
    
                return false;
            }
            public static bool UserCanUpdateContent(Page page, IPrincipal user)
            {
                PageACLEntry permissions = CalculatePagePermissions(page, user);
    
                if (permissions.FullControl == true || permissions.UpdateContent == true)
                {
                    return true;
                }
    
                return false;
            }
            /// <summary>
            /// Determines if the current User can append children to the given page.
            /// </summary>
            /// <param name="page">The page.</param>
            /// <param name="user">The user.</param>
            /// <returns>
            /// access right indication as bool
            /// </returns>
            public static bool UserCanAddChildTo(Page page, IPrincipal user)
            {
                PageACLEntry permissions = CalculatePagePermissions(page, user);
    
                if (permissions.FullControl == true || permissions.UpdateMeta == true)
                {
                    return true;
                }
    
                return false;
            }
        }
    }
    

    This now gives me all the control I simply pass that a page and an IPrincipal object and I get back an ACLEntry that represents the level of access.

    I decided to further abstract away my security implementation by making the Calculation method private and only the CanX methods public.

    So now it’s as simple as

    bool result = PermissionsHelper.UserCanRead(page, user);
    

    It seems like theres a lot of code but if you take out the formatting and comments (to meet coding standards) there’s actually very little code, and if you copy this in in to a class file in Visual Studio it’s actually very easy to follow and maintain.

    You may also note, not once do I pass in a repository or service class to get data, that’s because I use this to build objects that are written using code first EF modelling an i’m using lazy loading, so your implementation might require a bit more than page.parent.AClEntries to go crawling up the tree.

    Oh just in case you need it here’s my page class …

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace Core.Objects.CMS
    {
        /// <summary>
        /// Represents a managed CMS page
        /// </summary>
        [Table("Pages")]
        public class Page
        {
            /// <summary>
            /// Gets or sets the page id.
            /// </summary>
            /// <value>
            /// The page id.
            /// </value>
            public int PageId { get; set; }
            /// <summary>
            /// Gets or sets the version.
            /// </summary>
            /// <value>
            /// The version.
            /// </value>
            public int Version { get; set; }
            /// <summary>
            /// Gets or sets the title.
            /// </summary>
            /// <value>
            /// The title.
            /// </value>
            public string Title { get; set; }
            /// <summary>
            /// Gets or sets the template.
            /// </summary>
            /// <value>
            /// The template.
            /// </value>
            public string Template { get; set; }
            /// <summary>
            /// Gets or sets the path.
            /// </summary>
            /// <value>
            /// The path.
            /// </value>
            public string Path { get; set; }
            /// <summary>
            /// Gets or sets the parent.
            /// </summary>
            /// <value>
            /// The parent.
            /// </value>
            public virtual Page Parent { get; set; }
            /// <summary>
            /// Gets or sets the children.
            /// </summary>
            /// <value>
            /// The children.
            /// </value>
            public virtual List<Page> Children { get; set; }
            /// <summary>
            /// Gets or sets the content.
            /// </summary>
            /// <value>
            /// The content.
            /// </value>
            public virtual List<PageContent> Content { get; set; }
            /// <summary>
            /// Gets or sets the component stacks.
            /// </summary>
            /// <value>
            /// The component stacks.
            /// </value>
            public virtual List<Stack> ComponentStacks { get; set; }
            /// <summary>
            /// Gets or sets the acl rules.
            /// </summary>
            /// <value>
            /// The acl rules.
            /// </value>
            public virtual List<PageACLEntry> AclRules { get; set; }
        }
    }
    

    Very simple poco … using the power of EF to do all my on demand SQL crawling.
    The one down side … i doubt it’s particularly efficient if you have a page deeply nested in a tree.

    I’m still open to suggestions on improving this but this felt like the cleanest way to implement a managable solution at the time.
    Now i have total visibility of the problem I can look to make those efficiency gains.

    But at least you have a point of reference right 🙂

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm new to cakephp and following this tutorial. http://book.cakephp.org/2.0/en/tutorials-and-examples/blog-auth-example/auth.html I have created the blog
Following this question and answer , I still have a bit trouble in the
Using CakePHP 1.3, I have the following layout: /srv/www/_cakephp13/ /app/ /cake/ /plugins/ /vendors/ etc...
I have the following in a layout file; <?php $Filename = TheEvent.vcs; header(Content-Type: application/force-download);
While following the instructions on the CakePHP book to create an ACL controlled site
I can get Cake to output a submit button using the following PHP: <?php
I have a Goal model that HasAndBelongsToMany Users. This HABTM is named Participant. When
I am following the CakePHP ACL tutorial http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html I have a controller called ImagesController
I tried to implement rss feed following this simple explanation from cake book http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html
If I have the following, $this->Session->write('ScoreCardCriteria', 'test'); And want to add another item to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.