Member site page(s) access permissions using LIKE to compare members permissions field against site page permissions field.

6 posts by 2 authors in: Forums > CMS Builder
Last Post: January 15, 2016   (RSS)

By Mikey - January 14, 2016

I'm trying to set up an intranet for a client. The way I'm setting site page access permissions are as follows:

I have an category menu called "intranet_access_categories" were 30 plus categories exist within the name field. The site administrator will have the ability to create additional categories as need over time.

In the "members" section I have a multi-select field called "department_intranet_access" which pulls it's list data from the "intranet_access_categories".   A member can have one selection or multiple selections from the "department_intranet_access" to give them access to various site pages with matching (LIKE) .

There are various intranet site page section editors. In regards to this post I'm referencing the section editor "accounting_intranet" which has a field called "dept_intranet_access" which also pulls it's list data from the ""intranet_access_categories". An intranet site page can have one selection or multiple selections from the "dept_intranet_access" to give members with matching (LIKE) categories. 

If a site visitor is not a user they are redirected to the home page using !$CURRENT_USER
If a member is not given permission to access the intranet they are redirected to the home page using $CURRENT_USER['intranet_access'] == '0'
And if a member's access permissions do not match that of the site page, they are redirected to the home page using $membersRecords == !$intranetString

That's the idea of what needs to be achieve, however there's an issue with the $intranetString LIKE filtering. What's wrong is that if a member has ANY category in "department_intranet_access" that matches any intranet site page's "dept_intranet_access" permission then they have access to all intranet site pages regardless of whether the remaining intranet site pages match the same category or not.

I suspect that my filtering method is incorrect, of the $membersRecords == !$intranetString is bad.

Anyone have any suggestions?

Here's my code:

  // load record from 'accounting_intranet'
  list($accounting_intranetRecords, $accounting_intranetMetaData) = getRecords(array(
    'tableName'   => 'accounting_intranet',
    'where'       => whereRecordNumberInUrl(0),
    'loadUploads' => true,
    'allowSearch' => false,
    'limit'       => '1',
  ));
  $accounting_intranetRecord = @$accounting_intranetRecords[0]; // get first record
  if (!$accounting_intranetRecord) { dieWith404("Record not found!"); } // show error message if no record found
  
//=========== permission filter ==========//
// members can have access to multiple site pages within the intranet, so there's a multi-select list that a member can be given access to multiple labels' values using a num value comparison of LIKE.

// compare accounting_intranetRecord's multi-select settings for the field "dept_intranet_access" and compare it to the members accounts field "department_intranet_access". If there's a match, allow acces to site page, otherwise redirect to home page. 
  $intranetString = '';
  if(is_array(@$accounting_intranetRecord['dept_intranet_access:values'])){
  
    $arrayCounters = count($accounting_intranetRecord['dept_intranet_access:values']);

    foreach($accounting_intranetRecord['dept_intranet_access:values'] as $keys => $filterItems){
      $intranetString .= "department_intranet_access LIKE '%\t$filterItems\t%'";
  
      if(($keys+1) != $arrayCounters){
        $intranetString .= " OR ";
      }
    }
  }
//=========== members access filtered ==========//  
// load records from 'members'
  list($membersRecords, $membersMetaData) = getRecords(array(
    'tableName'   => 'members',
    'where'       => $intranetString,
    'loadUploads' => true,
    'allowSearch' => false,
  ));
// If there's no match in the LIKE comparison intranetString, then redirect member to home page. 
  if (!$CURRENT_USER || $CURRENT_USER['intranet_access'] == '0' || $membersRecords == !$intranetString) { redirectBrowserToUrl("http://domainname.com/"); }

Thanks, Zicky

By gregThomas - January 14, 2016 - edited: January 14, 2016

Hey Zicky, 

I think this line might be the cause of the issue:

// If there's no match in the LIKE comparison intranetString, then redirect member to home page.   if (!$CURRENT_USER || $CURRENT_USER['intranet_access'] == '0' || $membersRecords == !$intranetString) { redirectBrowserToUrl("http://domainname.com/"); }

So this bit:

!$CURRENT_USER || $CURRENT_USER['intranet_access'] == '0'

looks good to me, but I'm not sure what this bit is meant to do:

 || $membersRecords == !$intranetString

The member records are returned as an array, and $intranetString is a string, so I think those two items could never match. Also the ! at the beginning of $intranetString would mean it's being treated as a boolean instead of a string.

Could you give me a few more details on what this line of code needs to do?

Cheers,

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By Mikey - January 14, 2016

Hey Greg,

I'll try to clarify what I'm trying to achieve.

So there's a category section editor called "intranet_access_categories" which I'm using to hold descriptive words to define various department(s) within the organization.

Example:
Accounting
Financing
Packing and Shipping
Administrative
etc...

There's a "members" multi section editor for front-end users. Within the 'members" records there's a department_intranet_access list field "pulldown (multi value)" which has the info below applied:
Get options from database (advanced)
Section Tablename "intranet_access_categories"
Use this field for option values "num"
Use this field for option labels "name"


Then there's various department category section editors such as "accounting_intranet, financing_intranet, packing_shipping_intranet, administration_intranet, etc...". Within the various department category section editor records there's a dept_intranet_access list field "pulldown (multi value)" which has the info below applied:
Get options from database (advanced)
Section Tablename "intranet_access_categories"
Use this field for option values "num"
Use this field for option labels "name"

1) A member may have one or multiple pulldown selections associated with their department_intranet_access permissions to access specific site pages.
2) A department page may have one or multiple pulldown selections associated with the department's dept_intranet_access pagepermissions. A department page may also have sub-category pages which have different department dept_intranet_access pagepermissions from their parent top tier category page.

What I'm trying to accomplish is a comparison of the "members" department_intranet_access permissions AGAINST the department's dept_intranet_access pagepermissions... so only members who have a LIKE (similar) value can access on those department pages with the same permission assigned to the site page.

So member "John Doe" may have permissions to access AccountingFinancing department pages and the Accounting Department's page may/or can have slightly different permissions such as Accounting,Packing and ShippingAdministrative and because there's a match for John Doe's members permission Accounting and the Department's page permission Accounting, then when John Doe lands on the Accounting Department page he is given access to the page.

So, I'm trying to do a comparison between "members" and department records permissions - to find a match to allow access to the site page, otherwise redirect. AND permissions of a member and a department page MAY NOT match exactly, but if there's a one instance of the category descriptive word(s) of "intranet_access_categories" do match (such as permissions of "members = Administrative, Accounting" LIKE "department page = Administrative, Packing and Shipping"), then the member can gain access to the Administrative site page. 

I hope that clarifies what I'm trying to achieve. 

Hi Zicky,

Thanks for the detailed explanation, now I understand what's needed. I've written some code that I think will do what you're looking for:


// load record from 'accounting_intranet'
list($accounting_intranetRecords, $accounting_intranetMetaData) = getRecords(array(
  'tableName'   => 'accounting_intranet',
  'where'       => whereRecordNumberInUrl(0),
  'loadUploads' => true,
  'allowSearch' => false,
  'limit'       => '1',
));
$accounting_intranetRecord = @$accounting_intranetRecords[0]; // get first record
if (!$accounting_intranetRecord) { dieWith404("Record not found!"); } // show error message if no record found
  
//Convert the departments the user has access to from a string to an array.
$userDeptValues = explode("\t", trim($CURRENT_USER['department_intranet_access'], "\t"));

//Cycle through the department access items, and check if we have matching values in the user department values.
if(is_array(@$accounting_intranetRecord['dept_intranet_access:values'])){
  $hasAccess = false;
  foreach($accounting_intranetRecord['dept_intranet_access:values'] as $keys => $value){
    if(in_array($value, $userDeptValues)){
      $hasAccess = true;
    }
  }
}

//If the user doesn't have access, redirect them away from this page.
if(!$hasAccess){
  redirectBrowserToUrl("http://domainname.com/"); 
  exit;
}

I've re-written the code so instead of looking for the member in the members section, we look through the current users access by converting their access levels from a string into an array. 

After this is done, we cycle through the sections access levels and check if the user and and sections departments ever match up. If they do we set the variable hasAccess to true. 

If the hasAccess variable is true then we allow the user to see the page, if not we redirect the user to a different page.

Cheers,

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By Mikey - January 15, 2016

Hey Greg,

Thanks for the help... works like a charm, and does exactly what I needed it to do.
Many thanks!!!

Zicky