2 Replies Latest reply on Jun 12, 2008 11:00 AM by Homestar9

    Optimization and Best Practices: User Goup Permissions

    Homestar9 Level 1
      Hello All,

      Recently I have done some soul searching on the best way to allow for complex user permissions on a web site while keeping server resources in mind. I am hoping that some of you will have some ideas or suggestions on the best way to implement a system like this using CF. First a little background:

      In my CF application I assign user accounts to a permission group so different users can access different pages. For example, I can assign user 'Joe Bob' to the 'Administrators' group which can access pretty much everything, whereas the user 'Jane Smith' has been assigned to the 'Contributors' group and can only access certain pages.

      Initially I assigned the permissions based on the name of the permissions group, so when the user logged on I created a session variable called AccountType which would contain the value, "Administrator", "Contributor", etc. That way, my templates could run a simple cfif to check if the person could see a particular resource,link,etc.

      However, now I am expanding the permissions scheme to allow site administrators to create their own user groups with their own unique names and permissions settings. The user account types are stored in a database and each separate permission is stored as a yes/no variable in a column. For example:

      UserTypeID......Name ..............CanLogIn........CanAccessProducts......CanAccessBlog.......etc...
      ------------------------------------------------------------------------------------------ -----------------------------------------------
      1 ...................Administrator.....yes................yes.............................. .yes
      2 ...................Contributor .........yes...............no................................yes
      3....................Store Manager.....yes...............yes..............................no

      So the problem arises: How should these permission settings be applied for the logged in users? I want to be conscious of both server memory as well processing/requests to the DB and ease of coding. Here are some ideas that I had:

      IDEA 1: When the user logs on, do just as I was doing and assign a session variable named UserType that stores the UserTypeID. Then, within application.cfm, check if the user is logged on, if yes, query the database (cached query) and get the permission values for that account type and store them in a structure which can be referenced as needed in that request.

      Pros: In this method, the work appears to mostly be done by the processor, db server. Since queries can be cached, I can use the same cached query for multiple users that log into the site so more than one user can share the cached query.

      Cons: I think that reading a cached query and then building a structure containing the values of the table on ever page load might be overkill and might demand unneeded processing.

      IDEA 2. This method is similar to #1 in that a session variable named UserType will be created when the user logs on. However the main difference is that the database won't be queried for a permission column until it is actually needed. So if the user tries to access page xyz.cfm, coldfusion checks the appropriate column in the table based on the UserType variable and either allows the user to see it or not.

      Pros: This could potentially save some server memory if there are a lot of users logged on at once and a lot of permission columns in the database.

      Cons: This could be a coding nightmare and will add a lot more lines of code on many templates since pretty much every template will make at least one permissions check.

      IDEA 3: Another method which might work would be when a user logs on, query the appropriate permissions records and store all of the yes/no columns as a structure in the session scope. On each page load (application.cfm), copy the structure stored in the session scope which contains all of the permissions to the local variable scope so it can be easily accessed by the page.

      Pros: Using this method, I only have to query the permissions once, and then access all the variables I need because they will be stored in memory.

      Cons: In the event that there are a LOT of permission variables (assuming 100 or so) this could cause each logged in user session to hold a lot of variables. I'm not sure how much server memory a structure containing 100 values is, but I want to keep that in mind so I don't hog too many resources unnecessarily.

      What are your thoughts on this topic? Do you have any suggestions or ideas for handling this type of situation?
        • 1. Re: Optimization and Best Practices: User Goup Permissions
          Nuukem
          Anyone have any ideas for this? I'm interested in a solution also.

          Thanks,

          Phil
          • 2. Re: Optimization and Best Practices: User Goup Permissions
            Homestar9 Level 1
            I was surprised no one was interested in discussing this one either. However, I played around with several different options and although I didn't do any performance benchmarking to compare which method would be the most efficient, I guestimated using common sense and ease of programming to come up with a solution similar to Idea 3 above.

            When the user logs in, the permissions table is queried and all of the permissions are added to a structure variable which is then stored in the session scope. This way, I can look up a particular permission any time I want without having to query the database.

            Additionally, if these templates will be accessed by non logged in users (like a forum application) I may need to have a structure for each non-logged in user as well. However, I believe the way to solve that problem efficiently is to store an empty permissions structure which contains all the same variables as the logged in user in the Application scope which can be referenced when needed.

            This method puts the most stress on system memory, but I believe that it is better to stress out the system memory rather than the processor. Also, I don't think that a hundred structures each containing a couple hundred variables really isn't a lot of data in the grand scheme of things.

            It would be cool to know though how much memory a session structure containing 100 variables would take up. Perhaps one of those monitoring programs like SeeFusion would shed some light on that. If anyone has a copy of SeeFusion (or similar) please feel free to post that information. It could be helpful to CF developers in many situations.