diff --git a/README.md b/README.md index 329c8d8..3c7131b 100644 --- a/README.md +++ b/README.md @@ -201,8 +201,7 @@ Wildcards can be used at various places: * equivalent to `$f3->allow('/','')` * equivalent to `$f3->allow('/')` -**IMPORTANT**: following the framework convention and unlike usual filesystem wildcards, -the plugin wildcards do not match empty strings. So `/admin*` doesn't match `/admin` (at least 1 character is required). +**NB**: wildcards match empty strings, so `/admin*` match `/admin`. Routes tokens are also supported, so `$f3->allow('/blog/@id/@slug')` is recognized. diff --git a/lib/access.php b/lib/access.php index 14179ce..597e7f7 100644 --- a/lib/access.php +++ b/lib/access.php @@ -81,9 +81,19 @@ function granted($route,$subject='') { $specific=isset($this->rules[$subject][$verb])?$this->rules[$subject][$verb]:array(); $global=isset($this->rules['*'][$verb])?$this->rules['*'][$verb]:array(); $rules=$specific+$global;//subject-specific rules have precedence over global rules - krsort($rules);//specific paths are processed first + //specific paths are processed first: + $paths=array(); + foreach ($keys=array_keys($rules) as $key) { + $path=str_replace('@','*@',$key); + if (substr($path,-1)!='*') + $path.='+'; + $paths[]=$path; + } + $vals=array_values($rules); + array_multisort($paths,SORT_DESC,$keys,$vals); + $rules=array_combine($keys,$vals); foreach($rules as $path=>$rule) - if (preg_match('/^'.preg_replace('/@\w*/','[^\/]+',str_replace('\*','.+',preg_quote($path,'/'))).'$/',$uri)) + if (preg_match('/^'.preg_replace('/@\w*/','[^\/]+',str_replace('\*','.*',preg_quote($path,'/'))).'$/',$uri)) return $rule; return $this->policy==self::ALLOW; } diff --git a/tests/tests.php b/tests/tests.php index cf14647..6ddf7e2 100644 --- a/tests/tests.php +++ b/tests/tests.php @@ -62,8 +62,8 @@ function run($f3) { $access->deny('/admin*'); $access->allow('/admin*','admin'); $test->expect( - !$access->granted('/admin/foo') && !$access->granted('/admin/foo/bar') && - $access->granted('/admin/foo','admin') && $access->granted('/admin/foo/bar','admin'), + !$access->granted('/admin') && !$access->granted('/admin/foo/bar') && + $access->granted('/admin','admin') && $access->granted('/admin/foo/bar','admin'), 'Wildcard suffix' ); $access->deny('/*/edit'); @@ -72,9 +72,12 @@ function run($f3) { !$access->granted('/blog/entry/edit') && $access->granted('/blog/entry/edit','admin'), 'Wildcard prefix' ); - $access->deny('/blog*','admin'); + $access->allow('/admin'); + $access->allow('/admin/special/path'); $test->expect( - !$access->granted('/blog/entry/edit','admin'), + $access->granted('/admin') && !$access->granted('/admin/foo/bar') && + $access->granted('/admin','admin') && $access->granted('/admin/foo/bar','admin') && + $access->granted('/admin/special/path') && $access->granted('/admin/special/path','admin'), 'Wildcard precedence order' ); //Tokens