mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 09:35:49 +02:00
Added tests for token API authentication
This commit is contained in:
parent
42356cc2a3
commit
c7a02ae870
4 changed files with 204 additions and 0 deletions
97
src/DataFixtures/APITokenFixtures.php
Normal file
97
src/DataFixtures/APITokenFixtures.php
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\DataFixtures;
|
||||||
|
|
||||||
|
use App\Entity\UserSystem\ApiToken;
|
||||||
|
use App\Entity\UserSystem\ApiTokenLevel;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||||
|
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
|
||||||
|
use Doctrine\Persistence\ObjectManager;
|
||||||
|
|
||||||
|
class APITokenFixtures extends Fixture implements DependentFixtureInterface
|
||||||
|
{
|
||||||
|
public const TOKEN_READONLY = 'tcp_readonly';
|
||||||
|
public const TOKEN_EDIT = 'tcp_edit';
|
||||||
|
public const TOKEN_ADMIN = 'tcp_admin';
|
||||||
|
public const TOKEN_FULL = 'tcp_full';
|
||||||
|
public const TOKEN_EXPIRED = 'tcp_expired';
|
||||||
|
|
||||||
|
public function load(ObjectManager $manager): void
|
||||||
|
{
|
||||||
|
/** @var User $admin_user */
|
||||||
|
$admin_user = $this->getReference(UserFixtures::ADMIN);
|
||||||
|
|
||||||
|
$read_only_token = new ApiToken();
|
||||||
|
$read_only_token->setUser($admin_user);
|
||||||
|
$read_only_token->setLevel(ApiTokenLevel::READ_ONLY);
|
||||||
|
$read_only_token->setName('read-only');
|
||||||
|
$this->setTokenSecret($read_only_token, self::TOKEN_READONLY);
|
||||||
|
$manager->persist($read_only_token);
|
||||||
|
|
||||||
|
$editor_token = new ApiToken();
|
||||||
|
$editor_token->setUser($admin_user);
|
||||||
|
$editor_token->setLevel(ApiTokenLevel::EDIT);
|
||||||
|
$editor_token->setName('edit');
|
||||||
|
$this->setTokenSecret($editor_token, self::TOKEN_EDIT);
|
||||||
|
$manager->persist($editor_token);
|
||||||
|
|
||||||
|
$admin_token = new ApiToken();
|
||||||
|
$admin_token->setUser($admin_user);
|
||||||
|
$admin_token->setLevel(ApiTokenLevel::ADMIN);
|
||||||
|
$admin_token->setName('admin');
|
||||||
|
$this->setTokenSecret($admin_token, self::TOKEN_ADMIN);
|
||||||
|
$manager->persist($admin_token);
|
||||||
|
|
||||||
|
$full_token = new ApiToken();
|
||||||
|
$full_token->setUser($admin_user);
|
||||||
|
$full_token->setLevel(ApiTokenLevel::FULL);
|
||||||
|
$full_token->setName('full');
|
||||||
|
$this->setTokenSecret($full_token, self::TOKEN_FULL);
|
||||||
|
$manager->persist($full_token);
|
||||||
|
|
||||||
|
$expired_token = new ApiToken();
|
||||||
|
$expired_token->setUser($admin_user);
|
||||||
|
$expired_token->setLevel(ApiTokenLevel::FULL);
|
||||||
|
$expired_token->setName('expired');
|
||||||
|
$expired_token->setValidUntil(new \DateTimeImmutable('-1 day'));
|
||||||
|
$this->setTokenSecret($expired_token, self::TOKEN_EXPIRED);
|
||||||
|
$manager->persist($expired_token);
|
||||||
|
|
||||||
|
$manager->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setTokenSecret(ApiToken $token, string $secret): void
|
||||||
|
{
|
||||||
|
//Access private property
|
||||||
|
$reflection = new \ReflectionClass($token);
|
||||||
|
$property = $reflection->getProperty('token');
|
||||||
|
$property->setValue($token, $secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDependencies(): array
|
||||||
|
{
|
||||||
|
return [UserFixtures::class];
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||||
|
|
||||||
class UserFixtures extends Fixture implements DependentFixtureInterface
|
class UserFixtures extends Fixture implements DependentFixtureInterface
|
||||||
{
|
{
|
||||||
|
public const ADMIN = 'user-admin';
|
||||||
|
|
||||||
public function __construct(protected UserPasswordHasherInterface $encoder, protected EntityManagerInterface $em)
|
public function __construct(protected UserPasswordHasherInterface $encoder, protected EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -50,6 +52,7 @@ class UserFixtures extends Fixture implements DependentFixtureInterface
|
||||||
$admin->setNeedPwChange(false);
|
$admin->setNeedPwChange(false);
|
||||||
$admin->setGroup($this->getReference(GroupFixtures::ADMINS));
|
$admin->setGroup($this->getReference(GroupFixtures::ADMINS));
|
||||||
$manager->persist($admin);
|
$manager->persist($admin);
|
||||||
|
$this->addReference(self::ADMIN, $admin);
|
||||||
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$user->setName('user');
|
$user->setName('user');
|
||||||
|
|
|
@ -1023,6 +1023,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
*/
|
*/
|
||||||
public function addApiToken(ApiToken $apiToken): void
|
public function addApiToken(ApiToken $apiToken): void
|
||||||
{
|
{
|
||||||
|
$apiToken->setUser($this);
|
||||||
$this->api_tokens->add($apiToken);
|
$this->api_tokens->add($apiToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
103
tests/API/APITokenAuthenticationTest.php
Normal file
103
tests/API/APITokenAuthenticationTest.php
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace API;
|
||||||
|
|
||||||
|
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
|
||||||
|
use App\DataFixtures\APITokenFixtures;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
use ApiPlatform\Symfony\Bundle\Test\Client;
|
||||||
|
class APITokenAuthenticationTest extends ApiTestCase
|
||||||
|
{
|
||||||
|
public function testUnauthenticated(): void
|
||||||
|
{
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
$client = static::createClient();
|
||||||
|
$client->request('GET', '/api/parts');
|
||||||
|
self::assertResponseStatusCodeSame(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testExpiredToken(): void
|
||||||
|
{
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
$client = $this->createClientWithCredentials(APITokenFixtures::TOKEN_EXPIRED);
|
||||||
|
$client->request('GET', '/api/parts');
|
||||||
|
self::assertResponseStatusCodeSame(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadOnlyToken(): void
|
||||||
|
{
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
$client = $this->createClientWithCredentials(APITokenFixtures::TOKEN_READONLY);
|
||||||
|
|
||||||
|
//Read should be possible
|
||||||
|
$client->request('GET', '/api/parts');
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
|
||||||
|
//Trying to list all users and create a new footprint should fail
|
||||||
|
$client->request('GET', '/api/users');
|
||||||
|
self::assertResponseStatusCodeSame(403);
|
||||||
|
|
||||||
|
$client->request('POST', '/api/footprints', ['json' => ['name' => 'post test']]);
|
||||||
|
self::assertResponseStatusCodeSame(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEditToken(): void
|
||||||
|
{
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
$client = $this->createClientWithCredentials(APITokenFixtures::TOKEN_EDIT);
|
||||||
|
|
||||||
|
//Read should be possible
|
||||||
|
$client->request('GET', '/api/parts');
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
|
||||||
|
//Trying to list all users
|
||||||
|
$client->request('GET', '/api/users');
|
||||||
|
self::assertResponseStatusCodeSame(403);
|
||||||
|
|
||||||
|
$client->request('POST', '/api/footprints', ['json' => ['name' => 'post test']]);
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAdminToken(): void
|
||||||
|
{
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
$client = $this->createClientWithCredentials(APITokenFixtures::TOKEN_ADMIN );
|
||||||
|
|
||||||
|
//Read should be possible
|
||||||
|
$client->request('GET', '/api/parts');
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
|
||||||
|
//Trying to list all users
|
||||||
|
$client->request('GET', '/api/users');
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
|
||||||
|
$client->request('POST', '/api/footprints', ['json' => ['name' => 'post test']]);
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createClientWithCredentials(string $token): Client
|
||||||
|
{
|
||||||
|
return static::createClient([], ['headers' => ['authorization' => 'Bearer '.$token]]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue