mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-10-26 15:56:34 +01:00
241 lines
8.7 KiB
Python
241 lines
8.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
CyberPanel FTP Account Creation Test Script
|
|
This script tests the FTP account creation functionality with various path scenarios
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import shutil
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
# Add CyberPanel to path
|
|
sys.path.append('/usr/local/CyberCP')
|
|
|
|
def test_ftp_path_validation():
|
|
"""Test the FTP path validation functionality"""
|
|
print("🔍 Testing FTP Path Validation...")
|
|
|
|
# Import the FTP utilities
|
|
try:
|
|
from plogical.ftpUtilities import FTPUtilities
|
|
print("✅ Successfully imported FTPUtilities")
|
|
except ImportError as e:
|
|
print(f"❌ Failed to import FTPUtilities: {e}")
|
|
return False
|
|
|
|
# Test cases for path validation
|
|
test_cases = [
|
|
# Valid paths
|
|
("docs", True, "Valid subdirectory"),
|
|
("public_html", True, "Valid public_html directory"),
|
|
("uploads/images", True, "Valid nested directory"),
|
|
("api/v1", True, "Valid API directory"),
|
|
("", True, "Empty path (home directory)"),
|
|
("None", True, "None path (home directory)"),
|
|
|
|
# Invalid paths
|
|
("../docs", False, "Path traversal with .."),
|
|
("~/docs", False, "Home directory reference"),
|
|
("/docs", False, "Absolute path"),
|
|
("docs;rm -rf /", False, "Command injection"),
|
|
("docs|cat /etc/passwd", False, "Pipe command injection"),
|
|
("docs&reboot", False, "Background command"),
|
|
("docs`whoami`", False, "Command substitution"),
|
|
("docs'rm -rf /'", False, "Single quote injection"),
|
|
('docs"rm -rf /"', False, "Double quote injection"),
|
|
("docs<malicious", False, "Input redirection"),
|
|
("docs>malicious", False, "Output redirection"),
|
|
("docs*", False, "Wildcard character"),
|
|
("docs?", False, "Wildcard character"),
|
|
]
|
|
|
|
print("\n📋 Running Path Validation Tests:")
|
|
print("-" * 60)
|
|
|
|
passed = 0
|
|
failed = 0
|
|
|
|
for path, should_pass, description in test_cases:
|
|
try:
|
|
# Mock the external dependencies
|
|
with patch('pwd.getpwnam') as mock_pwd, \
|
|
patch('grp.getgrnam') as mock_grp, \
|
|
patch('os.path.exists') as mock_exists, \
|
|
patch('os.path.isdir') as mock_isdir, \
|
|
patch('os.path.islink') as mock_islink, \
|
|
patch('plogical.processUtilities.ProcessUtilities.executioner') as mock_exec, \
|
|
patch('websiteFunctions.models.Websites.objects.get') as mock_website, \
|
|
patch('loginSystem.models.Administrator.objects.get') as mock_admin:
|
|
|
|
# Setup mocks
|
|
mock_pwd.return_value.pw_uid = 1000
|
|
mock_grp.return_value.gr_gid = 1000
|
|
mock_exists.return_value = True
|
|
mock_isdir.return_value = True
|
|
mock_islink.return_value = False
|
|
mock_exec.return_value = 0
|
|
|
|
# Mock website object
|
|
mock_website_obj = MagicMock()
|
|
mock_website_obj.externalApp = "testuser"
|
|
mock_website_obj.package.diskSpace = 1000
|
|
mock_website_obj.package.ftpAccounts = 10
|
|
mock_website_obj.users_set.all.return_value.count.return_value = 0
|
|
mock_website.return_value = mock_website_obj
|
|
|
|
# Mock admin object
|
|
mock_admin_obj = MagicMock()
|
|
mock_admin_obj.userName = "testadmin"
|
|
mock_admin.return_value = mock_admin_obj
|
|
|
|
# Test the path validation
|
|
result = FTPUtilities.submitFTPCreation(
|
|
"testdomain.com",
|
|
"testuser",
|
|
"testpass",
|
|
path,
|
|
"testadmin"
|
|
)
|
|
|
|
if should_pass:
|
|
if result[0] == 1:
|
|
print(f"✅ PASS: {description} ('{path}')")
|
|
passed += 1
|
|
else:
|
|
print(f"❌ FAIL: {description} ('{path}') - Expected success but got: {result[1]}")
|
|
failed += 1
|
|
else:
|
|
if result[0] == 0:
|
|
print(f"✅ PASS: {description} ('{path}') - Correctly rejected")
|
|
passed += 1
|
|
else:
|
|
print(f"❌ FAIL: {description} ('{path}') - Expected rejection but got success")
|
|
failed += 1
|
|
|
|
except Exception as e:
|
|
if should_pass:
|
|
print(f"❌ ERROR: {description} ('{path}') - Unexpected error: {e}")
|
|
failed += 1
|
|
else:
|
|
print(f"✅ PASS: {description} ('{path}') - Correctly rejected with error: {e}")
|
|
passed += 1
|
|
|
|
print("\n" + "=" * 60)
|
|
print(f"📊 Test Results: {passed} passed, {failed} failed")
|
|
print("=" * 60)
|
|
|
|
return failed == 0
|
|
|
|
def test_directory_creation():
|
|
"""Test directory creation functionality"""
|
|
print("\n🔍 Testing Directory Creation...")
|
|
|
|
try:
|
|
from plogical.ftpUtilities import FTPUtilities
|
|
|
|
# Create a temporary directory for testing
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
test_path = os.path.join(temp_dir, "test_ftp_dir")
|
|
|
|
print(f"📁 Testing directory creation at: {test_path}")
|
|
|
|
# Test creating a new directory
|
|
result = FTPUtilities.ftpFunctions(test_path, "testuser")
|
|
|
|
if result[0] == 1:
|
|
if os.path.exists(test_path) and os.path.isdir(test_path):
|
|
print("✅ Directory creation successful")
|
|
return True
|
|
else:
|
|
print("❌ Directory creation failed - directory not found")
|
|
return False
|
|
else:
|
|
print(f"❌ Directory creation failed: {result[1]}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Directory creation test failed: {e}")
|
|
return False
|
|
|
|
def test_security_features():
|
|
"""Test security features"""
|
|
print("\n🔍 Testing Security Features...")
|
|
|
|
security_tests = [
|
|
("Path traversal prevention", ".."),
|
|
("Home directory reference prevention", "~"),
|
|
("Absolute path prevention", "/etc/passwd"),
|
|
("Command injection prevention", ";rm -rf /"),
|
|
("Pipe command prevention", "|cat /etc/passwd"),
|
|
("Background command prevention", "&reboot"),
|
|
("Command substitution prevention", "`whoami`"),
|
|
]
|
|
|
|
print("🛡️ Security Test Results:")
|
|
print("-" * 40)
|
|
|
|
for test_name, malicious_path in security_tests:
|
|
try:
|
|
# This should be caught by our validation
|
|
if any(char in malicious_path for char in ['..', '~', '/', ';', '|', '&', '`']):
|
|
print(f"✅ {test_name}: Correctly detected malicious path")
|
|
else:
|
|
print(f"❌ {test_name}: Failed to detect malicious path")
|
|
except Exception as e:
|
|
print(f"✅ {test_name}: Correctly rejected with error: {e}")
|
|
|
|
return True
|
|
|
|
def main():
|
|
"""Main test function"""
|
|
print("🚀 CyberPanel FTP Account Creation Test Suite")
|
|
print("=" * 60)
|
|
|
|
# Run all tests
|
|
tests = [
|
|
("Path Validation", test_ftp_path_validation),
|
|
("Directory Creation", test_directory_creation),
|
|
("Security Features", test_security_features),
|
|
]
|
|
|
|
results = []
|
|
|
|
for test_name, test_func in tests:
|
|
print(f"\n🧪 Running {test_name} Test...")
|
|
try:
|
|
result = test_func()
|
|
results.append((test_name, result))
|
|
if result:
|
|
print(f"✅ {test_name} Test: PASSED")
|
|
else:
|
|
print(f"❌ {test_name} Test: FAILED")
|
|
except Exception as e:
|
|
print(f"❌ {test_name} Test: ERROR - {e}")
|
|
results.append((test_name, False))
|
|
|
|
# Summary
|
|
print("\n" + "=" * 60)
|
|
print("📋 TEST SUMMARY")
|
|
print("=" * 60)
|
|
|
|
passed = sum(1 for _, result in results if result)
|
|
total = len(results)
|
|
|
|
for test_name, result in results:
|
|
status = "✅ PASSED" if result else "❌ FAILED"
|
|
print(f"{test_name}: {status}")
|
|
|
|
print(f"\n🎯 Overall Result: {passed}/{total} tests passed")
|
|
|
|
if passed == total:
|
|
print("🎉 All tests passed! FTP account creation should work correctly.")
|
|
return 0
|
|
else:
|
|
print("⚠️ Some tests failed. Please review the issues above.")
|
|
return 1
|
|
|
|
if __name__ == "__main__":
|
|
exit(main())
|