[ADD] Add auth.oauth2.token

bzr revid: fme@openerp.com-20120926161831-q4uxxr3slqth9mzy
This commit is contained in:
Fabien Meghazi
2012-09-26 18:18:31 +02:00
parent 5e3a747290
commit 08cea541f8
6 changed files with 77 additions and 60 deletions
@@ -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:
@@ -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:
@@ -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;
@@ -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
@@ -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 = $('<li/>').addClass('oe_oauth_provider_error_text').text(msg);
$msg.appendTo(this.$('.oe_oauth_provider_error').show().find('ul'));
var $msg = $('<li/>').addClass('oe_oauth2_provider_error_text').text(msg);
$msg.appendTo(this.$('.oe_oauth2_provider_error').show().find('ul'));
return false;
},
});
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<t t-name="auth_oauth_provider">
<div class="oe_oauth_provider">
<t t-name="auth_oauth2_provider">
<div class="oe_oauth2_provider">
<h1>OpenERP OAuth</h1>
<div style="display: none" class="oe_oauth_provider_error">
<div style="display: none" class="oe_oauth2_provider_error">
<span class="oe_i">D</span>
<ul/>
</div>
<div style="display: none" class="oe_oauth_provider_approval">
<div style="display: none" class="oe_oauth2_provider_approval">
<b>TODO: get ClientID name</b> asks permission for:
<ul>
<li>
@@ -16,8 +16,8 @@
Basic information about your account
</li>
</ul>
<button class="oe_button oe_oauth_provider_allow">Allow Access</button>
<button class="oe_button oe_oauth_provider_deny">No thanks</button>
<button class="oe_button oe_oauth2_provider_allow">Allow Access</button>
<button class="oe_button oe_oauth2_provider_deny">No thanks</button>
</div>
</div>
</t>