sovaria-cli 0.3.0__tar.gz → 0.4.0__tar.gz
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.
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/PKG-INFO +3 -3
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/__init__.py +1 -1
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/auth_enterprise.py +75 -1
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/main.py +1 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/pyproject.toml +3 -3
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/.gitignore +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/README.md +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/__init__.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/__init__.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/admin.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/ai_data.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/alerts.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/api.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/audit.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/auth_product.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/billing.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/branches.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/builds.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/chrono.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/collections.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/connect.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/context.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/crashes.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/dashboard.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/data.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/db.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/deploy.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/env.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/fn_platform.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/gen.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/governance.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/iam.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/import_cmd.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/init_cmd.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/inspect.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/keys.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/knowledge.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/link_cmd.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/login.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/logs.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/mcp.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/messaging.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/metrics.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/oidc_providers.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/org.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/org_key.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/passkeys.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/policy.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/project.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/realtime.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/rules.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/schema.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/scope.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/secrets.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/shell.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/sim.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/simulate.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/storage.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/templates.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/test_cmd.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/commands/vector.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/__init__.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/api_client.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/api_helpers.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/auth_store.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/config.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/display.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/forge_local.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/importers.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/local_function_server.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/log_tail.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/migrations.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/mobile_types.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/output_mode.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/premium_display.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/project_context.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/schema_introspect.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/scope_picker.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/sim_offline.py +0 -0
- {sovaria_cli-0.3.0 → sovaria_cli-0.4.0}/apps/cli/src/utils/theme.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sovaria-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Sovaria BaaS command-line interface (sov)
|
|
5
5
|
Project-URL: Homepage, https://sovaria.in
|
|
6
6
|
Project-URL: Documentation, https://docs.sovaria.in/cli
|
|
@@ -12,7 +12,7 @@ Requires-Dist: httpx>=0.28.1
|
|
|
12
12
|
Requires-Dist: keyring>=25.0
|
|
13
13
|
Requires-Dist: pyyaml>=6.0
|
|
14
14
|
Requires-Dist: rich>=13.7.0
|
|
15
|
-
Requires-Dist: sovaria-sdk==0.
|
|
15
|
+
Requires-Dist: sovaria-sdk==0.6.0
|
|
16
16
|
Requires-Dist: tomli-w>=1.2.0
|
|
17
17
|
Requires-Dist: typer>=0.17.4
|
|
18
18
|
Provides-Extra: dev
|
|
@@ -22,7 +22,7 @@ Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
|
22
22
|
Requires-Dist: ruff>=0.9; extra == 'dev'
|
|
23
23
|
Requires-Dist: twine>=6.0; extra == 'dev'
|
|
24
24
|
Provides-Extra: mcp
|
|
25
|
-
Requires-Dist: sovaria-sdk[mcp]==0.
|
|
25
|
+
Requires-Dist: sovaria-sdk[mcp]==0.6.0; extra == 'mcp'
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
|
|
28
28
|
# Sovaria CLI
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"""Enterprise auth for a project's app users: SCIM 2.0 provisioning and blocking auth hooks.
|
|
2
2
|
|
|
3
|
+
sov saml list | add NAME --domain acme.com --metadata idp.xml | enable ID | disable ID | remove ID [--yes]
|
|
3
4
|
sov scim status | token [--yes] | revoke [--yes]
|
|
4
5
|
sov auth-hooks list | set before-sign-in --url https://… [--fail open] [--timeout-ms 1500] | set before-create
|
|
5
6
|
--function check-signup | test before-create [--email a@b.co] | delete before-create [--yes]
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
All need a project owner/admin; plan keys res.sso (Team+), auth.scim (Team+) and auth.blocking_hooks (Pro+).
|
|
8
9
|
"""
|
|
9
10
|
|
|
10
11
|
from __future__ import annotations
|
|
@@ -15,6 +16,7 @@ from apps.cli.src.utils.api_client import CLIRequestError, call_api
|
|
|
15
16
|
from apps.cli.src.utils.display import handle_cli_error, print_json
|
|
16
17
|
from apps.cli.src.utils.premium_display import run_with_spinner
|
|
17
18
|
|
|
19
|
+
saml_app = typer.Typer(help="SAML single sign-on for your app's users: one connection per customer identity provider")
|
|
18
20
|
scim_app = typer.Typer(help="SCIM 2.0 provisioning of app users and groups (Okta, Entra ID, Google Workspace …)")
|
|
19
21
|
hooks_app = typer.Typer(help="Blocking auth hooks: before-create and before-sign-in (refuse or add custom claims)")
|
|
20
22
|
|
|
@@ -38,6 +40,78 @@ def _event(raw: str) -> str:
|
|
|
38
40
|
return event
|
|
39
41
|
|
|
40
42
|
|
|
43
|
+
# ── SAML ──────────────────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@saml_app.command("list")
|
|
47
|
+
def saml_list(
|
|
48
|
+
profile: str | None = typer.Option(None, "--profile"),
|
|
49
|
+
org_id: str | None = typer.Option(None, "--org"),
|
|
50
|
+
project_id: str | None = typer.Option(None, "--project"),
|
|
51
|
+
) -> None:
|
|
52
|
+
"""The project's SAML connections, with the ACS URL and entity ID to give each IdP admin."""
|
|
53
|
+
print_json(_call("GET", "/api/v1/auth/saml/connections", "Loading SAML connections…", profile=profile,
|
|
54
|
+
org_id=org_id, project_id=project_id))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@saml_app.command("add")
|
|
58
|
+
def saml_add(
|
|
59
|
+
name: str = typer.Argument(..., help='A name, like "Acme (Okta)"'),
|
|
60
|
+
domain: list[str] = typer.Option(..., "--domain", "-d", help="Email domain this IdP signs in (repeat for more)"),
|
|
61
|
+
metadata: typer.FileText | None = typer.Option(None, "--metadata", help="The IdP's metadata XML file"),
|
|
62
|
+
entity_id: str | None = typer.Option(None, "--entity-id", help="IdP entity ID (instead of --metadata)"),
|
|
63
|
+
sso_url: str | None = typer.Option(None, "--sso-url", help="IdP HTTP-Redirect sign-in URL (instead of --metadata)"),
|
|
64
|
+
certificate: typer.FileText | None = typer.Option(None, "--certificate", help="IdP signing certificate PEM file"),
|
|
65
|
+
profile: str | None = typer.Option(None, "--profile"),
|
|
66
|
+
org_id: str | None = typer.Option(None, "--org"),
|
|
67
|
+
project_id: str | None = typer.Option(None, "--project"),
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Connect a customer's identity provider (metadata XML, or entity ID + sign-in URL + certificate)."""
|
|
70
|
+
body: dict = {"name": name, "domains": domain}
|
|
71
|
+
if metadata is not None:
|
|
72
|
+
body["metadata_xml"] = metadata.read()
|
|
73
|
+
elif entity_id and sso_url and certificate is not None:
|
|
74
|
+
body.update(idp_entity_id=entity_id, idp_sso_url=sso_url, idp_certificate_pem=certificate.read())
|
|
75
|
+
else:
|
|
76
|
+
raise typer.BadParameter("give --metadata, or --entity-id, --sso-url and --certificate")
|
|
77
|
+
print_json(_call("POST", "/api/v1/auth/saml/connections", "Adding the connection…", body=body, profile=profile,
|
|
78
|
+
org_id=org_id, project_id=project_id))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _toggle(connection_id: str, enabled: bool, profile, org_id, project_id) -> None:
|
|
82
|
+
print_json(_call("PATCH", f"/api/v1/auth/saml/connections/{connection_id}", "Saving…", body={"enabled": enabled},
|
|
83
|
+
profile=profile, org_id=org_id, project_id=project_id))
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@saml_app.command("enable")
|
|
87
|
+
def saml_enable(connection_id: str, profile: str | None = typer.Option(None, "--profile"),
|
|
88
|
+
org_id: str | None = typer.Option(None, "--org"), project_id: str | None = typer.Option(None, "--project")) -> None:
|
|
89
|
+
"""Turn a connection on."""
|
|
90
|
+
_toggle(connection_id, True, profile, org_id, project_id)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@saml_app.command("disable")
|
|
94
|
+
def saml_disable(connection_id: str, profile: str | None = typer.Option(None, "--profile"),
|
|
95
|
+
org_id: str | None = typer.Option(None, "--org"), project_id: str | None = typer.Option(None, "--project")) -> None:
|
|
96
|
+
"""Turn a connection off (its users keep their accounts)."""
|
|
97
|
+
_toggle(connection_id, False, profile, org_id, project_id)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@saml_app.command("remove")
|
|
101
|
+
def saml_remove(
|
|
102
|
+
connection_id: str,
|
|
103
|
+
yes: bool = typer.Option(False, "--yes", "-y"),
|
|
104
|
+
profile: str | None = typer.Option(None, "--profile"),
|
|
105
|
+
org_id: str | None = typer.Option(None, "--org"),
|
|
106
|
+
project_id: str | None = typer.Option(None, "--project"),
|
|
107
|
+
) -> None:
|
|
108
|
+
"""Remove a connection: its domains can no longer sign in with SSO (accounts stay)."""
|
|
109
|
+
if not yes:
|
|
110
|
+
typer.confirm("Remove this SAML connection? Its users can no longer sign in with SSO.", abort=True)
|
|
111
|
+
_call("DELETE", f"/api/v1/auth/saml/connections/{connection_id}", "Removing…", profile=profile,
|
|
112
|
+
org_id=org_id, project_id=project_id)
|
|
113
|
+
|
|
114
|
+
|
|
41
115
|
# ── SCIM ──────────────────────────────────────────────────────────────────────
|
|
42
116
|
|
|
43
117
|
|
|
@@ -100,6 +100,7 @@ app.add_typer(login_mod.app, name="auth", help="Authentication commands")
|
|
|
100
100
|
app.add_typer(auth_product_mod.app, name="auth-product", help="Product auth admin commands")
|
|
101
101
|
from apps.cli.src.commands import auth_enterprise as auth_enterprise_mod # noqa: E402
|
|
102
102
|
|
|
103
|
+
app.add_typer(auth_enterprise_mod.saml_app, name="saml", help="SAML single sign-on for your app's users")
|
|
103
104
|
app.add_typer(auth_enterprise_mod.scim_app, name="scim", help="SCIM 2.0 provisioning of app users and groups")
|
|
104
105
|
app.add_typer(auth_enterprise_mod.hooks_app, name="auth-hooks", help="Blocking auth hooks (before-create, before-sign-in)")
|
|
105
106
|
app.add_typer(context_mod.app, name="context", help="Context and identity commands")
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sovaria-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "Sovaria BaaS command-line interface (sov)"
|
|
9
9
|
readme = "apps/cli/README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -12,7 +12,7 @@ license = { text = "MIT" }
|
|
|
12
12
|
authors = [{ name = "Sovaria Team" }]
|
|
13
13
|
# Keep in sync with requirements.txt. Pin sovaria-sdk exactly and publish CLI+SDK together.
|
|
14
14
|
dependencies = [
|
|
15
|
-
"sovaria-sdk==0.
|
|
15
|
+
"sovaria-sdk==0.6.0",
|
|
16
16
|
"typer>=0.17.4",
|
|
17
17
|
"httpx>=0.28.1",
|
|
18
18
|
"keyring>=25.0",
|
|
@@ -31,7 +31,7 @@ sov = "apps.cli.src.main:cli_entry"
|
|
|
31
31
|
|
|
32
32
|
[project.optional-dependencies]
|
|
33
33
|
mcp = [
|
|
34
|
-
"sovaria-sdk[mcp]==0.
|
|
34
|
+
"sovaria-sdk[mcp]==0.6.0",
|
|
35
35
|
]
|
|
36
36
|
dev = [
|
|
37
37
|
"pytest>=8.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|