You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.9 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2016 Florent de Labarre
  3. # Copyright 2017 Camptocamp
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
  5. import uuid
  6. from odoo import api, fields, models, exceptions
  7. from odoo.addons import base
  8. base.res.res_users.USER_PRIVATE_FIELDS.\
  9. append('oauth_master_uuid')
  10. class ResUsers(models.Model):
  11. _inherit = 'res.users'
  12. oauth_access_token_ids = fields.One2many(
  13. comodel_name='auth.oauth.multi.token',
  14. inverse_name='user_id',
  15. string='OAuth tokens',
  16. copy=False
  17. )
  18. oauth_access_max_token = fields.Integer(
  19. string='Max number of simultaneous connections',
  20. default=10,
  21. required=True
  22. )
  23. oauth_master_uuid = fields.Char(
  24. string='Master UUID',
  25. copy=False,
  26. readonly=True,
  27. required=True,
  28. default=lambda self: self._generate_oauth_master_uuid(),
  29. )
  30. def _generate_oauth_master_uuid(self):
  31. return uuid.uuid4().hex
  32. @property
  33. def multi_token_model(self):
  34. return self.env['auth.oauth.multi.token']
  35. @api.model
  36. def _auth_oauth_signin(self, provider, validation, params):
  37. """Override to handle sign-in with multi token."""
  38. res = super(ResUsers, self)._auth_oauth_signin(
  39. provider, validation, params)
  40. oauth_uid = validation['user_id']
  41. # Lookup for user by oauth uid and provider
  42. user = self.search([
  43. ('oauth_uid', '=', oauth_uid),
  44. ('oauth_provider_id', '=', provider)]
  45. )
  46. if not user:
  47. raise exceptions.AccessDenied()
  48. user.ensure_one()
  49. # user found and unique: create a token
  50. self.multi_token_model.create({
  51. 'user_id': user.id,
  52. 'oauth_access_token': params['access_token'],
  53. 'active_token': True,
  54. })
  55. return res
  56. @api.multi
  57. def action_oauth_clear_token(self):
  58. """Inactivate current user tokens."""
  59. self.mapped('oauth_access_token_ids')._oauth_clear_token()
  60. for res in self:
  61. res.oauth_master_uuid = self._generate_oauth_master_uuid()
  62. @api.model
  63. def check_credentials(self, password):
  64. """Override to check credentials against multi tokens."""
  65. try:
  66. return super(ResUsers, self).check_credentials(password)
  67. except exceptions.AccessDenied:
  68. res = self.multi_token_model.sudo().search([
  69. ('user_id', '=', self.env.uid),
  70. ('oauth_access_token', '=', password),
  71. ('active_token', '=', True),
  72. ])
  73. if not res:
  74. raise
  75. def _get_session_token_fields(self):
  76. res = super(ResUsers, self)._get_session_token_fields()
  77. res.remove('oauth_access_token')
  78. return res | {'oauth_master_uuid'}