mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-19 00:29:35 +00:00
Add INITIAL_ADMIN_API_KEY environment variable support
- Add configuration parameter for initial admin API key - Implement getInitialAdminApiToken() method in AbstractMultiPlatformMigration - Create migration to automatically generate admin API token on initial setup - Add CLAUDE.md to .gitignore for local development documentation
This commit is contained in:
parent
a6be786d5d
commit
c498803859
4 changed files with 105 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -48,3 +48,6 @@ yarn-error.log
|
||||||
###> phpstan/phpstan ###
|
###> phpstan/phpstan ###
|
||||||
phpstan.neon
|
phpstan.neon
|
||||||
###< phpstan/phpstan ###
|
###< phpstan/phpstan ###
|
||||||
|
|
||||||
|
# Claude Code project documentation (local development only)
|
||||||
|
CLAUDE.md
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ parameters:
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
|
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
|
||||||
|
|
||||||
|
######################################################################################################################
|
||||||
|
# API Configuration
|
||||||
|
######################################################################################################################
|
||||||
|
partdb.api.initial_admin_key: '%env(trim:string:INITIAL_ADMIN_API_KEY)%' # Initial admin API key for automated access (env only)
|
||||||
|
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
|
|
@ -104,3 +108,5 @@ parameters:
|
||||||
env(SAML_ROLE_MAPPING): '{}'
|
env(SAML_ROLE_MAPPING): '{}'
|
||||||
|
|
||||||
env(DATABASE_EMULATE_NATURAL_SORT): 0
|
env(DATABASE_EMULATE_NATURAL_SORT): 0
|
||||||
|
|
||||||
|
env(INITIAL_ADMIN_API_KEY): ''
|
||||||
|
|
|
||||||
71
migrations/Version20250907000000.php
Normal file
71
migrations/Version20250907000000.php
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use App\Migration\AbstractMultiPlatformMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
||||||
|
final class Version20250907000000 extends AbstractMultiPlatformMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Create initial admin API token if INITIAL_ADMIN_API_KEY environment variable is set';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createInitialAdminApiToken(): void
|
||||||
|
{
|
||||||
|
$apiToken = $this->getInitialAdminApiToken();
|
||||||
|
if (empty($apiToken)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a proper API token with the 'tcp_' prefix and the provided key
|
||||||
|
$fullToken = 'tcp_' . $apiToken;
|
||||||
|
|
||||||
|
// Set expiration to 1 year from now
|
||||||
|
$validUntil = date('Y-m-d H:i:s', strtotime('+1 year'));
|
||||||
|
$currentDateTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
// Insert the API token for the admin user (user_id = 2)
|
||||||
|
// Level 4 = FULL access (can do everything the user can do)
|
||||||
|
$sql = "INSERT INTO api_tokens (user_id, name, token, level, valid_until, datetime_added, last_modified)
|
||||||
|
VALUES (2, 'Initial Admin Token', ?, 4, ?, ?, ?)";
|
||||||
|
|
||||||
|
$this->addSql($sql, [$fullToken, $validUntil, $currentDateTime, $currentDateTime]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mySQLUp(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->createInitialAdminApiToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mySQLDown(Schema $schema): void
|
||||||
|
{
|
||||||
|
// Remove the initial admin token if it exists
|
||||||
|
$this->addSql("DELETE FROM api_tokens WHERE name = 'Initial Admin Token' AND user_id = 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sqLiteUp(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->createInitialAdminApiToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sqLiteDown(Schema $schema): void
|
||||||
|
{
|
||||||
|
// Remove the initial admin token if it exists
|
||||||
|
$this->addSql("DELETE FROM api_tokens WHERE name = 'Initial Admin Token' AND user_id = 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postgreSQLUp(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->createInitialAdminApiToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postgreSQLDown(Schema $schema): void
|
||||||
|
{
|
||||||
|
// Remove the initial admin token if it exists
|
||||||
|
$this->addSql("DELETE FROM api_tokens WHERE name = 'Initial Admin Token' AND user_id = 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,6 +35,7 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration
|
||||||
{
|
{
|
||||||
final public const ADMIN_PW_LENGTH = 10;
|
final public const ADMIN_PW_LENGTH = 10;
|
||||||
protected string $admin_pw = '';
|
protected string $admin_pw = '';
|
||||||
|
protected string $admin_api_token = '';
|
||||||
|
|
||||||
/** @noinspection SenselessProxyMethodInspection
|
/** @noinspection SenselessProxyMethodInspection
|
||||||
* This method is required to redefine the logger type hint to protected
|
* This method is required to redefine the logger type hint to protected
|
||||||
|
|
@ -108,6 +109,23 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration
|
||||||
return password_hash((string) $this->admin_pw, PASSWORD_DEFAULT);
|
return password_hash((string) $this->admin_pw, PASSWORD_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the initial admin API token if configured via environment variable.
|
||||||
|
* If not configured, returns empty string (no token will be created).
|
||||||
|
*/
|
||||||
|
public function getInitialAdminApiToken(): string
|
||||||
|
{
|
||||||
|
if ($this->admin_api_token === '') {
|
||||||
|
$apiKey = getenv('INITIAL_ADMIN_API_KEY');
|
||||||
|
if (!empty($apiKey)) {
|
||||||
|
// Use the provided API key directly (should be generated with openssl rand -hex 32)
|
||||||
|
$this->admin_api_token = $apiKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->admin_api_token;
|
||||||
|
}
|
||||||
|
|
||||||
public function postUp(Schema $schema): void
|
public function postUp(Schema $schema): void
|
||||||
{
|
{
|
||||||
parent::postUp($schema);
|
parent::postUp($schema);
|
||||||
|
|
@ -117,6 +135,13 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration
|
||||||
$this->logger->warning('<bg=yellow;fg=black>The initial password for the "admin" user is: '.$this->admin_pw.'</>');
|
$this->logger->warning('<bg=yellow;fg=black>The initial password for the "admin" user is: '.$this->admin_pw.'</>');
|
||||||
$this->logger->warning('');
|
$this->logger->warning('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->admin_api_token !== '') {
|
||||||
|
$this->logger->warning('');
|
||||||
|
$this->logger->warning('<bg=green;fg=black>Initial admin API token has been created with the provided key</>');
|
||||||
|
$this->logger->warning('<bg=yellow;fg=black>Use this token in Authorization header: Bearer tcp_'.$this->admin_api_token.'</>');
|
||||||
|
$this->logger->warning('');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue