CdmsPermissions.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. namespace App\Models;
  3. use Encore\Admin\Traits\DefaultDatetimeFormat;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Support\Str;
  8. class CdmsPermissions extends Model
  9. {
  10. use DefaultDatetimeFormat;
  11. /**
  12. * @var array
  13. */
  14. protected $fillable = ['name', 'slug', 'http_method', 'http_path'];
  15. /**
  16. * @var array
  17. */
  18. public static $httpMethods = [
  19. 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD',
  20. ];
  21. /**
  22. * Create a new Eloquent model instance.
  23. *
  24. * @param array $attributes
  25. */
  26. public function __construct(array $attributes = [])
  27. {
  28. $connection = config('tenancy.database.connection') ?: config('database.default');
  29. $this->setConnection($connection);
  30. $this->setTable(config('tenancy.database.permissions_table'));
  31. parent::__construct($attributes);
  32. }
  33. /**
  34. * Permission belongs to many roles.
  35. *
  36. * @return BelongsToMany
  37. */
  38. public function roles(): BelongsToMany
  39. {
  40. $pivotTable = config('tenancy.database.role_permissions_table');
  41. $relatedModel = config('tenancy.database.roles_model');
  42. return $this->belongsToMany($relatedModel, $pivotTable, 'permission_id', 'role_id');
  43. }
  44. /**
  45. * If request should pass through the current permission.
  46. *
  47. * @param Request $request
  48. *
  49. * @return bool
  50. */
  51. public function shouldPassThrough(Request $request): bool
  52. {
  53. if (empty($this->http_method) && empty($this->http_path)) {
  54. return true;
  55. }
  56. $method = $this->http_method;
  57. $matches = array_map(function ($path) use ($method) {
  58. $path = trim(config('tenancy.route.prefix'), '/').$path;
  59. if (Str::contains($path, ':')) {
  60. list($method, $path) = explode(':', $path);
  61. $method = explode(',', $method);
  62. }
  63. return compact('method', 'path');
  64. }, explode("\n", $this->http_path));
  65. foreach ($matches as $match) {
  66. if ($this->matchRequest($match, $request)) {
  67. return true;
  68. }
  69. }
  70. return false;
  71. }
  72. /**
  73. * filter \r.
  74. *
  75. * @param string $path
  76. *
  77. * @return mixed
  78. */
  79. public function getHttpPathAttribute($path)
  80. {
  81. return str_replace("\r\n", "\n", $path);
  82. }
  83. /**
  84. * If a request match the specific HTTP method and path.
  85. *
  86. * @param array $match
  87. * @param Request $request
  88. *
  89. * @return bool
  90. */
  91. protected function matchRequest(array $match, Request $request): bool
  92. {
  93. if ($match['path'] == '/') {
  94. $path = '/';
  95. } else {
  96. $path = trim($match['path'], '/');
  97. }
  98. if (!$request->is($path)) {
  99. return false;
  100. }
  101. $method = collect($match['method'])->filter()->map(function ($method) {
  102. return strtoupper($method);
  103. });
  104. return $method->isEmpty() || $method->contains($request->method());
  105. }
  106. /**
  107. * @param $method
  108. */
  109. public function setHttpMethodAttribute($method)
  110. {
  111. if (is_array($method)) {
  112. $this->attributes['http_method'] = implode(',', $method);
  113. }
  114. }
  115. /**
  116. * @param $method
  117. *
  118. * @return array
  119. */
  120. public function getHttpMethodAttribute($method)
  121. {
  122. if (is_string($method)) {
  123. return array_filter(explode(',', $method));
  124. }
  125. return $method;
  126. }
  127. /**
  128. * Detach models from the relationship.
  129. *
  130. * @return void
  131. */
  132. protected static function boot()
  133. {
  134. parent::boot();
  135. static::deleting(function ($model) {
  136. $model->roles()->detach();
  137. });
  138. }
  139. }