Introducción

1

Desarrollo de Aplicaciones en Laravel con TDD y PHP Unit

2

Desarrollo de Proyectos con TDD en Laravel y Testing PHP

Proyecto

3

Instalación y configuración inicial de proyectos en Laravel

4

Configuración de Relaciones y Pruebas Unitarias en Laravel

5

Configuración de Relaciones en Laravel usando Testing

6

Protección de Rutas en Laravel con Middleware de Autenticación

7

Pruebas Automatizadas para Registro y Redirección en Base de Datos

8

Configuración de Actualización de Registros con Pruebas en PHP

9

Validación de Datos en Controladores: Configuración y Pruebas

10

Eliminación de Registros en Base de Datos con PHP y Tests

Póliticas de Acceso

11

Configuración de Políticas de Acceso en Repositorios

12

Políticas de Acceso y Eliminación de Repositorios en PHP

13

Configuración de Acceso a Repositorios Propios en Aplicaciones Web

14

Configuración del Método Show en Controladores PHP

Vistas del proyecto

15

Formulario de Edición con Diseño y Tests en Laravel

16

Testing de Formularios en PHP: Creación y Validación de Vistas

17

Configuración de Controladores y Vistas en Laravel para el Área Pública

18

Diseño Web con Tailwind CSS: Mejora de Apariencia y Formato

19

Pruebas y Configuración de Seeders en Proyectos Laravel

Refactorización

20

Refactorización de Código con Validación en PHP

21

Refactorización de Políticas de Acceso en Laravel

22

Configuración de Botones para Repositorios en Proyectos Web

Conclusión

23

Importancia de las Pruebas en Desarrollo de Software

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Refactorización de Políticas de Acceso en Laravel

21/23
Recursos

¿Cómo mejorar el código en la fase de refactorización?

La refactorización es una etapa crucial dentro del ciclo de desarrollo de software, especialmente cuando aplicamos el desarrollo guiado por pruebas (TDD). En este proceso, después de confirmar que las pruebas pasan con éxito, tenemos la oportunidad de optimizar nuestro código para hacerlo más legible y mantenible. Durante esta clase, nos enfocamos en las políticas de acceso y cómo implementarlas eficazmente en Laravel para mejorar nuestro código, simplificar la lógica y asegurar que el código continúe funcionando correctamente después de los cambios.

¿Qué es la creación de políticas en Laravel?

Para empezar con la refactorización en Laravel, creamos una política utilizando el comando phpArtisan de la siguiente manera:

php artisan make:policy NombreDeLaPolitica

Se recomienda terminar el nombre con el sufijo "Policy" para mantener una convención estándar. Crear políticas nos permite encapsular condiciones que podemos reutilizar en distintas partes de nuestra aplicación.

¿Cómo se aplica la política de manera efectiva en el controlador?

Una vez creada la política, la siguiente labor es configurarla adecuadamente en el controlador:

  1. Registrar la política: La política debe ser registrada en el AuthServiceProvider de Laravel para que el framework la reconozca y pueda aplicarla.

  2. Ajustar el controlador: Empezamos por reemplazar las comprobaciones condicionales con llamadas al método authorize, que aprovechará la lógica definida en la política. Esto no solo simplifica el código, sino que también mejora su legibilidad.

    $this->authorize('pass', $recurso);
    
  3. Eliminar el uso redundante de Request: Al cambiar la forma de acceder a la información del usuario, podemos eliminar la dependencia directa del objeto Request, reduciendo la complejidad y mejorando la eficiencia del código.

¿Qué errores pueden surgir y cómo solucionarlos?

Durante el proceso de refactorización, es esencial ejecutar tests para garantizar que el sistema sigue funcionando como se espera. Si al realizar cambios, alguno de los tests falla, es necesario revisitar el código, identificar errores o inconsistencias y corregirlos antes de avanzar.

Los tests nos indican que un cambio no ha impactado negativamente en el sistema:

  • Verifica errores de clase faltante: Si intentas usar una clase que no existe o no está correctamente importada, se mostrarán errores. Asegúrate de que todas las clases estén correctamente declaradas e importadas.

  • Mantén las configuraciones: Al unir modelos a políticas en el AuthServiceProvider, asegúrate de seguir correctamente el ejemplo proporcionado y descomentar las líneas de ejemplo si es necesario.

¿Por qué es crucial tener tests?

El testing es una herramienta invaluable cuando se hacen cambios extensos en la base de código. Los tests permiten:

  • Detectar de inmediato errores introducidos durante la refactorización.
  • Avanzar con confianza en la implementación de nuevas características o en la presentación de un proyecto, ya que sabes que las bases del código están bien probadas y son fiables.

Al realizar el ejercicio de refactorización y testing, podrás avanzar al siguiente nivel con seguridad. La refactorización no solo mantiene el código limpio y eficiente, sino que asegura que el desarrollo sea sostenible a largo plazo.

Aportes 8

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

php artisan make:policy RepositoryPolicy
php artisan test

Modificaciones:

  • app/Http/Controllers/RepositoryController.php
  • app/Policies/RepositoryPolicy.php
  • app/Providers/AuthServiceProvider.php
En la versión más reciente de Laravel, específicamente Laravel 11.10.0., ha habido algunos cambios significativos en la estructura y la configuración del framework. Uno de esos cambios incluye la forma en que se maneja la autenticación y la autorización. Les comparto como lo realice por si alguno se encuentra en el mismo punto que yo.\ auth()->user()->repositories        ]);    }     public function show(Repository $repository)    {        *$this*->authorize('pass', $repository);         *return* view('repositories.show', compact('repository'));    }     public function create()    {        *return* view('repositories.create');    }     public function store(RepositoryRequest $request)    {        $request->user()->repositories()->create($request->all());         *return* redirect()->route('repositories.index');    }     public function edit(Repository $repository)    {        *$this*->authorize('pass', $repository);         *return* view('repositories.edit', compact('repository'));    }     public function update(RepositoryRequest $request, Repository $repository)    {        *$this*->authorize('pass', $repository);         $repository->update($request->all());         *return* redirect()->route('repositories.edit', $repository);    }     public function destroy(Repository $repository)    {        *$this*->authorize('pass', $repository);         $repository->delete();         *return* redirect()->route('repositories.index');    }} namespace App\Providers; use Illuminate\Support\ServiceProvider;use Illuminate\Support\Facades\Gate;use App\Models\Repository;use App\Policies\RepositoryPolicy; class AppServiceProvider extends ServiceProvider{    */\*\*     \* Register any application services.     \*/*    public function register(): void    {        *//*    }     */\*\*     \* Bootstrap any application services.     \*/*    public function boot(): void    {        *// Registrar la política para el modelo Repository*        Gate::policy(Repository::class, RepositoryPolicy::class);    }} namespace App\Policies; use App\Models\Repository;use App\Models\User;use Illuminate\Auth\Access\HandlesAuthorization; class RepositoryPolicy{    use HandlesAuthorization;     */\*\*     \* Determine if the given repository can be accessed by the user.     \*     \* @param  \App\Models\User  $user     \* @param  \App\Models\Repository  $repository     \* @return bool     \*/*    public function pass(User $user, Repository $repository)    {        *// Define tu lógica de autorización aquí*        *return* $user->id === $repository->user\_id;    }} Despues de que crees RepositoryPolicy.php debes de realizar algunas importanciones, quedaría asi el archivo final: ```js id === $repository->user_id; } } ```Luego en el AppServiceProvider.php debes manejar otras importaciones y Registrar la política para el modelo Repository: ```js auth()->user()->repositories ]); } public function show(Repository $repository) { $this->authorize('pass', $repository); return view('repositories.show', compact('repository')); } public function create() { return view('repositories.create'); } public function store(RepositoryRequest $request) { $request->user()->repositories()->create($request->all()); return redirect()->route('repositories.index'); } public function edit(Repository $repository) { $this->authorize('pass', $repository); return view('repositories.edit', compact('repository')); } public function update(RepositoryRequest $request, Repository $repository) { $this->authorize('pass', $repository); $repository->update($request->all()); return redirect()->route('repositories.edit', $repository); } public function destroy(Repository $repository) { $this->authorize('pass', $repository); $repository->delete(); return redirect()->route('repositories.index'); } } ```Espero haber ayudado en este paso.

Se pudiera utilizar owner en lugar de pass creo que seria un nombre más explicito para nuestra policy

Para Agosto 2024 hay CAMBIOS importantes para (jugar) con los permisos. Se introdujo el concepto de GATES y se mantiene POLICIES. **Una Policy sigue usandose para dar permisos a los metodos del controlador.** Ahora se **registra** asi, pero dentro de AppServiceProvider: ```js public function boot(): void { Gate::policy(Repository::class, RepositoryPolicy::class); } ``` Y dentro del controlador se usa asi: ```js public function edit(Repository $repository) { Gate::authorize('pass', $repository); return view('repositories.edit', compact('repository')); } ```

Muy interesante…excelente curso. Aunque tengo mucho tiempo trabajando con Laravel, sabia que existian las Policies pero nunca las habia usado…me gusto muchisimo y efectivamente ayuda a que el codigo sea mas limpio…Laravel es quizas el framework de desarrollo web mas completo…al menos de php…

Les dejo mi commit de la clase
https://github.com/jlbousing/practica-tdd/commit/6f7f881171a8fc812151cf2483a7b6b0e378b417

Para Laravel 11 deben agregar el trait ** AuthorizesRequests*.* Queda de esta forma ```js namespace App\Http\Controllers; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; class RepositoryController extends Controller { use AuthorizesRequests; ```*use* Illuminate\Foundation\Auth\Access\AuthorizesRequests;
La autorización de las politicas se puede hacer directamente desde el formRequest para dejar aun mas limpio el controlador: Acá un ejemplo donde dependiendo de si vamos a actualizar o a crear le paso diferentes valores, pero podria ser tranquilamente una sola condición como en la clase: ```js public function authorize(): bool { $response = false; switch ($this->method()) { case 'PUT': $response = $this->user()->can("update", $this->repository); break; case 'POST': $response = $this->user()->can("create", Repository::class); break; default: $response = false; break; } return $response; ; } ```Lo hice de esta manera porque para crear le voy a pedir solamente que este logueado, pero para actualizar debe ser el dueño de el repositorio.