File size: 2,531 Bytes
c91c7db
 
 
 
 
 
 
 
 
 
3493993
c91c7db
 
 
 
3493993
 
c91c7db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from __future__ import annotations

import argparse
import asyncio
import json

from app.core.config import get_settings
from app.security.database import SecurityDatabase
from app.security.schemas import APIKeyCreate, APIKeyView
from app.security.service import APIKeyService
from app.security.tenancy import TenantService


async def _create(arguments: argparse.Namespace) -> None:
    settings = get_settings()
    database = SecurityDatabase(settings.database_url, auto_migrate=settings.security_auto_migrate)
    service = APIKeyService(database, settings, TenantService(database))
    await database.initialize()
    try:
        record, secret = await service.create(
            APIKeyCreate(
                name=arguments.name,
                environment=arguments.environment,
                role=arguments.role,
                expires_in_seconds=arguments.expires_in,
            ),
            created_by="security-cli",
        )
        payload = APIKeyView.model_validate(record).model_dump(mode="json")
        payload["api_key"] = secret
        print(json.dumps(payload, indent=2))
    finally:
        await database.close()


def _bootstrap(arguments: argparse.Namespace) -> None:
    material = APIKeyService.generate_material(arguments.environment)
    print("Store the API key in your password manager. It will not be shown again.\n")
    print(f"API_KEY={material.api_key}")
    print(f"AUTH_BOOTSTRAP_KEY_HASH={material.key_hash}")
    print(f"AUTH_BOOTSTRAP_KEY_PREFIX={material.key_prefix}")
    print(f"AUTH_BOOTSTRAP_ENVIRONMENT={material.environment}")


def main() -> None:
    parser = argparse.ArgumentParser(description="MediaRouter API-key administration")
    commands = parser.add_subparsers(dest="command", required=True)
    bootstrap = commands.add_parser(
        "generate-bootstrap", help="Generate a key and hash-only bootstrap settings"
    )
    bootstrap.add_argument("--environment", choices=("live", "test"), default="live")
    create = commands.add_parser("create", help="Create a key directly in the configured database")
    create.add_argument("--name", required=True)
    create.add_argument("--environment", choices=("live", "test"), default="live")
    create.add_argument("--role", default="admin")
    create.add_argument("--expires-in", type=int, default=None)
    arguments = parser.parse_args()
    if arguments.command == "generate-bootstrap":
        _bootstrap(arguments)
    else:
        asyncio.run(_create(arguments))


if __name__ == "__main__":
    main()