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//', 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 = '
• '.join(reasons) if reasons else 'Access denied' message = f'''

🚫 Access Denied

Current User: {current_user.name} ({current_user.login})

Document: {package.doc_number}

Reason(s):

• {reason_html}

Please contact the document administrator if you believe you should have access to this document.

''' 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, })