Permission.php 3.2 KB

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