google_credentials.py 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. import logging
  4. import requests
  5. from datetime import timedelta
  6. from odoo import fields, models, _
  7. from odoo.exceptions import UserError
  8. from odoo.addons.google_account.models.google_service import GOOGLE_TOKEN_ENDPOINT
  9. _logger = logging.getLogger(__name__)
  10. class GoogleCredentials(models.Model):
  11. """"Google Account of res_users"""
  12. _name = 'google.calendar.credentials'
  13. _description = 'Google Calendar Account Data'
  14. user_ids = fields.One2many('res.users', 'google_calendar_account_id', required=True)
  15. calendar_rtoken = fields.Char('Refresh Token', copy=False)
  16. calendar_token = fields.Char('User token', copy=False)
  17. calendar_token_validity = fields.Datetime('Token Validity', copy=False)
  18. calendar_sync_token = fields.Char('Next Sync Token', copy=False)
  19. calendar_cal_id = fields.Char('Calendar ID', copy=False, help='Last Calendar ID who has been synchronized. If it is changed, we remove all links between GoogleID and Odoo Google Internal ID')
  20. synchronization_stopped = fields.Boolean('Google Synchronization stopped', copy=False)
  21. def _set_auth_tokens(self, access_token, refresh_token, ttl):
  22. self.write({
  23. 'calendar_rtoken': refresh_token,
  24. 'calendar_token': access_token,
  25. 'calendar_token_validity': fields.Datetime.now() + timedelta(seconds=ttl) if ttl else False,
  26. })
  27. def _google_calendar_authenticated(self):
  28. self.ensure_one()
  29. return bool(self.sudo().calendar_rtoken)
  30. def _is_google_calendar_valid(self):
  31. self.ensure_one()
  32. return self.calendar_token_validity and self.calendar_token_validity >= (fields.Datetime.now() + timedelta(minutes=1))
  33. def _refresh_google_calendar_token(self):
  34. # LUL TODO similar code exists in google_drive. Should be factorized in google_account
  35. self.ensure_one()
  36. get_param = self.env['ir.config_parameter'].sudo().get_param
  37. client_id = get_param('google_calendar_client_id')
  38. client_secret = get_param('google_calendar_client_secret')
  39. if not client_id or not client_secret:
  40. raise UserError(_("The account for the Google Calendar service is not configured."))
  41. headers = {"content-type": "application/x-www-form-urlencoded"}
  42. data = {
  43. 'refresh_token': self.calendar_rtoken,
  44. 'client_id': client_id,
  45. 'client_secret': client_secret,
  46. 'grant_type': 'refresh_token',
  47. }
  48. try:
  49. _dummy, response, _dummy = self.env['google.service']._do_request(GOOGLE_TOKEN_ENDPOINT, params=data, headers=headers, method='POST', preuri='')
  50. ttl = response.get('expires_in')
  51. self.write({
  52. 'calendar_token': response.get('access_token'),
  53. 'calendar_token_validity': fields.Datetime.now() + timedelta(seconds=ttl),
  54. })
  55. except requests.HTTPError as error:
  56. if error.response.status_code in (400, 401): # invalid grant or invalid client
  57. # Delete refresh token and make sure it's commited
  58. self.env.cr.rollback()
  59. self._set_auth_tokens(False, False, 0)
  60. self.env.cr.commit()
  61. error_key = error.response.json().get("error", "nc")
  62. error_msg = _("An error occurred while generating the token. Your authorization code may be invalid or has already expired [%s]. "
  63. "You should check your Client ID and secret on the Google APIs plateform or try to stop and restart your calendar synchronisation.",
  64. error_key)
  65. raise UserError(error_msg)