Added `ProviderResourceBinding` model, migrations, policies, and supporting framework for canonical resource identity mapping as defined in Spec 381. This provides the structural capability to resolve baseline and posture discrepancies by binding logical entities across source providers to canonical identities. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #452
100 lines
3.0 KiB
PHP
100 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Policies;
|
|
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\ProviderResourceBinding;
|
|
use App\Models\User;
|
|
use App\Services\Auth\ManagedEnvironmentAccessScopeResolver;
|
|
use App\Support\Auth\Capabilities;
|
|
use Illuminate\Auth\Access\HandlesAuthorization;
|
|
use Illuminate\Auth\Access\Response;
|
|
|
|
class ProviderResourceBindingPolicy
|
|
{
|
|
use HandlesAuthorization;
|
|
|
|
public function view(User $user, ProviderResourceBinding $binding): Response
|
|
{
|
|
$tenant = $this->tenantForBinding($binding);
|
|
|
|
if (! $tenant instanceof ManagedEnvironment) {
|
|
return Response::denyAsNotFound();
|
|
}
|
|
|
|
if ((int) $binding->workspace_id !== (int) $tenant->workspace_id) {
|
|
return Response::denyAsNotFound();
|
|
}
|
|
|
|
return $this->authorizeEnvironment($user, $tenant, Capabilities::WORKSPACE_BASELINES_VIEW);
|
|
}
|
|
|
|
public function createForEnvironment(User $user, ManagedEnvironment $tenant): Response
|
|
{
|
|
return $this->authorizeEnvironment($user, $tenant, Capabilities::WORKSPACE_BASELINES_MANAGE);
|
|
}
|
|
|
|
public function update(User $user, ProviderResourceBinding $binding): Response
|
|
{
|
|
return $this->manage($user, $binding);
|
|
}
|
|
|
|
public function revoke(User $user, ProviderResourceBinding $binding): Response
|
|
{
|
|
return $this->manage($user, $binding);
|
|
}
|
|
|
|
public function delete(User $user, ProviderResourceBinding $binding): Response
|
|
{
|
|
return $this->manage($user, $binding);
|
|
}
|
|
|
|
private function manage(User $user, ProviderResourceBinding $binding): Response
|
|
{
|
|
$tenant = $this->tenantForBinding($binding);
|
|
|
|
if (! $tenant instanceof ManagedEnvironment) {
|
|
return Response::denyAsNotFound();
|
|
}
|
|
|
|
if ((int) $binding->workspace_id !== (int) $tenant->workspace_id) {
|
|
return Response::denyAsNotFound();
|
|
}
|
|
|
|
return $this->authorizeEnvironment($user, $tenant, Capabilities::WORKSPACE_BASELINES_MANAGE);
|
|
}
|
|
|
|
private function authorizeEnvironment(User $user, ManagedEnvironment $tenant, string $capability): Response
|
|
{
|
|
$decision = app(ManagedEnvironmentAccessScopeResolver::class)->decision($user, $tenant, $capability);
|
|
|
|
if (! $decision->workspaceMember || ! $decision->managedEnvironmentAllowed) {
|
|
return Response::denyAsNotFound();
|
|
}
|
|
|
|
if (! $decision->capabilityAllowed) {
|
|
return Response::denyWithStatus(403, 'Missing required baseline capability.');
|
|
}
|
|
|
|
return Response::allow();
|
|
}
|
|
|
|
private function tenantForBinding(ProviderResourceBinding $binding): ?ManagedEnvironment
|
|
{
|
|
if ($binding->relationLoaded('tenant') && $binding->tenant instanceof ManagedEnvironment) {
|
|
return $binding->tenant;
|
|
}
|
|
|
|
if (! is_numeric($binding->managed_environment_id)) {
|
|
return null;
|
|
}
|
|
|
|
return ManagedEnvironment::query()
|
|
->withTrashed()
|
|
->whereKey((int) $binding->managed_environment_id)
|
|
->first();
|
|
}
|
|
}
|