Make config part of bootstrap.
This commit is contained in:
+11
-4
@@ -10,6 +10,7 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from paskia import authsession, db, globals
|
from paskia import authsession, db, globals
|
||||||
|
from paskia.db.structs import Config
|
||||||
from paskia.util import hostutil
|
from paskia.util import hostutil
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -30,15 +31,18 @@ def _log_reset_link(passphrase: str, message: str | None = None) -> str:
|
|||||||
return reset_link
|
return reset_link
|
||||||
|
|
||||||
|
|
||||||
async def bootstrap_system() -> None:
|
async def bootstrap_system(config: Config | None = None) -> None:
|
||||||
"""
|
"""
|
||||||
Bootstrap the entire system with default data.
|
Bootstrap the entire system with default data.
|
||||||
|
|
||||||
Uses db.bootstrap() which performs all operations in a single transaction.
|
Uses db.bootstrap() which performs all operations in a single transaction.
|
||||||
The transaction log will show a single "bootstrap" action with all changes.
|
The transaction log will show a single "bootstrap" action with all changes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config: Configuration to store (rp_id, rp_name, origins, etc.)
|
||||||
"""
|
"""
|
||||||
# Call the single-transaction bootstrap function
|
# Call the single-transaction bootstrap function
|
||||||
reset_passphrase = db.bootstrap()
|
reset_passphrase = db.bootstrap(config=config)
|
||||||
|
|
||||||
# Log the reset link (this is separate from the transaction log)
|
# Log the reset link (this is separate from the transaction log)
|
||||||
_log_reset_link(reset_passphrase, "✅ Bootstrap completed!")
|
_log_reset_link(reset_passphrase, "✅ Bootstrap completed!")
|
||||||
@@ -89,10 +93,13 @@ async def check_admin_credentials() -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
async def bootstrap_if_needed() -> bool:
|
async def bootstrap_if_needed(config: Config | None = None) -> bool:
|
||||||
"""
|
"""
|
||||||
Check if system needs bootstrapping and perform it if necessary.
|
Check if system needs bootstrapping and perform it if necessary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config: Configuration to store during bootstrap (rp_id, rp_name, origins, etc.)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if bootstrapping was performed, False if system was already set up
|
bool: True if bootstrapping was performed, False if system was already set up
|
||||||
"""
|
"""
|
||||||
@@ -105,7 +112,7 @@ async def bootstrap_if_needed() -> bool:
|
|||||||
|
|
||||||
# No admin permission found, need to bootstrap
|
# No admin permission found, need to bootstrap
|
||||||
# Bootstrap creates the admin user AND the reset link, so no need to check credentials after
|
# Bootstrap creates the admin user AND the reset link, so no need to check credentials after
|
||||||
await bootstrap_system()
|
await bootstrap_system(config=config)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -109,13 +109,19 @@ class UuidResolver:
|
|||||||
return role_data["display_name"]
|
return role_data["display_name"]
|
||||||
|
|
||||||
# Check permissions
|
# Check permissions
|
||||||
if "permissions" in self._previous and uuid_str in self._previous["permissions"]:
|
if (
|
||||||
|
"permissions" in self._previous
|
||||||
|
and uuid_str in self._previous["permissions"]
|
||||||
|
):
|
||||||
perm_data = self._previous["permissions"][uuid_str]
|
perm_data = self._previous["permissions"][uuid_str]
|
||||||
if isinstance(perm_data, dict) and "display_name" in perm_data:
|
if isinstance(perm_data, dict) and "display_name" in perm_data:
|
||||||
return perm_data["display_name"]
|
return perm_data["display_name"]
|
||||||
|
|
||||||
# Check credentials - look up user name
|
# Check credentials - look up user name
|
||||||
if "credentials" in self._previous and uuid_str in self._previous["credentials"]:
|
if (
|
||||||
|
"credentials" in self._previous
|
||||||
|
and uuid_str in self._previous["credentials"]
|
||||||
|
):
|
||||||
cred_data = self._previous["credentials"][uuid_str]
|
cred_data = self._previous["credentials"][uuid_str]
|
||||||
if isinstance(cred_data, dict) and "user" in cred_data:
|
if isinstance(cred_data, dict) and "user" in cred_data:
|
||||||
user_uuid = cred_data["user"]
|
user_uuid = cred_data["user"]
|
||||||
|
|||||||
@@ -723,6 +723,7 @@ def bootstrap(
|
|||||||
admin_name: str = "Admin",
|
admin_name: str = "Admin",
|
||||||
reset_passphrase: str | None = None,
|
reset_passphrase: str | None = None,
|
||||||
reset_expiry: datetime | None = None,
|
reset_expiry: datetime | None = None,
|
||||||
|
config: Config | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Bootstrap the entire system in a single transaction.
|
"""Bootstrap the entire system in a single transaction.
|
||||||
|
|
||||||
@@ -732,6 +733,7 @@ def bootstrap(
|
|||||||
- Organization with Administration role
|
- Organization with Administration role
|
||||||
- Admin user with Administration role
|
- Admin user with Administration role
|
||||||
- Reset token for admin registration
|
- Reset token for admin registration
|
||||||
|
- Config (if provided)
|
||||||
|
|
||||||
This is the only way to create a new database file.
|
This is the only way to create a new database file.
|
||||||
All data is created atomically - if any step fails, nothing is written.
|
All data is created atomically - if any step fails, nothing is written.
|
||||||
@@ -741,6 +743,7 @@ def bootstrap(
|
|||||||
admin_name: Display name for the admin user (default: "Admin")
|
admin_name: Display name for the admin user (default: "Admin")
|
||||||
reset_passphrase: Passphrase for the reset token (generated if not provided)
|
reset_passphrase: Passphrase for the reset token (generated if not provided)
|
||||||
reset_expiry: Expiry datetime for the reset token (default: 14 days)
|
reset_expiry: Expiry datetime for the reset token (default: 14 days)
|
||||||
|
config: Configuration to store (rp_id, rp_name, origins, etc.)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The reset passphrase for admin registration.
|
The reset passphrase for admin registration.
|
||||||
@@ -821,6 +824,10 @@ def bootstrap(
|
|||||||
)
|
)
|
||||||
_db.reset_tokens[reset_token.key] = reset_token
|
_db.reset_tokens[reset_token.key] = reset_token
|
||||||
|
|
||||||
|
# Set config if provided
|
||||||
|
if config is not None:
|
||||||
|
_db.config = config
|
||||||
|
|
||||||
return reset_passphrase
|
return reset_passphrase
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -199,16 +199,14 @@ def main():
|
|||||||
|
|
||||||
startupbox.print_startup_config(config)
|
startupbox.print_startup_config(config)
|
||||||
|
|
||||||
# Build config to save (will be saved after bootstrap in async_main)
|
# Build config to save (for bootstrap or explicit --save)
|
||||||
save_config = None
|
cli_config = Config(
|
||||||
if args.save:
|
rp_id=args.rp_id,
|
||||||
save_config = Config(
|
rp_name=args.rp_name,
|
||||||
rp_id=args.rp_id,
|
origins=args.origins,
|
||||||
rp_name=args.rp_name,
|
auth_host=args.auth_host,
|
||||||
origins=args.origins,
|
listen=args.listen,
|
||||||
auth_host=args.auth_host,
|
)
|
||||||
listen=args.listen,
|
|
||||||
)
|
|
||||||
|
|
||||||
run_kwargs: dict = {
|
run_kwargs: dict = {
|
||||||
"log_level": "warning", # Suppress startup messages; we use custom logging
|
"log_level": "warning", # Suppress startup messages; we use custom logging
|
||||||
@@ -230,9 +228,11 @@ def main():
|
|||||||
origins=config.origins,
|
origins=config.origins,
|
||||||
bootstrap=False,
|
bootstrap=False,
|
||||||
)
|
)
|
||||||
await bootstrap_if_needed()
|
# Pass config to bootstrap - it will be saved within the bootstrap transaction
|
||||||
if save_config is not None:
|
await bootstrap_if_needed(config=cli_config)
|
||||||
await set_config(save_config)
|
# Also save config if --save was explicitly used (even without bootstrap)
|
||||||
|
if args.save:
|
||||||
|
await set_config(cli_config)
|
||||||
await flush()
|
await flush()
|
||||||
|
|
||||||
if len(endpoints) > 1:
|
if len(endpoints) > 1:
|
||||||
|
|||||||
Reference in New Issue
Block a user