humanbound-cli 0.3.1__tar.gz → 0.3.2__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.
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/PKG-INFO +1 -1
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/client.py +83 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/auth.py +38 -7
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/main.py +3 -2
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli.egg-info/PKG-INFO +1 -1
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/pyproject.toml +1 -1
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/LICENSE +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/README.md +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/__init__.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/__init__.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/api_keys.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/campaigns.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/coverage.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/docs.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/experiments.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/findings.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/guardrails.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/init.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/logs.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/members.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/orgs.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/posture.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/projects.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/providers.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/scan.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/test.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/commands/upload_logs.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/config.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/exceptions.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/extractors/__init__.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/extractors/openapi.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/extractors/repo.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/pytest_plugin/__init__.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/pytest_plugin/fixtures.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/pytest_plugin/report.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/report.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/serve/__init__.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/serve/config_builder.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/serve/local_server.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/serve/runtime_detector.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli/serve/tunnel_client.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli.egg-info/SOURCES.txt +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli.egg-info/dependency_links.txt +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli.egg-info/entry_points.txt +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli.egg-info/requires.txt +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/humanbound_cli.egg-info/top_level.txt +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/relay/relay.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/setup.cfg +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/tests/__init__.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/tests/cli_integration_test.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/tests/conftest.py +0 -0
- {humanbound_cli-0.3.1 → humanbound_cli-0.3.2}/tests/test_cli_commands.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: humanbound-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Humanbound CLI - command line interface for AI agent security testing.
|
|
5
5
|
Author-email: Kostas Siabanis <hello@humanbound.ai>, Demetris Gerogiannis <hello@humanbound.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -206,6 +206,89 @@ ERROR_HTML = """<!DOCTYPE html>
|
|
|
206
206
|
</html>"""
|
|
207
207
|
|
|
208
208
|
|
|
209
|
+
LOGOUT_HTML = """<!DOCTYPE html>
|
|
210
|
+
<html>
|
|
211
|
+
<head>
|
|
212
|
+
<title>Humanbound CLI - Logged Out</title>
|
|
213
|
+
<style>
|
|
214
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
215
|
+
body {
|
|
216
|
+
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
|
|
217
|
+
background: linear-gradient(135deg, #0d1117 0%, #161b22 100%);
|
|
218
|
+
color: #e6edf3;
|
|
219
|
+
min-height: 100vh;
|
|
220
|
+
display: flex;
|
|
221
|
+
align-items: center;
|
|
222
|
+
justify-content: center;
|
|
223
|
+
}
|
|
224
|
+
.container {
|
|
225
|
+
text-align: center;
|
|
226
|
+
padding: 3rem;
|
|
227
|
+
background: rgba(22, 27, 34, 0.8);
|
|
228
|
+
border: 1px solid #30363d;
|
|
229
|
+
border-radius: 12px;
|
|
230
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
|
|
231
|
+
max-width: 480px;
|
|
232
|
+
}
|
|
233
|
+
.icon {
|
|
234
|
+
width: 64px;
|
|
235
|
+
height: 64px;
|
|
236
|
+
margin-bottom: 1.5rem;
|
|
237
|
+
background: #58a6ff;
|
|
238
|
+
border-radius: 50%;
|
|
239
|
+
display: flex;
|
|
240
|
+
align-items: center;
|
|
241
|
+
justify-content: center;
|
|
242
|
+
margin-left: auto;
|
|
243
|
+
margin-right: auto;
|
|
244
|
+
}
|
|
245
|
+
.icon svg { width: 32px; height: 32px; fill: white; }
|
|
246
|
+
h1 {
|
|
247
|
+
font-size: 1.5rem;
|
|
248
|
+
font-weight: 600;
|
|
249
|
+
margin-bottom: 0.75rem;
|
|
250
|
+
color: #58a6ff;
|
|
251
|
+
}
|
|
252
|
+
p {
|
|
253
|
+
color: #8b949e;
|
|
254
|
+
font-size: 0.9rem;
|
|
255
|
+
line-height: 1.6;
|
|
256
|
+
}
|
|
257
|
+
.command {
|
|
258
|
+
background: #0d1117;
|
|
259
|
+
border: 1px solid #30363d;
|
|
260
|
+
border-radius: 6px;
|
|
261
|
+
padding: 1rem;
|
|
262
|
+
margin-top: 1.5rem;
|
|
263
|
+
font-size: 0.85rem;
|
|
264
|
+
}
|
|
265
|
+
.command code {
|
|
266
|
+
color: #7ee787;
|
|
267
|
+
}
|
|
268
|
+
.prompt { color: #6e7681; }
|
|
269
|
+
.close-hint {
|
|
270
|
+
margin-top: 1.5rem;
|
|
271
|
+
font-size: 0.8rem;
|
|
272
|
+
color: #6e7681;
|
|
273
|
+
}
|
|
274
|
+
</style>
|
|
275
|
+
</head>
|
|
276
|
+
<body>
|
|
277
|
+
<div class="container">
|
|
278
|
+
<div class="icon">
|
|
279
|
+
<svg viewBox="0 0 24 24"><path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z"/></svg>
|
|
280
|
+
</div>
|
|
281
|
+
<h1>Session Revoked</h1>
|
|
282
|
+
<p>Your local credentials and browser session have been cleared.</p>
|
|
283
|
+
<div class="command">
|
|
284
|
+
<span class="prompt">$</span> <code>hb login</code>
|
|
285
|
+
</div>
|
|
286
|
+
<p class="close-hint">You can close this tab</p>
|
|
287
|
+
</div>
|
|
288
|
+
</body>
|
|
289
|
+
</html>"""
|
|
290
|
+
|
|
291
|
+
|
|
209
292
|
class HumanboundClient:
|
|
210
293
|
"""API client for Humanbound platform with OAuth authentication."""
|
|
211
294
|
|
|
@@ -65,20 +65,51 @@ def login(base_url: str, port: int, force: bool):
|
|
|
65
65
|
|
|
66
66
|
@auth_group.command("logout")
|
|
67
67
|
@click.option("--revoke", is_flag=True, help="Also clear browser SSO session (opens browser)")
|
|
68
|
-
|
|
68
|
+
@click.option("--port", default=8085, help="Local callback port (default: 8085)")
|
|
69
|
+
def logout(revoke: bool, port: int):
|
|
69
70
|
"""Clear stored credentials."""
|
|
70
|
-
import webbrowser
|
|
71
|
-
from ..config import get_auth0_domain, get_auth0_client_id
|
|
72
|
-
|
|
73
71
|
client = HumanboundClient()
|
|
74
72
|
client.logout() # This already prints the success message
|
|
75
73
|
|
|
76
74
|
if revoke:
|
|
75
|
+
import webbrowser
|
|
76
|
+
import urllib.parse
|
|
77
|
+
import http.server
|
|
78
|
+
import socketserver
|
|
79
|
+
from ..config import get_auth0_domain, get_auth0_client_id
|
|
80
|
+
from ..client import LOGOUT_HTML
|
|
81
|
+
|
|
77
82
|
auth0_domain = get_auth0_domain()
|
|
78
83
|
client_id = get_auth0_client_id()
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
return_to = f"http://localhost:{port}"
|
|
85
|
+
|
|
86
|
+
logout_url = (
|
|
87
|
+
f"https://{auth0_domain}/v2/logout?"
|
|
88
|
+
+ urllib.parse.urlencode({"client_id": client_id, "returnTo": return_to})
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
class LogoutHandler(http.server.BaseHTTPRequestHandler):
|
|
92
|
+
def do_GET(self):
|
|
93
|
+
self.send_response(200)
|
|
94
|
+
self.send_header("Content-type", "text/html")
|
|
95
|
+
self.end_headers()
|
|
96
|
+
self.wfile.write(LOGOUT_HTML.encode())
|
|
97
|
+
|
|
98
|
+
def log_message(self, format, *args):
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
socketserver.TCPServer.allow_reuse_address = True
|
|
102
|
+
server = socketserver.TCPServer(("", port), LogoutHandler)
|
|
103
|
+
server.timeout = 30
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
console.print("Opening browser to clear Auth0 session...")
|
|
107
|
+
webbrowser.open(logout_url)
|
|
108
|
+
server.handle_request()
|
|
109
|
+
finally:
|
|
110
|
+
server.server_close()
|
|
111
|
+
|
|
112
|
+
console.print("[green]Browser session revoked.[/green]")
|
|
82
113
|
else:
|
|
83
114
|
console.print(
|
|
84
115
|
"[dim]Note: Your browser may still have an active Auth0 session. "
|
|
@@ -98,10 +98,11 @@ def login_alias(ctx):
|
|
|
98
98
|
|
|
99
99
|
@cli.command("logout")
|
|
100
100
|
@click.option("--revoke", is_flag=True, help="Also clear browser SSO session (opens browser)")
|
|
101
|
+
@click.option("--port", default=8085, help="Local callback port (default: 8085)")
|
|
101
102
|
@click.pass_context
|
|
102
|
-
def logout_alias(ctx, revoke):
|
|
103
|
+
def logout_alias(ctx, revoke, port):
|
|
103
104
|
"""Clear stored credentials (alias for 'auth logout')."""
|
|
104
|
-
ctx.invoke(auth.logout, revoke=revoke)
|
|
105
|
+
ctx.invoke(auth.logout, revoke=revoke, port=port)
|
|
105
106
|
|
|
106
107
|
|
|
107
108
|
@cli.command("whoami")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: humanbound-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Humanbound CLI - command line interface for AI agent security testing.
|
|
5
5
|
Author-email: Kostas Siabanis <hello@humanbound.ai>, Demetris Gerogiannis <hello@humanbound.ai>
|
|
6
6
|
License: Apache-2.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
|