bemade-addons/odoo_to_odoo_bemade/models/project.py
mathis b792e43873 [IMP] Odoo Sync Modules: Major Enhancements and Fixes
- Added comprehensive README files for all three sync modules
- Implemented advanced logging system with multiple log levels (DEBUG, INFO, WARNING, ERROR)
- Added automatic sensitive data masking for security in log payloads
- Implemented log retention policy (90 days local, 7 years in AWS S3 Glacier)
- Added AWS S3 integration for long-term log archiving
- Fixed validation error with bemade_instance_id in sync model creation
- Refactored model inheritance structure from _inherit to _inherits for proper delegation
- Fixed duplicate sync model prevention logic
- Restored Test Connection button in instance view
- Fixed connection test logging to properly record success/failure
- Fixed queue creation for connection test logs
- Removed unnecessary Synchronized Module tab from odoo_to_odoo_bemade
- Added database indexing on create_date for performance optimization
- Fixed foreign key constraint violations in field mappings creation
- Enhanced error handling throughout the synchronization process
2025-08-15 08:40:17 -04:00

98 lines
3.4 KiB
Python

# Copyright 2025 Bemade
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.html)
"""Project Extension for Client Synchronization.
This module extends the project model to support client synchronization features,
including marking projects as client projects and generating API tokens for
secure client connections.
"""
import logging
import secrets
from odoo import api, fields, models, _
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class ProjectProject(models.Model):
_name = 'project.project'
_inherit = 'project.project'
is_client_project = fields.Boolean(
string='Client Project',
default=False,
help='Check this box to mark this project as a client project for synchronization'
)
client_key = fields.Char(
string='Client Key',
readonly=True,
help='Unique client key for this project. Generated when project is marked as client project.'
)
client_api_token = fields.Char(
string='Client API Token',
readonly=True,
help='API token for client synchronization. Generated when project is marked as client project.'
)
client_instance_id = fields.Many2one(
comodel_name='odoo.to.bemade.instance',
string='Client Instance',
readonly=True,
help='The client instance associated with this project'
)
sync_model_ids = fields.One2many(
comodel_name='odoo.to.bemade.sync.model',
inverse_name='project_id',
string='Synchronized Models',
help='Models configured for synchronization with this project'
)
@api.onchange('is_client_project')
def _onchange_is_client_project(self):
"""Generate API token and client key when project is marked as client project."""
if self.is_client_project and not self.client_api_token:
self.client_api_token = self._generate_api_token()
# Generate a unique client key based on project ID and a random component
if self.id:
self.client_key = f"{self.id}-{self._generate_api_token()[:8]}"
else:
self.client_key = self._generate_api_token()[:16]
elif not self.is_client_project:
self.client_api_token = False
self.client_key = False
self.client_instance_id = False
def _generate_api_token(self):
"""Generate a secure API token for client authentication.
Returns:
str: A secure random token
"""
return secrets.token_urlsafe(32)
def action_generate_api_token(self):
"""Manually generate or regenerate API token for client project.
This method can be called from the UI to generate a new API token
for an existing client project.
"""
for record in self:
if not record.is_client_project:
raise UserError(_("Only client projects can have API tokens. Please mark this project as a client project first."))
record.client_api_token = record._generate_api_token()
return True
def action_revoke_api_token(self):
"""Revoke the API token for a client project.
This method clears the API token and disconnects any associated client instance.
"""
for record in self:
record.client_api_token = False
record.client_instance_id = False
return True