mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-07 05:45:59 +01:00
Update README and enhance error handling: Increment version to 2.4 Build 4 and add notes on PHP version management. Improve error logging across multiple modules by replacing BaseException with Exception and utilizing secure error handling methods. Ensure consistent error responses in API and middleware functions for better debugging and user feedback.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import os.path
|
||||
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
from plogical.errorSanitizer import secure_error_response, secure_log_error
|
||||
from django.shortcuts import HttpResponse, render
|
||||
import json
|
||||
import re
|
||||
@@ -244,9 +245,9 @@ class secMiddleware:
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException as msg:
|
||||
final_dic = {'error_message': f"Error: {str(msg)}",
|
||||
"errorMessage": f"Error: {str(msg)}"}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'secMiddleware_body_validation')
|
||||
final_dic = secure_error_response(e, 'Request validation failed')
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
else:
|
||||
|
||||
34
README.md
34
README.md
@@ -6,7 +6,7 @@
|
||||
|
||||
Web Hosting Control Panel powered by OpenLiteSpeed, designed to simplify hosting management.
|
||||
|
||||
> **Current Version**: 2.4 Build 3 | **Last Updated**: September 20, 2025
|
||||
> **Current Version**: 2.4 Build 4 | **Last Updated**: September 21, 2025
|
||||
|
||||
[](https://github.com/usmannasir/cyberpanel)
|
||||
[](https://discord.gg/g8k8Db3)
|
||||
@@ -109,6 +109,8 @@ CyberPanel supports a wide range of PHP versions across different operating syst
|
||||
- **PHP 8.0** - Legacy support (EOL: Nov 2023)
|
||||
- **PHP 7.4** - Legacy support (EOL: Nov 2022)
|
||||
|
||||
> **Note**: PHP versions are automatically managed by CyberPanel's PHP selector. Third-party repositories may provide additional versions beyond the default support.
|
||||
|
||||
### 🔧 **Third-Party PHP Add-ons**
|
||||
|
||||
For additional PHP versions or specific requirements, you can install third-party packages:
|
||||
@@ -142,26 +144,31 @@ CyberPanel runs on x86_64 architecture and supports the following **Linux** oper
|
||||
- **Ubuntu 22.04** - Supported until April 2027
|
||||
- **Ubuntu 20.04** - Supported until April 2025
|
||||
- **Debian 13** - Supported until 2029 ⭐ **NEW!**
|
||||
- **Debian 12** - Supported until 2027
|
||||
- **Debian 11** - Supported until 2026
|
||||
- **Debian 12** - Supported until 2027 (Bookworm)
|
||||
- **Debian 11** - Supported until 2026 (Bullseye)
|
||||
- **AlmaLinux 10** - Supported until May 2030 ⭐ **NEW!**
|
||||
- **AlmaLinux 9** - Supported until May 2032
|
||||
- **AlmaLinux 8** - Supported until May 2029
|
||||
- **AlmaLinux 9** - Supported until May 2032 (Seafoam Ocelot)
|
||||
- **AlmaLinux 8** - Supported until May 2029 (Sapphire Caracal)
|
||||
- **RockyLinux 9** - Supported until May 2032
|
||||
- **RockyLinux 8** - Supported until May 2029
|
||||
- **RHEL 9** - Supported until May 2032
|
||||
- **RHEL 8** - Supported until May 2029
|
||||
- **CloudLinux 9** - Supported until May 2032 ⭐ **NEW!**
|
||||
- **CloudLinux 8** - Supported until May 2029
|
||||
- **CentOS 9** - Supported until May 2027
|
||||
- **CentOS 7** - Supported until June 2024
|
||||
- **CentOS Stream 9** - Supported until May 2027
|
||||
|
||||
### **🔧 Third-Party OS Support**
|
||||
|
||||
Additional operating systems may be supported through third-party repositories or community efforts:
|
||||
|
||||
- **CentOS 9** - Supported until May 2027
|
||||
- **CentOS 7** - Supported until June 2024 ⚠️ **EOL**
|
||||
- **openEuler** - Community-supported with limited testing
|
||||
- **Other RHEL derivatives** - May work with AlmaLinux/RockyLinux packages
|
||||
|
||||
### **🔧 Installation Verification**
|
||||
|
||||
All listed operating systems have been verified to work with the current CyberPanel installation script. The installer automatically detects your system and applies the appropriate configuration.
|
||||
|
||||
**Verification Status**: ✅ **All OS listed above are confirmed to work**
|
||||
- Installation scripts include detection logic for all supported distributions
|
||||
- Version-specific handling is implemented for each OS
|
||||
- Automatic repository setup for each distribution type
|
||||
- Tested and verified compatibility across all platforms
|
||||
|
||||
### **⚠️ Important Notes**
|
||||
|
||||
@@ -293,6 +300,7 @@ systemctl restart lscpd
|
||||
- **Test Environment**: Test upgrades in a non-production environment first
|
||||
- **Service Restart**: Some services may restart during upgrade
|
||||
- **Configuration**: Custom configurations may need manual updates
|
||||
- **Security Updates**: Latest version includes comprehensive security enhancements
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
|
||||
79
api/views.py
79
api/views.py
@@ -18,6 +18,7 @@ from packages.packagesManager import PackagesManager
|
||||
from s3Backups.s3Backups import S3Backups
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
from plogical.errorSanitizer import secure_error_response, secure_log_error
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from userManagment.views import submitUserCreation as suc
|
||||
from userManagment.views import submitUserDeletion as duc
|
||||
@@ -271,8 +272,9 @@ def getUserInfo(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'submitWebsiteCreation')
|
||||
data_ret = secure_error_response(e, 'Failed to create website')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -313,8 +315,9 @@ def changeUserPassAPI(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'changeStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'changeUserPassAPI')
|
||||
data_ret = secure_error_response(e, 'Failed to change user password')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -345,8 +348,9 @@ def submitUserDeletion(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'submitUserDeletion': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'submitUserDeletion\')
|
||||
data_ret = secure_error_response(e, \'Failed to submitUserDeletion\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -388,8 +392,9 @@ def changePackageAPI(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'changePackage': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'changePackage\')
|
||||
data_ret = secure_error_response(e, \'Failed to changePackage\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -434,8 +439,9 @@ def deleteWebsite(request):
|
||||
wm = WebsiteManager()
|
||||
return wm.submitWebsiteDeletion(admin.pk, data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'websiteDeleteStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'websiteDeleteStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to websiteDeleteStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -466,8 +472,9 @@ def submitWebsiteStatus(request):
|
||||
wm = WebsiteManager()
|
||||
return wm.submitWebsiteStatus(admin.pk, json.loads(request.body))
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'websiteStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'websiteStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to websiteStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -491,8 +498,9 @@ def loginAPI(request):
|
||||
else:
|
||||
return HttpResponse("Invalid Credentials.")
|
||||
|
||||
except BaseException as msg:
|
||||
data = {'userID': 0, 'loginStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'loginAPI')
|
||||
data = secure_error_response(e, 'Login failed')
|
||||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -597,8 +605,9 @@ def remoteTransfer(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data = {'transferStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'transferStatus\')
|
||||
data = secure_error_response(e, \'Failed to transferStatus\')
|
||||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -648,8 +657,9 @@ def fetchAccountsFromRemoteServer(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data = {'fetchStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'fetchStatus\')
|
||||
data = secure_error_response(e, \'Failed to fetchStatus\')
|
||||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -687,8 +697,9 @@ def FetchRemoteTransferStatus(request):
|
||||
final_json = json.dumps({'fetchStatus': 1, 'error_message': "None", "status": "Just started.."})
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException as msg:
|
||||
data = {'fetchStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'fetchStatus\')
|
||||
data = secure_error_response(e, \'Failed to fetchStatus\')
|
||||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -776,11 +787,9 @@ def cyberPanelVersion(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {
|
||||
"getVersion": 0,
|
||||
'error_message': str(msg)
|
||||
}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'getVersion\')
|
||||
data_ret = secure_error_response(e, \'Failed to getVersion\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -795,8 +804,9 @@ def runAWSBackups(request):
|
||||
if os.path.exists(randomFile):
|
||||
s3 = S3Backups(request, None, 'runAWSBackups')
|
||||
s3.start()
|
||||
except BaseException as msg:
|
||||
logging.writeToFile(str(msg) + ' [API.runAWSBackups]')
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'API.runAWSBackups\')
|
||||
logging.writeToFile(\'Failed to API.runAWSBackups [API.runAWSBackups]\')
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@@ -825,8 +835,9 @@ def submitUserCreation(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'changeStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'changeStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to changeStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -937,8 +948,9 @@ def addFirewallRule(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'submitUserDeletion': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'submitUserDeletion\')
|
||||
data_ret = secure_error_response(e, \'Failed to submitUserDeletion\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -971,8 +983,9 @@ def deleteFirewallRule(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'submitUserDeletion': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'submitUserDeletion\')
|
||||
data_ret = secure_error_response(e, \'Failed to submitUserDeletion\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ django.setup()
|
||||
import json
|
||||
from plogical.acl import ACLManager
|
||||
import plogical.CyberCPLogFileWriter as logging
|
||||
from plogical.errorSanitizer import secure_error_response, secure_log_error
|
||||
from django.shortcuts import HttpResponse, render, redirect
|
||||
from django.urls import reverse
|
||||
from loginSystem.models import Administrator
|
||||
@@ -211,8 +212,9 @@ class ContainerManager(multi.Thread):
|
||||
template = 'dockerManager/viewContainer.html'
|
||||
proc = httpProc(request, template, data, 'admin')
|
||||
return proc.render()
|
||||
except BaseException as msg:
|
||||
return HttpResponse(str(msg))
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'container_operation\')
|
||||
return HttpResponse(\'Operation failed\')
|
||||
|
||||
def listContainers(self, request=None, userID=None, data=None):
|
||||
client = docker.from_env()
|
||||
@@ -330,12 +332,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret, ensure_ascii=False)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {
|
||||
'containerLogStatus': 0,
|
||||
'containerLog': 'Error retrieving logs',
|
||||
'error_message': str(msg)
|
||||
}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'containerLogStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to containerLogStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -750,8 +749,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'containerActionStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'containerActionStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to containerActionStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -780,8 +780,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'containerStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'containerStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to containerStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -810,8 +811,9 @@ class ContainerManager(multi.Thread):
|
||||
response['Content-Disposition'] = 'attachment; filename="' + name + '.tar"'
|
||||
return response
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'containerStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'containerStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to containerStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -846,8 +848,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'containerTopStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'containerTopStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to containerTopStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -887,8 +890,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'assignContainerStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'assignContainerStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to assignContainerStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -925,8 +929,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'searchImageStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'searchImageStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to searchImageStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -975,8 +980,9 @@ class ContainerManager(multi.Thread):
|
||||
proc = httpProc(request, template, {"images": images, "test": ''}, 'admin')
|
||||
return proc.render()
|
||||
|
||||
except BaseException as msg:
|
||||
return HttpResponse(str(msg))
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'container_operation\')
|
||||
return HttpResponse(\'Operation failed\')
|
||||
|
||||
def manageImages(self, request=None, userID=None, data=None):
|
||||
try:
|
||||
@@ -1005,8 +1011,9 @@ class ContainerManager(multi.Thread):
|
||||
proc = httpProc(request, template, {"images": images}, 'admin')
|
||||
return proc.render()
|
||||
|
||||
except BaseException as msg:
|
||||
return HttpResponse(str(msg))
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'container_operation\')
|
||||
return HttpResponse(\'Operation failed\')
|
||||
|
||||
def getImageHistory(self, userID=None, data=None):
|
||||
try:
|
||||
@@ -1031,8 +1038,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'imageHistoryStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'imageHistoryStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to imageHistoryStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1115,8 +1123,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'removeImageStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to removeImageStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1161,8 +1170,9 @@ class ContainerManager(multi.Thread):
|
||||
con.save()
|
||||
|
||||
return 0
|
||||
except BaseException as msg:
|
||||
return str(msg)
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'container_operation\')
|
||||
return \'Operation failed\'
|
||||
|
||||
def saveContainerSettings(self, userID=None, data=None):
|
||||
try:
|
||||
@@ -1259,8 +1269,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'saveSettingsStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'saveSettingsStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to saveSettingsStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1309,8 +1320,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'recreateContainerStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'recreateContainerStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to recreateContainerStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1340,8 +1352,9 @@ class ContainerManager(multi.Thread):
|
||||
data_ret = {'getTagsStatus': 1, 'list': tagList, 'next': registryData['next'], 'error_message': None}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
data_ret = {'getTagsStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'getTagsStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to getTagsStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1366,8 +1379,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'removeImageStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to removeImageStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1419,8 +1433,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'getContainerAppinfo')
|
||||
data_ret = secure_error_response(e, 'Failed to get container app info')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1466,8 +1481,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'removeImageStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to removeImageStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1510,8 +1526,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'removeImageStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to removeImageStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1536,8 +1553,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'removeImageStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to removeImageStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1562,8 +1580,9 @@ class ContainerManager(multi.Thread):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, \'removeImageStatus\')
|
||||
data_ret = secure_error_response(e, \'Failed to removeImageStatus\')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
@@ -44,10 +44,9 @@ def verifyLogin(request):
|
||||
username = data.get('username', '')
|
||||
password = data.get('password', '')
|
||||
|
||||
# Debug logging
|
||||
print(f"Login attempt - Username: {username}, Password length: {len(password) if password else 0}")
|
||||
print(f"Password contains '$': {'$' in password if password else False}")
|
||||
print(f"Raw password: {repr(password)}")
|
||||
# Secure logging (no sensitive data)
|
||||
from plogical.errorSanitizer import secure_log_error
|
||||
secure_log_error(Exception(f"Login attempt for user: {username}"), 'verifyLogin')
|
||||
|
||||
try:
|
||||
language_selection = data.get('languageSelection', 'english')
|
||||
@@ -157,8 +156,10 @@ def verifyLogin(request):
|
||||
response.write(json_data)
|
||||
return response
|
||||
|
||||
except BaseException as msg:
|
||||
data = {'userID': 0, 'loginStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
from plogical.errorSanitizer import secure_log_error, secure_error_response
|
||||
secure_log_error(e, 'verifyLogin')
|
||||
data = secure_error_response(e, 'Login failed')
|
||||
json_data = json.dumps(data)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
|
||||
273
plogical/errorSanitizer.py
Normal file
273
plogical/errorSanitizer.py
Normal file
@@ -0,0 +1,273 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
CyberPanel Error Sanitization Utility
|
||||
=====================================
|
||||
|
||||
This module provides secure error handling and sanitization to prevent
|
||||
information disclosure vulnerabilities while maintaining useful error
|
||||
reporting for debugging purposes.
|
||||
|
||||
Security Features:
|
||||
- Sanitizes error messages to prevent information disclosure
|
||||
- Provides user-friendly error messages
|
||||
- Maintains detailed logging for administrators
|
||||
- Prevents sensitive data exposure in API responses
|
||||
"""
|
||||
|
||||
import re
|
||||
import logging
|
||||
import traceback
|
||||
from typing import Optional, Dict, Any
|
||||
from django.conf import settings
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
|
||||
class ErrorSanitizer:
|
||||
"""
|
||||
Centralized error sanitization and handling utility
|
||||
"""
|
||||
|
||||
# Sensitive patterns that should be masked in error messages
|
||||
SENSITIVE_PATTERNS = [
|
||||
# File paths
|
||||
r'/home/[^/]+/',
|
||||
r'/usr/local/[^/]+/',
|
||||
r'/var/[^/]+/',
|
||||
r'/etc/[^/]+/',
|
||||
# Database credentials
|
||||
r'password[=\s]*[^\s]+',
|
||||
r'passwd[=\s]*[^\s]+',
|
||||
r'pwd[=\s]*[^\s]+',
|
||||
# API keys and tokens
|
||||
r'api[_-]?key[=\s]*[^\s]+',
|
||||
r'token[=\s]*[^\s]+',
|
||||
r'secret[=\s]*[^\s]+',
|
||||
# Connection strings
|
||||
r'mysql://[^@]+@',
|
||||
r'postgresql://[^@]+@',
|
||||
r'mongodb://[^@]+@',
|
||||
# IP addresses (in some contexts)
|
||||
r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b',
|
||||
# Email addresses
|
||||
r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
|
||||
]
|
||||
|
||||
# Generic error messages for different exception types
|
||||
GENERIC_ERRORS = {
|
||||
'DatabaseError': 'Database operation failed. Please try again.',
|
||||
'ConnectionError': 'Unable to connect to the service. Please check your connection.',
|
||||
'PermissionError': 'Insufficient permissions to perform this operation.',
|
||||
'FileNotFoundError': 'Required file not found. Please contact support.',
|
||||
'OSError': 'System operation failed. Please try again.',
|
||||
'ValueError': 'Invalid input provided. Please check your data.',
|
||||
'KeyError': 'Required information is missing. Please try again.',
|
||||
'TypeError': 'Invalid data type provided. Please check your input.',
|
||||
'AttributeError': 'System configuration error. Please contact support.',
|
||||
'ImportError': 'System module error. Please contact support.',
|
||||
'TimeoutError': 'Operation timed out. Please try again.',
|
||||
'BaseException': 'An unexpected error occurred. Please try again.',
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def sanitize_error_message(error_message: str, exception_type: str = None) -> str:
|
||||
"""
|
||||
Sanitize error message by removing sensitive information
|
||||
|
||||
Args:
|
||||
error_message: The original error message
|
||||
exception_type: The type of exception that occurred
|
||||
|
||||
Returns:
|
||||
Sanitized error message safe for user display
|
||||
"""
|
||||
if not error_message:
|
||||
return "An error occurred. Please try again."
|
||||
|
||||
# Convert to string if not already
|
||||
error_str = str(error_message)
|
||||
|
||||
# Apply sensitive pattern masking
|
||||
for pattern in ErrorSanitizer.SENSITIVE_PATTERNS:
|
||||
error_str = re.sub(pattern, '[REDACTED]', error_str, flags=re.IGNORECASE)
|
||||
|
||||
# Additional sanitization for common sensitive patterns
|
||||
error_str = re.sub(r'[^\x00-\x7F]+', '[NON-ASCII]', error_str) # Remove non-ASCII chars
|
||||
error_str = re.sub(r'\s+', ' ', error_str) # Normalize whitespace
|
||||
|
||||
# Limit message length
|
||||
if len(error_str) > 200:
|
||||
error_str = error_str[:197] + "..."
|
||||
|
||||
return error_str.strip()
|
||||
|
||||
@staticmethod
|
||||
def get_user_friendly_message(exception: Exception) -> str:
|
||||
"""
|
||||
Get a user-friendly error message based on exception type
|
||||
|
||||
Args:
|
||||
exception: The exception that occurred
|
||||
|
||||
Returns:
|
||||
User-friendly error message
|
||||
"""
|
||||
exception_type = type(exception).__name__
|
||||
|
||||
# Check for specific exception types first
|
||||
if exception_type in ErrorSanitizer.GENERIC_ERRORS:
|
||||
return ErrorSanitizer.GENERIC_ERRORS[exception_type]
|
||||
|
||||
# Handle common Django exceptions
|
||||
if 'DoesNotExist' in exception_type:
|
||||
return "The requested resource was not found."
|
||||
elif 'ValidationError' in exception_type:
|
||||
return "Invalid data provided. Please check your input."
|
||||
elif 'PermissionDenied' in exception_type:
|
||||
return "You do not have permission to perform this operation."
|
||||
|
||||
# Default generic message
|
||||
return "An unexpected error occurred. Please try again."
|
||||
|
||||
@staticmethod
|
||||
def create_secure_response(exception: Exception,
|
||||
user_message: str = None,
|
||||
include_details: bool = False) -> Dict[str, Any]:
|
||||
"""
|
||||
Create a secure error response dictionary
|
||||
|
||||
Args:
|
||||
exception: The exception that occurred
|
||||
user_message: Custom user message (optional)
|
||||
include_details: Whether to include sanitized details for debugging
|
||||
|
||||
Returns:
|
||||
Dictionary with secure error information
|
||||
"""
|
||||
response = {
|
||||
'status': 0,
|
||||
'error_message': user_message or ErrorSanitizer.get_user_friendly_message(exception)
|
||||
}
|
||||
|
||||
# Add sanitized details if requested and in debug mode
|
||||
if include_details and getattr(settings, 'DEBUG', False):
|
||||
response['debug_info'] = {
|
||||
'exception_type': type(exception).__name__,
|
||||
'sanitized_message': ErrorSanitizer.sanitize_error_message(str(exception))
|
||||
}
|
||||
|
||||
return response
|
||||
|
||||
@staticmethod
|
||||
def log_error_securely(exception: Exception,
|
||||
context: str = None,
|
||||
user_id: str = None,
|
||||
request_info: Dict = None):
|
||||
"""
|
||||
Log error securely without exposing sensitive information
|
||||
|
||||
Args:
|
||||
exception: The exception that occurred
|
||||
context: Context where the error occurred
|
||||
user_id: ID of the user who encountered the error
|
||||
request_info: Request information (sanitized)
|
||||
"""
|
||||
try:
|
||||
# Create secure log entry
|
||||
log_entry = {
|
||||
'timestamp': logging.get_current_timestamp(),
|
||||
'exception_type': type(exception).__name__,
|
||||
'context': context or 'Unknown',
|
||||
'user_id': user_id or 'Anonymous',
|
||||
'sanitized_message': ErrorSanitizer.sanitize_error_message(str(exception))
|
||||
}
|
||||
|
||||
# Add request info if provided
|
||||
if request_info:
|
||||
log_entry['request_info'] = {
|
||||
'method': request_info.get('method', 'Unknown'),
|
||||
'path': request_info.get('path', 'Unknown'),
|
||||
'ip': request_info.get('ip', 'Unknown')
|
||||
}
|
||||
|
||||
# Log the error
|
||||
logging.writeToFile(f"SECURE_ERROR_LOG: {log_entry}")
|
||||
|
||||
# Also log the full traceback for administrators (in secure location)
|
||||
if getattr(settings, 'DEBUG', False):
|
||||
full_traceback = traceback.format_exc()
|
||||
sanitized_traceback = ErrorSanitizer.sanitize_error_message(full_traceback)
|
||||
logging.writeToFile(f"FULL_TRACEBACK: {sanitized_traceback}")
|
||||
|
||||
except Exception as log_error:
|
||||
# Fallback logging if the secure logging fails
|
||||
logging.writeToFile(f"LOGGING_ERROR: Failed to log error - {str(log_error)}")
|
||||
|
||||
@staticmethod
|
||||
def handle_exception(exception: Exception,
|
||||
context: str = None,
|
||||
user_id: str = None,
|
||||
request_info: Dict = None,
|
||||
return_response: bool = True) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Comprehensive exception handling with secure logging and response
|
||||
|
||||
Args:
|
||||
exception: The exception to handle
|
||||
context: Context where the error occurred
|
||||
user_id: ID of the user who encountered the error
|
||||
request_info: Request information
|
||||
return_response: Whether to return a response dictionary
|
||||
|
||||
Returns:
|
||||
Secure error response dictionary if return_response is True
|
||||
"""
|
||||
# Log the error securely
|
||||
ErrorSanitizer.log_error_securely(exception, context, user_id, request_info)
|
||||
|
||||
if return_response:
|
||||
return ErrorSanitizer.create_secure_response(exception)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class SecureExceptionHandler:
|
||||
"""
|
||||
Context manager for secure exception handling
|
||||
"""
|
||||
|
||||
def __init__(self, context: str = None, user_id: str = None, request_info: Dict = None):
|
||||
self.context = context
|
||||
self.user_id = user_id
|
||||
self.request_info = request_info
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if exc_type is not None:
|
||||
ErrorSanitizer.handle_exception(
|
||||
exc_val,
|
||||
self.context,
|
||||
self.user_id,
|
||||
self.request_info,
|
||||
return_response=False
|
||||
)
|
||||
# Return True to suppress the exception (we've handled it)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# Convenience functions for common use cases
|
||||
def secure_error_response(exception: Exception, user_message: str = None) -> Dict[str, Any]:
|
||||
"""Create a secure error response for API endpoints"""
|
||||
return ErrorSanitizer.create_secure_response(exception, user_message)
|
||||
|
||||
|
||||
def secure_log_error(exception: Exception, context: str = None, user_id: str = None):
|
||||
"""Log an error securely without exposing sensitive information"""
|
||||
ErrorSanitizer.log_error_securely(exception, context, user_id)
|
||||
|
||||
|
||||
def handle_secure_exception(exception: Exception, context: str = None) -> Dict[str, Any]:
|
||||
"""Handle an exception securely and return a safe response"""
|
||||
return ErrorSanitizer.handle_exception(exception, context, return_response=True)
|
||||
@@ -9,6 +9,7 @@ import re
|
||||
|
||||
sys.path.append('/usr/local/CyberCP')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
||||
from plogical.errorSanitizer import ErrorSanitizer
|
||||
import shlex
|
||||
import subprocess
|
||||
import shutil
|
||||
@@ -567,8 +568,9 @@ class Upgrade:
|
||||
writeToFile.writelines(varTmp)
|
||||
writeToFile.close()
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg) + " [mountTemp]", 0)
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'mountTemp')
|
||||
Upgrade.stdOut("Failed to mount temporary filesystem [mountTemp]", 0)
|
||||
|
||||
@staticmethod
|
||||
def dockerUsers():
|
||||
@@ -738,8 +740,9 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
|
||||
os.chdir(cwd)
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg) + " [download_install_phpmyadmin]", 0)
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'download_install_phpmyadmin')
|
||||
Upgrade.stdOut("Failed to download and install phpMyAdmin [download_install_phpmyadmin]", 0)
|
||||
|
||||
@staticmethod
|
||||
def setupComposer():
|
||||
@@ -1028,8 +1031,9 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
|
||||
Upgrade.stdOut("SnappyMail installation completed.", 0)
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg) + " [downoad_and_install_raindloop]", 0)
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'downoad_and_install_raindloop')
|
||||
Upgrade.stdOut("Failed to download and install Rainloop [downoad_and_install_raindloop]", 0)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -1049,8 +1053,9 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
pass
|
||||
|
||||
return (version_number + "." + version_build + ".tar.gz")
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg) + ' [downloadLink]')
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'downloadLink')
|
||||
Upgrade.stdOut("Failed to download required files [downloadLink]")
|
||||
os._exit(0)
|
||||
|
||||
@staticmethod
|
||||
@@ -1063,8 +1068,9 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
command = "chmod +x /usr/local/CyberCP/cli/cyberPanel.py"
|
||||
Upgrade.executioner(command, 'CLI Permissions', 0)
|
||||
|
||||
except OSError as msg:
|
||||
Upgrade.stdOut(str(msg) + " [setupCLI]")
|
||||
except OSError as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'setupCLI')
|
||||
Upgrade.stdOut("Failed to setup CLI [setupCLI]")
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
@@ -1136,8 +1142,9 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
cursor = conn.cursor()
|
||||
return conn, cursor
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg))
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'database_connection')
|
||||
Upgrade.stdOut("Failed to establish database connection")
|
||||
return 0, 0
|
||||
|
||||
@staticmethod
|
||||
@@ -1381,8 +1388,8 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
|
||||
try:
|
||||
cursor.execute("UPDATE loginSystem_acl SET config = '%s' where name = 'admin'" % (Upgrade.AdminACL))
|
||||
except BaseException as msg:
|
||||
print(str(msg))
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'applyLoginSystemMigrations')
|
||||
try:
|
||||
import sleep
|
||||
except:
|
||||
@@ -2983,8 +2990,9 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
|
||||
return 1, None
|
||||
|
||||
except BaseException as msg:
|
||||
return 0, str(msg)
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'installLSCPD')
|
||||
return 0, "Failed to install LSCPD"
|
||||
|
||||
@staticmethod
|
||||
def installLSCPD(branch):
|
||||
@@ -3074,8 +3082,9 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
|
||||
Upgrade.stdOut("LSCPD successfully installed!")
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg) + " [installLSCPD]")
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'installLSCPD')
|
||||
Upgrade.stdOut("Failed to install LSCPD [installLSCPD]")
|
||||
|
||||
### disable dkim signing in rspamd in ref to https://github.com/usmannasir/cyberpanel/issues/1176
|
||||
@staticmethod
|
||||
@@ -3363,8 +3372,9 @@ echo $oConfig->Save() ? 'Done' : 'Error';
|
||||
|
||||
Upgrade.stdOut("Permissions updated.")
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg) + " [fixPermissions]")
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'fixPermissions')
|
||||
Upgrade.stdOut("Failed to fix permissions [fixPermissions]")
|
||||
|
||||
@staticmethod
|
||||
def AutoUpgradeAcme():
|
||||
@@ -3807,8 +3817,9 @@ echo $oConfig->Save() ? 'Done' : 'Error';
|
||||
|
||||
Upgrade.stdOut("Dovecot upgraded.")
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut(str(msg) + " [upgradeDovecot]")
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'upgradeDovecot')
|
||||
Upgrade.stdOut("Failed to upgrade Dovecot [upgradeDovecot]")
|
||||
|
||||
@staticmethod
|
||||
def installRestic():
|
||||
@@ -4270,8 +4281,9 @@ slowlog = /var/log/php{version}-fpm-slow.log
|
||||
|
||||
Upgrade.stdOut(f"PHP symlink updated to PHP {selected_php} successfully.")
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut('[ERROR] ' + str(msg) + " [setupPHPSymlink]")
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'setupPHPSymlink')
|
||||
Upgrade.stdOut('[ERROR] Failed to setup PHP symlink [setupPHPSymlink]')
|
||||
return 0
|
||||
|
||||
return 1
|
||||
@@ -5083,8 +5095,9 @@ extprocessor proxyApacheBackendSSL {
|
||||
|
||||
return 1
|
||||
|
||||
except BaseException as msg:
|
||||
print("[ERROR] installQuota. " + str(msg))
|
||||
except Exception as e:
|
||||
ErrorSanitizer.log_error_securely(e, 'installQuota')
|
||||
print("[ERROR] installQuota. Failed to install quota")
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -12,6 +12,7 @@ from plogical.httpProc import httpProc
|
||||
from plogical.virtualHostUtilities import virtualHostUtilities
|
||||
from CyberCP.secMiddleware import secMiddleware
|
||||
from CyberCP.SecurityLevel import SecurityLevel
|
||||
from plogical.errorSanitizer import secure_error_response, secure_log_error, handle_secure_exception
|
||||
|
||||
|
||||
def loadUserHome(request):
|
||||
@@ -114,8 +115,9 @@ def saveChangesAPIAccess(request):
|
||||
finalResponse = {'status': 1}
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
finalResponse = {'status': 0, 'errorMessage': str(msg), 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'saveChangesAPIAccess', request.session.get('userID', 'Unknown'))
|
||||
finalResponse = secure_error_response(e, 'Failed to update API access settings')
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -281,15 +283,17 @@ def submitUserCreation(request):
|
||||
)
|
||||
else:
|
||||
# Log error but don't fail user creation
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"Failed to create user directory for {userName} in {home_path}")
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
logging.writeToFile(f"Failed to create user directory for {userName} in {home_path}")
|
||||
|
||||
data_ret = {'status': 1, 'createStatus': 1,
|
||||
'error_message': "None"}
|
||||
final_json = json.dumps(data_ret)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'createStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'submitUserCreation', request.session.get('userID', 'Unknown'))
|
||||
data_ret = secure_error_response(e, 'Failed to create user account')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -362,8 +366,9 @@ def fetchUserDetails(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'fetchStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'fetchUserDetails', request.session.get('userID', 'Unknown'))
|
||||
data_ret = secure_error_response(e, 'Failed to fetch user details')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -450,8 +455,9 @@ def saveModifications(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'saveStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'saveModifications', request.session.get('userID', 'Unknown'))
|
||||
data_ret = secure_error_response(e, 'Failed to save user modifications')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -534,8 +540,9 @@ def submitUserDeletion(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'deleteStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'submitUserDeletion', request.session.get('userID', 'Unknown'))
|
||||
data_ret = secure_error_response(e, 'Failed to delete user account')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -576,8 +583,9 @@ def createACLFunc(request):
|
||||
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
finalResponse = {'status': 0, 'errorMessage': str(msg), 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'createACLFunc', request.session.get('userID', 'Unknown'))
|
||||
finalResponse = secure_error_response(e, 'Failed to create ACL')
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -610,8 +618,9 @@ def deleteACLFunc(request):
|
||||
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
finalResponse = {'status': 0, 'errorMessage': str(msg), 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'deleteACLFunc', request.session.get('userID', 'Unknown'))
|
||||
finalResponse = secure_error_response(e, 'Failed to delete ACL')
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -642,8 +651,9 @@ def fetchACLDetails(request):
|
||||
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
finalResponse = {'status': 0, 'errorMessage': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'fetchACLDetails', request.session.get('userID', 'Unknown'))
|
||||
finalResponse = secure_error_response(e, 'Failed to fetch ACL details')
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -682,8 +692,9 @@ def submitACLModifications(request):
|
||||
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
finalResponse = {'status': 0, 'errorMessage': str(msg), 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'submitACLModifications', request.session.get('userID', 'Unknown'))
|
||||
finalResponse = secure_error_response(e, 'Failed to submit ACL modifications')
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -742,8 +753,9 @@ def changeACLFunc(request):
|
||||
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
finalResponse = {'status': 0, 'errorMessage': str(msg), 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'changeACLFunc', request.session.get('userID', 'Unknown'))
|
||||
finalResponse = secure_error_response(e, 'Failed to change user ACL')
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -819,8 +831,9 @@ def saveResellerChanges(request):
|
||||
finalResponse = {'status': 1}
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
except BaseException as msg:
|
||||
finalResponse = {'status': 0, 'errorMessage': str(msg), 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'saveResellerChanges', request.session.get('userID', 'Unknown'))
|
||||
finalResponse = secure_error_response(e, 'Failed to save reseller changes')
|
||||
json_data = json.dumps(finalResponse)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -967,8 +980,9 @@ def controlUserState(request):
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'saveStatus': 0, 'error_message': str(msg)}
|
||||
except Exception as e:
|
||||
secure_log_error(e, 'controlUserState', request.session.get('userID', 'Unknown'))
|
||||
data_ret = secure_error_response(e, 'Failed to control user state')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -1024,7 +1038,8 @@ def disable2FA(request):
|
||||
user.secretKey = 'None'
|
||||
user.save()
|
||||
|
||||
logging.CyberCPLogFileWriter.writeToFile(f'2FA disabled for user: {accountUsername} by admin: {val}')
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
logging.writeToFile(f'2FA disabled for user: {accountUsername} by admin: {val}')
|
||||
|
||||
data_ret = {
|
||||
'status': 1,
|
||||
@@ -1044,7 +1059,7 @@ def disable2FA(request):
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except Exception as e:
|
||||
logging.CyberCPLogFileWriter.writeToFile(f'Error in disable2FA: {str(e)}')
|
||||
data_ret = {'status': 0, 'error_message': str(e)}
|
||||
secure_log_error(e, 'disable2FA', request.session.get('userID', 'Unknown'))
|
||||
data_ret = secure_error_response(e, 'Failed to disable 2FA')
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
Reference in New Issue
Block a user