feat(panel-admin): RBAC com roles e policies no painel admin - #514
Draft
danielhe4rt wants to merge 3 commits into
Draft
feat(panel-admin): RBAC com roles e policies no painel admin#514danielhe4rt wants to merge 3 commits into
danielhe4rt wants to merge 3 commits into
Conversation
Publishes spatie/laravel-permission and moves its migration into the identity module, where the ServiceProvider already loads migrations from. Two fixes the published stub needs in this project: - model_morph_key was unsignedBigInteger, which cannot hold the UUID primary key our User model uses. Assigning a role would have failed at insert time, not at migrate time. - timestamps() becomes timestampsTz(), as every date column in this project must be timezone aware. Adds the HasRoles trait to User so the schema can be exercised. The rest of the authorization rework (dropping isAdmin, gating canAccessPanel) lands in a later commit.
Replaces the username allowlist with real authorization. Panel access now means holding a role, and each of the 15 resources is governed by a policy generated from Shield. Shield needed three accommodations for this repository: - It reads only the root composer.json when resolving PSR-4, so the He4rt\PanelAdmin namespace is declared there for it to find. - It rejects the '_' separator alongside snake case, so the config carries a placeholder separator and a custom builder joins the parts. - It only looks for a sibling "Policies" directory when a model lives under "Models", which would scatter panel policies across the domain modules. The policies live in this module and are bound to their models here. isAdmin() is gone, along with the he4rt.admins config it read. The Telescope gate now asks for the super_admin role. Tests that relied on the allowlist build a real role instead. Two helpers carry that: panelUserWith() for specific permissions and panelAdminUser() for the super admin. Also disables the Cloudflare proxy lookup under phpunit: it fetches over HTTP and caches forever, so a cold cache turned every routed test into a 500 once stray requests are banned.
Registering the policies inside Filament::serving() only bound them during an HTTP request. A Livewire component exercised directly — which is how most panel tests drive it — ran with no policy at all, so a user carrying a moderation permission could open a marketing page and get a 200. Gate::guessPolicyNamesUsing() resolves them in every context. The callback returns the framework's own default alongside ours, and the Gate discards whichever does not exist. Adds the pair that would have caught this: the same wrong-area check over both a Livewire component and an HTTP route.
Contributor
|
@danielhe4rt Poderia me passar como está o andamento dessa issue? Se ainda fará algo com ela, ou se é somente revisão mesmo? Pois com suas alterações e preciso esperar para finalizar o pr #487 que tinha coisas referente a essas politicas. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contexto
O acesso ao painel admin era decidido por uma lista de usernames em
config/he4rt.php. Quem estava na lista via tudo; quem não estava não via nada. Não havia meio-termo — nenhuma forma de dar a um moderador acesso só à moderação, ou a um responsável por marketing acesso só ao encurtador.Este PR troca o allowlist por autorização de verdade:
spatie/laravel-permissionpara o schema de roles/permissions efilament-shieldpara gerar as permissions a partir dos recursos do painel. Acessar o painel passa a significar possuir um role, e cada um dos 15 recursos é governado por uma policy.Ainda é draft — o fluxo está funcional, mas faltam as pontas descritas em Pendências antes de mergear.
Alterações
identity— publica a migration dospatie/laravel-permissiondentro do módulo, com dois ajustes que o stub publicado exige aqui:model_morph_keyvira UUID (oUserusa UUID como PK, então atribuir role falharia no insert, não no migrate) etimestamps()viratimestampsTz(). AdicionaHasRolesaoUser.panel-admin— 15 policies geradas pelo Shield, uma por recurso. Elas vivem no módulo de apresentação, não ao lado de cada model de domínio, porque autorizar uma tela é uma preocupação de apresentação.Gate::guessPolicyNamesUsing()— registrar dentro deFilament::serving()só resolvia as policies durante um request HTTP. Um componente Livewire exercitado diretamente rodava sem policy nenhuma, então um usuário com permissão de moderação abria uma página de marketing e recebia 200.composer.jsonda raiz ao resolver PSR-4 (daí a declaração do namespaceHe4rt\PanelAdminlá); ele rejeita o separador_junto de snake case (daí o separador placeholder na config e o builder próprio); e ele só procura um diretórioPoliciesirmão quando o model está sobModels.isAdmin()removido. O gate do Telescope agora pede o rolesuper_admin.tests/Pest.phpcarregam isso:panelUserWith()para permissions específicas epanelAdminUser()para o super admin. Novos:PermissionTablesTest,PolicyCoverageTesteAreaIsolationTest(este último cobrindo tanto componente Livewire quanto rota HTTP).Plano de Testes
make checkmake test/adminsuper_adminacessa todos os 15 recursos e o TelescopePendências antes de sair do draft
super_admine o atribua a alguém. O allowlist era o que cumpria esse papel; nada tomou o lugar dele, então após o deploy ninguém entra no painel.NavigationBuilder, edefaultNavigation()não inclui os itens doRoleResourcedo Shield. A rota existe, o link não.UserResourcenopanel-admin. Dá para criar roles no Shield, mas o vínculo user↔role só via tinker. Candidato a PR separado.config/he4rt.phpainda carrega'admins' => env('HE4RT_ADMINS_USERNAMES', ...), que já não é lido por nada.docs/admin/en/users/authentication.mderoles.md.Issues Relacionadas