added acl to project

pull/44/head
A1Gard 2 months ago
parent 8188820ac3
commit f91986c4b7

@ -79,8 +79,27 @@ class UserController extends XController
*/ */
public function edit(User $item) public function edit(User $item)
{ {
$routes = [];
foreach (\Route::getRoutes()->getRoutes() as $route) {
$action = $route->getAction();
if (array_key_exists('as', $action)) {
$routeName = explode('.', $action['as']);
if (isset($routeName[2]) && $routeName[0] == 'admin') {
if (!isset($routes[$routeName[1]])) {
$routes[$routeName[1]] = [];
if ($routeName[2] != 'edit' && $routeName[2] != 'create')
$routes[$routeName[1]][] = $routeName[2];
} else {
if ($routeName[2] != 'edit' && $routeName[2] != 'create')
$routes[$routeName[1]][] = $routeName[2];
}
}
}
}
unset($routes['home'], $routes['user'], $routes['ckeditor'],$routes['area'],$routes['lang'],$routes['gfx']);
// //
return view($this->formView, compact('item')); return view($this->formView, compact('item','routes'));
} }
public function bulk(Request $request) public function bulk(Request $request)

@ -8,6 +8,8 @@ use Symfony\Component\HttpFoundation\Response;
class Acl class Acl
{ {
private $excepts = ['ckeditor', 'home'];
/** /**
* Handle an incoming request. * Handle an incoming request.
* *
@ -15,6 +17,31 @@ class Acl
*/ */
public function handle(Request $request, Closure $next): Response public function handle(Request $request, Closure $next): Response
{ {
$route = \Route::getCurrentRoute();
// check admin page & user is not super admin
if (auth()->check() && isset($route->action['as'])) {
// explode user request to process
$requestPath = explode('.', $route->action['as']);
// ignore admin and not admin page
if ($requestPath[0] == 'admin' && !auth()->user()->hasRole('developer') && !auth()->user()->hasRole('admin')) {
// check excpet and has 3 routes and has user acceess
if (!in_array($requestPath[1], $this->excepts) &&
isset($requestPath[2]) &&
!auth()->user()->hasAccess($route->action['as'])) {
return abort(403, __("You dont't have acccess this action"));
}
// check delete or destroy with bulk action
if (isset($requestPath[2]) && $requestPath[2] == 'bulk' && $request->input('bulk') == 'delete') {
$requestPath[2] = 'delete';
if (!auth()->user()->hasAccess(implode('.', $requestPath))) {
$requestPath[2] = 'destroy';
if (!auth()->user()->hasAccess(implode('.', $requestPath))) {
return abort(403, __("You dont't have acccess this action"));
}
}
}
}
}
return $next($request); return $next($request);
} }
} }

@ -105,4 +105,24 @@ class User extends Authenticatable
{ {
return $this->hasMany(AdminLog::class, 'user_id', 'id'); return $this->hasMany(AdminLog::class, 'user_id', 'id');
} }
public function accesses(){
return $this->hasMany(Access::class);
}
public function hasAnyAccess($name){
if ($this->hasRole('SUSPENDED')){
return false;
}
if ($this->hasRole('admin') || $this->hasRole('developer')) {
return true;
}
return $this->accesses()->where('route','LIKE','%.'.$name.'.%')->count() > 0;
}
public function hasAccess($route){
if ($this->hasRole('SUSPENDED')){
return false;
}
return $this->accesses()->where('route',$route)->count() > 0;
}
} }

@ -107,8 +107,90 @@
<label> &nbsp;</label> <label> &nbsp;</label>
<input name="" type="submit" class="btn btn-primary mt-2" value="{{__('Save')}}"/> <input name="" type="submit" class="btn btn-primary mt-2" value="{{__('Save')}}"/>
</div> </div>
@if(isset($item) && $item->hasRole('user'))
<div class="col-12">
<br>
<button class="btn btn-secondary" type="button"
data-bs-toggle="collapse" href="#collapseExample" role="button"
aria-expanded="false" aria-controls="collapseExample">
{{__("ACL")}}
({{$item->accesses()->count()}})
</button>
<div class="mt-2">
<div class="collapse" id="collapseExample">
<div class="card card-body">
@foreach($routes as $name => $route)
<div class="switches-holder">
<div class="rule-title">
<div class="form-check form-switch">
<input class="form-check-input main-switch" type="checkbox"
role="switch"
id="main{{$name}}">
<label class="form-check-label"
for="main{{$name}}"> {{__($name)}} </label>
</div>
</div>
<div class="row">
@foreach($route as $r)
<div class="col-md-3">
<div class="px-3 py-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox"
role="switch"
name="acl[]"
@if ($item->hasAccess("admin.{$name}.{$r}"))
checked
@endif
value="admin.{{$name}}.{{$r}}"
id="s{{$r}}">
<label class="form-check-label"
for="s{{$r}}">
@if($r == 'all' || $r == 'index' | $r == 'list')
{{__("Show list")}}
@else
{{__('!'.$r)}}
@endif
</label>
</div>
</div>
</div>
@endforeach
</div>
</div>
<hr>
@endforeach
</div>
</div>
</div>
<hr>
</div>
@endif
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@endsection @endsection
@section('js-content')
<script>
document.addEventListener('DOMContentLoaded',function () {
document.querySelectorAll('.main-switch').forEach(function (chk) {
chk.addEventListener('change', function () {
let state = this.checked;
this.closest('.switches-holder').querySelectorAll('.row input[type="checkbox"]').forEach(function (subCheck) {
subCheck.checked = state;
});
});
});
});
</script>
@endsection

Loading…
Cancel
Save