190 lines
8.7 KiB
Python
190 lines
8.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import openerp
|
|
from openerp.http import request
|
|
from openerp.osv import osv
|
|
from openerp import SUPERUSER_ID
|
|
from openerp.tools.translate import _
|
|
from datetime import datetime
|
|
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
|
|
|
import werkzeug.urls
|
|
import urllib2
|
|
import simplejson
|
|
|
|
import logging
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
TIMEOUT = 20
|
|
|
|
class google_service(osv.osv_memory):
|
|
_name = 'google.service'
|
|
|
|
def generate_refresh_token(self, cr, uid, service, authorization_code, context=None):
|
|
ir_config = self.pool['ir.config_parameter']
|
|
client_id = ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service)
|
|
client_secret = ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_secret' % service)
|
|
redirect_uri = ir_config.get_param(cr, SUPERUSER_ID, 'google_redirect_uri')
|
|
|
|
#Get the Refresh Token From Google And store it in ir.config_parameter
|
|
headers = {"Content-type": "application/x-www-form-urlencoded"}
|
|
data = dict(code=authorization_code, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, grant_type="authorization_code")
|
|
data = werkzeug.url_encode(data)
|
|
try:
|
|
req = urllib2.Request("https://accounts.google.com/o/oauth2/token", data, headers)
|
|
content = urllib2.urlopen(req, timeout=TIMEOUT).read()
|
|
except urllib2.HTTPError:
|
|
error_msg = "Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired"
|
|
raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context)
|
|
|
|
content = simplejson.loads(content)
|
|
return content.get('refresh_token')
|
|
|
|
def _get_google_token_uri(self, cr, uid, service, scope, context=None):
|
|
ir_config = self.pool['ir.config_parameter']
|
|
params = {
|
|
'scope': scope,
|
|
'redirect_uri': ir_config.get_param(cr, SUPERUSER_ID, 'google_redirect_uri'),
|
|
'client_id': ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service),
|
|
'response_type': 'code',
|
|
'client_id': ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service),
|
|
}
|
|
uri = 'https://accounts.google.com/o/oauth2/auth?%s' % werkzeug.url_encode(params)
|
|
return uri
|
|
|
|
# If no scope is passed, we use service by default to get a default scope
|
|
def _get_authorize_uri(self, cr, uid, from_url, service, scope=False, context=None):
|
|
""" This method return the url needed to allow this instance of OpenErp to access to the scope of gmail specified as parameters """
|
|
state_obj = dict(d=cr.dbname, s=service, f=from_url)
|
|
|
|
base_url = self.get_base_url(cr, uid, context)
|
|
client_id = self.get_client_id(cr, uid, service, context)
|
|
|
|
params = {
|
|
'response_type': 'code',
|
|
'client_id': client_id,
|
|
'state': simplejson.dumps(state_obj),
|
|
'scope': scope or 'https://www.googleapis.com/auth/%s' % (service,),
|
|
'redirect_uri': base_url + '/google_account/authentication',
|
|
'approval_prompt': 'force',
|
|
'access_type': 'offline'
|
|
}
|
|
|
|
uri = self.get_uri_oauth(a='auth') + "?%s" % werkzeug.url_encode(params)
|
|
return uri
|
|
|
|
def _get_google_token_json(self, cr, uid, authorize_code, service, context=None):
|
|
res = False
|
|
base_url = self.get_base_url(cr, uid, context)
|
|
client_id = self.get_client_id(cr, uid, service, context)
|
|
client_secret = self.get_client_secret(cr, uid, service, context)
|
|
|
|
params = {
|
|
'code': authorize_code,
|
|
'client_id': client_id,
|
|
'client_secret': client_secret,
|
|
'grant_type': 'authorization_code',
|
|
'redirect_uri': base_url + '/google_account/authentication'
|
|
}
|
|
|
|
headers = {"content-type": "application/x-www-form-urlencoded"}
|
|
|
|
try:
|
|
uri = self.get_uri_oauth(a='token')
|
|
data = werkzeug.url_encode(params)
|
|
|
|
st, res, ask_time = self._do_request(cr, uid, uri, params=data, headers=headers, type='POST', preuri='', context=context)
|
|
except urllib2.HTTPError:
|
|
error_msg = "Something went wrong during your token generation. Maybe your Authorization Code is invalid"
|
|
raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context)
|
|
return res
|
|
|
|
def _refresh_google_token_json(self, cr, uid, refresh_token, service, context=None): # exchange_AUTHORIZATION vs Token (service = calendar)
|
|
res = False
|
|
client_id = self.get_client_id(cr, uid, service, context)
|
|
client_secret = self.get_client_secret(cr, uid, service, context)
|
|
|
|
params = {
|
|
'refresh_token': refresh_token,
|
|
'client_id': client_id,
|
|
'client_secret': client_secret,
|
|
'grant_type': 'refresh_token',
|
|
}
|
|
|
|
headers = {"content-type": "application/x-www-form-urlencoded"}
|
|
|
|
try:
|
|
uri = self.get_uri_oauth(a='token')
|
|
|
|
data = werkzeug.url_encode(params)
|
|
st, res, ask_time = self._do_request(cr, uid, uri, params=data, headers=headers, type='POST', preuri='', context=context)
|
|
except urllib2.HTTPError, e:
|
|
if e.code == 400: # invalid grant
|
|
registry = openerp.modules.registry.RegistryManager.get(request.session.db)
|
|
with registry.cursor() as cur:
|
|
self.pool['res.users'].write(cur, uid, [uid], {'google_%s_rtoken' % service: False}, context=context)
|
|
error_key = simplejson.loads(e.read()).get("error", "nc")
|
|
_logger.exception("Bad google request : %s !" % error_key)
|
|
error_msg = "Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]" % error_key
|
|
raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context)
|
|
return res
|
|
|
|
def _do_request(self, cr, uid, uri, params={}, headers={}, type='POST', preuri="https://www.googleapis.com", context=None):
|
|
if context is None:
|
|
context = {}
|
|
|
|
""" Return a tuple ('HTTP_CODE', 'HTTP_RESPONSE') """
|
|
_logger.debug("Uri: %s - Type : %s - Headers: %s - Params : %s !" % (uri, type, headers, werkzeug.url_encode(params) if type == 'GET' else params))
|
|
|
|
status = 418
|
|
response = ""
|
|
ask_time = datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
|
try:
|
|
if type.upper() == 'GET' or type.upper() == 'DELETE':
|
|
data = werkzeug.url_encode(params)
|
|
req = urllib2.Request(preuri + uri + "?" + data)
|
|
elif type.upper() == 'POST' or type.upper() == 'PATCH' or type.upper() == 'PUT':
|
|
req = urllib2.Request(preuri + uri, params, headers)
|
|
else:
|
|
raise ('Method not supported [%s] not in [GET, POST, PUT, PATCH or DELETE]!' % (type))
|
|
req.get_method = lambda: type.upper()
|
|
|
|
request = urllib2.urlopen(req, timeout=TIMEOUT)
|
|
status = request.getcode()
|
|
|
|
if int(status) in (204, 404): # Page not found, no response
|
|
response = False
|
|
else:
|
|
content = request.read()
|
|
response = simplejson.loads(content)
|
|
|
|
try:
|
|
ask_time = datetime.strptime(request.headers.get('date'), "%a, %d %b %Y %H:%M:%S %Z")
|
|
except:
|
|
pass
|
|
except urllib2.HTTPError, e:
|
|
if e.code in (204, 404):
|
|
status = e.code
|
|
response = ""
|
|
else:
|
|
_logger.exception("Bad google request : %s !" % e.read())
|
|
if e.code in (400, 401, 410):
|
|
raise e
|
|
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong with your request to google"), context=context)
|
|
return (status, response, ask_time)
|
|
|
|
def get_base_url(self, cr, uid, context=None):
|
|
return self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://www.openerp.com?NoBaseUrl', context=context)
|
|
|
|
def get_client_id(self, cr, uid, service, context=None):
|
|
return self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % (service,), default=False, context=context)
|
|
|
|
def get_client_secret(self, cr, uid, service, context=None):
|
|
return self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'google_%s_client_secret' % (service,), default=False, context=context)
|
|
|
|
def get_uri_oauth(self, a=''): # a = optional action
|
|
return "https://accounts.google.com/o/oauth2/%s" % (a,)
|
|
|
|
def get_uri_api(self):
|
|
return 'https://www.googleapis.com'
|