1

I want to create something like permissions in my project. How do I check is string match one of the regex in array?

//Array of user (group) permissions.
$arrayOfPermissions = [
    'admin.users.edit',
    'admin.users.*',
    'dashboard.view',

];

//Check is this permission presents in array
$stringToMatch = 'admin.users.view';

* sign mean that user have all permissions in this group.

For exemple:

If user have permission admin.users.* so he should pass validation for admin.users.view

UPD: I use this now, but it looks like this is not good.

private function checkPerms($permission)
{
    $arrayOfPermissions = [
        'admin.dashboard.view',
        'admin.users.*'

    ];

    foreach ($arrayOfPermissions as $perm)
    {
        if(preg_match("/".$perm."/", $permission))
        {
            return true;
        }
    }

    return false;
}

//This should return `true`
checkPerms("admin.users.view");

P.S. I use Laravel.

KAMAEL
  • 175
  • 2
  • 16
  • Array values are not regexes. – u_mulder May 16 '17 at 19:11
  • Why not just `admin.users` ? – splash58 May 16 '17 at 19:25
  • @splash58 because if user have permission like `admin.users.*` he should can do any staff where required `admin.users.edit` or `admin.users.create` etc. – KAMAEL May 16 '17 at 19:45
  • @u_mulder `*` sign is regex – KAMAEL May 16 '17 at 19:46
  • Maybe [this different permissions concept would be interesting](http://stackoverflow.com/questions/9811114/why-do-enum-permissions-often-have-0-1-2-4-values). – bobble bubble May 16 '17 at 19:57
  • 1
    This isn't an answer, but note that in regexes, `.` is a special character, and `*` doesn't mean the same thing it means in a wildcard match, typeglob, etc. If you want a regex to match a literal `.`, use `\.`. If you want a typeglob-style `*`, use `.+` (or `.*` if you want the empty string to be a valid match). For example, instead of `'admin.users.*'`, use `'admin\\.users\\..+'`. The string you've used as a regex will match the strings you want to match, but also others such as `admin-userstrike`. – David Knipe May 16 '17 at 20:03

3 Answers3

1

Assuming the array of permissions include permissions ending with a wildcard (*) or ones with full names.

Iterate through the permissions,

  • If they contain a wildcard (*), check if the permission to be checked starts with it
  • Else the permission should be completely matched

Code:

echo hasPermission($arrayOfPermissions, $stringToMatch) ? "Has Access" : "Access Denied";

function hasPermission($arrayOfPermissions, $stringToMatch) 
    // Iterate through all permissions
    foreach ($arrayOfPermissions as $permission) {
        // Check if permission contains a wildcard
        if(strpos($permission, '.*')) {
            $prefix = substr($permission, 0, strpos($permission, '.*'));
            if(startsWith($stringToMatch, $prefix))
                return true;
        // Else, match completely
        } else {
            if($permission == $stringToMatch)
                return true;
        }
    }
    return false;
}

function startsWith($string, $test)
{
    $length = strlen($test);
    return (substr($string, 0, $length) === $test);
}
degant
  • 4,861
  • 1
  • 17
  • 29
0

you can check by in_array() or you imploding the values and the regex would like this: /(permission1|permisson2..)/

daHormez
  • 21
  • 2
-1

I guess here is what you could do:

  • Remove the .* from the string, if any.
  • In a foreach loop through permission check if string starts with manipulated string from above

No regex needed.

jrn
  • 2,640
  • 4
  • 29
  • 51