mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-18 16:19:34 +00:00
Merge f9e7fb4491 into f0dc80aac9
This commit is contained in:
commit
3c2b597c47
7 changed files with 128 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -48,3 +48,6 @@ yarn-error.log
|
|||
###> phpstan/phpstan ###
|
||||
phpstan.neon
|
||||
###< 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
|
||||
|
||||
######################################################################################################################
|
||||
# API Configuration
|
||||
######################################################################################################################
|
||||
partdb.api.initial_admin_key: '%env(trim:string:INITIAL_ADMIN_API_KEY)%' # Initial admin API key for automated access (env only)
|
||||
|
||||
######################################################################################################################
|
||||
# Miscellaneous
|
||||
|
|
@ -104,3 +108,5 @@ parameters:
|
|||
env(SAML_ROLE_MAPPING): '{}'
|
||||
|
||||
env(DATABASE_EMULATE_NATURAL_SORT): 0
|
||||
|
||||
env(INITIAL_ADMIN_API_KEY): ''
|
||||
|
|
|
|||
|
|
@ -32,6 +32,14 @@ tokens as you want and also delete them again.
|
|||
When deleting a token, it is immediately invalidated and can not be used anymore, which means that the application can
|
||||
not access the API anymore with this token.
|
||||
|
||||
### Initial Admin API Token
|
||||
|
||||
For automated deployments and CI/CD pipelines, Part-DB supports automatically creating an initial admin API token
|
||||
during database setup. Set the `INITIAL_ADMIN_API_KEY` environment variable to a 64-character random string
|
||||
(generate with `openssl rand -hex 32`) before running database migrations. Part-DB will create an API token named
|
||||
"Initial Admin Token" with FULL scope that expires after 1 year. The token can be used immediately with the format
|
||||
`Bearer tcp_<your-64-char-key>` in the Authorization header.
|
||||
|
||||
### Token permissions and scopes
|
||||
|
||||
API tokens are ultimately limited by the permissions of the user, which belongs to the token. That means that the token
|
||||
|
|
|
|||
|
|
@ -114,6 +114,11 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
|
|||
particularly for securing and protecting various aspects of your application. It's a secret key that is used for
|
||||
cryptographic operations and security measures (session management, CSRF protection, etc..). Therefore this
|
||||
value should be handled as confidential data and not shared publicly.
|
||||
* `INITIAL_ADMIN_API_KEY` (env only): When set to a 64-character random string (generate with `openssl rand -hex 32`),
|
||||
Part-DB will automatically create an API token named "Initial Admin Token" for the admin user during database
|
||||
migrations. This token will have FULL scope and expire after 1 year. This is useful for automated deployments,
|
||||
CI/CD pipelines, and Docker setups where you need immediate API access without manual token creation. The token
|
||||
can be used with the format `Bearer tcp_<your-64-char-key>` in the Authorization header.
|
||||
* `SHOW_PART_IMAGE_OVERLAY`: Set to 0 to disable the part image overlay, which appears if you hover over an image in the
|
||||
part image gallery
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,11 @@ services:
|
|||
# Use gravatars for user avatars, when user has no own avatar defined
|
||||
- USE_GRAVATAR=0
|
||||
|
||||
# Automatically create an admin API token during database setup (useful for CI/CD pipelines)
|
||||
# Generate a 64-character random string with: openssl rand -hex 32
|
||||
# The token will be available as: Bearer tcp_<your-64-char-key>
|
||||
#- INITIAL_ADMIN_API_KEY=your_64_character_random_string_here
|
||||
|
||||
# Override value if you want to show a given text on homepage.
|
||||
# When this is empty the content of config/banner.md is used as banner
|
||||
#- BANNER=This is a test banner<br>with a line break
|
||||
|
|
@ -146,6 +151,11 @@ services:
|
|||
# However you can add add any other environment configuration you want here
|
||||
# See .env file for all available options or https://docs.part-db.de/configuration.html
|
||||
|
||||
# Automatically create an admin API token during database setup (useful for CI/CD pipelines)
|
||||
# Generate a 64-character random string with: openssl rand -hex 32
|
||||
# The token will be available as: Bearer tcp_<your-64-char-key>
|
||||
#- INITIAL_ADMIN_API_KEY=your_64_character_random_string_here
|
||||
|
||||
# Override value if you want to show to show a given text on homepage.
|
||||
# When this is outcommented the webUI can be used to configure the banner
|
||||
#- BANNER=This is a test banner<br>with a line break
|
||||
|
|
|
|||
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;
|
||||
protected string $admin_pw = '';
|
||||
protected string $admin_api_token = '';
|
||||
|
||||
/** @noinspection SenselessProxyMethodInspection
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
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('');
|
||||
}
|
||||
|
||||
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