2014-01-28 08:59:45 +00:00
import functools
2012-08-12 23:26:12 +00:00
import logging
2012-08-15 22:47:08 +00:00
import simplejson
2013-02-12 16:33:01 +00:00
import werkzeug . utils
2012-11-16 16:24:21 +00:00
from werkzeug . exceptions import BadRequest
2012-08-12 23:26:12 +00:00
2013-02-12 16:33:01 +00:00
import openerp
2012-11-16 16:24:21 +00:00
from openerp import SUPERUSER_ID
2013-10-22 17:06:59 +00:00
from openerp import http
2014-02-19 10:30:32 +00:00
from openerp . http import request
2012-11-16 16:24:21 +00:00
from openerp . addons . web . controllers . main import db_monodb , set_cookie_and_redirect , login_and_redirect
from openerp . modules . registry import RegistryManager
2014-01-27 18:16:06 +00:00
from openerp . tools . translate import _
2012-08-12 23:26:12 +00:00
_logger = logging . getLogger ( __name__ )
2014-01-28 08:59:45 +00:00
#----------------------------------------------------------
# helpers
#----------------------------------------------------------
def fragment_to_query_string ( func ) :
@functools.wraps ( func )
def wrapper ( self , * a , * * kw ) :
if not kw :
return """ <html><head><script>
var l = window . location ;
var q = l . hash . substring ( 1 ) ;
2014-02-11 14:55:29 +00:00
var r = l . pathname + l . search ;
2014-01-28 08:59:45 +00:00
if ( q . length != = 0 ) {
var s = l . search ? ( l . search == = ' ? ' ? ' ' : ' & ' ) : ' ? ' ;
r = l . pathname + l . search + s + q ;
}
window . location = r ;
< / script > < / head > < body > < / body > < / html > """
return func ( self , * a , * * kw )
return wrapper
2012-11-16 16:24:21 +00:00
#----------------------------------------------------------
# Controller
#----------------------------------------------------------
2014-01-27 18:16:06 +00:00
class OAuthLogin ( openerp . addons . web . controllers . main . Home ) :
def list_providers ( self ) :
2012-09-27 12:34:29 +00:00
try :
2014-01-27 18:16:06 +00:00
provider_obj = request . registry . get ( ' auth.oauth.provider ' )
providers = provider_obj . search_read ( request . cr , SUPERUSER_ID , [ ( ' enabled ' , ' = ' , True ) ] )
2012-09-27 12:34:29 +00:00
except Exception :
2014-01-27 18:16:06 +00:00
providers = [ ]
for provider in providers :
return_url = request . httprequest . url_root + ' auth_oauth/signin '
2014-01-28 10:45:59 +00:00
state = self . get_state ( provider )
2014-01-27 18:16:06 +00:00
params = dict (
debug = request . debug ,
response_type = ' token ' ,
client_id = provider [ ' client_id ' ] ,
redirect_uri = return_url ,
scope = provider [ ' scope ' ] ,
state = simplejson . dumps ( state ) ,
)
provider [ ' auth_link ' ] = provider [ ' auth_endpoint ' ] + ' ? ' + werkzeug . url_encode ( params )
return providers
2014-01-28 10:45:59 +00:00
def get_state ( self , provider ) :
2014-02-12 10:15:47 +00:00
state = dict (
2014-01-28 10:45:59 +00:00
d = request . session . db ,
p = provider [ ' id ' ]
)
2014-02-12 10:15:47 +00:00
token = request . params . get ( ' token ' )
if token :
state [ ' t ' ] = token
return state
2014-01-28 10:45:59 +00:00
2014-01-27 18:16:06 +00:00
@http.route ( )
def web_login ( self , * args , * * kw ) :
2014-01-28 10:45:59 +00:00
providers = self . list_providers ( )
2014-01-27 18:16:06 +00:00
response = super ( OAuthLogin , self ) . web_login ( * args , * * kw )
2014-02-19 10:30:32 +00:00
if response . is_qweb :
2014-01-27 18:16:06 +00:00
error = request . params . get ( ' oauth_error ' )
if error == ' 1 ' :
error = _ ( " Sign up is not allowed on this database. " )
elif error == ' 2 ' :
error = _ ( " Access Denied " )
elif error == ' 3 ' :
error = _ ( " You do not have access to this database or your invitation has expired. Please ask for an invitation and be sure to follow the link in your invitation email. " )
else :
error = None
2014-01-28 18:11:56 +00:00
2014-02-19 10:30:32 +00:00
response . qcontext [ ' providers ' ] = providers
2014-01-28 18:11:56 +00:00
if error :
2014-02-19 10:30:32 +00:00
response . qcontext [ ' error ' ] = error
2014-01-27 18:16:06 +00:00
return response
2014-02-12 10:15:47 +00:00
@http.route ( )
def web_auth_signup ( self , * args , * * kw ) :
providers = self . list_providers ( )
if len ( providers ) == 1 :
werkzeug . exceptions . abort ( werkzeug . utils . redirect ( providers [ 0 ] [ ' auth_link ' ] , 303 ) )
response = super ( OAuthLogin , self ) . web_auth_signup ( * args , * * kw )
2014-02-27 15:49:55 +00:00
response . qcontext . update ( providers = providers )
2014-02-12 10:15:47 +00:00
return response
@http.route ( )
def web_auth_reset_password ( self , * args , * * kw ) :
providers = self . list_providers ( )
if len ( providers ) == 1 :
werkzeug . exceptions . abort ( werkzeug . utils . redirect ( providers [ 0 ] [ ' auth_link ' ] , 303 ) )
response = super ( OAuthLogin , self ) . web_auth_reset_password ( * args , * * kw )
2014-02-27 15:49:55 +00:00
response . qcontext . update ( providers = providers )
2014-02-12 10:15:47 +00:00
return response
2014-01-27 18:16:06 +00:00
class OAuthController ( http . Controller ) :
2012-08-14 11:55:55 +00:00
2013-06-24 09:52:55 +00:00
@http.route ( ' /auth_oauth/signin ' , type = ' http ' , auth = ' none ' )
2014-01-28 08:59:45 +00:00
@fragment_to_query_string
2013-06-24 09:52:55 +00:00
def signin ( self , * * kw ) :
2012-08-15 22:47:08 +00:00
state = simplejson . loads ( kw [ ' state ' ] )
dbname = state [ ' d ' ]
provider = state [ ' p ' ]
2012-11-16 16:24:21 +00:00
context = state . get ( ' c ' , { } )
registry = RegistryManager . get ( dbname )
2012-08-14 11:55:55 +00:00
with registry . cursor ( ) as cr :
2012-08-12 23:26:12 +00:00
try :
u = registry . get ( ' res.users ' )
2012-11-16 16:24:21 +00:00
credentials = u . auth_oauth ( cr , SUPERUSER_ID , provider , kw , context = context )
2012-08-12 23:26:12 +00:00
cr . commit ( )
2013-03-19 15:41:39 +00:00
action = state . get ( ' a ' )
menu = state . get ( ' m ' )
2014-01-27 18:16:06 +00:00
url = ' /web '
2013-03-19 15:41:39 +00:00
if action :
2014-01-27 18:16:06 +00:00
url = ' /web#action= %s ' % action
2013-03-19 15:41:39 +00:00
elif menu :
2014-01-27 18:16:06 +00:00
url = ' /web#menu_id= %s ' % menu
2013-06-24 09:52:55 +00:00
return login_and_redirect ( * credentials , redirect_url = url )
2012-08-12 23:26:12 +00:00
except AttributeError :
# auth_signup is not installed
2012-11-16 16:24:21 +00:00
_logger . error ( " auth_signup not installed on database %s : oauth sign up cancelled. " % ( dbname , ) )
2014-01-27 18:16:06 +00:00
url = " /web/login?oauth_error=1 "
2013-02-12 16:33:01 +00:00
except openerp . exceptions . AccessDenied :
# oauth credentials not valid, user could be on a temporary session
_logger . info ( ' OAuth2: access denied, redirect to main page in case a valid session exists, without setting cookies ' )
2014-01-27 18:16:06 +00:00
url = " /web/login?oauth_error=3 "
2013-02-12 16:33:01 +00:00
redirect = werkzeug . utils . redirect ( url , 303 )
redirect . autocorrect_location_header = False
return redirect
2012-11-16 16:24:21 +00:00
except Exception , e :
2012-08-12 23:26:12 +00:00
# signup error
2012-10-10 12:19:19 +00:00
_logger . exception ( " OAuth2: %s " % str ( e ) )
2014-01-27 18:16:06 +00:00
url = " /web/login?oauth_error=2 "
2012-08-14 11:55:55 +00:00
2013-06-24 09:52:55 +00:00
return set_cookie_and_redirect ( url )
2012-11-16 16:24:21 +00:00
2013-06-24 09:52:55 +00:00
@http.route ( ' /auth_oauth/oea ' , type = ' http ' , auth = ' none ' )
def oea ( self , * * kw ) :
2012-11-16 16:24:21 +00:00
""" login user via OpenERP Account provider """
dbname = kw . pop ( ' db ' , None )
if not dbname :
2013-06-24 09:52:55 +00:00
dbname = db_monodb ( )
2012-11-16 16:24:21 +00:00
if not dbname :
return BadRequest ( )
registry = RegistryManager . get ( dbname )
with registry . cursor ( ) as cr :
IMD = registry [ ' ir.model.data ' ]
2013-06-07 14:48:49 +00:00
try :
model , provider_id = IMD . get_object_reference ( cr , SUPERUSER_ID , ' auth_oauth ' , ' provider_openerp ' )
except ValueError :
2014-01-27 18:16:06 +00:00
return set_cookie_and_redirect ( ' /web?db= %s ' % dbname )
2012-11-16 16:24:21 +00:00
assert model == ' auth.oauth.provider '
state = {
' d ' : dbname ,
' p ' : provider_id ,
' c ' : { ' no_user_creation ' : True } ,
}
kw [ ' state ' ] = simplejson . dumps ( state )
2013-06-24 09:52:55 +00:00
return self . signin ( * * kw )
2012-08-12 23:26:12 +00:00
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: