Permission.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. namespace Dcat\Admin\Middleware;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Auth\Permission as Checker;
  5. use Dcat\Admin\Support\Helper;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Support\Str;
  8. class Permission
  9. {
  10. /**
  11. * @var string
  12. */
  13. protected $middlewarePrefix = 'admin.permission:';
  14. /**
  15. * Handle an incoming request.
  16. *
  17. * @param \Illuminate\Http\Request $request
  18. * @param \Closure $next
  19. * @param array $args
  20. *
  21. * @return mixed
  22. */
  23. public function handle(Request $request, \Closure $next, ...$args)
  24. {
  25. $user = Admin::user();
  26. if (
  27. ! $user
  28. || ! empty($args)
  29. || ! config('admin.permission.enable')
  30. || $this->shouldPassThrough($request)
  31. || $user->isAdministrator()
  32. || $this->checkRoutePermission($request)
  33. ) {
  34. return $next($request);
  35. }
  36. if (! $user->allPermissions()->first(function ($permission) use ($request) {
  37. return $permission->shouldPassThrough($request);
  38. })) {
  39. Checker::error();
  40. }
  41. return $next($request);
  42. }
  43. /**
  44. * If the route of current request contains a middleware prefixed with 'admin.permission:',
  45. * then it has a manually set permission middleware, we need to handle it first.
  46. *
  47. * @param Request $request
  48. *
  49. * @return bool
  50. */
  51. public function checkRoutePermission(Request $request)
  52. {
  53. if (! $middleware = collect($request->route()->middleware())->first(function ($middleware) {
  54. return Str::startsWith($middleware, $this->middlewarePrefix);
  55. })) {
  56. return false;
  57. }
  58. $args = explode(',', str_replace($this->middlewarePrefix, '', $middleware));
  59. $method = array_shift($args);
  60. if (! method_exists(Checker::class, $method)) {
  61. throw new \InvalidArgumentException("Invalid permission method [$method].");
  62. }
  63. call_user_func_array([Checker::class, $method], [$args]);
  64. return true;
  65. }
  66. /**
  67. * @param \Illuminate\Http\Request $request
  68. *
  69. * @return bool
  70. */
  71. protected function isApiRoute($request)
  72. {
  73. return $request->routeIs('dcat.api.*');
  74. }
  75. /**
  76. * Determine if the request has a URI that should pass through verification.
  77. *
  78. * @param \Illuminate\Http\Request $request
  79. *
  80. * @return bool
  81. */
  82. protected function shouldPassThrough($request)
  83. {
  84. if ($this->isApiRoute($request)) {
  85. return true;
  86. }
  87. foreach (config('admin.permission.except', []) as $except) {
  88. $except = admin_base_path($except);
  89. if ($except !== '/') {
  90. $except = trim($except, '/');
  91. }
  92. if (Helper::matchRequestPath($except)) {
  93. return true;
  94. }
  95. }
  96. return false;
  97. }
  98. }