Bug === When we copy a GMail outgoing / incoming mail server, an error occurs because we try to refetch the access token, based on the same authorization code (which can be used only once). To fix this issue, we do not copy the authorization code (and other related fields). Task-2751996 X-original-commit: 47c056215c5f50d8a1d9e862ee275eceefdb09e7 Part-of: odoo/odoo#87731
87 lines
4.0 KiB
Python
87 lines
4.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import logging
|
|
import time
|
|
|
|
from odoo import api, fields, models
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class GoogleGmailMixin(models.AbstractModel):
|
|
|
|
_name = 'google.gmail.mixin'
|
|
_description = 'Google Gmail Mixin'
|
|
|
|
_SERVICE_SCOPE = 'https://mail.google.com/'
|
|
|
|
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')
|
|
def _compute_gmail_uri(self):
|
|
Config = self.env['ir.config_parameter'].sudo()
|
|
google_gmail_client_id = Config.get_param('google_gmail_client_id')
|
|
google_gmail_client_secret = Config.get_param('google_gmail_client_secret')
|
|
|
|
if not google_gmail_client_id or not google_gmail_client_secret:
|
|
self.google_gmail_uri = False
|
|
else:
|
|
google_gmail_uri = self.env['google.service']._get_google_token_uri('gmail', scope=self._SERVICE_SCOPE)
|
|
self.google_gmail_uri = google_gmail_uri
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
for values in vals_list:
|
|
if values.get('google_gmail_authorization_code'):
|
|
# Generate the refresh token
|
|
values['google_gmail_refresh_token'] = self.env['google.service'].generate_refresh_token(
|
|
'gmail', values['google_gmail_authorization_code'])
|
|
values['google_gmail_access_token'] = False
|
|
values['google_gmail_access_token_expiration'] = False
|
|
|
|
return super(GoogleGmailMixin, self).create(vals_list)
|
|
|
|
def write(self, values):
|
|
authorization_code = values.get('google_gmail_authorization_code')
|
|
if (
|
|
authorization_code
|
|
and not all(authorization_code == code for code in self.mapped('google_gmail_authorization_code'))
|
|
):
|
|
# Update the refresh token
|
|
values['google_gmail_refresh_token'] = self.env['google.service'].generate_refresh_token(
|
|
'gmail', authorization_code)
|
|
values['google_gmail_access_token'] = False
|
|
values['google_gmail_access_token_expiration'] = False
|
|
|
|
return super(GoogleGmailMixin, self).write(values)
|
|
|
|
def _generate_oauth2_string(self, user, refresh_token):
|
|
"""Generate a OAuth2 string which can be used for authentication.
|
|
|
|
:param user: Email address of the Gmail account to authenticate
|
|
:param refresh_token: Refresh token for the given Gmail account
|
|
|
|
:return: The SASL argument for the OAuth2 mechanism.
|
|
"""
|
|
self.ensure_one()
|
|
now_timestamp = int(time.time())
|
|
if not self.google_gmail_access_token \
|
|
or not self.google_gmail_access_token_expiration \
|
|
or self.google_gmail_access_token_expiration < now_timestamp:
|
|
self.google_gmail_access_token, expires_in = self.env['google.service']._get_access_token(
|
|
refresh_token, 'gmail', self._SERVICE_SCOPE)
|
|
self.google_gmail_access_token_expiration = now_timestamp + expires_in
|
|
|
|
_logger.info('Google Gmail: fetch new access token. Expire in %i minutes', expires_in // 60)
|
|
else:
|
|
_logger.info(
|
|
'Google Gmail: reuse existing access token. Expire in %i minutes',
|
|
(self.google_gmail_access_token_expiration - now_timestamp) // 60)
|
|
|
|
return 'user=%s\1auth=Bearer %s\1\1' % (user, self.google_gmail_access_token)
|