From 4dca02ca9c5bc0cac9b66f6110fb53aec4524f84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Schenkels?=
Date: Fri, 5 Oct 2018 15:43:47 +0200
Subject: [PATCH 01/33] [ADD] auth_oidc module
---
auth_oidc/__init__.py | 6 +++
auth_oidc/__manifest__.py | 25 +++++++++
auth_oidc/controllers/__init__.py | 6 +++
auth_oidc/controllers/main.py | 25 +++++++++
auth_oidc/models/__init__.py | 6 +++
auth_oidc/models/auth_oauth_provider.py | 64 ++++++++++++++++++++++++
auth_oidc/models/res_users.py | 25 +++++++++
auth_oidc/static/description/icon.png | Bin 0 -> 2780 bytes
auth_oidc/views/auth_oauth_provider.xml | 14 ++++++
9 files changed, 171 insertions(+)
create mode 100644 auth_oidc/__init__.py
create mode 100644 auth_oidc/__manifest__.py
create mode 100644 auth_oidc/controllers/__init__.py
create mode 100644 auth_oidc/controllers/main.py
create mode 100644 auth_oidc/models/__init__.py
create mode 100644 auth_oidc/models/auth_oauth_provider.py
create mode 100644 auth_oidc/models/res_users.py
create mode 100755 auth_oidc/static/description/icon.png
create mode 100644 auth_oidc/views/auth_oauth_provider.xml
diff --git a/auth_oidc/__init__.py b/auth_oidc/__init__.py
new file mode 100644
index 0000000000..000324e3e2
--- /dev/null
+++ b/auth_oidc/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+# Copyright© 2016 ICTSTUDIO
+# License: AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+from . import controllers
+from . import models
diff --git a/auth_oidc/__manifest__.py b/auth_oidc/__manifest__.py
new file mode 100644
index 0000000000..bb96a321f1
--- /dev/null
+++ b/auth_oidc/__manifest__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Copyright© 2016 ICTSTUDIO
+# License: AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+{
+ 'name': 'Authentication OpenID Connect',
+ 'version': '10.0.1.0.0',
+ 'license': 'AGPL-3',
+ 'author': 'ICTSTUDIO, André Schenkels',
+ 'website': 'https://www.ictstudio.eu',
+ 'description': """
+Allow users to login through OpenID Connect Provider.
+=====================================================
+- Keycloak with ClientID and Secret + Implicit Flow
+
+""",
+ 'external_dependencies': {'python': [
+ 'jose',
+ 'cryptography'
+ ]},
+ 'depends': ['auth_oauth'],
+ 'data': [
+ 'views/auth_oauth_provider.xml',
+ ],
+}
diff --git a/auth_oidc/controllers/__init__.py b/auth_oidc/controllers/__init__.py
new file mode 100644
index 0000000000..832d7f07a1
--- /dev/null
+++ b/auth_oidc/controllers/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+# Copyright© 2016 ICTSTUDIO
+# License: AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+import main
+
diff --git a/auth_oidc/controllers/main.py b/auth_oidc/controllers/main.py
new file mode 100644
index 0000000000..7e99f1e930
--- /dev/null
+++ b/auth_oidc/controllers/main.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Copyright© 2016 ICTSTUDIO
+# License: AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+import werkzeug.utils
+import uuid
+
+from odoo.addons.auth_oauth.controllers.main import OAuthLogin
+
+
+class OpenIDLogin(OAuthLogin):
+
+ def list_providers(self):
+ providers = super(OpenIDLogin, self).list_providers()
+ for provider in providers:
+ if provider.get('flow') == 'id_token':
+ provider['nonce'] = uuid.uuid1().hex
+ params = werkzeug.url_decode(provider['auth_link'].split('?')[-1])
+ params.pop('response_type')
+ params.update(dict(response_type='id_token',
+ nonce=provider['nonce']))
+ if provider.get('scope'):
+ params['scope'] = provider['scope']
+ provider['auth_link'] = "%s?%s" % (provider['auth_endpoint'], werkzeug.url_encode(params))
+ return providers
diff --git a/auth_oidc/models/__init__.py b/auth_oidc/models/__init__.py
new file mode 100644
index 0000000000..37e1a690a6
--- /dev/null
+++ b/auth_oidc/models/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+# Copyright© 2016 ICTSTUDIO
+# License: AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+from . import auth_oauth_provider
+from . import res_users
diff --git a/auth_oidc/models/auth_oauth_provider.py b/auth_oidc/models/auth_oauth_provider.py
new file mode 100644
index 0000000000..a593736b9a
--- /dev/null
+++ b/auth_oidc/models/auth_oauth_provider.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Copyright© 2016 ICTSTUDIO
+# License: AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+from odoo import models, fields, api
+from jose import jwt
+import urllib2
+import json
+
+
+class AuthOauthProvider(models.Model):
+ _inherit = 'auth.oauth.provider'
+
+ flow = fields.Selection([
+ ('access_token', 'OAuth2'),
+ ('id_token', 'OpenID Connect')
+ ],
+ string='Auth Flow',
+ required=True,
+ default='access_token')
+
+ token_map = fields.Char(
+ help="Some Oauth providers don't map keys in their responses "
+ "exactly as required. It is important to ensure user_id and "
+ "email at least are mapped. For OpenID Connect user_id is "
+ "the sub key in the standard.")
+
+ validation_endpoint = fields.Char(
+ help='For OpenID Connect this should be the location for public keys ')
+
+ @api.model
+ def _get_key(self, header):
+ if self.flow != 'id_token':
+ return False
+ f = urllib2.urlopen(self.validation_endpoint)
+ response = json.loads(f.read())
+ rsa_key = {}
+ for key in response["keys"]:
+ if key["kid"] == header.get('kid'):
+ rsa_key = key
+ return rsa_key
+
+ @api.model
+ def map_token_values(self, res):
+ if self.token_map:
+ for pair in self.token_map.split(' '):
+ from_key, to_key = pair.split(':')
+ if to_key not in res:
+ res[to_key] = res.get(from_key, '')
+ return res
+
+ @api.multi
+ def _parse_id_token(self, id_token):
+ self.ensure_one()
+ res = {}
+ header = jwt.get_unverified_header(id_token)
+ res.update(jwt.decode(
+ id_token,
+ self._get_key(header),
+ algorithms=['RS256'],
+ audience=self.client_id))
+
+ res.update(self.map_token_values(res))
+ return res
\ No newline at end of file
diff --git a/auth_oidc/models/res_users.py b/auth_oidc/models/res_users.py
new file mode 100644
index 0000000000..1c67ab2d43
--- /dev/null
+++ b/auth_oidc/models/res_users.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Copyright© 2016 ICTSTUDIO
+# License: AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+from odoo import models, api
+
+
+class ResUsers(models.Model):
+ _inherit = 'res.users'
+
+ @api.model
+ def _auth_oauth_validate(self, provider, access_token):
+ """ return the validation data corresponding to the access token """
+ oauth_provider = self.env['auth.oauth.provider'].browse(provider)
+ if oauth_provider.flow == 'id_token':
+ return oauth_provider._parse_id_token(access_token)
+ else:
+ return super(ResUsers, self)._auth_oauth_validate()
+
+ @api.model
+ def auth_oauth(self, provider, params):
+ id_token = params.get('id_token')
+ if id_token:
+ params['access_token'] = id_token
+ return super(ResUsers, self).auth_oauth(provider, params)
diff --git a/auth_oidc/static/description/icon.png b/auth_oidc/static/description/icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..06a05ebd480fdd359c2600a27660aced7a5a48a0
GIT binary patch
literal 2780
zcma)8_gfN-7Dhxcw`q!d?}`e^kpow1&aAX7Z>S}1Gc_lPBhy4$_&E?q!;xw3G?Srz
zWrZVirKmX)Ck`xy9M|vu1K)klc%SDz=lt?M=Z81L)!9~9Kvn<%00`ULS-Tw|_MhSh
zAM_40?=J@c_HnSa2JHV6#cgFz512!@?5;!{TnztHJeJzTm;(|LY42nM`2hh59zJ#T
zh5o@zAi&<*;$qC`3TgEr!Q;qB3KKZ?B16;b0ZKrQG2}ygCh2bJjkbw)$nW#SW!NFq
z0~7x43FeB<3;J$e%A;9N`Uie9$Zt45CjI$n0Q!#3*QiS2ORrD%1s-{c{7U`HixHo&
z&M1QSwzrG0>GknuVW=XK(jNx9jaeAM!m#*27GnRJsn;y8U{1m#h-9sn^Qr(L@c5<^
z9G>2_8$XuSkB6Ns|GP4zscHcS@l6m(R7&sky1Dwz9@ih
zY%fIL3SY!*<+mwOCMlWPTyulwFLz>rGC-+$t_-#gJb;TXtDX+(-4}rEuB=k&j`I;o
zNA%V%_ZlZeyYR>jzXk#Pt4auUO8lCE4k?Wh{FmPY`($58>cb_)3wKwR47ZnLZ>{8q
zuY+p9gmZVBLV9o=DZJWJOk94zN~!h`Wsb0fb8Adf`!#&6ro0i)rxt)>#$(Tg
z0AGIfoSk5Xf{PHTZ}dckQO${Z>4X?;&*G1Q(WRAN=f>A#cWOgNFn0BwtR0R7TKN+
z(jL})?+nc>b*}MG1NaH6-i*6z%K9`^C4u9I{w(2<6vUwX3SyR&MmP*XDjk6}oc|%O
zFJ59Y@^G43_N=nR-2V~@nTEXz1*c2m2b>yulQPotKX5;*wVpp3>>y;Hs<5<5+s-i;
zjjZxtJFFWQ6c9;|PgXvm4!E%>63Yg)NCCu+)GjVcXuDsx7Ybe6t7f)N^d2vFm;>#Y
z(0YDtp>{rL9Tsoy?Mn)M;@vI+q08zDL3y7ub);O4SbNoO%s8^}bOEhH1)wde89Mm~
z_<*t9(Pj!wyscD|(83YAN5~abdybHoA?kZgW)>^hsEQ*|CthA;u;s3!Y=geBGkGzk
z(YLJt1ZWmudD-j!`kMrv`9%Q%WVh94p9+atV}2ZvoVH^cH?G!tl0j)yshJrVd+YJA
zC>GLM7_X8CZ|*@);*FC)N$hTR2R00ELNU?DTD3N%DusKkj8&d7ualaA{El@IlfnW2
z5MCh?5_h(;@_a)VK?-_U_gPMMiTbEk-?5f?(pGiHc9ItM4C}<|P4g;wyV97=n+MV)
zQ8(%fi=X=fPF<+|lq|CHVW;1}tp(Ll0PWhG+UNtM35vE9bp(tPGvJCWugr7a_qPCa
z+WeHMWre5J%hTSt`2
z(n*2+R76n1i)PP!+rml4OjwK8g$ZU_ind|^InS*zbVvf!t7RtypqRnLcx5~eKEF8f
zwPGtL&5m*;cFz({@F@}fNoyBQ(DR+WJbp~qzB(P?Sm;8ojqE?FHDM!8iv)tJEtIHtw
zwW`~3O>I#rdOcVmmy`uh&6C+dCAfi5@xqQRzld*0jyk{9+x+5tJ%yyX*8;N3z3Vhm
z7To>tnw77$>c7)`mD*sjoAgr5=d#4fxZQ`U*b}mQYzhqEQQEH-;I|XAimoO;MV}nc
z=X%YZj|6N_6yDW$y8Jy6cHNm}q!ARpu
Do not contact contributors directly about support or help with technical issues.
From 2b696a81f6fd16a572d25a923c9602e4572ef818 Mon Sep 17 00:00:00 2001
From: djaen
Date: Fri, 27 Jan 2023 17:54:08 +0100
Subject: [PATCH 24/33] [16.0][MIG] auth_oidc: Migration to 16.0
---
auth_oidc/README.rst | 24 ++++---
auth_oidc/__manifest__.py | 2 +-
auth_oidc/i18n/auth_oidc.pot | 10 +--
auth_oidc/models/auth_oauth_provider.py | 2 +-
auth_oidc/models/res_users.py | 1 +
auth_oidc/readme/CONTRIBUTORS.rst | 1 +
auth_oidc/static/description/index.html | 87 +++++++++++++------------
7 files changed, 68 insertions(+), 59 deletions(-)
diff --git a/auth_oidc/README.rst b/auth_oidc/README.rst
index 3c6265151c..6cafbe6c07 100644
--- a/auth_oidc/README.rst
+++ b/auth_oidc/README.rst
@@ -2,10 +2,13 @@
Authentication OpenID Connect
=============================
-.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+..
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! source digest: sha256:0e77943e35a7d7c6fb3b6f9e5753d5870e6023f5614e17f7bc0c32522086c49a
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
@@ -14,16 +17,16 @@ Authentication OpenID Connect
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github
- :target: https://github.com/OCA/server-auth/tree/15.0/auth_oidc
+ :target: https://github.com/OCA/server-auth/tree/16.0/auth_oidc
:alt: OCA/server-auth
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/server-auth-15-0/server-auth-15-0-auth_oidc
+ :target: https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-auth_oidc
:alt: Translate me on Weblate
-.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/251/15.0
- :alt: Try me on Runbot
+.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=16.0
+ :alt: Try me on Runboat
-|badge1| |badge2| |badge3| |badge4| |badge5|
+|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows users to login through an OpenID Connect provider using the
authorization code flow or implicit flow.
@@ -136,8 +139,8 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
-If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+If you spotted it first, help us to smash it by providing a detailed and welcomed
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -156,6 +159,7 @@ Contributors
* Alexandre Fayolle
* Stéphane Bidoul
+* David Jaen
Maintainers
~~~~~~~~~~~
@@ -178,6 +182,6 @@ Current `maintainer `__:
|maintainer-sbidoul|
-This module is part of the `OCA/server-auth `_ project on GitHub.
+This module is part of the `OCA/server-auth `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/auth_oidc/__manifest__.py b/auth_oidc/__manifest__.py
index cdbf492ec0..845d7a27db 100644
--- a/auth_oidc/__manifest__.py
+++ b/auth_oidc/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Authentication OpenID Connect",
- "version": "15.0.1.0.0",
+ "version": "16.0.1.0.0",
"license": "AGPL-3",
"author": (
"ICTSTUDIO, André Schenkels, "
diff --git a/auth_oidc/i18n/auth_oidc.pot b/auth_oidc/i18n/auth_oidc.pot
index a6146631d4..0dc7d5e576 100644
--- a/auth_oidc/i18n/auth_oidc.pot
+++ b/auth_oidc/i18n/auth_oidc.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 15.0\n"
+"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -93,13 +93,13 @@ msgid ""
msgstr ""
#. module: auth_oidc
-#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__validation_endpoint
-msgid "UserInfo URL"
+#: model:ir.model,name:auth_oidc.model_res_users
+msgid "User"
msgstr ""
#. module: auth_oidc
-#: model:ir.model,name:auth_oidc.model_res_users
-msgid "Users"
+#: model:ir.model.fields,field_description:auth_oidc.field_auth_oauth_provider__validation_endpoint
+msgid "UserInfo URL"
msgstr ""
#. module: auth_oidc
diff --git a/auth_oidc/models/auth_oauth_provider.py b/auth_oidc/models/auth_oauth_provider.py
index 6a40e87ed6..b969fa3e8d 100644
--- a/auth_oidc/models/auth_oauth_provider.py
+++ b/auth_oidc/models/auth_oauth_provider.py
@@ -48,7 +48,7 @@ class AuthOauthProvider(models.Model):
@tools.ormcache("self.jwks_uri", "kid")
def _get_key(self, kid):
- r = requests.get(self.jwks_uri)
+ r = requests.get(self.jwks_uri, timeout=10)
r.raise_for_status()
response = r.json()
for key in response["keys"]:
diff --git a/auth_oidc/models/res_users.py b/auth_oidc/models/res_users.py
index c487504e2a..a1be73ec88 100644
--- a/auth_oidc/models/res_users.py
+++ b/auth_oidc/models/res_users.py
@@ -37,6 +37,7 @@ def _auth_oauth_get_tokens_auth_code_flow(self, oauth_provider, params):
redirect_uri=request.httprequest.url_root + "auth_oauth/signin",
),
auth=auth,
+ timeout=10,
)
response.raise_for_status()
response_json = response.json()
diff --git a/auth_oidc/readme/CONTRIBUTORS.rst b/auth_oidc/readme/CONTRIBUTORS.rst
index d721552d86..303011adb2 100644
--- a/auth_oidc/readme/CONTRIBUTORS.rst
+++ b/auth_oidc/readme/CONTRIBUTORS.rst
@@ -1,2 +1,3 @@
* Alexandre Fayolle
* Stéphane Bidoul
+* David Jaen
diff --git a/auth_oidc/static/description/index.html b/auth_oidc/static/description/index.html
index 737081829c..384f6ddcff 100644
--- a/auth_oidc/static/description/index.html
+++ b/auth_oidc/static/description/index.html
@@ -1,20 +1,20 @@
-
+
-
+
Authentication OpenID Connect