kctl-ak 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. kctl_ak/SKILL.extra.md +20 -0
  2. kctl_ak/__init__.py +3 -0
  3. kctl_ak/__main__.py +5 -0
  4. kctl_ak/cli.py +156 -0
  5. kctl_ak/commands/__init__.py +0 -0
  6. kctl_ak/commands/apps.py +557 -0
  7. kctl_ak/commands/audit.py +609 -0
  8. kctl_ak/commands/blueprints.py +159 -0
  9. kctl_ak/commands/brands.py +200 -0
  10. kctl_ak/commands/certificates.py +190 -0
  11. kctl_ak/commands/config_cmd.py +528 -0
  12. kctl_ak/commands/dashboard.py +245 -0
  13. kctl_ak/commands/doctor_cmd.py +82 -0
  14. kctl_ak/commands/flows.py +319 -0
  15. kctl_ak/commands/groups.py +435 -0
  16. kctl_ak/commands/health.py +168 -0
  17. kctl_ak/commands/mail.py +287 -0
  18. kctl_ak/commands/maintenance.py +451 -0
  19. kctl_ak/commands/notifications.py +248 -0
  20. kctl_ak/commands/outposts.py +273 -0
  21. kctl_ak/commands/policies.py +251 -0
  22. kctl_ak/commands/property_mappings.py +205 -0
  23. kctl_ak/commands/providers.py +596 -0
  24. kctl_ak/commands/provision.py +645 -0
  25. kctl_ak/commands/sessions.py +211 -0
  26. kctl_ak/commands/setup.py +691 -0
  27. kctl_ak/commands/skill_cmd.py +76 -0
  28. kctl_ak/commands/stages.py +303 -0
  29. kctl_ak/commands/system.py +257 -0
  30. kctl_ak/commands/tokens.py +258 -0
  31. kctl_ak/commands/users.py +1251 -0
  32. kctl_ak/core/__init__.py +0 -0
  33. kctl_ak/core/callbacks.py +34 -0
  34. kctl_ak/core/client.py +108 -0
  35. kctl_ak/core/config.py +295 -0
  36. kctl_ak/core/exceptions.py +23 -0
  37. kctl_ak/core/mailer.py +204 -0
  38. kctl_ak/core/output.py +7 -0
  39. kctl_ak/core/resolve.py +69 -0
  40. kctl_ak/models/__init__.py +0 -0
  41. kctl_ak/models/application.py +42 -0
  42. kctl_ak/models/blueprint.py +17 -0
  43. kctl_ak/models/event.py +24 -0
  44. kctl_ak/models/flow.py +32 -0
  45. kctl_ak/models/group.py +39 -0
  46. kctl_ak/models/pagination.py +24 -0
  47. kctl_ak/models/provider.py +56 -0
  48. kctl_ak/models/provision.py +67 -0
  49. kctl_ak/models/role.py +12 -0
  50. kctl_ak/models/session.py +20 -0
  51. kctl_ak/models/system.py +50 -0
  52. kctl_ak/models/token.py +31 -0
  53. kctl_ak/models/user.py +48 -0
  54. kctl_ak/provision/__init__.py +0 -0
  55. kctl_ak/provision/chain.py +466 -0
  56. kctl_ak/provision/config.py +23 -0
  57. kctl_ak/provision/mailcow_client.py +96 -0
  58. kctl_ak/provision/odoo_client.py +133 -0
  59. kctl_ak/provision/webhook_setup.py +210 -0
  60. kctl_ak/reports/__init__.py +0 -0
  61. kctl_ak/reports/access_control.py +435 -0
  62. kctl_ak/roles/__init__.py +0 -0
  63. kctl_ak/roles/loader.py +57 -0
  64. kctl_ak/roles/provisioner.py +101 -0
  65. kctl_ak-0.2.0.dist-info/METADATA +20 -0
  66. kctl_ak-0.2.0.dist-info/RECORD +68 -0
  67. kctl_ak-0.2.0.dist-info/WHEEL +4 -0
  68. kctl_ak-0.2.0.dist-info/entry_points.txt +2 -0
kctl_ak/SKILL.extra.md ADDED
@@ -0,0 +1,20 @@
1
+ ## OAuth2 Provider Management for React SPAs
2
+
3
+ React PWAs (SPA clients) MUST use `client_type: public` — they cannot keep secrets.
4
+
5
+ ```bash
6
+ # Check current client type
7
+ kctl-ak providers oauth2 get <id>
8
+
9
+ # Fix to public if needed
10
+ kctl-ak providers oauth2 update <id> --client-type public
11
+
12
+ # Get credentials
13
+ kctl-ak providers oauth2 credentials <id>
14
+ ```
15
+
16
+ ## Critical Rules
17
+
18
+ 1. React/SPA apps = `public` client type (NEVER `confidential`)
19
+ 2. Server-side apps (Odoo, FastAPI) = `confidential` client type
20
+ 3. Redirect URIs must exactly match what the app sends
kctl_ak/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """kctl-ak: Kodemeio Authentik CLI."""
2
+
3
+ __version__ = "0.2.0"
kctl_ak/__main__.py ADDED
@@ -0,0 +1,5 @@
1
+ """Allow running as: python -m kctl_ak."""
2
+
3
+ from kctl_ak.cli import app
4
+
5
+ app()
kctl_ak/cli.py ADDED
@@ -0,0 +1,156 @@
1
+ """Main CLI entry point for kctl-ak."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+ from kctl_lib import KctlError, handle_cli_error
9
+
10
+ from kctl_ak import __version__
11
+ from kctl_ak.commands.apps import app as apps_app
12
+ from kctl_ak.commands.audit import app as audit_app
13
+ from kctl_ak.commands.blueprints import app as blueprints_app
14
+ from kctl_ak.commands.brands import app as brands_app
15
+ from kctl_ak.commands.certificates import app as certificates_app
16
+ from kctl_ak.commands.config_cmd import app as config_app
17
+ from kctl_ak.commands.dashboard import app as dashboard_app
18
+ from kctl_ak.commands.flows import app as flows_app
19
+ from kctl_ak.commands.groups import app as groups_app
20
+ from kctl_ak.commands.health import app as health_app
21
+ from kctl_ak.commands.mail import app as mail_app
22
+ from kctl_ak.commands.maintenance import app as maintenance_app
23
+ from kctl_ak.commands.notifications import app as notifications_app
24
+ from kctl_ak.commands.outposts import app as outposts_app
25
+ from kctl_ak.commands.policies import app as policies_app
26
+ from kctl_ak.commands.property_mappings import app as property_mappings_app
27
+ from kctl_ak.commands.providers import app as providers_app
28
+ from kctl_ak.commands.sessions import app as sessions_app
29
+ from kctl_ak.commands.setup import app as setup_app
30
+ from kctl_ak.commands.stages import app as stages_app
31
+ from kctl_ak.commands.system import app as system_app
32
+ from kctl_ak.commands.tokens import app as tokens_app
33
+ from kctl_ak.commands.users import app as users_app
34
+ from kctl_ak.commands.provision import app as provision_app
35
+ from kctl_ak.core.callbacks import AppContext
36
+ from kctl_ak.commands.doctor_cmd import app as doctor_app
37
+ from kctl_ak.commands.skill_cmd import app as skill_app
38
+ from kctl_lib.self_update import notify_if_outdated
39
+
40
+
41
+ def version_callback(value: bool) -> None:
42
+ if value:
43
+ typer.echo(f"kctl-ak {__version__}")
44
+ raise typer.Exit()
45
+
46
+
47
+ app = typer.Typer(
48
+ name="kctl-ak",
49
+ help="Kodemeio Authentik CLI - manage your Authentik identity provider.",
50
+ no_args_is_help=True,
51
+ rich_markup_mode="rich",
52
+ pretty_exceptions_enable=False,
53
+ )
54
+
55
+
56
+ @app.callback()
57
+ def main(
58
+ ctx: typer.Context,
59
+ json_output: Annotated[bool, typer.Option("--json", help="Output as JSON")] = False,
60
+ quiet: Annotated[bool, typer.Option("--quiet", "-q", help="Suppress info messages")] = False,
61
+ profile: Annotated[str | None, typer.Option("--profile", "-p", help="Config profile name")] = None,
62
+ url: Annotated[str | None, typer.Option("--url", help="API URL override")] = None,
63
+ token: Annotated[str | None, typer.Option("--token", help="API token override")] = None,
64
+ version: Annotated[
65
+ bool, typer.Option("--version", "-V", callback=version_callback, is_eager=True, help="Show version")
66
+ ] = False,
67
+ ) -> None:
68
+ """Kodemeio Authentik CLI."""
69
+ ctx.ensure_object(dict)
70
+ ctx.obj = AppContext(
71
+ json_mode=json_output,
72
+ quiet=quiet,
73
+ profile=profile,
74
+ url_override=url,
75
+ token_override=token,
76
+ )
77
+ notify_if_outdated(ctx.obj.output, "kctl-ak", __version__)
78
+
79
+
80
+ # Register all command groups
81
+ app.add_typer(users_app, name="users")
82
+ app.add_typer(groups_app, name="groups")
83
+ app.add_typer(apps_app, name="apps")
84
+ app.add_typer(providers_app, name="providers")
85
+ app.add_typer(flows_app, name="flows")
86
+ app.add_typer(audit_app, name="audit")
87
+ app.add_typer(sessions_app, name="sessions")
88
+ app.add_typer(tokens_app, name="tokens")
89
+ app.add_typer(blueprints_app, name="blueprints")
90
+ app.add_typer(maintenance_app, name="maintenance")
91
+ app.add_typer(setup_app, name="setup")
92
+ app.add_typer(health_app, name="health")
93
+ app.add_typer(dashboard_app, name="dashboard")
94
+ app.add_typer(config_app, name="config")
95
+ app.add_typer(mail_app, name="mail")
96
+ app.add_typer(policies_app, name="policies")
97
+ app.add_typer(stages_app, name="stages")
98
+ app.add_typer(property_mappings_app, name="property-mappings")
99
+ app.add_typer(certificates_app, name="certificates")
100
+ app.add_typer(outposts_app, name="outposts")
101
+ app.add_typer(brands_app, name="brands")
102
+ app.add_typer(notifications_app, name="notifications")
103
+ app.add_typer(system_app, name="system")
104
+ app.add_typer(provision_app, name="provision")
105
+ app.add_typer(doctor_app, name="doctor")
106
+ app.add_typer(skill_app, name="skill", hidden=True)
107
+
108
+
109
+ @app.command("self-update")
110
+ def self_update_cmd(ctx: typer.Context) -> None:
111
+ """Check for updates and upgrade kctl-ak."""
112
+ actx = ctx.obj
113
+ out = actx.output
114
+
115
+ from kctl_lib.self_update import check_update
116
+ from kctl_lib.self_update import update as do_update
117
+
118
+ latest = check_update("kctl-ak", __version__)
119
+ if latest:
120
+ out.info(f"Updating to {latest}...")
121
+ do_update("kctl-ak")
122
+ out.success(f"Updated to {latest}")
123
+ else:
124
+ out.success("Already up to date")
125
+
126
+
127
+ @app.command()
128
+ def completions(
129
+ shell: Annotated[str, typer.Argument(help="Shell type: zsh, bash, fish")] = "zsh",
130
+ install: Annotated[bool, typer.Option("--install", help="Install completions")] = False,
131
+ ) -> None:
132
+ """Generate or install shell completions."""
133
+ from kctl_lib.completions import get_completion_script, install_completions
134
+
135
+ if install:
136
+ path = install_completions("kctl-ak", shell)
137
+ if path:
138
+ typer.echo(f"Completions installed to {path}")
139
+ else:
140
+ typer.echo(f"Could not install completions for {shell}", err=True)
141
+ raise typer.Exit(code=1)
142
+ else:
143
+ script = get_completion_script("kctl-ak", shell)
144
+ typer.echo(script)
145
+
146
+
147
+ def _run() -> None:
148
+ """Entry point with error handling."""
149
+ try:
150
+ app()
151
+ except KctlError as e:
152
+ handle_cli_error(e)
153
+
154
+
155
+ if __name__ == "__main__":
156
+ _run()
File without changes