Skip to content

Commit f16df7e

Browse files
author
Mateus Junges
authored
Merge pull request mateusjunges#97 from mateusjunges/issue-78
Fix mateusjunges#78
2 parents 167721f + 7e2bddc commit f16df7e

File tree

4 files changed

+142
-1
lines changed

4 files changed

+142
-1
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
All notable changes to `mateusjunges/laravel-acl` will be documented in this file.
44

5+
6+
## [UNRELEASED]
7+
- Check wildcard permissions
8+
- Tests for new middleware
9+
510
## 1.7.5
611
- Fix [#93](https://github.com/mateusjunges/laravel-acl/issues/93)
712
- Add database connection check before register gates
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Junges\ACL\Middlewares;
4+
5+
use Closure;
6+
use Illuminate\Support\Facades\Auth;
7+
use Junges\ACL\Exceptions\UnauthorizedException;
8+
9+
class HierarchicalMiddleware
10+
{
11+
/**
12+
* Handle an incoming request.
13+
*
14+
* @param $request
15+
* @param Closure $next
16+
* @param $permissions
17+
* @return bool
18+
*/
19+
public function handle($request, Closure $next, $permissions)
20+
{
21+
if (Auth::guest()) {
22+
throw UnauthorizedException::notLoggedIn();
23+
}
24+
25+
$permissions = is_array($permissions) ? $permissions : explode('|', $permissions);
26+
27+
foreach ($permissions as $permission) {
28+
$parts = explode('.', $permission);
29+
$ability = '';
30+
foreach ($parts as $part) {
31+
$ability .= $ability ? '.'.$part : $part;
32+
33+
if (Auth::user()->can($ability)) {
34+
// Grant access on the first match
35+
return $next($request);
36+
}
37+
}
38+
}
39+
throw UnauthorizedException::forPermissions();
40+
}
41+
}

tests/HierarchicalPermissionsTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace Junges\ACL\Test;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Http\Response;
7+
use Illuminate\Support\Facades\Auth;
8+
use Junges\ACL\Exceptions\UnauthorizedException;
9+
use Junges\ACL\Middlewares\HierarchicalMiddleware;
10+
11+
class HierarchicalPermissionsTest extends TestCase
12+
{
13+
protected $hierarchicalMiddleware;
14+
15+
/**
16+
* Set up the test.
17+
*/
18+
public function setUp()
19+
{
20+
parent::setUp();
21+
$this->hierarchicalMiddleware = new HierarchicalMiddleware($this->app);
22+
}
23+
24+
/**
25+
* @test
26+
*/
27+
public function a_guest_can_not_access_a_protected_route()
28+
{
29+
$this->assertEquals(
30+
$this->execMiddleware($this->hierarchicalMiddleware, 'edit-news.edit-website'),
31+
Response::HTTP_FORBIDDEN
32+
);
33+
}
34+
35+
/**
36+
* @test
37+
*/
38+
public function logged_in_user_can_access_a_route_protected_by_hierarchical_middleware_if_one_of_the_hierarchical_permissions_match()
39+
{
40+
Auth::login($this->testUser);
41+
42+
Auth::user()->assignPermissions([
43+
'admin.auth',
44+
]);
45+
$this->assertEquals(
46+
$this->execMiddleware($this->hierarchicalMiddleware, 'admin.auth.users'),
47+
Response::HTTP_OK
48+
);
49+
}
50+
51+
/**
52+
* @test
53+
*/
54+
public function logged_in_user_can_not_access_a_route_protected_by_hierarchical_middleware_if_no_hierarchical_permissions_match()
55+
{
56+
Auth::login($this->testUser);
57+
58+
$this->assertEquals(
59+
$this->execMiddleware($this->hierarchicalMiddleware, 'admin.auth.users'),
60+
Response::HTTP_FORBIDDEN
61+
);
62+
}
63+
64+
/**
65+
* Execute the specified middleware.
66+
* @param $middleware
67+
* @param $parameter
68+
* @return int
69+
*/
70+
private function execMiddleware($middleware, $parameter)
71+
{
72+
try {
73+
return $middleware->handle(new Request(), function () {
74+
return (new Response())->setContent('<html></html>');
75+
}, $parameter)->status();
76+
} catch (UnauthorizedException $exception) {
77+
return $exception->getStatusCode();
78+
}
79+
}
80+
}

tests/TestCase.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ public function getEnvironmentSetUp($app)
126126
*/
127127
public function configureDatabase($app)
128128
{
129-
DB::statement('DROP TABLE IF EXISTS test_users CASCADE;');
130129
DB::statement('DROP TABLE IF EXISTS test_permissions CASCADE;');
130+
DB::statement('DROP TABLE IF EXISTS test_users CASCADE;');
131131
DB::statement('DROP TABLE IF EXISTS test_groups CASCADE;');
132132
DB::statement('DROP TABLE IF EXISTS test_user_has_permissions CASCADE;');
133133
DB::statement('DROP TABLE IF EXISTS test_user_has_groups CASCADE;');
@@ -169,6 +169,11 @@ public function configureDatabase($app)
169169
/*
170170
* Create the tables on the database
171171
*/
172+
(new \CreatePermissionsTable())->down();
173+
(new \CreateGroupsTable())->down();
174+
(new \CreateGroupHasPermissionsTable())->down();
175+
(new \CreateUserHasPermissionsTable())->down();
176+
(new \CreateUserHasGroupsTable())->down();
172177
(new \CreatePermissionsTable())->up();
173178
(new \CreateGroupsTable())->up();
174179
(new \CreateGroupHasPermissionsTable())->up();
@@ -241,5 +246,15 @@ public function configureDatabase($app)
241246
'slug' => 'edit-news',
242247
'description' => 'This permission allows you to edit the news page',
243248
]);
249+
Permission::create([
250+
'name' => 'Test hierarchical permissions',
251+
'slug' => 'admin.auth',
252+
'description' => 'This is a hierarchical permission test',
253+
]);
254+
Permission::create([
255+
'name' => 'Test hierarchical permissions 1',
256+
'slug' => 'admin.auth.users',
257+
'description' => 'This is a hierarchical permission test',
258+
]);
244259
}
245260
}

0 commit comments

Comments
 (0)