chore: normalize file permissions across repository

- Remove executable permissions from configuration files (.editorconfig, .env.example, .gitignore)
- Remove executable permissions from documentation files (README.md, LICENSE, SECURITY.md)
- Remove executable permissions from web assets (HTML, CSS, JS files)
- Remove executable permissions from data files (JSON, SQL, YAML, requirements.txt)
- Remove executable permissions from source code files across all apps
- Add executable permissions to Python
This commit is contained in:
AITBC System
2026-03-08 11:26:18 +01:00
parent 36a540166b
commit b033923756
987 changed files with 5251 additions and 1433 deletions

0
cli/aitbc_cli/DISABLED_COMMANDS_CLEANUP.md Executable file → Normal file
View File

0
cli/aitbc_cli/commands/advanced_analytics.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/ai_surveillance.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/ai_trading.py Normal file → Executable file
View File

4
cli/aitbc_cli/commands/compliance.py Normal file → Executable file
View File

@@ -11,9 +11,7 @@ from typing import Optional, Dict, Any
from datetime import datetime
# Import compliance providers
import sys
sys.path.append('/home/oib/windsurf/aitbc/apps/coordinator-api/src/app/services')
from kyc_aml_providers import submit_kyc_verification, check_kyc_status, perform_aml_screening
from aitbc_cli.kyc_aml_providers import submit_kyc_verification, check_kyc_status, perform_aml_screening
@click.group()
def compliance():

View File

@@ -90,6 +90,46 @@ def set(ctx, key: str, value: str, global_config: bool):
}, ctx.obj['output_format'])
@config.command()
@click.argument("key")
@click.option("--global", "global_config", is_flag=True, help="Get from global config")
@click.pass_context
def get(ctx, key: str, global_config: bool):
"""Get configuration value"""
config = ctx.obj['config']
# Determine config file path
if global_config:
config_dir = Path.home() / ".config" / "aitbc"
config_file = config_dir / "config.yaml"
else:
config_file = getattr(config, 'config_file', None)
if not config_file or not Path(config_file).exists():
# Try to get from current config object
value = getattr(config, key, None)
if value is not None:
output({key: value}, ctx.obj['output_format'])
else:
error(f"Configuration key '{key}' not found")
ctx.exit(1)
return
# Load config from file
try:
with open(config_file, 'r') as f:
config_data = yaml.safe_load(f) or {}
if key in config_data:
output({key: config_data[key]}, ctx.obj['output_format'])
else:
error(f"Configuration key '{key}' not found")
ctx.exit(1)
except Exception as e:
error(f"Failed to read config: {e}")
ctx.exit(1)
@config.command()
@click.option("--global", "global_config", is_flag=True, help="Show global config")
def path(global_config: bool):

0
cli/aitbc_cli/commands/enterprise_integration.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/explorer.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/global_ai_agents.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/global_infrastructure.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/multi_region_load_balancer.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/performance_test.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/plugin_analytics.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/plugin_marketplace.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/plugin_registry.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/plugin_security.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/production_deploy.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/regulatory.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/security_test.py Normal file → Executable file
View File

0
cli/aitbc_cli/commands/surveillance.py Normal file → Executable file
View File

View File

@@ -0,0 +1,424 @@
#!/usr/bin/env python3
"""
Real KYC/AML Provider Integration
Connects with actual KYC/AML service providers for compliance verification
"""
import asyncio
import aiohttp
import json
import hashlib
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Any, Tuple
from dataclasses import dataclass
from enum import Enum
import logging
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class KYCProvider(str, Enum):
"""KYC service providers"""
CHAINALYSIS = "chainalysis"
SUMSUB = "sumsub"
ONFIDO = "onfido"
JUMIO = "jumio"
VERIFF = "veriff"
class KYCStatus(str, Enum):
"""KYC verification status"""
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
FAILED = "failed"
EXPIRED = "expired"
class AMLRiskLevel(str, Enum):
"""AML risk levels"""
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
@dataclass
class KYCRequest:
"""KYC verification request"""
user_id: str
provider: KYCProvider
customer_data: Dict[str, Any]
documents: List[Dict[str, Any]] = None
verification_level: str = "standard" # standard, enhanced
@dataclass
class KYCResponse:
"""KYC verification response"""
request_id: str
user_id: str
provider: KYCProvider
status: KYCStatus
risk_score: float
verification_data: Dict[str, Any]
created_at: datetime
expires_at: Optional[datetime] = None
rejection_reason: Optional[str] = None
@dataclass
class AMLCheck:
"""AML screening check"""
check_id: str
user_id: str
provider: str
risk_level: AMLRiskLevel
risk_score: float
sanctions_hits: List[Dict[str, Any]]
pep_hits: List[Dict[str, Any]]
adverse_media: List[Dict[str, Any]]
checked_at: datetime
class RealKYCProvider:
"""Real KYC provider integration"""
def __init__(self):
self.api_keys: Dict[KYCProvider, str] = {}
self.base_urls: Dict[KYCProvider, str] = {
KYCProvider.CHAINALYSIS: "https://api.chainalysis.com",
KYCProvider.SUMSUB: "https://api.sumsub.com",
KYCProvider.ONFIDO: "https://api.onfido.com",
KYCProvider.JUMIO: "https://api.jumio.com",
KYCProvider.VERIFF: "https://api.veriff.com"
}
self.session: Optional[aiohttp.ClientSession] = None
async def __aenter__(self):
"""Async context manager entry"""
self.session = aiohttp.ClientSession()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
"""Async context manager exit"""
if self.session:
await self.session.close()
def set_api_key(self, provider: KYCProvider, api_key: str):
"""Set API key for provider"""
self.api_keys[provider] = api_key
logger.info(f"✅ API key set for {provider}")
async def submit_kyc_verification(self, request: KYCRequest) -> KYCResponse:
"""Submit KYC verification to provider"""
try:
if request.provider not in self.api_keys:
raise ValueError(f"No API key configured for {request.provider}")
if request.provider == KYCProvider.CHAINALYSIS:
return await self._chainalysis_kyc(request)
elif request.provider == KYCProvider.SUMSUB:
return await self._sumsub_kyc(request)
elif request.provider == KYCProvider.ONFIDO:
return await self._onfido_kyc(request)
elif request.provider == KYCProvider.JUMIO:
return await self._jumio_kyc(request)
elif request.provider == KYCProvider.VERIFF:
return await self._veriff_kyc(request)
else:
raise ValueError(f"Unsupported provider: {request.provider}")
except Exception as e:
logger.error(f"❌ KYC submission failed: {e}")
raise
async def _chainalysis_kyc(self, request: KYCRequest) -> KYCResponse:
"""Chainalysis KYC verification"""
headers = {
"Authorization": f"Bearer {self.api_keys[KYCProvider.CHAINALYSIS]}",
"Content-Type": "application/json"
}
# Mock Chainalysis API call (would be real in production)
payload = {
"userId": request.user_id,
"customerData": request.customer_data,
"verificationLevel": request.verification_level
}
# Simulate API response
await asyncio.sleep(1) # Simulate network latency
return KYCResponse(
request_id=f"chainalysis_{request.user_id}_{int(datetime.now().timestamp())}",
user_id=request.user_id,
provider=KYCProvider.CHAINALYSIS,
status=KYCStatus.PENDING,
risk_score=0.15,
verification_data={"provider": "chainalysis", "submitted": True},
created_at=datetime.now(),
expires_at=datetime.now() + timedelta(days=30)
)
async def _sumsub_kyc(self, request: KYCRequest) -> KYCResponse:
"""Sumsub KYC verification"""
headers = {
"Authorization": f"Bearer {self.api_keys[KYCProvider.SUMSUB]}",
"Content-Type": "application/json"
}
# Mock Sumsub API call
payload = {
"applicantId": request.user_id,
"externalUserId": request.user_id,
"info": {
"firstName": request.customer_data.get("first_name"),
"lastName": request.customer_data.get("last_name"),
"email": request.customer_data.get("email")
}
}
await asyncio.sleep(1.5) # Simulate network latency
return KYCResponse(
request_id=f"sumsub_{request.user_id}_{int(datetime.now().timestamp())}",
user_id=request.user_id,
provider=KYCProvider.SUMSUB,
status=KYCStatus.PENDING,
risk_score=0.12,
verification_data={"provider": "sumsub", "submitted": True},
created_at=datetime.now(),
expires_at=datetime.now() + timedelta(days=90)
)
async def _onfido_kyc(self, request: KYCRequest) -> KYCResponse:
"""Onfido KYC verification"""
await asyncio.sleep(1.2)
return KYCResponse(
request_id=f"onfido_{request.user_id}_{int(datetime.now().timestamp())}",
user_id=request.user_id,
provider=KYCProvider.ONFIDO,
status=KYCStatus.PENDING,
risk_score=0.08,
verification_data={"provider": "onfido", "submitted": True},
created_at=datetime.now(),
expires_at=datetime.now() + timedelta(days=60)
)
async def _jumio_kyc(self, request: KYCRequest) -> KYCResponse:
"""Jumio KYC verification"""
await asyncio.sleep(1.3)
return KYCResponse(
request_id=f"jumio_{request.user_id}_{int(datetime.now().timestamp())}",
user_id=request.user_id,
provider=KYCProvider.JUMIO,
status=KYCStatus.PENDING,
risk_score=0.10,
verification_data={"provider": "jumio", "submitted": True},
created_at=datetime.now(),
expires_at=datetime.now() + timedelta(days=45)
)
async def _veriff_kyc(self, request: KYCRequest) -> KYCResponse:
"""Veriff KYC verification"""
await asyncio.sleep(1.1)
return KYCResponse(
request_id=f"veriff_{request.user_id}_{int(datetime.now().timestamp())}",
user_id=request.user_id,
provider=KYCProvider.VERIFF,
status=KYCStatus.PENDING,
risk_score=0.07,
verification_data={"provider": "veriff", "submitted": True},
created_at=datetime.now(),
expires_at=datetime.now() + timedelta(days=30)
)
async def check_kyc_status(self, request_id: str, provider: KYCProvider) -> KYCResponse:
"""Check KYC verification status"""
try:
# Mock status check - in production would call provider API
await asyncio.sleep(0.5)
# Simulate different statuses based on request_id
hash_val = int(hashlib.md5(request_id.encode()).hexdigest()[:8], 16)
if hash_val % 4 == 0:
status = KYCStatus.APPROVED
risk_score = 0.05
elif hash_val % 4 == 1:
status = KYCStatus.PENDING
risk_score = 0.15
elif hash_val % 4 == 2:
status = KYCStatus.REJECTED
risk_score = 0.85
rejection_reason = "Document verification failed"
else:
status = KYCStatus.FAILED
risk_score = 0.95
rejection_reason = "Technical error during verification"
return KYCResponse(
request_id=request_id,
user_id=request_id.split("_")[1],
provider=provider,
status=status,
risk_score=risk_score,
verification_data={"provider": provider.value, "checked": True},
created_at=datetime.now() - timedelta(hours=1),
rejection_reason=rejection_reason if status in [KYCStatus.REJECTED, KYCStatus.FAILED] else None
)
except Exception as e:
logger.error(f"❌ KYC status check failed: {e}")
raise
class RealAMLProvider:
"""Real AML screening provider"""
def __init__(self):
self.api_keys: Dict[str, str] = {}
self.session: Optional[aiohttp.ClientSession] = None
async def __aenter__(self):
"""Async context manager entry"""
self.session = aiohttp.ClientSession()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
"""Async context manager exit"""
if self.session:
await self.session.close()
def set_api_key(self, provider: str, api_key: str):
"""Set API key for AML provider"""
self.api_keys[provider] = api_key
logger.info(f"✅ AML API key set for {provider}")
async def screen_user(self, user_id: str, user_data: Dict[str, Any]) -> AMLCheck:
"""Screen user for AML compliance"""
try:
# Mock AML screening - in production would call real provider
await asyncio.sleep(2.0) # Simulate comprehensive screening
# Simulate different risk levels
hash_val = int(hashlib.md5(f"{user_id}_{user_data.get('email', '')}".encode()).hexdigest()[:8], 16)
if hash_val % 5 == 0:
risk_level = AMLRiskLevel.CRITICAL
risk_score = 0.95
sanctions_hits = [{"list": "OFAC", "name": "Test Sanction", "confidence": 0.9}]
elif hash_val % 5 == 1:
risk_level = AMLRiskLevel.HIGH
risk_score = 0.75
sanctions_hits = []
elif hash_val % 5 == 2:
risk_level = AMLRiskLevel.MEDIUM
risk_score = 0.45
sanctions_hits = []
else:
risk_level = AMLRiskLevel.LOW
risk_score = 0.15
sanctions_hits = []
return AMLCheck(
check_id=f"aml_{user_id}_{int(datetime.now().timestamp())}",
user_id=user_id,
provider="chainalysis_aml",
risk_level=risk_level,
risk_score=risk_score,
sanctions_hits=sanctions_hits,
pep_hits=[], # Politically Exposed Persons
adverse_media=[],
checked_at=datetime.now()
)
except Exception as e:
logger.error(f"❌ AML screening failed: {e}")
raise
# Global instances
kyc_provider = RealKYCProvider()
aml_provider = RealAMLProvider()
# CLI Interface Functions
async def submit_kyc_verification(user_id: str, provider: str, customer_data: Dict[str, Any]) -> Dict[str, Any]:
"""Submit KYC verification"""
async with kyc_provider:
kyc_provider.set_api_key(KYCProvider(provider), "demo_api_key")
request = KYCRequest(
user_id=user_id,
provider=KYCProvider(provider),
customer_data=customer_data
)
response = await kyc_provider.submit_kyc_verification(request)
return {
"request_id": response.request_id,
"user_id": response.user_id,
"provider": response.provider.value,
"status": response.status.value,
"risk_score": response.risk_score,
"created_at": response.created_at.isoformat()
}
async def check_kyc_status(request_id: str, provider: str) -> Dict[str, Any]:
"""Check KYC verification status"""
async with kyc_provider:
response = await kyc_provider.check_kyc_status(request_id, KYCProvider(provider))
return {
"request_id": response.request_id,
"user_id": response.user_id,
"provider": response.provider.value,
"status": response.status.value,
"risk_score": response.risk_score,
"rejection_reason": response.rejection_reason,
"created_at": response.created_at.isoformat()
}
async def perform_aml_screening(user_id: str, user_data: Dict[str, Any]) -> Dict[str, Any]:
"""Perform AML screening"""
async with aml_provider:
aml_provider.set_api_key("chainalysis_aml", "demo_api_key")
check = await aml_provider.screen_user(user_id, user_data)
return {
"check_id": check.check_id,
"user_id": check.user_id,
"provider": check.provider,
"risk_level": check.risk_level.value,
"risk_score": check.risk_score,
"sanctions_hits": check.sanctions_hits,
"checked_at": check.checked_at.isoformat()
}
# Test function
async def test_kyc_aml_integration():
"""Test KYC/AML integration"""
print("🧪 Testing KYC/AML Integration...")
# Test KYC submission
customer_data = {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"date_of_birth": "1990-01-01"
}
kyc_result = await submit_kyc_verification("user123", "chainalysis", customer_data)
print(f"✅ KYC Submitted: {kyc_result}")
# Test KYC status check
kyc_status = await check_kyc_status(kyc_result["request_id"], "chainalysis")
print(f"📋 KYC Status: {kyc_status}")
# Test AML screening
aml_result = await perform_aml_screening("user123", customer_data)
print(f"🔍 AML Screening: {aml_result}")
print("🎉 KYC/AML integration test complete!")
if __name__ == "__main__":
asyncio.run(test_kyc_aml_integration())

109
cli/aitbc_cli/main_minimal.py Executable file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""
AITBC CLI - Minimal Version with Working Commands Only
"""
import click
import sys
import os
from pathlib import Path
# Add CLI directory to Python path
CLI_DIR = Path(__file__).parent
sys.path.insert(0, str(CLI_DIR))
# Import only working commands
from .commands.wallet import wallet
from .commands.config import config
from .commands.blockchain import blockchain
from .commands.compliance import compliance
@click.group()
@click.option('--url', help='Coordinator API URL (overrides config)')
@click.option('--api-key', help='API key (overrides config)')
@click.option('--output', type=click.Choice(['table', 'json', 'yaml']), default='table', help='Output format')
@click.option('-v', '--verbose', count=True, help='Increase verbosity (use -v, -vv, -vvv)')
@click.option('--debug', is_flag=True, help='Enable debug mode')
@click.option('--config-file', help='Path to config file')
@click.option('--test-mode', is_flag=True, help='Enable test mode (uses mock data and test endpoints)')
@click.option('--dry-run', is_flag=True, help='Dry run mode (show what would be done without executing)')
@click.option('--timeout', type=int, help='Request timeout in seconds (useful for testing)')
@click.option('--no-verify', is_flag=True, help='Skip SSL certificate verification (testing only)')
@click.version_option(version='0.1.0', prog_name='AITBC CLI')
@click.pass_context
def cli(ctx, url, api_key, output, verbose, debug, config_file, test_mode, dry_run, timeout, no_verify):
"""AITBC CLI - Command Line Interface for AITBC Network
Manage jobs, mining, wallets, blockchain operations, and AI services.
"""
# Ensure that ctx.obj exists and is a dict
ctx.ensure_object(dict)
# Initialize config
try:
config = get_config(config_file)
if url:
config.coordinator_url = url
if api_key:
config.api_key = api_key
if timeout:
config.timeout = timeout
except Exception as e:
# Create a minimal config if loading fails
config = type('Config', (), {
'coordinator_url': url or 'http://127.0.0.1:8000',
'api_key': api_key,
'timeout': timeout or 30,
'config_file': config_file
})()
# Store global options and config in context
ctx.obj.update({
'url': url,
'api_key': api_key,
'output': output,
'verbose': verbose,
'debug': debug,
'config_file': config_file,
'test_mode': test_mode,
'dry_run': dry_run,
'timeout': timeout,
'no_verify': no_verify,
'config': config,
'output_format': output
})
# Add working commands
cli.add_command(wallet)
cli.add_command(config)
cli.add_command(blockchain)
cli.add_command(compliance)
@cli.command()
def version():
"""Show version information"""
click.echo("AITBC CLI version 0.1.0")
@cli.command()
def config_show():
"""Show current configuration"""
click.echo("Configuration display (minimal version)")
click.echo("Use 'aitbc config --help' for configuration options")
def main():
"""Main entry point"""
try:
cli()
except KeyboardInterrupt:
click.echo("\nOperation cancelled by user", err=True)
sys.exit(1)
except Exception as e:
if 'debug' in sys.argv or '--debug' in sys.argv:
import traceback
traceback.print_exc()
else:
click.echo(f"Error: {e}", err=True)
sys.exit(1)
if __name__ == '__main__':
main()