mirror of
https://github.com/infinition/Bjorn.git
synced 2026-03-19 10:10:24 +00:00
feat: Add login page with dynamic RGB effects and password toggle functionality
feat: Implement package management utilities with JSON endpoints for listing and uninstalling packages feat: Create plugin management utilities with endpoints for listing, configuring, and installing plugins feat: Develop schedule and trigger management utilities with CRUD operations for schedules and triggers
This commit is contained in:
0
actions/custom/__init__.py
Normal file
0
actions/custom/__init__.py
Normal file
105
actions/custom/example_bjorn_action.py
Normal file
105
actions/custom/example_bjorn_action.py
Normal file
@@ -0,0 +1,105 @@
|
||||
"""example_bjorn_action.py - Custom action template using the Bjorn action format."""
|
||||
|
||||
import time
|
||||
import logging
|
||||
from logger import Logger
|
||||
|
||||
logger = Logger(name="example_bjorn_action", level=logging.DEBUG)
|
||||
|
||||
# ---- Bjorn action metadata (required for Bjorn format detection) ----
|
||||
b_class = "ExampleBjornAction"
|
||||
b_module = "custom/example_bjorn_action"
|
||||
b_name = "Example Bjorn Action"
|
||||
b_description = "Demo custom action with shared_data access and DB queries."
|
||||
b_author = "Bjorn Community"
|
||||
b_version = "1.0.0"
|
||||
b_action = "custom"
|
||||
b_enabled = 1
|
||||
b_priority = 50
|
||||
b_port = None
|
||||
b_service = None
|
||||
b_trigger = None
|
||||
b_parent = None
|
||||
b_cooldown = 0
|
||||
b_rate_limit = None
|
||||
b_tags = '["custom", "example", "template"]'
|
||||
|
||||
# ---- Argument schema (drives the web UI controls) ----
|
||||
b_args = {
|
||||
"target_ip": {
|
||||
"type": "text",
|
||||
"default": "192.168.1.1",
|
||||
"description": "Target IP address to probe"
|
||||
},
|
||||
"scan_count": {
|
||||
"type": "number",
|
||||
"default": 3,
|
||||
"min": 1,
|
||||
"max": 100,
|
||||
"description": "Number of probe iterations"
|
||||
},
|
||||
"verbose": {
|
||||
"type": "checkbox",
|
||||
"default": False,
|
||||
"description": "Enable verbose output"
|
||||
},
|
||||
"mode": {
|
||||
"type": "select",
|
||||
"choices": ["quick", "normal", "deep"],
|
||||
"default": "normal",
|
||||
"description": "Scan depth"
|
||||
}
|
||||
}
|
||||
|
||||
b_examples = [
|
||||
{"name": "Quick local scan", "args": {"target_ip": "192.168.1.1", "scan_count": 1, "mode": "quick"}},
|
||||
{"name": "Deep scan", "args": {"target_ip": "10.0.0.1", "scan_count": 10, "mode": "deep", "verbose": True}},
|
||||
]
|
||||
|
||||
|
||||
class ExampleBjornAction:
|
||||
"""Custom Bjorn action with full shared_data access."""
|
||||
|
||||
def __init__(self, shared_data):
|
||||
self.shared_data = shared_data
|
||||
logger.info("ExampleBjornAction initialized")
|
||||
|
||||
def execute(self, ip, port, row, status_key):
|
||||
"""Main entry point called by action_runner / orchestrator.
|
||||
|
||||
Args:
|
||||
ip: Target IP address
|
||||
port: Target port (may be empty)
|
||||
row: Dict with MAC Address, IPs, Ports, Alive
|
||||
status_key: Action class name (for status tracking)
|
||||
|
||||
Returns:
|
||||
'success' or 'failed'
|
||||
"""
|
||||
verbose = getattr(self.shared_data, "verbose", False)
|
||||
scan_count = int(getattr(self.shared_data, "scan_count", 3))
|
||||
mode = getattr(self.shared_data, "mode", "normal")
|
||||
|
||||
print(f"[*] Running ExampleBjornAction on {ip} (mode={mode}, count={scan_count})")
|
||||
|
||||
# Example: query DB for known hosts
|
||||
try:
|
||||
host_count = self.shared_data.db.query_one(
|
||||
"SELECT COUNT(1) c FROM hosts"
|
||||
)
|
||||
print(f"[*] Known hosts in DB: {host_count['c'] if host_count else 0}")
|
||||
except Exception as e:
|
||||
print(f"[!] DB query failed: {e}")
|
||||
|
||||
# Simulate work
|
||||
for i in range(scan_count):
|
||||
if getattr(self.shared_data, "orchestrator_should_exit", False):
|
||||
print("[!] Stop requested, aborting")
|
||||
return "failed"
|
||||
print(f"[*] Probe {i+1}/{scan_count} on {ip}...")
|
||||
if verbose:
|
||||
print(f" MAC={row.get('MAC Address', 'unknown')} mode={mode}")
|
||||
time.sleep(1)
|
||||
|
||||
print(f"[+] Done. {scan_count} probes completed on {ip}")
|
||||
return "success"
|
||||
97
actions/custom/example_free_script.py
Normal file
97
actions/custom/example_free_script.py
Normal file
@@ -0,0 +1,97 @@
|
||||
"""example_free_script.py - Custom script template using plain Python (no shared_data)."""
|
||||
|
||||
import argparse
|
||||
import time
|
||||
import sys
|
||||
|
||||
# ---- Display metadata (optional, used by the web UI) ----
|
||||
b_name = "Example Free Script"
|
||||
b_description = "Standalone Python script demo with argparse and progress output."
|
||||
b_author = "Bjorn Community"
|
||||
b_version = "1.0.0"
|
||||
b_tags = '["custom", "example", "template", "free"]'
|
||||
|
||||
# ---- Argument schema (drives the web UI controls, same format as Bjorn actions) ----
|
||||
b_args = {
|
||||
"target": {
|
||||
"type": "text",
|
||||
"default": "192.168.1.0/24",
|
||||
"description": "Target host or CIDR range"
|
||||
},
|
||||
"timeout": {
|
||||
"type": "number",
|
||||
"default": 5,
|
||||
"min": 1,
|
||||
"max": 60,
|
||||
"description": "Timeout per probe in seconds"
|
||||
},
|
||||
"output_format": {
|
||||
"type": "select",
|
||||
"choices": ["text", "json", "csv"],
|
||||
"default": "text",
|
||||
"description": "Output format"
|
||||
},
|
||||
"dry_run": {
|
||||
"type": "checkbox",
|
||||
"default": False,
|
||||
"description": "Simulate without actually probing"
|
||||
}
|
||||
}
|
||||
|
||||
b_examples = [
|
||||
{"name": "Quick local check", "args": {"target": "192.168.1.1", "timeout": 2, "output_format": "text"}},
|
||||
{"name": "Dry run JSON", "args": {"target": "10.0.0.0/24", "timeout": 5, "output_format": "json", "dry_run": True}},
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Example free-form Bjorn custom script")
|
||||
parser.add_argument("--target", default="192.168.1.0/24", help="Target host or CIDR")
|
||||
parser.add_argument("--timeout", type=int, default=5, help="Timeout per probe (seconds)")
|
||||
parser.add_argument("--output-format", default="text", choices=["text", "json", "csv"])
|
||||
parser.add_argument("--dry-run", action="store_true", help="Simulate without probing")
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"[*] Example Free Script starting")
|
||||
print(f"[*] Target: {args.target}")
|
||||
print(f"[*] Timeout: {args.timeout}s")
|
||||
print(f"[*] Format: {args.output_format}")
|
||||
print(f"[*] Dry run: {args.dry_run}")
|
||||
print()
|
||||
|
||||
# Simulate some work with progress output
|
||||
steps = 5
|
||||
for i in range(steps):
|
||||
print(f"[*] Step {i+1}/{steps}: {'simulating' if args.dry_run else 'probing'} {args.target}...")
|
||||
time.sleep(1)
|
||||
|
||||
# Example output in different formats
|
||||
results = [
|
||||
{"host": "192.168.1.1", "status": "up", "latency": "2ms"},
|
||||
{"host": "192.168.1.100", "status": "up", "latency": "5ms"},
|
||||
]
|
||||
|
||||
if args.output_format == "json":
|
||||
import json
|
||||
print(json.dumps(results, indent=2))
|
||||
elif args.output_format == "csv":
|
||||
print("host,status,latency")
|
||||
for r in results:
|
||||
print(f"{r['host']},{r['status']},{r['latency']}")
|
||||
else:
|
||||
for r in results:
|
||||
print(f" {r['host']} {r['status']} ({r['latency']})")
|
||||
|
||||
print()
|
||||
print(f"[+] Done. Found {len(results)} hosts.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\n[!] Interrupted")
|
||||
sys.exit(130)
|
||||
except Exception as e:
|
||||
print(f"\n[!] Error: {e}")
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user