"""Management tools for programs and targets."""
import uuid
from typing import Dict, Any, List, Optional
from datetime import datetime
from ..models import (
BugBountyProgram,
Platform,
ScopeRule,
ScopeType,
Severity,
Target,
AuditLogEntry,
)
from ..config import ConfigManager
from ..utils.validators import ScopeValidator
from ..storage.database import DatabaseManager
class ManagementTools:
"""Tools for managing bug bounty programs and targets."""
def __init__(self, config: ConfigManager, db: DatabaseManager):
"""Initialize management tools.
Args:
config: Configuration manager
db: Database manager
"""
self.config = config
self.db = db
async def add_program(
self,
program_name: str,
platform: str,
scope_domains: List[str],
scope_ips: Optional[List[str]] = None,
out_of_scope: Optional[List[str]] = None,
api_token: Optional[str] = None,
url: Optional[str] = None,
) -> Dict[str, Any]:
"""Add a new bug bounty program.
Args:
program_name: Name of the program
platform: Platform (hackerone, bugcrowd, etc.)
scope_domains: List of in-scope domains
scope_ips: List of in-scope IP ranges
out_of_scope: List of out-of-scope targets
api_token: API token for platform integration
url: Program URL
Returns:
Dictionary with program details
"""
# Generate program ID
program_id = f"{platform}-{program_name.lower().replace(' ', '-')}"
# Build scope rules
in_scope_rules = []
for domain in scope_domains:
in_scope_rules.append(ScopeRule(
type=ScopeType.DOMAIN,
target=domain,
wildcard=domain.startswith('*.')
))
if scope_ips:
for ip in scope_ips:
in_scope_rules.append(ScopeRule(
type=ScopeType.IP_RANGE,
target=ip
))
out_of_scope_rules = []
if out_of_scope:
for target in out_of_scope:
# Auto-detect type
if any(c.isalpha() for c in target):
scope_type = ScopeType.DOMAIN
else:
scope_type = ScopeType.IP_RANGE
out_of_scope_rules.append(ScopeRule(
type=scope_type,
target=target
))
# Create program
program = BugBountyProgram(
program_id=program_id,
platform=Platform(platform.lower()),
name=program_name,
url=url or f"https://{platform}.com/{program_name}",
in_scope=in_scope_rules,
out_of_scope=out_of_scope_rules,
enrolled=True, # Automatically enroll when adding
api_token=api_token,
)
# Save to config
self.config.save_program(program)
# Log audit
self.db.log_audit(AuditLogEntry(
action="add_program",
program_id=program_id,
success=True,
details={
'program_name': program_name,
'platform': platform,
'in_scope_count': len(in_scope_rules),
'out_of_scope_count': len(out_of_scope_rules),
}
))
return {
'success': True,
'program_id': program_id,
'message': f"Program '{program_name}' added successfully",
'in_scope_count': len(in_scope_rules),
'out_of_scope_count': len(out_of_scope_rules),
}
async def list_programs(
self,
platform: Optional[str] = None,
enrolled_only: bool = False,
) -> Dict[str, Any]:
"""List configured bug bounty programs.
Args:
platform: Filter by platform (optional)
enrolled_only: Only show enrolled programs
Returns:
Dictionary with program list
"""
platform_enum = Platform(platform.lower()) if platform else None
programs = self.config.list_programs(platform_enum, enrolled_only)
return {
'success': True,
'count': len(programs),
'programs': [
{
'program_id': p.program_id,
'name': p.name,
'platform': p.platform,
'enrolled': p.enrolled,
'in_scope_count': len(p.in_scope),
'out_of_scope_count': len(p.out_of_scope),
'url': p.url,
}
for p in programs
]
}
async def get_program_scope(self, program_id: str) -> Dict[str, Any]:
"""Get detailed scope information for a program.
Args:
program_id: Program identifier
Returns:
Dictionary with scope details
"""
program = self.config.get_program(program_id)
if not program:
return {
'success': False,
'error': f"Program '{program_id}' not found"
}
validator = ScopeValidator(program)
return {
'success': True,
**validator.get_scope_summary()
}
async def validate_target(self, program_id: str, target: str) -> Dict[str, Any]:
"""Validate if a target is in scope for a program.
Args:
program_id: Program identifier
target: Target to validate
Returns:
Dictionary with validation result
"""
program = self.config.get_program(program_id)
if not program:
return {
'success': False,
'in_scope': False,
'error': f"Program '{program_id}' not found"
}
validator = ScopeValidator(program)
is_valid, reason = validator.validate_target(target)
# Log validation attempt
self.db.log_audit(AuditLogEntry(
action="validate_target",
program_id=program_id,
target=target,
success=True,
validation_result=reason,
details={'in_scope': is_valid}
))
return {
'success': True,
'in_scope': is_valid,
'reason': reason,
'program_id': program_id,
'target': target,
}
async def add_target(
self,
program_id: str,
target: str,
target_type: Optional[str] = None,
notes: Optional[str] = None,
) -> Dict[str, Any]:
"""Add a target to a program.
Args:
program_id: Program identifier
target: Target value
target_type: Type of target (optional, auto-detected)
notes: Optional notes
Returns:
Dictionary with result
"""
program = self.config.get_program(program_id)
if not program:
return {
'success': False,
'error': f"Program '{program_id}' not found"
}
# Validate target
validator = ScopeValidator(program)
is_valid, reason = validator.validate_target(target)
# Auto-detect type if not provided
if not target_type:
normalized = validator._normalize_target(target)
detected_type = validator._detect_target_type(normalized)
target_type = detected_type.value
# Create target
target_obj = Target(
target_id=str(uuid.uuid4()),
program_id=program_id,
value=target,
type=ScopeType(target_type),
in_scope=is_valid,
notes=notes,
)
# Save to database
self.db.save_target(target_obj)
return {
'success': True,
'target_id': target_obj.target_id,
'in_scope': is_valid,
'validation_reason': reason,
}
async def get_statistics(
self,
program_id: Optional[str] = None,
) -> Dict[str, Any]:
"""Get statistics on scans and findings.
Args:
program_id: Filter by program ID (optional)
Returns:
Dictionary with statistics
"""
stats = self.db.get_statistics(program_id)
return {
'success': True,
'program_id': program_id,
**stats
}