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.

130 lines
5.1 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2016 SYLEAM
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  4. import hashlib
  5. import uuid
  6. import logging
  7. from openerp import models, api, fields
  8. from ..oauth2.validator import OdooValidator
  9. _logger = logging.getLogger(__name__)
  10. try:
  11. from oauthlib import oauth2
  12. except ImportError:
  13. _logger.debug('Cannot `import oauthlib`.')
  14. class OAuthProviderClient(models.Model):
  15. _name = 'oauth.provider.client'
  16. _description = 'OAuth Provider Client'
  17. name = fields.Char(required=True, help='Name of this client.')
  18. identifier = fields.Char(
  19. string='Client Identifier', required=True, readonly=True,
  20. default=lambda self: str(uuid.uuid4()), copy=False,
  21. help='Unique identifier of the client.')
  22. secret = fields.Char(
  23. help='Optional secret used to authenticate the client.')
  24. skip_authorization = fields.Boolean(
  25. help='Check this box if the user shouldn\'t be prompted to authorize '
  26. 'or not the requested scopes.')
  27. application_type = fields.Selection(
  28. selection=[
  29. ('web application', 'Web Application'),
  30. ('mobile application', 'Mobile Application'),
  31. ('legacy application', 'Legacy Application'),
  32. ('backend application', 'Backend Application (not implemented)'),
  33. ], required=True, default='web application',
  34. help='Application type to be used with this client.')
  35. grant_type = fields.Selection(
  36. selection=[
  37. ('authorization_code', 'Authorization Code'),
  38. ('implicit', 'Implicit'),
  39. ('password', 'Password'),
  40. ('client_credentials', 'Client Credentials'),
  41. ], string='OAuth Grant Type',
  42. compute='_compute_grant_response_type', store=True,
  43. help='Grant type used by the client for OAuth.')
  44. response_type = fields.Selection(
  45. selection=[
  46. ('code', 'Authorization Code'),
  47. ('token', 'Token'),
  48. ('none', 'None'),
  49. ], string='OAuth Response Type',
  50. compute='_compute_grant_response_type', store=True,
  51. help='Response type used by the client for OAuth.')
  52. token_type = fields.Selection(
  53. selection=[('random', 'Randomly generated')],
  54. required=True, default='random',
  55. help='Type of token to return. The base module only provides randomly '
  56. 'generated tokens.')
  57. scope_ids = fields.Many2many(
  58. comodel_name='oauth.provider.scope', string='Allowed Scopes',
  59. help='List of scopes the client is allowed to access.')
  60. redirect_uri_ids = fields.One2many(
  61. comodel_name='oauth.provider.redirect.uri', inverse_name='client_id',
  62. string='OAuth Redirect URIs',
  63. help='Allowed redirect URIs for the client.')
  64. _sql_constraints = [
  65. ('identifier_unique', 'UNIQUE (identifier)',
  66. 'The identifier of the client must be unique !'),
  67. ]
  68. @api.model
  69. def application_type_mapping(self):
  70. return {
  71. 'web application': ('authorization_code', 'code'),
  72. 'mobile application': ('implicit', 'token'),
  73. 'legacy application': ('password', 'none'),
  74. 'backend application': ('client_credentials', 'none'),
  75. }
  76. @api.multi
  77. @api.depends('application_type')
  78. def _compute_grant_response_type(self):
  79. applications = self.application_type_mapping()
  80. for client in self:
  81. client.grant_type, client.response_type = applications[
  82. client.application_type]
  83. @api.multi
  84. def get_oauth2_server(self, validator=None, **kwargs):
  85. """ Returns an OAuth2 server instance, depending on the client application type
  86. Generates an OdooValidator instance if no custom validator is defined
  87. All other arguments are directly passed to the server constructor (for
  88. example, a token generator function)
  89. """
  90. self.ensure_one()
  91. if validator is None:
  92. validator = OdooValidator()
  93. if self.application_type == 'web application':
  94. return oauth2.WebApplicationServer(validator, **kwargs)
  95. elif self.application_type == 'mobile application':
  96. return oauth2.MobileApplicationServer(validator, **kwargs)
  97. elif self.application_type == 'legacy application':
  98. return oauth2.LegacyApplicationServer(validator, **kwargs)
  99. elif self.application_type == 'backend application':
  100. return oauth2.BackendApplicationServer(validator, **kwargs)
  101. @api.multi
  102. def generate_user_id(self, user):
  103. """ Generates a unique user identifier for this client
  104. Include the client and user identifiers in the final identifier to
  105. generate a different identifier for the same user, depending on the
  106. client accessing this user. By doing this, clients cannot find a list
  107. of common users by comparing their identifiers list from tokeninfo.
  108. """
  109. self.ensure_one()
  110. user_identifier = self.identifier \
  111. + user.sudo().oauth_identifier
  112. # Use a sha256 to avoid a too long final string
  113. return hashlib.sha256(user_identifier).hexdigest()