Move api key reset to authenticator, set api_key on registration

This commit is contained in:
Igor Scheller 2023-11-15 18:33:34 +01:00 committed by Michael Weimann
parent 0dbf88ad1c
commit f826cee63c
8 changed files with 43 additions and 25 deletions

View File

@ -234,7 +234,7 @@ function user_controller()
} }
if (empty($user_source->api_key)) { if (empty($user_source->api_key)) {
User_reset_api_key($user_source, false); auth()->resetApiKey($user_source);
} }
if ($user_source->state->force_active) { if ($user_source->state->force_active) {

View File

@ -137,22 +137,6 @@ function User_validate_planned_departure_date($planned_arrival_date, $planned_de
return new ValidationResult(true, $planned_departure_date); return new ValidationResult(true, $planned_departure_date);
} }
/**
* Generates a new api key for given user.
*
* @param User $user
* @param bool $log
*/
function User_reset_api_key($user, $log = true)
{
$user->api_key = bin2hex(random_bytes(32));
$user->save();
if ($log) {
engelsystem_log(sprintf('API key resetted (%s).', User_Nick_render($user, true)));
}
}
/** /**
* @param User $user * @param User $user
* @return float * @return float

View File

@ -35,7 +35,8 @@ function user_myshifts()
$shifts_user = User::find($shift_entry_id); $shifts_user = User::find($shift_entry_id);
if ($request->has('reset')) { if ($request->has('reset')) {
if ($request->input('reset') == 'ack') { if ($request->input('reset') == 'ack') {
User_reset_api_key($user); auth()->resetApiKey($user);
engelsystem_log(sprintf('API key resetted (%s).', User_Nick_render($user, true)));
success(__('Key changed.')); success(__('Key changed.'));
throw_redirect(url('/users', ['action' => 'view', 'user_id' => $shifts_user->id])); throw_redirect(url('/users', ['action' => 'view', 'user_id' => $shifts_user->id]));
} }

View File

@ -263,7 +263,7 @@ function view_user_shifts()
$shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter); $shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter);
if (empty($user->api_key)) { if (empty($user->api_key)) {
User_reset_api_key($user, false); auth()->resetApiKey($user);
} }
$filled = [ $filled = [

View File

@ -296,17 +296,20 @@ class User
$defaultGroup = Group::find($this->authenticator->getDefaultRole()); $defaultGroup = Group::find($this->authenticator->getDefaultRole());
$user->groups()->attach($defaultGroup); $user->groups()->attach($defaultGroup);
auth()->resetApiKey($user);
if ($this->determineIsPasswordEnabled() && array_key_exists('password', $data)) { if ($this->determineIsPasswordEnabled() && array_key_exists('password', $data)) {
auth()->setPassword($user, $data['password']); auth()->setPassword($user, $data['password']);
} }
$assignedAngelTypeNames = $this->assignAngelTypes($user, $rawData); $assignedAngelTypeNames = $this->assignAngelTypes($user, $rawData);
$this->logger->info(sprintf( $this->logger->info(
'User %s signed up as: %s', 'User {user} signed up as: {angeltypes}',
sprintf('%s (%u)', $user->displayName, $user->id), [
join(', ', $assignedAngelTypeNames), 'user' => sprintf('%s (%u)', $user->displayName, $user->id),
)); 'angeltypes' => join(', ', $assignedAngelTypeNames),
]
);
$this->dbConnection->commit(); $this->dbConnection->commit();

View File

@ -187,6 +187,12 @@ class Authenticator
return $this->user; return $this->user;
} }
public function resetApiKey(User $user): void
{
$user->api_key = bin2hex(random_bytes(32));
$user->save();
}
/** /**
* Get the user by its api key * Get the user by its api key
*/ */

View File

@ -18,6 +18,7 @@ use Engelsystem\Test\Unit\ServiceProviderTest;
use Engelsystem\Test\Utils\SignUpConfig; use Engelsystem\Test\Utils\SignUpConfig;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
@ -48,7 +49,7 @@ class UserTest extends ServiceProviderTest
$this->config->set('oauth', []); $this->config->set('oauth', []);
$this->session = new Session(new MockArraySessionStorage()); $this->session = new Session(new MockArraySessionStorage());
$this->app->instance(SessionInterface::class, $this->session); $this->app->instance(SessionInterface::class, $this->session);
$this->app->instance(LoggerInterface::class, $this->getMockForAbstractClass(LoggerInterface::class)); $this->app->instance(LoggerInterface::class, new NullLogger());
$this->app->instance(ServerRequestInterface::class, new Request()); $this->app->instance(ServerRequestInterface::class, new Request());
$this->app->instance(Authenticator::class, $this->app->make(Authenticator::class)); $this->app->instance(Authenticator::class, $this->app->make(Authenticator::class));
@ -112,6 +113,7 @@ class UserTest extends ServiceProviderTest
$this->assertSame('fritz', $user->name); $this->assertSame('fritz', $user->name);
$this->assertSame('fritz@example.com', $user->email); $this->assertSame('fritz@example.com', $user->email);
$this->assertSame(false, $user->state->arrived); $this->assertSame(false, $user->state->arrived);
$this->assertNotEmpty($user->api_key);
} }
/** /**

View File

@ -12,6 +12,7 @@ use Engelsystem\Models\User\User;
use Engelsystem\Test\Unit\HasDatabase; use Engelsystem\Test\Unit\HasDatabase;
use Engelsystem\Test\Unit\Helpers\Stub\UserModelImplementation; use Engelsystem\Test\Unit\Helpers\Stub\UserModelImplementation;
use Engelsystem\Test\Unit\ServiceProviderTest; use Engelsystem\Test\Unit\ServiceProviderTest;
use Illuminate\Support\Str;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Session;
@ -183,6 +184,27 @@ class AuthenticatorTest extends ServiceProviderTest
$this->assertEquals('F00Bar', $user->api_key); $this->assertEquals('F00Bar', $user->api_key);
} }
/**
* @covers \Engelsystem\Helpers\Authenticator::resetApiKey
*/
public function testResetApiKey(): void
{
$this->initDatabase();
$user = User::factory()->create();
$oldKey = $user->api_key;
$auth = new Authenticator(new Request(), new Session(new MockArraySessionStorage()), new User());
$auth->resetApiKey($user);
$updatedUser = User::all()->last();
$newApiKey = $updatedUser->api_key;
$this->assertNotEquals($oldKey, $newApiKey);
$this->assertTrue(Str::isAscii($newApiKey));
$this->assertEquals(64, Str::length($newApiKey));
}
/** /**
* @covers \Engelsystem\Helpers\Authenticator::can * @covers \Engelsystem\Helpers\Authenticator::can
*/ */