mirror of
https://github.com/trustedsec/hate_crack.git
synced 2026-03-12 21:23:05 -07:00
fix: handle Hashview create_job error response correctly
When the Hashview server returns HTTP 200 with an error message and no job_id (due to its internal notify_email bug), the CLI and interactive paths now: - exit 1 (not 0) in the CLI path - print "✗ Error" instead of "✓ Success" - print a hint to check the Hashview UI before retrying, preventing duplicate job creation Adds test for the error response path in test_cli_flags.py.
This commit is contained in:
@@ -2898,10 +2898,9 @@ def hashview_api():
|
||||
customer_id,
|
||||
limit_recovered,
|
||||
)
|
||||
print(
|
||||
f"\n✓ Success: {job_result.get('msg', 'Job created')}"
|
||||
)
|
||||
msg = job_result.get("msg", "")
|
||||
if "job_id" in job_result:
|
||||
print(f"\n✓ Success: {msg or 'Job created'}")
|
||||
print(f" Job ID: {job_result['job_id']}")
|
||||
print(
|
||||
"\nNote: Job created with automatically assigned tasks based on"
|
||||
@@ -2928,6 +2927,14 @@ def hashview_api():
|
||||
print(
|
||||
f"\n✓ Success: {start_result.get('msg', 'Job started')}"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"\n✗ Error: {msg or 'Job creation failed (no job_id returned)'}"
|
||||
)
|
||||
print(
|
||||
" Note: The Hashview server may have created the job"
|
||||
" despite this error. Check the Hashview UI before retrying."
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"\n✗ Error creating job: {str(e)}")
|
||||
except Exception as e:
|
||||
@@ -3595,11 +3602,6 @@ def main():
|
||||
action="store_true",
|
||||
help="Limit to recovered hashes only",
|
||||
)
|
||||
hv_upload_hashfile_job.add_argument(
|
||||
"--no-notify-email",
|
||||
action="store_true",
|
||||
help="Disable email notifications",
|
||||
)
|
||||
return parser, hashview_parser
|
||||
|
||||
# Removed add_common_args(parser) since config items are now only set via config file
|
||||
@@ -3761,12 +3763,19 @@ def main():
|
||||
upload_result["hashfile_id"],
|
||||
args.customer_id,
|
||||
limit_recovered=args.limit_recovered,
|
||||
notify_email=not args.no_notify_email,
|
||||
)
|
||||
print(f"\n✓ Success: {job_result.get('msg', 'Job created')}")
|
||||
msg = job_result.get("msg", "")
|
||||
if "job_id" in job_result:
|
||||
print(f"\n✓ Success: {msg or 'Job created'}")
|
||||
print(f" Job ID: {job_result['job_id']}")
|
||||
sys.exit(0)
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(f"\n✗ Error: {msg or 'Job creation failed (no job_id returned)'}")
|
||||
print(
|
||||
" Note: The Hashview server may have created the job despite this error."
|
||||
" Check the Hashview UI before retrying."
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
print("✗ Error: No hashview subcommand provided.")
|
||||
hashview_parser.print_help()
|
||||
|
||||
@@ -258,7 +258,6 @@ def test_hashview_upload_hashfile_job_flags(monkeypatch, tmp_path, capsys):
|
||||
"--job-name",
|
||||
"TestJob",
|
||||
"--limit-recovered",
|
||||
"--no-notify-email",
|
||||
],
|
||||
)
|
||||
assert code == 0
|
||||
@@ -267,6 +266,102 @@ def test_hashview_upload_hashfile_job_flags(monkeypatch, tmp_path, capsys):
|
||||
assert "Job created" in out
|
||||
|
||||
|
||||
def test_hashview_upload_hashfile_job_no_notify_email_by_default(
|
||||
monkeypatch, tmp_path, capsys
|
||||
):
|
||||
"""CLI must not send notify_email - it causes the server to create the job but
|
||||
return 'Failed to add job: notify_email is invalid', hiding the created job and
|
||||
causing a second job to be created on retry."""
|
||||
captured_kwargs: dict = {}
|
||||
|
||||
class TrackingAPI:
|
||||
def __init__(self, base_url, api_key, debug=False):
|
||||
pass
|
||||
|
||||
def upload_hashfile(
|
||||
self, file_path, customer_id, hash_type, file_format=5, hashfile_name=None
|
||||
):
|
||||
return {"msg": "Hashfile uploaded", "hashfile_id": 456}
|
||||
|
||||
def create_job(
|
||||
self, name, hashfile_id, customer_id, limit_recovered=False, notify_email=None
|
||||
):
|
||||
captured_kwargs["notify_email"] = notify_email
|
||||
return {"msg": "Job created", "job_id": 789}
|
||||
|
||||
hashfile = tmp_path / "hashes.txt"
|
||||
hashfile.write_text("hash1\n")
|
||||
monkeypatch.setattr(hc_main, "HashviewAPI", TrackingAPI)
|
||||
monkeypatch.setattr(hc_main, "hashview_api_key", "dummy")
|
||||
monkeypatch.setattr(hc_main, "hashview_url", "https://hv.example.com")
|
||||
code = _run_main(
|
||||
monkeypatch,
|
||||
[
|
||||
"hashview",
|
||||
"upload-hashfile-job",
|
||||
"--file",
|
||||
str(hashfile),
|
||||
"--customer-id",
|
||||
"1",
|
||||
"--hash-type",
|
||||
"1000",
|
||||
"--job-name",
|
||||
"TestJob",
|
||||
],
|
||||
)
|
||||
assert code == 0
|
||||
assert captured_kwargs["notify_email"] is None
|
||||
|
||||
|
||||
def test_hashview_upload_hashfile_job_error_response_exits_nonzero(
|
||||
monkeypatch, tmp_path, capsys
|
||||
):
|
||||
"""When create_job returns an error response (no job_id), exit code must be 1
|
||||
and output must show ✗ Error with a hint to check the Hashview UI."""
|
||||
|
||||
class ErrorJobAPI:
|
||||
def __init__(self, base_url, api_key, debug=False):
|
||||
pass
|
||||
|
||||
def upload_hashfile(
|
||||
self, file_path, customer_id, hash_type, file_format=5, hashfile_name=None
|
||||
):
|
||||
return {"msg": "Hashfile uploaded", "hashfile_id": 456}
|
||||
|
||||
def create_job(
|
||||
self, name, hashfile_id, customer_id, limit_recovered=False, notify_email=None
|
||||
):
|
||||
return {
|
||||
"msg": "Failed to add job: 'notify_email' is an invalid keyword argument for JobNotifications"
|
||||
}
|
||||
|
||||
hashfile = tmp_path / "hashes.txt"
|
||||
hashfile.write_text("hash1\n")
|
||||
monkeypatch.setattr(hc_main, "HashviewAPI", ErrorJobAPI)
|
||||
monkeypatch.setattr(hc_main, "hashview_api_key", "dummy")
|
||||
monkeypatch.setattr(hc_main, "hashview_url", "https://hv.example.com")
|
||||
code = _run_main(
|
||||
monkeypatch,
|
||||
[
|
||||
"hashview",
|
||||
"upload-hashfile-job",
|
||||
"--file",
|
||||
str(hashfile),
|
||||
"--customer-id",
|
||||
"1",
|
||||
"--hash-type",
|
||||
"1000",
|
||||
"--job-name",
|
||||
"TestJob",
|
||||
],
|
||||
)
|
||||
assert code == 1
|
||||
out = capsys.readouterr().out
|
||||
assert "✗ Error" in out
|
||||
assert "Job ID:" not in out
|
||||
assert "Check the Hashview UI before retrying" in out
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 8. Argparse error cases (exit 2)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user