diff --git a/.tx/config b/.tx/config index 0441233b01d..5c69a01da0e 100644 --- a/.tx/config +++ b/.tx/config @@ -272,6 +272,11 @@ file_filter = addons/fetchmail_gmail/i18n/.po source_file = addons/fetchmail_gmail/i18n/fetchmail_gmail.pot source_lang = en +[odoo-master.fetchmail_outlook] +file_filter = addons/fetchmail_outlook/i18n/.po +source_file = addons/fetchmail_outlook/i18n/fetchmail_outlook.pot +source_lang = en + [odoo-master.fleet] file_filter = addons/fleet/i18n/.po source_file = addons/fleet/i18n/fleet.pot @@ -537,6 +542,11 @@ file_filter = addons/microsoft_calendar/i18n/.po source_file = addons/microsoft_calendar/i18n/microsoft_calendar.pot source_lang = en +[odoo-master.microsoft_outlook] +file_filter = addons/microsoft_outlook/i18n/.po +source_file = addons/microsoft_outlook/i18n/microsoft_outlook.pot +source_lang = en + [odoo-master.mrp] file_filter = addons/mrp/i18n/.po source_file = addons/mrp/i18n/mrp.pot diff --git a/addons/fetchmail_gmail/views/fetchmail_server_views.xml b/addons/fetchmail_gmail/views/fetchmail_server_views.xml index 76056ebd6ac..6bbce61d229 100644 --- a/addons/fetchmail_gmail/views/fetchmail_server_views.xml +++ b/addons/fetchmail_gmail/views/fetchmail_server_views.xml @@ -3,6 +3,7 @@ fetchmail.server.view.form.inherit.gmail fetchmail.server + 100 diff --git a/addons/fetchmail_outlook/__init__.py b/addons/fetchmail_outlook/__init__.py new file mode 100644 index 00000000000..dc5e6b693d1 --- /dev/null +++ b/addons/fetchmail_outlook/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/addons/fetchmail_outlook/__manifest__.py b/addons/fetchmail_outlook/__manifest__.py new file mode 100644 index 00000000000..259c29627e9 --- /dev/null +++ b/addons/fetchmail_outlook/__manifest__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + "name": "Fetchmail Outlook", + "version": "1.0", + "category": "Hidden", + "description": "OAuth authentication for incoming Outlook mail server", + "depends": [ + "microsoft_outlook", + "fetchmail", + ], + "data": [ + "views/fetchmail_server_views.xml", + ], + "auto_install": True, + "license": "LGPL-3", +} diff --git a/addons/fetchmail_outlook/i18n/fetchmail_outlook.pot b/addons/fetchmail_outlook/i18n/fetchmail_outlook.pot new file mode 100644 index 00000000000..be13ef59c91 --- /dev/null +++ b/addons/fetchmail_outlook/i18n/fetchmail_outlook.pot @@ -0,0 +1,110 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fetchmail_outlook +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~15.2+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-03-31 13:55+0000\n" +"PO-Revision-Date: 2022-03-31 13:55+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: fetchmail_outlook +#: model_terms:ir.ui.view,arch_db:fetchmail_outlook.fetchmail_server_view_form +msgid "" +"\n" +" Connect your Outlook account" +msgstr "" + +#. module: fetchmail_outlook +#: model_terms:ir.ui.view,arch_db:fetchmail_outlook.fetchmail_server_view_form +msgid "" +"\n" +" Edit Settings" +msgstr "" + +#. module: fetchmail_outlook +#: model_terms:ir.ui.view,arch_db:fetchmail_outlook.fetchmail_server_view_form +msgid "" +" + + + fetchmail.server.view.form.inherit.outlook + fetchmail.server + 1000 + + + + + + + + + + +
+
+ + Outlook Token Valid + + + + +
+
+ + {} + +
+
+
diff --git a/addons/google_gmail/models/google_gmail_mixin.py b/addons/google_gmail/models/google_gmail_mixin.py index 72ff093e845..10e8cd7cd73 100644 --- a/addons/google_gmail/models/google_gmail_mixin.py +++ b/addons/google_gmail/models/google_gmail_mixin.py @@ -16,10 +16,10 @@ class GoogleGmailMixin(models.AbstractModel): _SERVICE_SCOPE = 'https://mail.google.com/' - google_gmail_authorization_code = fields.Char(string='Authorization Code', groups='base.group_system') - google_gmail_refresh_token = fields.Char(string='Refresh Token', groups='base.group_system') - google_gmail_access_token = fields.Char(string='Access Token', groups='base.group_system') - google_gmail_access_token_expiration = fields.Integer(string='Access Token Expiration Timestamp', groups='base.group_system') + google_gmail_authorization_code = fields.Char(string='Authorization Code', groups='base.group_system', copy=False) + google_gmail_refresh_token = fields.Char(string='Refresh Token', groups='base.group_system', copy=False) + google_gmail_access_token = fields.Char(string='Access Token', groups='base.group_system', copy=False) + google_gmail_access_token_expiration = fields.Integer(string='Access Token Expiration Timestamp', groups='base.group_system', copy=False) google_gmail_uri = fields.Char(compute='_compute_gmail_uri', string='URI', help='The URL to generate the authorization code from Google', groups='base.group_system') @api.depends('google_gmail_authorization_code') diff --git a/addons/google_gmail/models/ir_mail_server.py b/addons/google_gmail/models/ir_mail_server.py index 97af27957b1..eb338bc1c55 100644 --- a/addons/google_gmail/models/ir_mail_server.py +++ b/addons/google_gmail/models/ir_mail_server.py @@ -30,7 +30,6 @@ class IrMailServer(models.Model): self.smtp_encryption = 'starttls' self.smtp_port = 587 else: - self.smtp_encryption = 'none' self.google_gmail_authorization_code = False self.google_gmail_refresh_token = False self.google_gmail_access_token = False diff --git a/addons/microsoft_outlook/__init__.py b/addons/microsoft_outlook/__init__.py new file mode 100644 index 00000000000..7d34c7c054a --- /dev/null +++ b/addons/microsoft_outlook/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import controllers +from . import models diff --git a/addons/microsoft_outlook/__manifest__.py b/addons/microsoft_outlook/__manifest__.py new file mode 100644 index 00000000000..a0895703282 --- /dev/null +++ b/addons/microsoft_outlook/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + "name": "Microsoft Outlook", + "version": "1.0", + "category": "Hidden", + "description": "Outlook support for outgoing mail servers", + "depends": [ + "mail", + ], + "data": [ + "views/ir_mail_server_views.xml", + "views/res_config_settings_views.xml", + "views/templates.xml", + ], + "auto_install": False, + "license": "LGPL-3", +} diff --git a/addons/microsoft_outlook/controllers/__init__.py b/addons/microsoft_outlook/controllers/__init__.py new file mode 100644 index 00000000000..afcdc91f726 --- /dev/null +++ b/addons/microsoft_outlook/controllers/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -* +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import main diff --git a/addons/microsoft_outlook/controllers/main.py b/addons/microsoft_outlook/controllers/main.py new file mode 100644 index 00000000000..9206275a184 --- /dev/null +++ b/addons/microsoft_outlook/controllers/main.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import json +import logging +import werkzeug + +from werkzeug.exceptions import Forbidden + +from odoo import http +from odoo.exceptions import UserError +from odoo.http import request +from odoo.tools import consteq + +_logger = logging.getLogger(__name__) + + +class MicrosoftOutlookController(http.Controller): + @http.route('/microsoft_outlook/confirm', type='http', auth='user') + def microsoft_outlook_callback(self, code=None, state=None, error_description=None, **kwargs): + """Callback URL during the OAuth process. + + Outlook redirects the user browser to this endpoint with the authorization code. + We will fetch the refresh token and the access token thanks to this authorization + code and save those values on the given mail server. + """ + if not request.env.user.has_group('base.group_system'): + _logger.error('Microsoft Outlook: Non system user try to link an Outlook account.') + raise Forbidden() + + try: + state = json.loads(state) + model_name = state['model'] + rec_id = state['id'] + csrf_token = state['csrf_token'] + except Exception: + _logger.error('Microsoft Outlook: Wrong state value %r.', state) + raise Forbidden() + + if error_description: + return request.render('microsoft_outlook.microsoft_outlook_oauth_error', { + 'error': error_description, + 'model_name': model_name, + 'rec_id': rec_id, + }) + + model = request.env[model_name] + + if not issubclass(type(model), request.env.registry['microsoft.outlook.mixin']): + # The model must inherits from the "microsoft.outlook.mixin" mixin + raise Forbidden() + + record = model.browse(rec_id).exists() + if not record: + raise Forbidden() + + if not csrf_token or not consteq(csrf_token, record._get_outlook_csrf_token()): + _logger.error('Microsoft Outlook: Wrong CSRF token during Outlook authentication.') + raise Forbidden() + + try: + refresh_token, access_token, expiration = record._fetch_outlook_refresh_token(code) + except UserError as e: + return request.render('microsoft_outlook.microsoft_outlook_oauth_error', { + 'error': str(e.name), + 'model_name': model_name, + 'rec_id': rec_id, + }) + + record.write({ + 'microsoft_outlook_refresh_token': refresh_token, + 'microsoft_outlook_access_token': access_token, + 'microsoft_outlook_access_token_expiration': expiration, + }) + + return werkzeug.utils.redirect(f'/web?#id={rec_id}&model={model_name}&view_type=form', 303) diff --git a/addons/microsoft_outlook/i18n/microsoft_outlook.pot b/addons/microsoft_outlook/i18n/microsoft_outlook.pot new file mode 100644 index 00000000000..7435d6efb5d --- /dev/null +++ b/addons/microsoft_outlook/i18n/microsoft_outlook.pot @@ -0,0 +1,188 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * microsoft_outlook +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~15.2+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-03-31 13:54+0000\n" +"PO-Revision-Date: 2022-03-31 13:54+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: microsoft_outlook +#: model_terms:ir.ui.view,arch_db:microsoft_outlook.ir_mail_server_view_form +msgid "" +"\n" +" Connect your Outlook account" +msgstr "" + +#. module: microsoft_outlook +#: model_terms:ir.ui.view,arch_db:microsoft_outlook.ir_mail_server_view_form +msgid "" +"\n" +" Edit Settings" +msgstr "" + +#. module: microsoft_outlook +#: model_terms:ir.ui.view,arch_db:microsoft_outlook.ir_mail_server_view_form +msgid "" +" + + + ir.mail_server.view.form.inherit.outlook + ir.mail_server + + + + + + + + + + +
+
+ + Outlook Token Valid + + + + +
+
+
+
+
diff --git a/addons/microsoft_outlook/views/res_config_settings_views.xml b/addons/microsoft_outlook/views/res_config_settings_views.xml new file mode 100644 index 00000000000..94cdb4b6705 --- /dev/null +++ b/addons/microsoft_outlook/views/res_config_settings_views.xml @@ -0,0 +1,35 @@ + + + + + res.config.settings.view.form.inherit.microsoft_outlook + res.config.settings + + +
+
+
+ Outlook Credentials +
+ Send and receive email with your Outlook account. +
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/microsoft_outlook/views/templates.xml b/addons/microsoft_outlook/views/templates.xml new file mode 100644 index 00000000000..7139c4bb6e6 --- /dev/null +++ b/addons/microsoft_outlook/views/templates.xml @@ -0,0 +1,15 @@ + + + +