import json import logging import jwt as pyjwt from odoo.http import request _logger = logging.getLogger(__name__) class EncoachMixin: """Shared authentication and response helpers for all EnCoach API controllers.""" def _authenticate(self): """Decode JWT Bearer token and return the corresponding ``res.users`` record. Returns ``None`` when the token is missing, expired or invalid. """ auth_header = request.httprequest.headers.get("Authorization", "") if not auth_header.startswith("Bearer "): return None token = auth_header[7:] secret = ( request.env["ir.config_parameter"] .sudo() .get_param("encoach.jwt_secret") ) if not secret: _logger.error("System parameter 'encoach.jwt_secret' is not configured") return None try: payload = pyjwt.decode(token, secret, algorithms=["HS256"]) except pyjwt.ExpiredSignatureError: return None except pyjwt.InvalidTokenError: return None user_id = payload.get("user_id") if not user_id: return None user = request.env["res.users"].sudo().browse(int(user_id)) if not user.exists(): return None return user def _json_response(self, data, status=200): return request.make_json_response(data, status=status) def _error_response(self, message, status=400, code=None): body = {"error": message} if code: body["code"] = code return request.make_json_response(body, status=status) def _get_json_body(self): try: return json.loads(request.httprequest.get_data(as_text=True)) except (ValueError, TypeError): return {} def _paginate_params(self, kwargs): page = max(int(kwargs.get("page", 1)), 1) limit = min(max(int(kwargs.get("limit", 20)), 1), 100) offset = (page - 1) * limit return offset, limit, page def _serialize(self, record): """Delegate to the record's own to_encoach_dict() if available.""" if hasattr(record, "to_encoach_dict"): return record.to_encoach_dict() return {"id": record.id} def _serialize_list(self, records): return [self._serialize(r) for r in records]