Skip to content

Commit 66c8b9e

Browse files
committed
[FIX] google_gmail, fetchmail_gmail: use Odoo endpoint for authentication
Purpose ======= The flow where we copy / paste the authorization code will be depreciated. Because of that, we know use the newest authentication system which use redirect URI. Technical ========= Now, the user is redirected to an Odoo endpoint "google_gmail/confirm" and the access token / refresh token are automatically fetched. Documentation https://developers.google.com/identity/protocols/oauth2/native-app Task-2852560 closes odoo#94404 X-original-commit: b62d2b4 Signed-off-by: Thibault Delavallee (tde) <[email protected]>
1 parent a58f639 commit 66c8b9e

File tree

8 files changed

+320
-58
lines changed

8 files changed

+320
-58
lines changed

addons/fetchmail_gmail/i18n/fetchmail_gmail.pot

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,24 @@ msgstr ""
2828
#. module: fetchmail_gmail
2929
#: model:ir.model.fields,field_description:fetchmail_gmail.field_fetchmail_server__google_gmail_authorization_code
3030
#: model_terms:ir.ui.view,arch_db:fetchmail_gmail.fetchmail_server_view_form
31-
msgid "Authorization Code"
31+
msgid ""
32+
"<i class=\"fa fa-arrow-right\"/>\n"
33+
" Connect your Gmail account"
34+
msgstr ""
35+
36+
#. module: fetchmail_gmail
37+
#: model_terms:ir.ui.view,arch_db:fetchmail_gmail.fetchmail_server_view_form
38+
msgid ""
39+
"<i class=\"fa fa-cog\"/>\n"
40+
" Edit Settings"
41+
msgstr ""
42+
43+
#. module: fetchmail_gmail
44+
#: model_terms:ir.ui.view,arch_db:fetchmail_gmail.fetchmail_server_view_form
45+
msgid ""
46+
"<span attrs=\"{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_refresh_token', '=', False)]}\" class=\"badge badge-success\">\n"
47+
" Gmail Token Valid\n"
48+
" </span>"
3249
msgstr ""
3350

3451
#. module: fetchmail_gmail

addons/fetchmail_gmail/views/fetchmail_server_views.xml

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,30 @@
1010
<field name="use_google_gmail_service" string="Gmail" attrs="{'readonly': [('state', '=', 'done')]}"/>
1111
</field>
1212
<field name="user" position="after">
13-
<field string="Authorization Code" name="google_gmail_authorization_code" password="True"
14-
attrs="{'required': [('use_google_gmail_service', '=', True)], 'invisible': [('use_google_gmail_service', '=', False)], 'readonly': [('state', '=', 'done')]}"
15-
style="word-break: break-word;"/>
16-
<field name="google_gmail_uri"
17-
class="fa fa-arrow-right oe_edit_only"
18-
widget="url"
19-
text=" Get an Authorization Code"
20-
attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_uri', '=', False)]}"
21-
nolabel="1"/>
22-
<div class="alert alert-warning" role="alert"
23-
attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_uri', '!=', False)]}">
24-
Setup your Gmail API credentials in the general settings to link a Gmail account.
13+
<field name="google_gmail_uri" invisible="1"/>
14+
<field name="google_gmail_refresh_token" invisible="1"/>
15+
<div></div>
16+
<div attrs="{'invisible': [('use_google_gmail_service', '=', False)]}">
17+
<span attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_refresh_token', '=', False)]}"
18+
class="badge badge-success">
19+
Gmail Token Valid
20+
</span>
21+
<button type="object"
22+
name="open_google_gmail_uri" class="btn-link px-0"
23+
attrs="{'invisible': ['|', '|', ('google_gmail_uri', '=', False), ('use_google_gmail_service', '=', False), ('google_gmail_refresh_token', '!=', False)]}">
24+
<i class="fa fa-arrow-right"/>
25+
Connect your Gmail account
26+
</button>
27+
<button type="object"
28+
name="open_google_gmail_uri" class="btn-link px-0"
29+
attrs="{'invisible': ['|', '|', ('google_gmail_uri', '=', False), ('use_google_gmail_service', '=', False), ('google_gmail_refresh_token', '=', False)]}">
30+
<i class="fa fa-cog"/>
31+
Edit Settings
32+
</button>
33+
<div class="alert alert-warning" role="alert"
34+
attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_uri', '!=', False)]}">
35+
Setup your Gmail API credentials in the general settings to link a Gmail account.
36+
</div>
2537
</div>
2638
</field>
2739
<field name="password" position="attributes">

addons/google_gmail/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding: utf-8 -*-
22
# Part of Odoo. See LICENSE file for full copyright and licensing details.
33

4+
from . import controllers
45
from . import models
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# -*- coding: utf-8 -*
2+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
3+
4+
from . import main
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# -*- coding: utf-8 -*-
2+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
3+
4+
import json
5+
import logging
6+
import werkzeug
7+
8+
from werkzeug.exceptions import Forbidden
9+
from werkzeug.urls import url_encode
10+
11+
from odoo import _, http
12+
from odoo.exceptions import UserError
13+
from odoo.http import request
14+
from odoo.tools import consteq
15+
16+
_logger = logging.getLogger(__name__)
17+
18+
19+
class GoogleGmailController(http.Controller):
20+
@http.route('/google_gmail/confirm', type='http', auth='user')
21+
def google_gmail_callback(self, code=None, state=None, error=None, **kwargs):
22+
"""Callback URL during the OAuth process.
23+
24+
Gmail redirects the user browser to this endpoint with the authorization code.
25+
We will fetch the refresh token and the access token thanks to this authorization
26+
code and save those values on the given mail server.
27+
"""
28+
if not request.env.user.has_group('base.group_system'):
29+
_logger.error('Google Gmail: non-system user trying to link an Gmail account.')
30+
raise Forbidden()
31+
32+
if error:
33+
return _('An error occur during the authentication process: %s.') % error
34+
35+
try:
36+
state = json.loads(state)
37+
model_name = state['model']
38+
rec_id = state['id']
39+
csrf_token = state['csrf_token']
40+
except Exception:
41+
_logger.error('Google Gmail: Wrong state value %r.', state)
42+
raise Forbidden()
43+
44+
model = request.env[model_name]
45+
46+
if not issubclass(type(model), request.env.registry['google.gmail.mixin']):
47+
# The model must inherits from the "google.gmail.mixin" mixin
48+
raise Forbidden()
49+
50+
record = model.browse(rec_id).exists()
51+
if not record:
52+
raise Forbidden()
53+
54+
if not csrf_token or not consteq(csrf_token, record._get_gmail_csrf_token()):
55+
_logger.error('Google Gmail: Wrong CSRF token during Gmail authentication.')
56+
raise Forbidden()
57+
58+
try:
59+
refresh_token, access_token, expiration = record._fetch_gmail_refresh_token(code)
60+
except UserError as e:
61+
return _('An error occur during the authentication process: %s.') % str(e.name)
62+
63+
record.write({
64+
'google_gmail_access_token': access_token,
65+
'google_gmail_access_token_expiration': expiration,
66+
'google_gmail_authorization_code': code,
67+
'google_gmail_refresh_token': refresh_token,
68+
})
69+
70+
url_params = {
71+
'id': rec_id,
72+
'model': model_name,
73+
'view_type': 'form'
74+
}
75+
url = '/web?#' + url_encode(url_params)
76+
return werkzeug.utils.redirect(url, 303)

addons/google_gmail/i18n/google_gmail.pot

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,28 @@ msgstr ""
1515
"Content-Transfer-Encoding: \n"
1616
"Plural-Forms: \n"
1717

18+
#. module: google_gmail
19+
#: model_terms:ir.ui.view,arch_db:google_gmail.ir_mail_server_view_form
20+
msgid ""
21+
"<i class=\"fa fa-arrow-right\"/>\n"
22+
" Connect your Gmail account"
23+
msgstr ""
24+
25+
#. module: google_gmail
26+
#: model_terms:ir.ui.view,arch_db:google_gmail.ir_mail_server_view_form
27+
msgid ""
28+
"<i class=\"fa fa-cog\"/>\n"
29+
" Edit Settings"
30+
msgstr ""
31+
32+
#. module: google_gmail
33+
#: model_terms:ir.ui.view,arch_db:google_gmail.ir_mail_server_view_form
34+
msgid ""
35+
"<span attrs=\"{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_refresh_token', '=', False)]}\" class=\"badge badge-success\">\n"
36+
" Gmail Token Valid\n"
37+
" </span>"
38+
msgstr ""
39+
1840
#. module: google_gmail
1941
#: model_terms:ir.ui.view,arch_db:google_gmail.res_config_settings_view_form
2042
msgid "<span class=\"o_form_label\">Gmail Credentials</span>"
@@ -32,10 +54,22 @@ msgstr ""
3254
msgid "Access Token Expiration Timestamp"
3355
msgstr ""
3456

57+
#. module: google_gmail
58+
#: code:addons/google_gmail/controllers/main.py:0
59+
#: code:addons/google_gmail/controllers/main.py:0
60+
#, python-format
61+
msgid "An error occur during the authentication process: %s."
62+
msgstr ""
63+
64+
#. module: google_gmail
65+
#: code:addons/google_gmail/models/google_gmail_mixin.py:0
66+
#, python-format
67+
msgid "An error occurred when fetching the access token."
68+
msgstr ""
69+
3570
#. module: google_gmail
3671
#: model:ir.model.fields,field_description:google_gmail.field_google_gmail_mixin__google_gmail_authorization_code
3772
#: model:ir.model.fields,field_description:google_gmail.field_ir_mail_server__google_gmail_authorization_code
38-
#: model_terms:ir.ui.view,arch_db:google_gmail.ir_mail_server_view_form
3973
msgid "Authorization Code"
4074
msgstr ""
4175

@@ -90,6 +124,18 @@ msgstr ""
90124
msgid "Mail Server"
91125
msgstr ""
92126

127+
#. module: google_gmail
128+
#: code:addons/google_gmail/models/google_gmail_mixin.py:0
129+
#, python-format
130+
msgid "Only the administrator can link a Gmail mail server."
131+
msgstr ""
132+
133+
#. module: google_gmail
134+
#: code:addons/google_gmail/models/google_gmail_mixin.py:0
135+
#, python-format
136+
msgid "Please configure your Gmail credentials."
137+
msgstr ""
138+
93139
#. module: google_gmail
94140
#: model:ir.model.fields,field_description:google_gmail.field_google_gmail_mixin__google_gmail_refresh_token
95141
#: model:ir.model.fields,field_description:google_gmail.field_ir_mail_server__google_gmail_refresh_token

0 commit comments

Comments
 (0)