fx-shared-models 0.2.2__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fx_shared_models-0.2.2/fx_shared_models.egg-info → fx_shared_models-0.2.4}/PKG-INFO +1 -1
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4/fx_shared_models.egg-info}/PKG-INFO +1 -1
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/fx_shared_models.egg-info/SOURCES.txt +2 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/setup.py +1 -1
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/__init__.py +1 -1
- fx_shared_models-0.2.4/shared_models/common/__pycache__/mixins.cpython-313.pyc +0 -0
- fx_shared_models-0.2.4/shared_models/common/mixins.py +201 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/__pycache__/models.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/models.py +3 -3
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/LICENSE +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/MANIFEST.in +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/README.md +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/fx_shared_models.egg-info/dependency_links.txt +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/fx_shared_models.egg-info/requires.txt +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/fx_shared_models.egg-info/top_level.txt +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/setup.cfg +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/apps.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/0001_initial.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/0002_remove_account_group_type_account_has_bonus_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/0003_account_is_archived_account_is_trading_enabled.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/0004_alter_account_created_at_alter_account_created_by_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/0005_account_currency.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/0006_alter_account_options.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/models.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/common/__pycache__/base.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/common/__pycache__/utils.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/common/base.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/common/utils.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/company_ba/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/company_ba/apps.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/company_ba/migrations/0001_initial.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/company_ba/migrations/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/company_ba/models.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/constants.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/__pycache__/__init__.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/__pycache__/apps.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/apps.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0001_initial.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0002_alter_customer_email_alter_customer_first_name_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0004_customerauth_two_factor_backup_codes_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0005_customerauth_temp_webauthn_challenge.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0006_customerauth_webauthn_challenge.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0007_customerauth_blocked_customerauth_blocked_at_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0008_customer_email_hash.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/0001_initial.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/0002_alter_customer_email_alter_customer_first_name_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/0004_customerauth_two_factor_backup_codes_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/0005_customerauth_temp_webauthn_challenge.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/0006_customerauth_webauthn_challenge.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/0007_customerauth_blocked_customerauth_blocked_at_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/0008_customer_email_hash.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/apps.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0001_initial.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0002_alter_clientibmapping_id_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0003_commissiondistribution_is_pass_up_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0004_rename_ib_commissi_account_76e731_idx_ib_commissi_account_10d556_idx_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0005_alter_ibagreementmember_start_date.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0006_clientibmapping_agreement_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0007_alter_clientibmapping_mt5_login.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0008_commissiondistribution_is_processed_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/0009_commissiondistribution_processing_notes_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/models.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/services/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/services/commission_calculator_service.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/services/group_resolver.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/__pycache__/apps.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/__pycache__/serializers.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/apps.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0001_initial.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0002_rename_is_enabled_systemsetting_is_active.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0003_tradingplatformserver.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0004_tradingplatformserver_connection_timeout_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0005_accountsequence_accounttype.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0006_alter_accounttype_sequence.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0007_remove_accounttype_default_group_type_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0008_paymentgatewayconfig_paymentmethodconfig_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0009_alter_accountsequence_created_at_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/0010_alter_paymentgatewayconfig_gateway_and_more.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0001_initial.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0002_rename_is_enabled_systemsetting_is_active.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0003_tradingplatformserver.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0004_tradingplatformserver_connection_timeout_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0005_accountsequence_accounttype.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0006_alter_accounttype_sequence.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0007_remove_accounttype_default_group_type_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0008_paymentgatewayconfig_paymentmethodconfig_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0009_alter_accountsequence_created_at_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/0010_alter_paymentgatewayconfig_gateway_and_more.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/__init__.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/account_sequence.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/account_types.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/accounts.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/base.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/email.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/group_configurations.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/payment_methods.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/trading_platform.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__pycache__/transaction_configs.cpython-313.pyc +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/account_sequence.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/account_types.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/base.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/email.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/group_configurations.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/payment_methods.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/trading_platform.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/transaction_configs.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/serializers.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/apps.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/constants.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/enums.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/migrations/0001_initial.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/migrations/0002_transaction_mt5_ticket.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/migrations/0003_alter_transaction_options.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/migrations/__init__.py +0 -0
- {fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/models.py +0 -0
|
@@ -20,8 +20,10 @@ shared_models/accounts/migrations/0005_account_currency.py
|
|
|
20
20
|
shared_models/accounts/migrations/0006_alter_account_options.py
|
|
21
21
|
shared_models/accounts/migrations/__init__.py
|
|
22
22
|
shared_models/common/base.py
|
|
23
|
+
shared_models/common/mixins.py
|
|
23
24
|
shared_models/common/utils.py
|
|
24
25
|
shared_models/common/__pycache__/base.cpython-313.pyc
|
|
26
|
+
shared_models/common/__pycache__/mixins.cpython-313.pyc
|
|
25
27
|
shared_models/common/__pycache__/utils.cpython-313.pyc
|
|
26
28
|
shared_models/company_ba/__init__.py
|
|
27
29
|
shared_models/company_ba/apps.py
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from django.conf import settings
|
|
3
|
+
from django.db import models
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
class SensitiveFieldsTrackingMixin:
|
|
8
|
+
"""
|
|
9
|
+
Mixin to track changes in sensitive fields and log them appropriately.
|
|
10
|
+
"""
|
|
11
|
+
sensitive_fields = [] # List of fields to track
|
|
12
|
+
requires_approval_fields = [] # Fields that require approval before change
|
|
13
|
+
|
|
14
|
+
def __init__(self, *args, **kwargs):
|
|
15
|
+
super().__init__(*args, **kwargs)
|
|
16
|
+
self._original_sensitive_values = self._get_sensitive_values()
|
|
17
|
+
|
|
18
|
+
def _get_sensitive_values(self):
|
|
19
|
+
"""Get current values of sensitive fields"""
|
|
20
|
+
return {
|
|
21
|
+
field: getattr(self, field)
|
|
22
|
+
for field in self.sensitive_fields
|
|
23
|
+
if hasattr(self, field)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def _get_sensitive_field_changes(self):
|
|
27
|
+
"""Compare current values with original values"""
|
|
28
|
+
current_values = self._get_sensitive_values()
|
|
29
|
+
changes = {}
|
|
30
|
+
|
|
31
|
+
for field, original_value in self._original_sensitive_values.items():
|
|
32
|
+
current_value = current_values.get(field)
|
|
33
|
+
if current_value != original_value:
|
|
34
|
+
changes[field] = {
|
|
35
|
+
'from': original_value,
|
|
36
|
+
'to': current_value
|
|
37
|
+
}
|
|
38
|
+
return changes
|
|
39
|
+
|
|
40
|
+
def _get_actor_info(self, request=None):
|
|
41
|
+
"""Get actor information from request"""
|
|
42
|
+
if request and hasattr(request, 'user') and request.user and request.user.is_authenticated:
|
|
43
|
+
# User is authenticated
|
|
44
|
+
service_name = getattr(settings, 'SERVICE_NAME', '').lower()
|
|
45
|
+
actor_details = {
|
|
46
|
+
'email': getattr(request.user, 'email', None),
|
|
47
|
+
'username': getattr(request.user, 'username', None),
|
|
48
|
+
'first_name': getattr(request.user, 'first_name', None),
|
|
49
|
+
'last_name': getattr(request.user, 'last_name', None)
|
|
50
|
+
}
|
|
51
|
+
logger.debug(f"Found authenticated user: {actor_details['email']}")
|
|
52
|
+
|
|
53
|
+
if service_name == 'cp':
|
|
54
|
+
return {
|
|
55
|
+
'type': 'CUSTOMER',
|
|
56
|
+
'id': request.user.id,
|
|
57
|
+
'details': actor_details
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
'type': 'USER',
|
|
61
|
+
'id': request.user.id,
|
|
62
|
+
'details': actor_details
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
logger.debug("No authenticated user found, using SYSTEM actor")
|
|
66
|
+
return {
|
|
67
|
+
'type': 'SYSTEM',
|
|
68
|
+
'id': 0,
|
|
69
|
+
'details': {'system': 'automated'}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
def _get_affected_customer_id(self):
|
|
73
|
+
"""Get the affected customer ID"""
|
|
74
|
+
# Import locally to avoid circular imports
|
|
75
|
+
try:
|
|
76
|
+
from shared_models.customers.models import Customer
|
|
77
|
+
except ImportError:
|
|
78
|
+
# Fallback if the import fails
|
|
79
|
+
Customer = None
|
|
80
|
+
|
|
81
|
+
# If this model is a Customer
|
|
82
|
+
if Customer and isinstance(self, Customer):
|
|
83
|
+
return self.id
|
|
84
|
+
|
|
85
|
+
# If this model has a customer relation
|
|
86
|
+
if hasattr(self, 'customer_id'):
|
|
87
|
+
return self.customer_id
|
|
88
|
+
if hasattr(self, 'customer'):
|
|
89
|
+
return self.customer.id
|
|
90
|
+
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
def save(self, *args, **kwargs):
|
|
94
|
+
# Extract request from kwargs if present
|
|
95
|
+
request = kwargs.pop('request', None)
|
|
96
|
+
|
|
97
|
+
is_new = self._state.adding
|
|
98
|
+
if not is_new:
|
|
99
|
+
changes = self._get_sensitive_field_changes()
|
|
100
|
+
if changes:
|
|
101
|
+
self._handle_sensitive_field_changes(changes, request=request)
|
|
102
|
+
|
|
103
|
+
result = super().save(*args, **kwargs)
|
|
104
|
+
if not is_new:
|
|
105
|
+
self._original_sensitive_values = self._get_sensitive_values()
|
|
106
|
+
return result
|
|
107
|
+
|
|
108
|
+
def _handle_sensitive_field_changes(self, changes, request=None):
|
|
109
|
+
"""Handle changes in sensitive fields"""
|
|
110
|
+
# Get actor information using passed request if available
|
|
111
|
+
actor_info = self._get_actor_info(request)
|
|
112
|
+
affected_customer_id = self._get_affected_customer_id()
|
|
113
|
+
|
|
114
|
+
logger.debug(f"Handling sensitive changes. Actor: {actor_info}, Customer: {affected_customer_id}")
|
|
115
|
+
|
|
116
|
+
ip_address = None
|
|
117
|
+
user_agent = None
|
|
118
|
+
|
|
119
|
+
if request:
|
|
120
|
+
# Get IP address
|
|
121
|
+
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
|
122
|
+
if x_forwarded_for:
|
|
123
|
+
ip_address = x_forwarded_for.split(',')[0]
|
|
124
|
+
else:
|
|
125
|
+
ip_address = request.META.get('REMOTE_ADDR')
|
|
126
|
+
|
|
127
|
+
# Get user agent
|
|
128
|
+
user_agent = request.META.get('HTTP_USER_AGENT')
|
|
129
|
+
|
|
130
|
+
logger.debug(f"Request context found. IP: {ip_address}, UA: {user_agent}")
|
|
131
|
+
else:
|
|
132
|
+
logger.debug("No request context found")
|
|
133
|
+
|
|
134
|
+
for field, change in changes.items():
|
|
135
|
+
# Try to import AuditLogService, but make it optional
|
|
136
|
+
try:
|
|
137
|
+
from apps.common.modules.audit.services import AuditLogService
|
|
138
|
+
# Create audit log entry with full context
|
|
139
|
+
AuditLogService.log(
|
|
140
|
+
actor_type=actor_info['type'],
|
|
141
|
+
actor_id=actor_info['id'],
|
|
142
|
+
actor_details=actor_info['details'],
|
|
143
|
+
action='SENSITIVE_CHANGE',
|
|
144
|
+
description=f'Sensitive field {field} was changed',
|
|
145
|
+
customer_description=f'Your {field} information was updated',
|
|
146
|
+
target_object=self,
|
|
147
|
+
level='WARNING',
|
|
148
|
+
changes={
|
|
149
|
+
'field': field,
|
|
150
|
+
'changes': change,
|
|
151
|
+
'field_type': 'sensitive'
|
|
152
|
+
},
|
|
153
|
+
metadata={
|
|
154
|
+
'service': {
|
|
155
|
+
'name': getattr(settings, 'SERVICE_NAME', 'crm'),
|
|
156
|
+
'environment': getattr(settings, 'ENVIRONMENT', 'development')
|
|
157
|
+
},
|
|
158
|
+
'event': {
|
|
159
|
+
'dataset': 'sensitive_data',
|
|
160
|
+
'module': 'customer',
|
|
161
|
+
'field_name': field
|
|
162
|
+
},
|
|
163
|
+
'request': {
|
|
164
|
+
'ip_address': ip_address,
|
|
165
|
+
'user_agent': user_agent
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
affected_customer_id=affected_customer_id,
|
|
169
|
+
ip_address=ip_address,
|
|
170
|
+
user_agent=user_agent
|
|
171
|
+
)
|
|
172
|
+
except ImportError:
|
|
173
|
+
# Log that audit service is not available
|
|
174
|
+
logger.warning(f"AuditLogService not available. Sensitive field {field} was changed but not logged.")
|
|
175
|
+
|
|
176
|
+
# If field requires approval, handle it
|
|
177
|
+
if field in self.requires_approval_fields:
|
|
178
|
+
self._handle_approval_required_change(field, change)
|
|
179
|
+
|
|
180
|
+
def _handle_approval_required_change(self, field, change):
|
|
181
|
+
"""Handle changes that require approval"""
|
|
182
|
+
try:
|
|
183
|
+
from apps.common.modules.notifications.services import NotificationService
|
|
184
|
+
|
|
185
|
+
# Create a notification for admins
|
|
186
|
+
NotificationService.send_notification(
|
|
187
|
+
type='SENSITIVE_DATA',
|
|
188
|
+
subtype='CHANGE_APPROVAL_REQUIRED',
|
|
189
|
+
title=f'Approval Required: {field} Change',
|
|
190
|
+
message=f'A change to {field} requires approval',
|
|
191
|
+
level='WARNING',
|
|
192
|
+
data={
|
|
193
|
+
'field': field,
|
|
194
|
+
'changes': change,
|
|
195
|
+
'model': self._meta.model_name,
|
|
196
|
+
'object_id': self.pk
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
except ImportError:
|
|
200
|
+
# Log that notification service is not available
|
|
201
|
+
logger.warning(f"NotificationService not available. Approval required for {field} change but notification not sent.")
|
|
Binary file
|
|
@@ -5,7 +5,7 @@ from django.contrib.auth.hashers import make_password, check_password
|
|
|
5
5
|
from shared_models.common.base import BaseModel
|
|
6
6
|
from shared_models.common.utils import generate_referral_code
|
|
7
7
|
from encrypted_model_fields.fields import EncryptedEmailField, EncryptedCharField
|
|
8
|
-
from
|
|
8
|
+
from shared_models.common.mixins import SensitiveFieldsTrackingMixin
|
|
9
9
|
import hashlib
|
|
10
10
|
|
|
11
11
|
logger = logging.getLogger(__name__)
|
|
@@ -435,8 +435,8 @@ class CustomerAuth(SensitiveFieldsTrackingMixin, BaseModel):
|
|
|
435
435
|
blocked_reason = models.TextField(blank=True, null=True)
|
|
436
436
|
blocked_at = models.DateTimeField(null=True, blank=True)
|
|
437
437
|
unblocked_at = models.DateTimeField(null=True, blank=True)
|
|
438
|
-
blocked_by = models.ForeignKey('crm_user.CRMUser', null=True, blank=True, on_delete=models.SET_NULL, related_name='blocked_customers')
|
|
439
|
-
unblocked_by = models.ForeignKey('crm_user.CRMUser', null=True, blank=True, on_delete=models.SET_NULL, related_name='unblocked_customers')
|
|
438
|
+
# blocked_by = models.ForeignKey('crm_user.CRMUser', null=True, blank=True, on_delete=models.SET_NULL, related_name='blocked_customers')
|
|
439
|
+
# unblocked_by = models.ForeignKey('crm_user.CRMUser', null=True, blank=True, on_delete=models.SET_NULL, related_name='unblocked_customers')
|
|
440
440
|
|
|
441
441
|
def set_password(self, raw_password):
|
|
442
442
|
self.password = make_password(raw_password)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/fx_shared_models.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/0001_initial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/accounts/migrations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/company_ba/migrations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/0001_initial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/customers/migrations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/migrations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/ib_commission/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/base.py
RENAMED
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/models/email.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/system_settings/serializers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fx_shared_models-0.2.2 → fx_shared_models-0.2.4}/shared_models/transactions/migrations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|