1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
22 from openerp.osv import osv
23 from openerp import SUPERUSER_ID
24 from openerp.tools.translate import _
25 from openerp.addons.web.http import request
32 _logger = logging.getLogger(__name__)
34 class google_service(osv.osv_memory):
35 _name = 'google.service'
37 def generate_refresh_token(self, cr, uid, service, authorization_code, context=None):
38 ir_config = self.pool['ir.config_parameter']
39 client_id = ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service)
40 client_secret = ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_secret' % service)
41 redirect_uri = ir_config.get_param(cr, SUPERUSER_ID, 'google_redirect_uri')
43 #Get the Refresh Token From Google And store it in ir.config_parameter
44 headers = {"Content-type": "application/x-www-form-urlencoded"}
45 data = dict(code=authorization_code, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, grant_type="authorization_code")
46 data = werkzeug.url_encode(data)
48 req = urllib2.Request("https://accounts.google.com/o/oauth2/token", data, headers)
49 content = urllib2.urlopen(req).read()
50 except urllib2.HTTPError:
51 raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired"), context=context)
53 content = simplejson.loads(content)
54 return content.get('refresh_token')
56 def _get_google_token_uri(self, cr, uid, service, scope, context=None):
57 ir_config = self.pool['ir.config_parameter']
60 'redirect_uri': ir_config.get_param(cr, SUPERUSER_ID, 'google_redirect_uri'),
61 'client_id': ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service),
62 'response_type': 'code',
63 'client_id': ir_config.get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % service),
65 uri = 'https://accounts.google.com/o/oauth2/auth?%s' % werkzeug.url_encode(params)
68 #If no scope is passed, we use service by default to get a default scope
69 def _get_authorize_uri(self, cr, uid, from_url, service, scope = False, context=None):
70 """ This method return the url needed to allow this instance of OpenErp to access to the scope of gmail specified as parameters """
71 state_obj = dict(d=cr.dbname, s=service, f=from_url)
73 base_url = self.get_base_url(cr, uid, context)
74 client_id = self.get_client_id(cr, uid, service, context)
77 'response_type': 'code',
78 'client_id': client_id,
79 'state' : simplejson.dumps(state_obj),
80 'scope': scope or 'https://www.googleapis.com/auth/%s' % (service,),
81 'redirect_uri': base_url + '/google_account/authentication',
82 'approval_prompt':'force',
83 'access_type':'offline'
86 uri = self.get_uri_oauth(a='auth') + "?%s" % werkzeug.url_encode(params)
89 def _get_google_token_json(self, cr, uid, authorize_code, service, context=None):
91 base_url = self.get_base_url(cr, uid, context)
92 client_id = self.get_client_id(cr, uid, service, context)
93 client_secret = self.get_client_secret(cr, uid, service, context)
96 'code': authorize_code,
97 'client_id': client_id,
98 'client_secret': client_secret,
99 'grant_type' : 'authorization_code',
100 'redirect_uri': base_url + '/google_account/authentication'
103 headers = {"content-type": "application/x-www-form-urlencoded"}
106 data = werkzeug.url_encode(params)
107 req = urllib2.Request(self.get_uri_oauth(a='token'), data, headers)
109 content = urllib2.urlopen(req).read()
110 res = simplejson.loads(content)
111 except urllib2.HTTPError,e:
112 raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during your token generation. Maybe your Authorization Code is invalid"), context=context)
115 def _refresh_google_token_json(self, cr, uid, refresh_token, service, context=None): #exchange_AUTHORIZATION vs Token (service = calendar)
117 base_url = self.get_base_url(cr, uid, context)
118 client_id = self.get_client_id(cr, uid, service, context)
119 client_secret = self.get_client_secret(cr, uid, service, context)
122 'refresh_token': refresh_token,
123 'client_id': client_id,
124 'client_secret': client_secret,
125 'grant_type' : 'refresh_token'
128 headers = {"content-type": "application/x-www-form-urlencoded"}
131 data = werkzeug.url_encode(params)
132 req = urllib2.Request(self.get_uri_oauth(a='token'), data, headers)
133 content = urllib2.urlopen(req).read()
134 res = simplejson.loads(content)
135 except urllib2.HTTPError:
136 raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired"), context=context)
141 def _do_request(self,cr,uid,uri,params={},headers={},type='POST', context=None):
142 _logger.debug("Uri: %s - Type : %s - Headers: %s - Params : %s !" % (uri,type,headers,werkzeug.url_encode(params) if type =='GET' else params))
146 if type.upper() == 'GET' or type.upper() == 'DELETE':
147 data = werkzeug.url_encode(params)
148 req = urllib2.Request(self.get_uri_api() + uri + "?" + data)
149 elif type.upper() == 'POST' or type.upper() == 'PATCH' or type.upper() == 'PUT':
150 req = urllib2.Request(self.get_uri_api() + uri, params, headers)
152 raise ('Method not supported [%s] not in [GET, POST, PUT, PATCH or DELETE]!' % (type))
153 req.get_method = lambda: type.upper()
155 request = urllib2.urlopen(req)
157 if request.getcode() == 204: #No content returned, (ex: POST calendar/event/clear)
159 elif request.getcode() == 404: #Page not found
162 content=request.read()
163 res = simplejson.loads(content)
164 except urllib2.HTTPError,e:
165 _logger.exception("Bad google request : %s !" % e.read())
166 raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong with your request to google"), context=context)
169 def get_base_url(self, cr, uid, context=None):
170 return self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url',default='http://www.openerp.com?NoBaseUrl',context=context)
172 def get_client_id(self, cr, uid, service, context=None):
173 return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_id' % (service,),default=False,context=context)
175 def get_client_secret(self, cr, uid, service, context=None):
176 return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_secret' % (service,),default=False,context=context)
178 def get_uri_oauth(self,a=''): #a = optional action
179 return "https://accounts.google.com/o/oauth2/%s" % (a,)
181 def get_uri_api(self):
182 return 'https://www.googleapis.com'