CluPilotCloud/tests/Feature/PasswordPolicyTest.php

96 lines
3.4 KiB
PHP

<?php
use App\Livewire\Auth\ResetPassword;
use App\Models\User;
use App\Support\PasswordPolicy;
use App\Support\Settings;
use Illuminate\Support\Facades\Password as PasswordBroker;
use Livewire\Livewire;
/**
* Diese Installation hatte DREI Passwortregeln nebeneinander und keine davon
* einstellbar:
*
* App\Livewire\Auth\ResetPassword `min:12`, fest im Attribut
* App\Console\Commands\CreateAdmin Password::min(12)
* PasswordValidationRules Password::default() — also Laravels 8
*
* Ein Kunde, der sein Passwort zurücksetzte, musste zwölf Zeichen nehmen;
* derselbe Kunde bei der Registrierung acht. Gemeldet wurde die Zwölf, und beim
* Nachsehen war die eigentliche Auffälligkeit, dass es die Regel dreimal gibt.
*/
beforeEach(function () {
Settings::forget(PasswordPolicy::SETTING);
});
it('starts at six characters', function () {
expect(PasswordPolicy::minLength())->toBe(6);
});
it('lets the console set the length, within a floor and a ceiling', function () {
PasswordPolicy::set(10);
expect(PasswordPolicy::minLength())->toBe(10);
// Unterhalb der Grenze wird geklemmt, nicht abgelehnt: der Wert kommt aus
// einem Formular, und eine stillschweigend gespeicherte 1 wäre schlimmer
// als eine sichtbar geklemmte 6.
PasswordPolicy::set(2);
expect(PasswordPolicy::minLength())->toBe(PasswordPolicy::FLOOR);
PasswordPolicy::set(9999);
expect(PasswordPolicy::minLength())->toBe(PasswordPolicy::CEILING);
});
it('accepts a six-character password when resetting', function () {
// Der gemeldete Fall. Vorher: `min:12`, fest verdrahtet.
$user = User::factory()->create(['email' => 'kunde@example.test']);
$token = PasswordBroker::broker()->createToken($user);
Livewire::test(ResetPassword::class, ['token' => $token])
->set('email', $user->email)
->set('password', 'abcdef')
->set('password_confirmation', 'abcdef')
->call('save')
->assertHasNoErrors();
expect($user->fresh()->password)->not->toBe($user->password);
});
it('follows the configured length instead of a number of its own', function () {
PasswordPolicy::set(10);
$user = User::factory()->create(['email' => 'kunde@example.test']);
$token = PasswordBroker::broker()->createToken($user);
Livewire::test(ResetPassword::class, ['token' => $token])
->set('email', $user->email)
->set('password', 'abcdefgh')
->set('password_confirmation', 'abcdefgh')
->call('save')
->assertHasErrors('password');
});
it('keeps the rule in one place', function () {
// Der eigentliche Fund: drei Regeln nebeneinander. Ein Wächter, damit die
// vierte nicht danebengeschrieben wird.
$offenders = [];
foreach (['app/Livewire', 'app/Actions', 'app/Console/Commands', 'app/Http'] as $dir) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(base_path($dir)));
foreach ($files as $file) {
if ($file->getExtension() !== 'php') {
continue;
}
$body = file_get_contents($file->getPathname());
if (preg_match('/min:\d+\|confirmed|Password::min\(|Password::default\(\)/', $body)) {
$offenders[] = str_replace(base_path().'/', '', $file->getPathname());
}
}
}
expect($offenders)->toBe([], 'Passwortlänge gehört in App\Support\PasswordPolicy, nicht hierhin: '.implode(', ', $offenders));
});