Preserva base local aceite de identidade e acessos

This commit is contained in:
Codex
2026-10-25 21:29:22 +02:00
commit 26b80df545
112 changed files with 13259 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Shared\Context;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
trait BelongsToCompany
{
protected static function bootBelongsToCompany(): void
{
static::addGlobalScope('company', function (Builder $query): void {
foreach (app(CompanyContext::class)->identifiers() as $column => $value) {
$query->where($query->getModel()->qualifyColumn($column), $value);
}
});
static::saving(function (Model $model): void {
foreach (app(CompanyContext::class)->identifiers() as $column => $value) {
if ($model->getAttribute($column) !== null && (int) $model->getAttribute($column) !== $value) {
throw new AccessDeniedHttpException('Contexto de empresa incompatível.');
}
$model->setAttribute($column, $value);
}
});
static::deleting(function (Model $model): void {
foreach (app(CompanyContext::class)->identifiers() as $column => $value) {
if ((int) $model->getAttribute($column) !== $value) {
throw new AccessDeniedHttpException('Contexto de empresa incompatível.');
}
}
});
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace App\Shared\Context;
use App\Modules\Identity\Models\Company;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use App\Modules\Identity\Services\Permissions;
final class CompanyContext
{
private ?array $identifiers = null;
private ?int $userId = null;
private ?int $unitId = null;
public function selectFor(int $userId, int $tenantId, int $companyId, ?int $unitId = null): void
{
$this->clear();
$allowed = DB::table('company_memberships')
->where('user_id', $userId)->where('tenant_id', $tenantId)
->where('company_id', $companyId)->exists();
if (! $allowed || ! Company::query()->where('tenant_id', $tenantId)->whereKey($companyId)->exists()) {
throw new AccessDeniedHttpException('Empresa não autorizada.');
}
app(Permissions::class)->require($userId, $tenantId, $companyId, 'company.view');
if ($unitId !== null) {
app(Permissions::class)->require($userId, $tenantId, $companyId, 'unit.view', $unitId);
abort_unless(DB::table('units')->where('tenant_id', $tenantId)->where('company_id', $companyId)->where('id', $unitId)->exists(), 403);
}
$this->identifiers = ['tenant_id' => $tenantId, 'company_id' => $companyId];
$this->userId = $userId;
$this->unitId = $unitId;
}
public function identifiers(): array
{
return $this->identifiers ?? throw new AccessDeniedHttpException('Contexto de empresa obrigatório.');
}
public function clear(): void
{
$this->identifiers = null;
$this->userId = null;
$this->unitId = null;
}
public function userId(): int { $this->identifiers(); return $this->userId; }
public function unitId(): ?int { $this->identifiers(); return $this->unitId; }
public function permittedUnitIds(): array
{
$ids = $this->identifiers();
return app(Permissions::class)->unitIds($this->userId(), $ids['tenant_id'], $ids['company_id']);
}
}