Initial commit: OCA Technical packages (595 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:03 +02:00
commit 2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions

View file

@ -0,0 +1,4 @@
from . import service
from . import service_context_provider
from . import cerberus_validator
from . import user_component_context_provider

View file

@ -0,0 +1,53 @@
# Copyright 2021 Camptocamp
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo.addons.component.core import Component
class BaseRestCerberusValidator(Component):
"""Component used to lookup the input/output validator methods
To modify in your services collection::
class MyCollectionRestCerberusValidator(Component):
_name = "mycollection.rest.cerberus.validator"
_inherit = "base.rest.cerberus.validator"
_usage = "cerberus.validator"
_collection = "mycollection"
def get_validator_handler(self, service, method_name, direction):
# customize
def has_validator_handler(self, service, method_name, direction):
# customize
"""
_name = "base.rest.cerberus.validator"
_usage = "cerberus.validator"
_is_rest_service_component = False # marker to retrieve REST components
def get_validator_handler(self, service, method_name, direction):
"""Get the validator handler for a method
By default, it returns the method on the current service instance. It
can be customized to delegate the validators to another component.
The returned method will be called without arguments, and is expected
to return the schema.
direction is either "input" for request schema or "output" for responses.
"""
return getattr(service, method_name)
def has_validator_handler(self, service, method_name, direction):
"""Return if the service has a validator handler for a method
By default, it returns True if the the method exists on the service. It
can be customized to delegate the validators to another component.
The returned method will be called without arguments, and is expected
to return the schema.
direction is either "input" for request schema or "output" for responses.
"""
return hasattr(service, method_name)

View file

@ -0,0 +1,217 @@
# Copyright 2018 ACSONE SA/NV
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
import logging
from werkzeug import Response
from werkzeug.exceptions import NotFound
from odoo.http import request
from odoo.addons.component.core import AbstractComponent
from ..apispec.base_rest_service_apispec import BaseRestServiceAPISpec
from ..tools import ROUTING_DECORATOR_ATTR
_logger = logging.getLogger(__name__)
def to_int(val):
# The javascript VM ducktape only use float and so pass float
# to the api, the werkzeug request interpret params as unicode
# so we have to convert params from string to float to int
if isinstance(val, int):
return val
if val:
return int(float(val))
return None
def to_bool(val):
return val in ("true", "True", "1", True)
def skip_secure_params(func):
"""
Used to decorate methods
:param func:
:return:
"""
func.skip_secure_params = True
return func
def skip_secure_response(func):
"""
Used to decorate methods
:param func:
:return:
"""
func.skip_secure_response = True
return func
class BaseRestService(AbstractComponent):
_name = "base.rest.service"
_description = None # description included into the openapi doc
_is_rest_service_component = True # marker to retrieve REST components
def _prepare_extra_log(self, func, params, secure_params, res):
httprequest = request.httprequest
headers = dict(httprequest.headers)
return {
"application": "Rest Service",
"request_url": httprequest.url,
"request_method": httprequest.method,
"params": params,
"headers": headers,
"secure_params": secure_params,
"res": res,
"status": 200,
}
def _log_call(self, func, params, secure_params, res):
"""If you want to enjoy the advanced log install the module
logging_json"""
if request:
httprequest = request.httprequest
extra = self._prepare_extra_log(func, params, secure_params, res)
args = [httprequest.url, httprequest.method]
message = "REST call url %s method %s"
_logger.debug(message, *args, extra=extra)
def _prepare_input_params(self, method, params):
"""
Internal method used to process the input_param parameter. The
result will be used to call the final method. The processing is
delegated to the `resapi.RestMethodParam` instance specified by the
restapi.method` decorator on the method.
:param method:
:param params:
:return:
"""
method_name = method.__name__
if hasattr(method, "skip_secure_params"):
return params
routing = getattr(method, ROUTING_DECORATOR_ATTR, None)
if not routing:
_logger.warning(
"Method %s is not a public method of service %s",
method_name,
self._name,
)
raise NotFound()
input_param = routing["input_param"]
if input_param:
return input_param.from_params(self, params)
return {}
def _prepare_response(self, method, result):
"""
Internal method used to process the result of the method called by the
controller. The result of this process is returned to the controller
The processing is delegated to the `resapi.RestMethodParam` instance
specified by the `restapi.method` decorator on the method.
:param method: method
:param response:
:return: dict/json or `http.Response`
"""
method_name = method
if callable(method):
method_name = method.__name__
if hasattr(method, "skip_secure_response"):
return result
routing = getattr(method, ROUTING_DECORATOR_ATTR, None)
output_param = routing["output_param"]
if not output_param:
_logger.warning(
"DEPRECATED: You must define an output schema for method %s "
"in service %s",
method_name,
self._name,
)
return result
return output_param.to_response(self, result)
def dispatch(self, method_name, *args, params=None):
"""
This method dispatch the call to the final method.
Before the call parameters are processed by the
`restapi.RestMethodParam` object specified as input_param object.
The result of the method is therefore given to the
`restapi.RestMethodParam` object specified as output_param to build
the final response returned by the service
:param method_name:
:param *args: query path paramters args
:param params: A dictionary with the parameters of the method. Once
secured and sanitized, these parameters will be passed
to the method as keyword args.
:return:
"""
method = getattr(self, method_name, object())
params = params or {}
secure_params = self._prepare_input_params(method, params)
if isinstance(secure_params, dict):
# for backward compatibility methods expecting json params
# are declared as m(self, p1=None, p2=None) or m(self, **params)
res = method(*args, **secure_params)
else:
res = method(*args, secure_params)
self._log_call(method, params, secure_params, res)
if isinstance(res, Response):
return res
return self._prepare_response(method, res)
def _validator_delete(self):
"""
Default validator for delete method.
By default delete should never be called with parameters.
"""
return {}
def _validator_get(self):
"""
Default validator for get method.
By default get should not be called with parameters.
"""
return {}
def _get_api_spec(self, **params):
return BaseRestServiceAPISpec(self, **params)
def to_openapi(self, **params):
"""
Return the description of this REST service as an OpenAPI json document
:return: json document
"""
api_spec = self._get_api_spec(**params)
api_spec.generate_paths()
return api_spec.to_dict()
def _get_openapi_default_parameters(self):
return []
def _get_openapi_default_responses(self):
return {
"400": {"description": "One of the given parameter is not valid"},
"401": {
"description": "The user is not authorized. Authentication "
"is required"
},
"404": {"description": "Requested resource not found"},
"403": {
"description": "You don't have the permission to access the "
"requested resource."
},
}
@property
def request(self):
return self.work.request
@property
def controller(self):
return self.work.controller

View file

@ -0,0 +1,26 @@
# Copyright 2021 ACSONE SA/NV
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo.addons.component.core import Component
class BaseRestServiceContextProvider(Component):
_name = "base.rest.service.context.provider"
_usage = "component_context_provider"
def __init__(self, work_context):
super().__init__(work_context)
self.request = work_context.request
# pylint: disable=assignment-from-none
self.authenticated_partner_id = self._get_authenticated_partner_id()
def _get_authenticated_partner_id(self):
return None
def _get_component_context(self):
return {
"request": self.request,
"authenticated_partner_id": self.authenticated_partner_id,
"collection": self.collection,
}

View file

@ -0,0 +1,12 @@
# Copyright 2021 ACSONE SA/NV
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo.addons.component.core import AbstractComponent
class AbstractUserAuthenticatedPartnerProvider(AbstractComponent):
_name = "abstract.user.authenticated.partner.provider"
def _get_authenticated_partner_id(self):
return self.env.user.partner_id.id