[IMP] fetchmail_gmail, google_gmail: simplify the mail server form view
Purpose ======= A field `use_google_gmail_service` has been used in stable to define a mail server which use Gmail authentication. But now that the fields `smtp_authentication` exists, we want to use it to simplify the mail server form view. For the incoming mail server, the field `server_type` will be used for the same purpose. Add a new field to have the option to install `google_gmail` in the main settings page. Task-2170676 closes odoo/odoo#83413 Related: odoo/upgrade#3199 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -100,13 +100,14 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
|
||||
|
||||
def connect(self):
|
||||
self.ensure_one()
|
||||
if self.server_type == 'imap':
|
||||
connection_type = self._get_connection_type()
|
||||
if connection_type == 'imap':
|
||||
if self.is_ssl:
|
||||
connection = IMAP4_SSL(self.server, int(self.port))
|
||||
else:
|
||||
connection = IMAP4(self.server, int(self.port))
|
||||
self._imap_login(connection)
|
||||
elif self.server_type == 'pop':
|
||||
elif connection_type == 'pop':
|
||||
if self.is_ssl:
|
||||
connection = POP3_SSL(self.server, int(self.port))
|
||||
else:
|
||||
@@ -148,9 +149,10 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
|
||||
finally:
|
||||
try:
|
||||
if connection:
|
||||
if server.server_type == 'imap':
|
||||
connection_type = server._get_connection_type()
|
||||
if connection_type == 'imap':
|
||||
connection.close()
|
||||
elif server.server_type == 'pop':
|
||||
elif connection_type == 'pop':
|
||||
connection.quit()
|
||||
except Exception:
|
||||
# ignored, just a consequence of the previous exception
|
||||
@@ -160,7 +162,7 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
|
||||
@api.model
|
||||
def _fetch_mails(self):
|
||||
""" Method called by cron to fetch mails from servers """
|
||||
return self.search([('state', '=', 'done'), ('server_type', 'in', ['pop', 'imap'])]).fetch_mail()
|
||||
return self.search([('state', '=', 'done'), ('server_type', '!=', 'local')]).fetch_mail()
|
||||
|
||||
def fetch_mail(self):
|
||||
""" WARNING: meant for cron usage only - will commit() after each email! """
|
||||
@@ -174,7 +176,8 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
|
||||
count, failed = 0, 0
|
||||
imap_server = None
|
||||
pop_server = None
|
||||
if server.server_type == 'imap':
|
||||
connection_type = server._get_connection_type()
|
||||
if connection_type == 'imap':
|
||||
try:
|
||||
imap_server = server.connect()
|
||||
imap_server.select()
|
||||
@@ -198,7 +201,7 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
|
||||
if imap_server:
|
||||
imap_server.close()
|
||||
imap_server.logout()
|
||||
elif server.server_type == 'pop':
|
||||
elif connection_type == 'pop':
|
||||
try:
|
||||
while True:
|
||||
failed_in_loop = 0
|
||||
@@ -231,6 +234,14 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
|
||||
server.write({'date': fields.Datetime.now()})
|
||||
return True
|
||||
|
||||
def _get_connection_type(self):
|
||||
"""Return which connection must be used for this mail server (IMAP or POP).
|
||||
Can be overridden in sub-module to define which connection to use for a specific
|
||||
"server_type" (e.g. Gmail server).
|
||||
"""
|
||||
self.ensure_one()
|
||||
return self.server_type
|
||||
|
||||
@api.model
|
||||
def _update_cron(self):
|
||||
if self.env.context.get('fetchmail_cron_running'):
|
||||
@@ -238,6 +249,6 @@ odoo_mailgate: "|/path/to/odoo-mailgate.py --host=localhost -u %(uid)d -p PASSWO
|
||||
try:
|
||||
# Enabled/Disable cron based on the number of 'done' server of type pop or imap
|
||||
cron = self.env.ref('fetchmail.ir_cron_mail_gateway_action')
|
||||
cron.toggle(model=self._name, domain=[('state', '=', 'done'), ('server_type', 'in', ['pop', 'imap'])])
|
||||
cron.toggle(model=self._name, domain=[('state', '=', 'done'), ('server_type', '!=', 'local')])
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
<sheet>
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="server_type"/>
|
||||
<field name="date"/>
|
||||
<field name="server_type" widget="radio"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Server & Login" name="server_login_details">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "Fetchmail Gmail",
|
||||
"version": "1.0",
|
||||
"version": "1.1",
|
||||
"category": "Hidden",
|
||||
"description": "Google authentication for incoming mail server",
|
||||
"depends": [
|
||||
|
||||
@@ -1,34 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class FetchmailServer(models.Model):
|
||||
_name = 'fetchmail.server'
|
||||
_inherit = ['fetchmail.server', 'google.gmail.mixin']
|
||||
|
||||
@api.constrains('use_google_gmail_service', 'server_type')
|
||||
def _check_use_google_gmail_service(self):
|
||||
if any(server.use_google_gmail_service and server.server_type != 'imap' for server in self):
|
||||
raise UserError(_('Gmail authentication only supports IMAP server type.'))
|
||||
server_type = fields.Selection(selection_add=[('gmail', 'Gmail OAuth Authentication')], ondelete={'gmail': 'set default'})
|
||||
|
||||
@api.onchange('use_google_gmail_service')
|
||||
def _onchange_use_google_gmail_service(self):
|
||||
@api.onchange('server_type', 'is_ssl', 'object_id')
|
||||
def onchange_server_type(self):
|
||||
"""Set the default configuration for a IMAP Gmail server."""
|
||||
if self.use_google_gmail_service:
|
||||
if self.server_type == 'gmail':
|
||||
self.server = 'imap.gmail.com'
|
||||
self.server_type = 'imap'
|
||||
self.is_ssl = True
|
||||
self.port = 993
|
||||
else:
|
||||
self.server_type = 'pop'
|
||||
self.is_ssl = False
|
||||
self.google_gmail_authorization_code = False
|
||||
self.google_gmail_refresh_token = False
|
||||
self.google_gmail_access_token = False
|
||||
self.google_gmail_access_token_expiration = False
|
||||
super(FetchmailServer, self).onchange_server_type()
|
||||
|
||||
def _imap_login(self, connection):
|
||||
"""Authenticate the IMAP connection.
|
||||
@@ -36,9 +30,16 @@ class FetchmailServer(models.Model):
|
||||
If the mail server is Gmail, we use the OAuth2 authentication protocol.
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.use_google_gmail_service:
|
||||
if self.server_type == 'gmail':
|
||||
auth_string = self._generate_oauth2_string(self.user, self.google_gmail_refresh_token)
|
||||
connection.authenticate('XOAUTH2', lambda x: auth_string)
|
||||
connection.select('INBOX')
|
||||
else:
|
||||
super(FetchmailServer, self)._imap_login(connection)
|
||||
|
||||
def _get_connection_type(self):
|
||||
"""Return which connection must be used for this mail server (IMAP or POP).
|
||||
The Gmail mail server used an IMAP connection.
|
||||
"""
|
||||
self.ensure_one()
|
||||
return 'imap' if self.server_type == 'gmail' else super()._get_connection_type()
|
||||
|
||||
@@ -5,26 +5,25 @@
|
||||
<field name="model">fetchmail.server</field>
|
||||
<field name="inherit_id" ref="fetchmail.view_email_server_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="server" position="before">
|
||||
<field name="use_google_gmail_service" string="Gmail" attrs="{'readonly': [('state', '=', 'done')]}"/>
|
||||
</field>
|
||||
<field name="user" position="after">
|
||||
<field string="Authorization Code" name="google_gmail_authorization_code" password="True"
|
||||
attrs="{'required': [('use_google_gmail_service', '=', True)], 'invisible': [('use_google_gmail_service', '=', False)], 'readonly': [('state', '=', 'done')]}"
|
||||
attrs="{'required': [('server_type', '=', 'gmail')], 'invisible': [('server_type', '!=', 'gmail')], 'readonly': [('state', '=', 'done')]}"
|
||||
style="word-break: break-word;"/>
|
||||
<field name="google_gmail_uri"
|
||||
class="fa fa-arrow-right oe_edit_only"
|
||||
widget="url"
|
||||
text=" Get an Authorization Code"
|
||||
attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_uri', '=', False)]}"
|
||||
attrs="{'invisible': ['|', ('server_type', '!=', 'gmail'), ('google_gmail_uri', '=', False)]}"
|
||||
nolabel="1"/>
|
||||
<div class="alert alert-warning" role="alert"
|
||||
attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_uri', '!=', False)]}">
|
||||
Setup your Gmail API credentials in the general settings to link a Gmail account.
|
||||
attrs="{'invisible': ['|', ('server_type', '!=', 'gmail'), ('google_gmail_uri', '!=', False)]}">
|
||||
Setup your Gmail API credentials to link a Gmail account.
|
||||
</div>
|
||||
</field>
|
||||
<field name="password" position="attributes">
|
||||
<attribute name="attrs">{'required' : [('server_type', '!=', 'local'), ('use_google_gmail_service', '=', False), ('password', '!=', False)], 'invisible' : [('use_google_gmail_service', '=', True)]}</attribute>
|
||||
<attribute name="attrs">
|
||||
{'required' : [('server_type', '!=', 'local'), ('server_type', '!=', 'gmail'), ('password', '!=', False)], 'invisible' : [('server_type', '=', 'gmail')]}
|
||||
</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "Google Gmail",
|
||||
"version": "1.0",
|
||||
"version": "1.1",
|
||||
"category": "Hidden",
|
||||
"description": "Gmail support for incoming / outgoing mail servers",
|
||||
"depends": [
|
||||
|
||||
@@ -16,7 +16,6 @@ class GoogleGmailMixin(models.AbstractModel):
|
||||
|
||||
_SERVICE_SCOPE = 'https://mail.google.com/'
|
||||
|
||||
use_google_gmail_service = fields.Boolean('Gmail Authentication')
|
||||
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')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import base64
|
||||
|
||||
from odoo import models, api
|
||||
from odoo import fields, models, api
|
||||
|
||||
|
||||
class IrMailServer(models.Model):
|
||||
@@ -12,17 +12,20 @@ class IrMailServer(models.Model):
|
||||
_name = 'ir.mail_server'
|
||||
_inherit = ['ir.mail_server', 'google.gmail.mixin']
|
||||
|
||||
smtp_authentication = fields.Selection(
|
||||
selection_add=[('gmail', 'Gmail OAuth Authentication')],
|
||||
ondelete={'gmail': 'set default'})
|
||||
|
||||
@api.onchange('smtp_encryption')
|
||||
def _onchange_encryption(self):
|
||||
"""Do not change the SMTP configuration if it's a Gmail server
|
||||
|
||||
(e.g. the port which is already set)"""
|
||||
if not self.use_google_gmail_service:
|
||||
super()._onchange_encryption()
|
||||
if self.smtp_authentication != 'gmail':
|
||||
super(IrMailServer, self)._onchange_encryption()
|
||||
|
||||
@api.onchange('use_google_gmail_service')
|
||||
def _onchange_use_google_gmail_service(self):
|
||||
if self.use_google_gmail_service:
|
||||
@api.onchange('smtp_authentication')
|
||||
def _onchange_smtp_authentication(self):
|
||||
if self.smtp_authentication == 'gmail':
|
||||
self.smtp_host = 'smtp.gmail.com'
|
||||
self.smtp_encryption = 'starttls'
|
||||
self.smtp_port = 587
|
||||
@@ -34,10 +37,10 @@ class IrMailServer(models.Model):
|
||||
self.google_gmail_access_token_expiration = False
|
||||
|
||||
def _smtp_login(self, connection, smtp_user, smtp_password):
|
||||
if len(self) == 1 and self.use_google_gmail_service:
|
||||
if len(self) == 1 and self.smtp_authentication == 'gmail':
|
||||
auth_string = self._generate_oauth2_string(smtp_user, self.google_gmail_refresh_token)
|
||||
oauth_param = base64.b64encode(auth_string.encode()).decode()
|
||||
connection.ehlo()
|
||||
connection.docmd('AUTH', 'XOAUTH2 %s' % oauth_param)
|
||||
connection.docmd('AUTH', f'XOAUTH2 {oauth_param}')
|
||||
else:
|
||||
super(IrMailServer, self)._smtp_login(connection, smtp_user, smtp_password)
|
||||
|
||||
@@ -5,26 +5,25 @@
|
||||
<field name="model">ir.mail_server</field>
|
||||
<field name="inherit_id" ref="base.ir_mail_server_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="smtp_host" position="before">
|
||||
<field name="use_google_gmail_service" string="Gmail"/>
|
||||
</field>
|
||||
<field name="smtp_user" position="after">
|
||||
<field string="Authorization Code" name="google_gmail_authorization_code" password="True"
|
||||
attrs="{'required': [('use_google_gmail_service', '=', True)], 'invisible': [('use_google_gmail_service', '=', False)]}"
|
||||
style="word-break: break-word;"/>
|
||||
attrs="{'required': [('smtp_authentication', '=', 'gmail')], 'invisible': [('smtp_authentication', '!=', 'gmail')]}"/>
|
||||
<field name="google_gmail_uri"
|
||||
class="fa fa-arrow-right oe_edit_only"
|
||||
widget="url"
|
||||
text=" Get an Authorization Code"
|
||||
attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_uri', '=', False)]}"
|
||||
attrs="{'invisible': ['|', ('smtp_authentication', '!=', 'gmail'), ('google_gmail_uri', '=', False)]}"
|
||||
nolabel="1"/>
|
||||
<div class="alert alert-warning" role="alert"
|
||||
attrs="{'invisible': ['|', ('use_google_gmail_service', '=', False), ('google_gmail_uri', '!=', False)]}">
|
||||
Setup your Gmail API credentials in the general settings to link a Gmail account.
|
||||
attrs="{'invisible': ['|', ('smtp_authentication', '!=', 'gmail'), ('google_gmail_uri', '!=', False)]}">
|
||||
Setup your Gmail API credentials to link a Gmail account.
|
||||
</div>
|
||||
</field>
|
||||
<field name="smtp_user" position="attributes">
|
||||
<attribute name="attrs">{'invisible' : [('smtp_authentication', '!=', 'login'), ('smtp_authentication', '!=', 'gmail')]}</attribute>
|
||||
</field>
|
||||
<field name="smtp_pass" position="attributes">
|
||||
<attribute name="attrs">{'invisible' : [('use_google_gmail_service', '=', True)]}</attribute>
|
||||
<attribute name="attrs">{'invisible' : [('smtp_authentication', '=', 'gmail')]}</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -6,25 +6,14 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div id="emails" position="inside">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="google_gmail_setting"
|
||||
attrs="{'invisible': [('external_email_server_default', '=', False)]}">
|
||||
<div class="o_setting_right_pane">
|
||||
<span class="o_form_label">Gmail Credentials</span>
|
||||
<div class="text-muted">
|
||||
Send and receive email with your Gmail account.
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="row mt16" id="gmail_client_identifier">
|
||||
<label string="Client ID" for="google_gmail_client_identifier" class="col-lg-3 o_light_label"/>
|
||||
<field name="google_gmail_client_identifier" class="ml-2"/>
|
||||
</div>
|
||||
<div class="row mt16" id="gmail_client_secret">
|
||||
<label string="Client Secret" for="google_gmail_client_secret" class="col-lg-3 o_light_label"/>
|
||||
<field name="google_gmail_client_secret" class="ml-2"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="msg_module_google_gmail" position="replace">
|
||||
<div class="row mt16" id="gmail_client_identifier">
|
||||
<label string="Client ID" for="google_gmail_client_identifier" class="col-lg-3 o_light_label"/>
|
||||
<field name="google_gmail_client_identifier" class="ml-2" attrs="{'required': [('module_google_gmail', '=', True), ('external_email_server_default', '=', True)]}"/>
|
||||
</div>
|
||||
<div class="row mt16" id="gmail_client_secret">
|
||||
<label string="Client Secret" for="google_gmail_client_secret" class="col-lg-3 o_light_label"/>
|
||||
<field name="google_gmail_client_secret" class="ml-2" attrs="{'required': [('module_google_gmail', '=', True), ('external_email_server_default', '=', True)]}"/>
|
||||
</div>
|
||||
</div>
|
||||
</field>
|
||||
|
||||
@@ -15,6 +15,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
alias_domain = fields.Char(
|
||||
'Alias Domain', config_parameter='mail.catchall.domain',
|
||||
help="If you have setup a catch-all email domain redirected to the Odoo server, enter the domain name here.")
|
||||
module_google_gmail = fields.Boolean('Support Gmail Authentication')
|
||||
restrict_template_rendering = fields.Boolean(
|
||||
'Restrict Template Rendering',
|
||||
config_parameter='mail.restrict.template.rendering',
|
||||
|
||||
@@ -66,6 +66,22 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="google_gmail_setting"
|
||||
attrs="{'invisible': [('external_email_server_default', '=', False)]}">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_google_gmail"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Gmail Credentials" for="module_google_gmail"/>
|
||||
<a href="https://console.developers.google.com/" title="Get Gmail API credentials" class="o_doc_link" target="_blank"/>
|
||||
<div class="text-muted">
|
||||
Send and receive emails with your Gmail account.
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('module_google_gmail','=',False)]}" id="msg_module_google_gmail">
|
||||
<div class="mt16 text-warning"><strong>Save</strong> this page and come back here to set up the feature.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<span class="o_form_label">Custom ICE server list</span>
|
||||
|
||||
@@ -233,12 +233,12 @@ class IrMailServer(models.Model):
|
||||
if mail_server:
|
||||
smtp_server = mail_server.smtp_host
|
||||
smtp_port = mail_server.smtp_port
|
||||
if mail_server.smtp_authentication == "login":
|
||||
smtp_user = mail_server.smtp_user
|
||||
smtp_password = mail_server.smtp_pass
|
||||
else:
|
||||
if mail_server.smtp_authentication == "certificate":
|
||||
smtp_user = None
|
||||
smtp_password = None
|
||||
else:
|
||||
smtp_user = mail_server.smtp_user
|
||||
smtp_password = mail_server.smtp_pass
|
||||
smtp_encryption = mail_server.smtp_encryption
|
||||
smtp_debug = smtp_debug or mail_server.smtp_debug
|
||||
from_filter = mail_server.from_filter
|
||||
|
||||
Reference in New Issue
Block a user