Files
project_v19/xf_doc_approval_custom/controllers/document_access.py
T

94 lines
4.4 KiB
Python
Raw Normal View History

2026-07-01 14:41:49 +07:00
from odoo import http, fields, _
from odoo.http import request
from odoo.exceptions import AccessError, UserError
import logging
_logger = logging.getLogger(__name__)
class DocumentAccessController(http.Controller):
@http.route('/document/access/<int:package_id>/<string:token>',
type='http', auth='user', website=True)
def access_document(self, package_id, token, **kwargs):
"""Handle QR code document access with authorization check."""
try:
# Fetch the document package
package = request.env['xf.doc.approval.document.package'].sudo().browse(package_id)
if not package.exists():
return self._render_error('404', 'Document not found',
'The requested document does not exist.')
# Get current user
current_user = request.env.user
# Check access permission
has_access = package.check_qr_access(token, current_user)
if not has_access:
# Build detailed error message
reasons = []
if token != package.qr_access_token:
reasons.append('Invalid or incorrect QR code token')
if package.qr_token_expiry and fields.Datetime.now() > package.qr_token_expiry:
reasons.append(f'QR code expired on {package.qr_token_expiry}')
if package.authorized_user_ids and current_user not in package.authorized_user_ids:
authorized_names = ', '.join(package.authorized_user_ids.mapped('name'))
reasons.append(f'You are not in the authorized users list')
reasons.append(f'Authorized users: {authorized_names}')
reason_html = '<br/>• '.join(reasons) if reasons else 'Access denied'
message = f'''
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 20px auto;">
<h2 style="color: #dc3545;">🚫 Access Denied</h2>
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
<p><strong>Current User:</strong> {current_user.name} ({current_user.login})</p>
<p><strong>Document:</strong> {package.doc_number}</p>
</div>
<div style="background: #fff3cd; padding: 15px; border-radius: 5px; border-left: 4px solid #ffc107;">
<p><strong>Reason(s):</strong></p>
<p>• {reason_html}</p>
</div>
<p style="margin-top: 20px;">
<small>Please contact the document administrator if you believe you should have access to this document.</small>
</p>
</div>
'''
return self._render_error('403', 'Access Denied', message)
# Access granted - get document
first_doc = package.document_ids.filtered(lambda d: not d.is_reference)[:1]
if not first_doc:
return self._render_error('404', 'No Document File',
'No document file found in this package.')
# Log successful access
_logger.info(
'✓ QR Access GRANTED: User "%s" (ID: %s) accessed document package "%s" (ID: %s)',
current_user.name, current_user.id, package.doc_number, package.id
)
# Redirect to document file
file_name = first_doc.file_name or first_doc.name or ''
return request.redirect(
f'/web/content/xf.doc.approval.document/{first_doc.id}/file/{file_name}'
)
except Exception as e:
_logger.exception('Error in QR document access')
return self._render_error('500', 'Server Error', str(e))
def _render_error(self, error_code, title, message):
"""Render error page."""
return request.render('http_routing.http_error', {
'status_code': error_code,
'status_message': title,
'message': message,
})