whilesmart/eloquent-owner-access
Composer 安装命令:
composer require whilesmart/eloquent-owner-access
包简介
Pluggable polymorphic owner authorization for Laravel packages with owner_type/owner_id columns. Lets host apps decide who can see and modify owner-scoped records without coupling the underlying packages to a specific tenancy model.
README 文档
README
Pluggable polymorphic owner authorization for Laravel packages with owner_type / owner_id columns.
Domain packages (accounts, expenses, payments, invoices, products, customers, ...) expose CRUD endpoints scoped by a polymorphic owner. They should not have to know how the host app decides who owns what. This package gives them a single contract to consult and a default that preserves existing "trust the client" behavior, so adoption is incremental and safe.
Concept
One contract:
interface OwnerAuthorizer { public function authorize(?Authenticatable $user, string $ownerType, mixed $ownerId): bool; public function scope( Builder $query, ?Authenticatable $user, string $ownerTypeColumn = 'owner_type', string $ownerIdColumn = 'owner_id', ): Builder; }
authorize() is per-record (called from FormRequest::authorize() for store/update and from controllers for show/destroy). scope() constrains index queries.
The default binding is AllowAllAuthorizer (everything goes through). Hosts that want strict tenancy bind their own implementation.
Installation
composer require whilesmart/eloquent-owner-access
The service provider auto-registers via Laravel package discovery and bindIfs the default authorizer.
Usage in a package
In a StoreXRequest:
use Whilesmart\OwnerAccess\Concerns\AuthorizesOwnerRequest; class StoreAccountRequest extends FormRequest { use AuthorizesOwnerRequest; public function authorize(): bool { return $this->authorizeOwnerInRequest(); } public function rules(): array { /* ... */ } }
In an UpdateXRequest:
public function authorize(): bool { return $this->authorizeOwnerOfBoundModel('account'); }
In the controller:
use Whilesmart\OwnerAccess\Concerns\AuthorizesOwnerController; class AccountController extends Controller { use AuthorizesOwnerController; public function index(Request $request) { $query = Account::query(); $query = $this->scopeAccessibleOwners($query, $request->user()); // ... } public function show(Account $account, Request $request) { $this->authorizeAccessTo($account, $request->user()); // ... } public function destroy(Account $account, Request $request) { $this->authorizeAccessTo($account, $request->user()); $account->delete(); // ... } }
Update is already covered by UpdateXRequest::authorize(), so no controller change is needed there.
Usage in a host app
By default everything is allowed. To enforce tenancy, write an authorizer that consults your tenancy model and bind it:
namespace App\Authorization; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Database\Eloquent\Builder; use Whilesmart\OwnerAccess\Contracts\OwnerAuthorizer; class WorkspaceMemberAuthorizer implements OwnerAuthorizer { public function authorize(?Authenticatable $user, string $ownerType, mixed $ownerId): bool { if ($user === null || $ownerType !== \App\Models\Workspace::class) { return false; } return $user->workspaces()->whereKey($ownerId)->exists(); } public function scope(Builder $query, ?Authenticatable $user, string $ownerTypeColumn = 'owner_type', string $ownerIdColumn = 'owner_id'): Builder { if ($user === null) { return $query->whereRaw('0 = 1'); } return $query->where($ownerTypeColumn, \App\Models\Workspace::class) ->whereIn($ownerIdColumn, $user->workspaces()->pluck('workspaces.id')); } }
Then in AppServiceProvider::register():
$this->app->bind( \Whilesmart\OwnerAccess\Contracts\OwnerAuthorizer::class, \App\Authorization\WorkspaceMemberAuthorizer::class, );
That single binding switches every consuming package over to strict mode at once.
Backwards compatibility
The provider uses bindIf, so any explicit binding the host registers (before or after) wins. Without an explicit binding, the default AllowAllAuthorizer keeps current behavior.
Testing
composer test
License
MIT.
统计信息
- 总下载量: 35
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 8
- 依赖项目数: 5
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-25