diff --git a/addons/auth_oauth2_provider/auth_oauth2_provider.py b/addons/auth_oauth2_provider/auth_oauth2_provider.py index 1792d038b27..32977c4fabe 100644 --- a/addons/auth_oauth2_provider/auth_oauth2_provider.py +++ b/addons/auth_oauth2_provider/auth_oauth2_provider.py @@ -19,46 +19,65 @@ # ############################################################################## from openerp.osv import osv, fields +import datetime import uuid -class res_users(osv.osv): - """Oauth2 Provider Class""" - _inherit = 'res.users' +class auth_oauth2_token(osv.osv): + """Oauth2 Token Class""" + + _name = 'auth.oauth2.token' + _description = 'OAuth2 Token' _columns = { - # TODO: partial implementation supporting only one client_id for the moment. - 'last_oauth_token': fields.char('Last OAuth Token', size=32, readonly=True, invisible=True), - 'last_oauth_token_scope': fields.char('Last OAuth Token Scope', readonly=True, invisible=True), + 'token': fields.char('Token', size=32, readonly=True), + 'user_id': fields.many2one('res.users', 'User', required=True, select=True, readonly=True), + 'client': fields.char('Client', help="Client Application for which the token has been generated", readonly=True, select=True), # TODO: auth.oauth2.client object + 'scope': fields.char('Scope', help="Scope for which the token has ben delivered", readonly=True, select=True), + 'expires_at': fields.datetime('Token expiration date'), } - def auth_oauth_provider_get_token(self, cr, uid, client_id="", scope="", context=None): - token = str(uuid.uuid4()).replace('-', '') - self.write(cr, uid, [uid], { - "last_oauth_token": token, - "last_oauth_token_scope": scope, - }, context=context) - return token + TOKEN_EXPIRATION_TIMESPAN = 3600 # in seconds - def auth_oauth_provider_tokeninfo(self, cr, uid, access_token, context=None): - user_id = self.search(cr, uid, [('last_oauth_token', '=', access_token)], context=context) - if len(user_id) != 1: - return { - "error": "invalid_token" - } - user = self.browse(cr, uid, user_id[0], context=context) - if access_token == user.last_oauth_token: - r = { - "user_id": user.id, - "scope": user.last_oauth_token_scope, - #"audience": "8819981768.apps.googleusercontent.com", - #"expires_in": 436 - } - if user.partner_id.email: # TODO: should deliver only according to scopes - r['email'] = user.partner_id.email - return r - else: - return { - "error": "invalid_token" - } + _defaults = { + 'expires_at': lambda self, *a: datetime.datetime.utcnow() + datetime.timedelta(seconds=self.TOKEN_EXPIRATION_TIMESPAN), + } + + def get_token(self, cr, uid, client_id="", scope="", context=None): + token = str(uuid.uuid4()).replace('-', '') + self.create(cr, uid, { + 'token': token, + 'user_id': uid, + 'client': client_id, + 'scope': scope, + }, context=context) + return { + 'access_token': token, + 'expires_in': self.TOKEN_EXPIRATION_TIMESPAN, + } + + def tokeninfo(self, cr, uid, access_token, context=None): + token = self.search(cr, uid, [('token', '=', access_token)], context=context) + if not len(token): + return { "error": "invalid_token" } + token = self.browse(cr, uid, token[0], context=context) + expires_at = datetime.datetime.strptime(token.expires_at[:19], '%Y-%m-%d %H:%M:%S') + + # python 2.7's datetime.timedelta supports total_seconds() + # expires_in = int(round((expires_at - datetime.datetime.utcnow()).total_seconds())) + delta = expires_at - datetime.datetime.utcnow() + expires_in = (delta.microseconds + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6 + + if expires_in <= 0: + return { "error": "invalid_token" } + + r = { + "user_id": token.user_id.id, + "scope": token.scope, + "expires_in": expires_in, + "audience": token.client, + } + if token.user_id.email: # TODO: should deliver only according to scopes + r['email'] = token.user_id.email + return r # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth2_provider/controllers/main.py b/addons/auth_oauth2_provider/controllers/main.py index 944e3e44bf9..47e5d99df14 100644 --- a/addons/auth_oauth2_provider/controllers/main.py +++ b/addons/auth_oauth2_provider/controllers/main.py @@ -45,10 +45,8 @@ class AuthOAuthProvider(openerpweb.Controller): @openerpweb.jsonrequest def get_token(self, req, client_id="", scope="", **kw): - token = req.session.model('res.users').auth_oauth_provider_get_token(client_id, scope) - return { - 'access_token': token, - } + r = req.session.model('auth.oauth2.token').get_token(client_id, scope) + return r @openerpweb.httprequest def tokeninfo(self, req, dbname=None, access_token=None, **kw): @@ -57,10 +55,10 @@ class AuthOAuthProvider(openerpweb.Controller): try: registry = openerp.modules.registry.RegistryManager.get(dbname) with registry.cursor() as cr: - u = registry.get('res.users') - info = u.auth_oauth_provider_tokeninfo(cr, SUPERUSER_ID, access_token, kw) + u = registry.get('auth.oauth2.token') + info = u.tokeninfo(cr, SUPERUSER_ID, access_token, kw) return simplejson.dumps(info) except Exception, e: - return simplejson.dumps({ "error": e.message }) + return simplejson.dumps({ "error": str(e) }) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.css b/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.css index 778179b63b4..71e3fbe14ce 100644 --- a/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.css +++ b/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.css @@ -1,13 +1,13 @@ @charset "utf-8"; -.openerp .oe_oauth_provider { +.openerp .oe_oauth2_provider { padding: 0 10px; } -.openerp .oe_oauth_provider .oe_oauth_provider_error span.oe_i { +.openerp .oe_oauth2_provider .oe_oauth2_provider_error span.oe_i { font-size: 60px; color: #990000; float: left; } -.openerp .oe_oauth_provider .oe_oauth_provider_error ul { +.openerp .oe_oauth2_provider .oe_oauth2_provider_error ul { list-style: none; float: left; font-weight: bold; diff --git a/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.sass b/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.sass index 7921f4cc055..91dceb077db 100644 --- a/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.sass +++ b/addons/auth_oauth2_provider/static/src/css/auth_oauth2_provider.sass @@ -1,9 +1,9 @@ @charset "utf-8" -.openerp .oe_oauth_provider +.openerp .oe_oauth2_provider padding: 0 10px - .oe_oauth_provider_error + .oe_oauth2_provider_error span.oe_i font-size: 60px color: #900 diff --git a/addons/auth_oauth2_provider/static/src/js/auth_oauth2_provider.js b/addons/auth_oauth2_provider/static/src/js/auth_oauth2_provider.js index 84a89415ed3..0d807e0f4bc 100644 --- a/addons/auth_oauth2_provider/static/src/js/auth_oauth2_provider.js +++ b/addons/auth_oauth2_provider/static/src/js/auth_oauth2_provider.js @@ -1,11 +1,11 @@ -openerp.auth_oauth_provider = function(instance) { +openerp.auth_oauth2_provider = function(instance) { var QWeb = instance.web.qweb; var _t = instance.web._t; -instance.web.client_actions.add('oauth2_auth', 'instance.auth_oauth_provider.ProviderAction'); -instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ - template: "auth_oauth_provider", +instance.web.client_actions.add('oauth2_auth', 'instance.auth_oauth2_provider.ProviderAction'); +instance.auth_oauth2_provider.ProviderAction = instance.web.Widget.extend({ + template: "auth_oauth2_provider", start: function (parent) { var self = this; this._super.apply(this, arguments); @@ -23,7 +23,7 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ if (!this._error) { // params.approval_prompt TODO --> add 'none' (default) // TODO: get client_id and scope - this.$('.oe_oauth_provider_approval').show().on('click', '.oe_oauth_provider_allow', function() { + this.$('.oe_oauth2_provider_approval').show().on('click', '.oe_oauth2_provider_allow', function() { instance.session.rpc('/oauth2/get_token', { client_id: params.client_id || '', scope: params.scope || '', @@ -32,7 +32,7 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ }).fail(function() { self.error(_t("An error occured while contacting the OpenERP server.")); }); - }).on('click', '.oe_oauth_provider_deny', function() { + }).on('click', '.oe_oauth2_provider_deny', function() { self.redirect({ error: 'access_denied' }); @@ -61,8 +61,8 @@ instance.auth_oauth_provider.ProviderAction = instance.web.Widget.extend({ }, error: function(msg) { this._error = true; - var $msg = $('
  • ').addClass('oe_oauth_provider_error_text').text(msg); - $msg.appendTo(this.$('.oe_oauth_provider_error').show().find('ul')); + var $msg = $('
  • ').addClass('oe_oauth2_provider_error_text').text(msg); + $msg.appendTo(this.$('.oe_oauth2_provider_error').show().find('ul')); return false; }, }); diff --git a/addons/auth_oauth2_provider/static/src/xml/oauth_provider.xml b/addons/auth_oauth2_provider/static/src/xml/auth_oauth2_provider.xml similarity index 54% rename from addons/auth_oauth2_provider/static/src/xml/oauth_provider.xml rename to addons/auth_oauth2_provider/static/src/xml/auth_oauth2_provider.xml index 85985e4e974..d0723c70c33 100644 --- a/addons/auth_oauth2_provider/static/src/xml/oauth_provider.xml +++ b/addons/auth_oauth2_provider/static/src/xml/auth_oauth2_provider.xml @@ -1,14 +1,14 @@