399ed93dc8
Replaces cli.sh + lib/*.sh with a claude_bottle/ Python package and a
cli.py entry point. No external dependencies — uses only Python's
stdlib (json, subprocess, getpass, tempfile, argparse, re, etc.).
- claude_bottle/{log,docker,manifest,env_resolve,network,pipelock,
skills,ssh,cli}.py mirror the previous lib/*.sh modules.
- Tests converted to unittest under tests/test_*.py with a stdlib
runner at tests/run_tests.py (unit | integration | path).
- .githooks/commit-msg ported to Python; same Conventional Commits rules.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
34 lines
933 B
Python
34 lines
933 B
Python
"""Unit: is_ipv4_literal — the classifier that decides whether
|
|
bottle.ssh[].Hostname goes into ssrf.ip_allowlist (IPv4 literal) or
|
|
trusted_domains (hostname)."""
|
|
|
|
import unittest
|
|
|
|
from claude_bottle.pipelock import is_ipv4_literal
|
|
|
|
|
|
class TestIPv4Classify(unittest.TestCase):
|
|
def test_positive(self):
|
|
for ip in ("127.0.0.1", "10.0.0.5", "100.78.141.42", "0.0.0.0", "255.255.255.255"):
|
|
with self.subTest(ip=ip):
|
|
self.assertTrue(is_ipv4_literal(ip), ip)
|
|
|
|
def test_negative(self):
|
|
for hn in (
|
|
"github.com",
|
|
"gitea.dideric.is",
|
|
"100.78.141",
|
|
"100.78.141.42.5",
|
|
"::1",
|
|
"fe80::1",
|
|
"localhost",
|
|
"",
|
|
"1.2.3.4.example.com",
|
|
):
|
|
with self.subTest(hn=hn):
|
|
self.assertFalse(is_ipv4_literal(hn), hn)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|