Get PhpUnit code coverage back

14 March 2021

Since I upgraded to laravel 8, my usual phpunit setup greated me with a

PHPUnit 9.5.2 by Sebastian Bergmann and contributors.

  Warning - The configuration file did not pass validation!
  The following problems have been detected:

  Line 35:
  - Element 'log': This element is not expected.

  Test results may not be as expected.

I m used to have a beautiful little html web site that show me the code coverage with:

<logging>
    <log type="coverage-html" target="tests/code-coverage/" lowUpperBound="35" highLowerBound="70" />
</logging>

But it doesn’t work anymore, you need to use the <coverage> node:

<coverage processUncoveredFiles="true">
    <include>
        <directory suffix=".php">./app</directory>
    </include>
    <report>
        <html outputDirectory="html-coverage" lowUpperBound="50" highLowerBound="90"/>
    </report>
</coverage>

Utiliser la session Laravel avec les route/api

17 December 2019

Je cherchais une solution pour utiliser les routes api de Laravel avec la session web classique. Installer Passport est complexe et souvent inutile pour pas mal de projet. Il existe la solution de passer par un champ api_token dans la base de donnée, mais niveau sécurité, je trouve cela moyen.

Cependant, il est possible d’utiliser le driver de session classique :

Dans config/auth.php, il faut modifier les guards pour replacer token par session en dessous d’API :

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'session',
        'provider' => 'users',
        'hash' => false,
    ],
],

Ensuite dans app/Http/Kernel.php, il faut modifier le middlewareGroups « api » :

'api' => [
    'throttle:60,1',
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Session\Middleware\StartSession::class,
    'bindings',
],

Tester avec un projet Laravel 6 sans soucis !


Laravel : utiliser un trait php pour purifier le HTML d'un champ

12 February 2019

Lorsque l’ont stock du HTML dans le champ d’une base de donnée, il ne faut jamais le stocker sans le filtrer. C’est une mauvaise pratique bien connue, cela attire les failles XSS et personne n’aime en avoir.

Bref, voici une méthode sympa pour protéger un champ.

Dans un premier temps il faut installer HTMLPurifier :

composer require ezyang/htmlpurifier

Cette librairie permet de filtrer le html correctement. N’utilisez pas strip_tags, cette fonction n’est pas faite pour la sécurité.

Ma base de donnée contient assez bien de champs “description”, ils risquent tous de contenir du HTML, car ils sont remplis par un [CKeditor->https://ckeditor.com/].

Cela affecte tous ces champs, j’ai envie de les protéger facilement. J’ai donc créé un fichier ./app/traits/purify.php.

On va mixer le pouvoir des [mutators de Laravel->https://laravel.com/docs/5.7/eloquent-mutators#defining-a-mutator] et

<?php

namespace App;

use HTMLPurifier_Config;
use HTMLPurifier;

trait Purify
{
    /**
     * @property $allowed allowed html inside description field
     */
    private $allowed = 'p, strong, h2, h3, a[href], ul, ol, li, i';

    /**
     * Laravel mutator.
     * Filter all unauthorized HTML from the description field
     * @param $value
     */
    public function setDescriptionAttribute($value)
    {
        $config = HTMLPurifier_Config::createDefault();
        $config->set('HTML.Allowed', $this->allowed);
        $purifier = new HTMLPurifier($config);
        $this->attributes['description'] = $purifier->purify($value);
    }
}

Il suffit alors d’utiliser ce trait dans un modèle Laravel pour que les champs description soit automatiquement filtrés avant d’être insérés dans la base de donnée !

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class MyModel extends Model
{
    use Purify;
}

Laravel et PHP sont des outils vraiment formidables quand on comprend ce genre d’astuce !