Files
odoo_source/addons/google_gmail/models/google_gmail_mixin.py
T
std-odoo fdde704712 [FIX] google_gmail: do not copy the authorization code
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
2022-04-01 13:37:15 +02:00

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)