Skip to content

Commit

Permalink
[IMP] webservice: add support for oauth2
Browse files Browse the repository at this point in the history
  • Loading branch information
gurneyalex committed Feb 28, 2024
1 parent 19ac2ed commit 2b0bf7f
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 13 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# generated from manifests external_dependencies
requests-oauthlib
2 changes: 1 addition & 1 deletion webservice/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ WebService
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:303644ddb310b8c13e53c0cec4ea4f665b2ebb8a86b0c17bae78968c38633f4b
!! source digest: sha256:d577a7b3d22d30b8093f1893c30ad9fa0a58622a3fd96520ad4a821dd1bdf197
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
Expand Down
1 change: 1 addition & 0 deletions webservice/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"author": "Creu Blanca, Camptocamp, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/web-api",
"depends": ["component", "server_environment"],
"external_dependencies": {"python": ["requests-oauthlib"]},
"data": [
"security/ir.model.access.csv",
"security/ir_rule.xml",
Expand Down
43 changes: 32 additions & 11 deletions webservice/components/request_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import requests
from requests_oauthlib import OAuth2Session

from odoo.addons.component.core import Component

Expand All @@ -15,19 +16,19 @@ class BaseRestRequestsAdapter(Component):

# TODO: url and url_params could come from work_ctx
def _request(self, method, url=None, url_params=None, **kwargs):
Session = self._get_session_class()
url = self._get_url(url=url, url_params=url_params)
new_kwargs = kwargs.copy()
new_kwargs.update(
{
"auth": self._get_auth(**kwargs),
"headers": self._get_headers(**kwargs),
"timeout": None,
}
)
# pylint: disable=E8106
request = requests.request(method, url, **new_kwargs)
request.raise_for_status()
return request.content
session_kwargs = {
"auth": self._get_auth(**kwargs),
"headers": self._get_headers(**kwargs),
"timeout": None,
}
with Session(**session_kwargs) as session:
# pylint: disable=E8106
resp = session.request(method, url, **new_kwargs)
resp.raise_for_status()
return resp.content

def get(self, **kwargs):
return self._request("get", **kwargs)
Expand All @@ -44,11 +45,31 @@ def _get_auth(self, auth=False, **kwargs):
handler = getattr(self, "_get_auth_for_" + self.collection.auth_type, None)
return handler(**kwargs) if handler else None

def _get_session_class(self):
handler = getattr(
self, "_get_session_class_for_" + self.collection.auth_type, None
)
if handler is None:
return requests.Session
else:
return handler()

def _get_session_class_for_oauth2(self):
return OAuth2Session

def _get_auth_for_user_pwd(self, **kw):
if self.collection.username and self.collection.password:
return self.collection.username, self.collection.password
return None

def _get_auth_for_oauth2(self, **kwargs):
return {
"client_id": self.collection.oauth2_client_id,
"client_secret": self.collection.oauth2_client_secret,
"token_url": self.collection.oauth2_token_url,
"audience": self.collection.oaut2_audience,
}

def _get_headers(self, content_type=False, headers=False, **kwargs):
headers = headers or {}
result = {
Expand Down
11 changes: 11 additions & 0 deletions webservice/models/webservice_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class WebserviceBackend(models.Model):
("none", "Public"),
("user_pwd", "Username & password"),
("api_key", "API Key"),
("oauth2", "OAuth2"),
],
default="user_pwd",
required=True,
Expand All @@ -29,6 +30,12 @@ class WebserviceBackend(models.Model):
password = fields.Char(auth_type="user_pwd")
api_key = fields.Char(string="API Key", auth_type="api_key")
api_key_header = fields.Char(string="API Key header", auth_type="api_key")
oauth2_clientid = fields.Char(string="Client ID", auth_type="oauth2")
oauth2_client_secret = fields.Char(string="Client Secret", auth_type="oauth2")
oauth2_token_url = fields.Char(string="Token URL", auth_type="oauth2")
oauth2_audience = fields.Char(
string="Token URL"
) # no auth_type because not required
content_type = fields.Selection(
[
("application/json", "JSON"),
Expand Down Expand Up @@ -93,6 +100,10 @@ def _server_env_fields(self):
"api_key": {},
"api_key_header": {},
"content_type": {},
"oauth2_client_id": {},
"oauth2_client_secret": {},
"oauth2_token_url": {},
"oauth2_audience": {},
}
webservice_fields.update(base_fields)
return webservice_fields
3 changes: 2 additions & 1 deletion webservice/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
Expand Down Expand Up @@ -366,7 +367,7 @@ <h1 class="title">WebService</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:303644ddb310b8c13e53c0cec4ea4f665b2ebb8a86b0c17bae78968c38633f4b
!! source digest: sha256:d577a7b3d22d30b8093f1893c30ad9fa0a58622a3fd96520ad4a821dd1bdf197
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/web-api/tree/16.0/webservice"><img alt="OCA/web-api" src="https://img.shields.io/badge/github-OCA%2Fweb--api-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/web-api-16-0/web-api-16-0-webservice"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/web-api&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module creates WebService frameworks to be used globally</p>
Expand Down
16 changes: 16 additions & 0 deletions webservice/views/webservice_backend.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@
'required': [('auth_type', '=', 'api_key')],
}"
/>
<field
name="oauth2_client_id"
attrs="{'invisible': [('auth_type', '!=', 'oauth2')], 'required': [('auth_type', '=', 'oauth2')]}"
/>
<field
name="oauth2_client_secret"
attrs="{'invisible': [('auth_type', '!=', 'oauth2')], 'required': [('auth_type', '=', 'oauth2')]}"
/>
<field
name="oauth2_token_url"
attrs="{'invisible': [('auth_type', '!=', 'oauth2')], 'required': [('auth_type', '=', 'oauth2')]}"
/>
<field
name="oauth2_audience"
attrs="{'invisible': [('auth_type', '!=', 'oauth2')]}"
/>
</group>
</sheet>
</form>
Expand Down

0 comments on commit 2b0bf7f

Please sign in to comment.