def access(self, **kw): token = kw.get('token') db = kw.get('db') registry = registry_get(db) with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) user = env['res.users'].sudo().search([('authenticator_token', '=', token)]) if not user: raise AccessDenied() # Check if expire if fields.Datetime.from_string( user.authenticator_expire_in) < datetime.now(): raise AccessDenied() redirect = login_and_redirect(db, user.login, user.authenticator_token) user.write({ 'authenticator_token': False, 'authenticator_expire_in': False }) cr.commit() return redirect return set_cookie_and_redirect('/web')
def signin(self, req, **kw): """client obtained a saml token and passed it back to us... we need to validate it """ saml_response = kw.get('SAMLResponse') if kw.get('RelayState') is None: # here we are in front of a client that went through # some routes that "lost" its relaystate... this can happen # if the client visited his IDP and successfully logged in # then the IDP gave him a portal with his available applications # but the provided link does not include the necessary relaystate url = "/?type=signup" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = True return redirect state = simplejson.loads(kw['RelayState']) provider = state['p'] dbname = state['d'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_saml( provider, saml_response) action = state.get('a') menu = state.get('m') url = '/' if action: url = '/#action=%s' % action elif menu: url = '/#menu_id=%s' % menu return login_and_redirect(*credentials, redirect_url=url) except AttributeError as e: # auth_signup is not installed _logger.error("auth_signup not installed on database " "saml sign up cancelled.") url = "/#action=login&saml_error=no-signup" except odoo.exceptions.AccessDenied: # saml credentials not valid, # user could be on a temporary session _logger.info('SAML2: access denied, redirect to main page ' 'in case a valid session exists, ' 'without setting cookies') url = "/#action=login&saml_error=expired" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception: # signup error _logger.exception("SAML2: failure") url = "/#action=login&saml_error=access-denied" return set_cookie_and_redirect(url)
def oea(self, **kw): """login user via Odoo Account provider""" dbname = kw.pop('db', None) if not dbname: dbname = db_monodb() if not dbname: return BadRequest() registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) provider = env.ref('auth_oauth.provider_openerp') except ValueError: return set_cookie_and_redirect('/web?db=%s' % dbname) assert provider._name == 'auth.oauth.provider' state = { 'd': dbname, 'p': provider.id, 'c': {'no_user_creation': True}, } kw['state'] = json.dumps(state) return self.signin(**kw)
def _web_post_login(self, phone): """ 验证手机并登陆系统 :param phone: :return: """ dbname = request.session.db if not http.db_filter([dbname]): return BadRequest() context = {} registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth_sms('sms', phone) cr.commit() url = '/web' uid = request.session.authenticate(*credentials) if uid is not False: request.params['login_success'] = True return json.dumps({'state': True, 'msg': "登录成功"}) except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def oea(self, **kw): """login user via Odoo Account provider""" dbname = kw.pop('db', None) if not dbname: dbname = db_monodb() if not dbname: return BadRequest() if not http.db_filter([dbname]): return BadRequest() registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) provider = env.ref('auth_oauth.provider_openerp') except ValueError: return set_cookie_and_redirect('/web?db=%s' % dbname) assert provider._name == 'auth.oauth.provider' state = { 'd': dbname, 'p': provider.id, 'c': { 'no_user_creation': True }, } kw['state'] = json.dumps(state) return self.signin(**kw)
def signin_3rd(self, **kw): state = json.loads(kw['state']) dbname = state['d'] provider = state['p'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth_third( provider, kw) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus( state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu if credentials[0] == -1: from .controllers import gen_id credentials[1]['oauth_provider_id'] = provider qr_id = gen_id(credentials[1]) redirect = base64.urlsafe_b64encode( redirect.encode('utf-8')).decode('utf-8') url = '/corp/bind?qr_id=%s&redirect=%s' % (qr_id, redirect) else: return login_and_redirect(*credentials, redirect_url=url) except AttributeError: import traceback traceback.print_exc() # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except AccessDenied: import traceback traceback.print_exc() # 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' ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def _get_threebot_info(self, kw): provider = request.env.ref('auth_oauth.provider_threebot').sudo() signedhash = kw.get('signedhash') username = kw.get('username') data = kw.get('data') if signedhash is None or username is None or data is None: return set_cookie_and_redirect('/web/login?oauth_error=4') data = json.loads(data) res = requests.get( 'https://login.threefold.me/api/users/{0}'.format(username), {'Content-Type': 'application/json'}) if res.status_code != 200: return set_cookie_and_redirect('/web/login?oauth_error=5') user_pub_key = nacl.signing.VerifyKey( res.json()['publicKey'], encoder=nacl.encoding.Base64Encoder) nonce = base64.b64decode(data['nonce']) ciphertext = base64.b64decode(data['ciphertext']) private_key = nacl.signing.SigningKey( provider.private_key, encoder=nacl.encoding.Base64Encoder) state = user_pub_key.verify(base64.b64decode(signedhash)).decode() box = Box(private_key.to_curve25519_private_key(), user_pub_key.to_curve25519_public_key()) try: decrypted = box.decrypt(ciphertext, nonce) result = json.loads(decrypted) email = result['email']['email'] emailVerified = result['email']['verified'] if not emailVerified: return set_cookie_and_redirect('/web/login?oauth_error=7') except: return set_cookie_and_redirect('/web/login?oauth_error=8') return { 'state': json.loads(state), 'email': email, 'username': username }
def signin(self, **kw): # todo: instead of showing an error, generate new session data and redirect to Auth0 if not request.session['auth0.nonce']: return werkzeug.utils.redirect( '/web/login?err=Auth session expired - Try again', code=302) if request.params.get('state').replace( '%7', '|') != request.session['auth0.nonce']: request.session['auth0.nonce'] = None return request.render( 'website.http_error', { 'status_code': _('Bad Request'), 'status_message': _('State check failed (1). Try again.') }) provider_id = request.session['auth0.nonce'].split('|')[1] if not request.params.get('code'): return 'Expected "code" param in URL, but its not there. Try again.' request.session['auth0.nonce'] = None code = request.params.get('code') profile = self._validate(code, provider_id) # todo: create pages with explanations and make it easier for the user to retry if not profile: return 'Profile validation failed. Try again.' if 'email_verified' in profile: if not profile['email_verified']: return 'Please verify your email first then try again.' # sure the user is authentic, but do they have a login for this DB? if 'email' not in profile: return request.render( 'website.http_error', { 'status_code': _('Auth0'), 'status_message': _('Your profile does not have an email') }) login = profile['email'] password = self._ensure_password(login) if not password: return request.render( 'website.http_error', { 'status_code': _('Bad Request'), 'status_message': _('You are not allowed access to this database (1)') }) login_uid = request.session.authenticate( request.session['auth0.session_db'], login, password) if login_uid is False: return request.render( 'website.http_error', { 'status_code': _('Bad Request'), 'status_message': _('You are not allowed access to this database (2)') }) return set_cookie_and_redirect('/web')
class OAuthController(http.Controller): @http.route('/auth_oauth/signin', type='http', auth='none') @fragment_to_query_string def signin(self, **kw): state = json.loads(kw['state']) dbname = state['d'] if not http.db_filter([dbname]): return BadRequest() provider = state['p'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth(provider, kw) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus( state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu resp = login_and_redirect(*credentials, redirect_url=url) # Since /web is hardcoded, verify user has right to land on it if werkzeug.urls.url_parse( resp.location ).path == '/web' and not request.env.user.has_group( 'base.group_user'): resp.location = '/' return resp except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except 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' ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception, e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def auto_signin(self, **kw): """ 通过获得的【免登授权码或者临时授权码】获取用户信息 :param kw: :return: """ auth_code = kw.get('authCode') logging.info(">>>免登授权码: %s", auth_code) user_id = self.get_userid_by_auth_code(auth_code) if not user_id: return self._do_err_redirect( "钉钉免登失败!具体原因是无法获取用户code,请检查后台IP是否发生变化!") employee = request.env['hr.employee'].sudo().search( [('ding_id', '=', user_id)], limit=1) if not employee: return self._do_err_redirect("系统对应员工不存在!") logging.info(">>>员工{}正在尝试登录系统".format(employee.name)) dbname = request.session.db if not http.db_filter([dbname]): return BadRequest() context = {} registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth_dingtalk( "dingtalk", employee.sudo().ding_id) cr.commit() url = '/web' uid = request.session.authenticate(*credentials) if uid is not False: logging.info(">>>员工{}登录成功".format(employee.sudo().name)) # request.params['login_success'] = False return set_cookie_and_redirect(url) except Exception as e: _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
class OAuthController_extend(OAuthController): @http.route('/auth_oauth/signin', type='http', auth='none') @fragment_to_query_string def signin(self, **kw): kw = simplejson.loads(simplejson.dumps(kw).replace('+', '')) state = simplejson.loads(kw['state']) dbname = state['d'] provider = state['p'] context = state.get('c', {}) registry = RegistryManager.get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth(provider, kw) print credentials # u = registry.get('res.users') # credentials = u.auth_oauth(provider, kw) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus( state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu return login_and_redirect(*credentials, redirect_url=url) except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except odoo.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' ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception, e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def signin(self, **kw): state = json.loads(kw['state']) dbname = state['d'] if not http.db_filter([dbname]): return BadRequest() provider = state['p'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth(provider, kw) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus(state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu resp = login_and_redirect(*credentials, redirect_url=url) # Since /web is hardcoded, verify user has right to land on it if werkzeug.urls.url_parse(resp.location).path == '/web' and not request.env.user.has_group('base.group_user'): resp.location = '/' return resp except AttributeError: # auth_signup is not installed _logger.error("auth_signup not installed on database %s: oauth sign up cancelled." % (dbname,)) url = "/web/login?oauth_error=1" except 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') url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def oauth_script(self, model, **kw): # config = http.request.env['sce_dingtalk.config'].sudo().search([('res_model','=',model),('is_master','=',True)]) model = http.request.env['ir.model'].sudo().search([('model', '=', model)]) if model: config = model.sce_dingtalk_config_id else: config = False code = http.request.params.get('code') target = http.request.params.get('target') if not config: return "No Dingtalk Config." if not code: return http.request.render("sce_dingtalk.oauth_script", {"corpId": config[0].corpid}) # If open in pc, redirect to PC browser. if target and target == 'pc' and not http.request.params.get( 'pcopened'): return http.request.render( "sce_dingtalk.oauth_redirect", {"url": http.request.httprequest.url + "&pcopened=True"}) result = self._get_userid(config, code) if result['errcode'] == 40014: config._refresh_token() result = self._get_userid(config, code) userid = result.get("userid", False) # Dingtalk signin if not userid: return _("Cannot get uid from dingtalk.") try: credentials = http.request.env['res.users'].sudo( ).auth_dingtalk_client(userid, code) except AccessDenied: return _("Not registed user, please contact administrator.") uid = http.request.session.authenticate(*credentials) if uid: return set_cookie_and_redirect( urllib.parse.unquote(http.request.params.get('redirect'))) else: return _( "Dingtalk client signin faild, please contact administrator.")
def auto_signin(self, **kw): """ 通过获得的【免登授权码或者临时授权码】获取用户信息 :param kw: :return: """ if kw.get('authcode'): # 免登 auth_code = kw.get('authcode') _logger.info("获得的auth_code: %s", auth_code) userid = self.get_userid_by_auth_code(auth_code) state = dict( d=request.session.db, p='dingtalk', ) elif kw.get('code'): # 扫码或密码登录 tmp_auth_code = kw.get('code', "") _logger.info("获得的tmp_auth_code: %s", tmp_auth_code) unionid = self.get_unionid_by_tmp_auth_code(tmp_auth_code) userid = self.get_userid_by_unionid(unionid) state = json.loads(kw['state']) mobile = self.get_user_mobile_by_userid(userid) dbname = state['d'] if not http.db_filter([dbname]): return BadRequest() provider = 'dingtalk' # provider = state['p'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth_dingtalk( provider, mobile) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus( state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu resp = login_and_redirect(*credentials, redirect_url=url) # Since /web is hardcoded, verify user has right to land on it if werkzeug.urls.url_parse( resp.location ).path == '/web' and not request.env.user.has_group( 'base.group_user'): resp.location = '/' return resp except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except 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' ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def wecom_web_authorize(self, **kw): code = kw.pop("code", None) state = json.loads(kw["state"]) company = ( request.env["res.company"] .sudo() .search( [("corpid", "=", state["a"]), ("is_wecom_organization", "=", True),], ) ) try: wxapi = ( request.env["wecom.service_api"] .sudo() .InitServiceApi(company, "auth_secret", "auth") ) response = wxapi.httpCall( request.env["wecom.service_api_list"] .sudo() .get_server_api_call("GET_USER_INFO_BY_CODE"), {"code": code,}, ) dbname = state["d"] if not http.db_filter([dbname]): return BadRequest() provider = state["p"] context = {"no_user_creation": True} registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = ( env["res.users"].sudo().wxwrok_auth_oauth(provider, response) ) cr.commit() action = state.get("a") menu = state.get("m") redirect = ( werkzeug.urls.url_unquote_plus(state["r"]) if state.get("r") else False ) url = "/web" if redirect: url = redirect elif action: url = "/web#action=%s" % action elif menu: url = "/web#menu_id=%s" % menu resp = login_and_redirect(*credentials, redirect_url=url) # Since /web is hardcoded, verify user has right to land on it if werkzeug.urls.url_parse( resp.location ).path == "/web" and not request.env.user.has_group( "base.group_user" ): resp.location = "/" return resp except AttributeError: # auth_signup is not installed _logger.error( _( "auth_signup not installed on database %s: oauth sign up cancelled." ) % (dbname,) ) url = "/web/login?oauth_error=1" except 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" ) ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url) except ApiException as e: return request.env["wecom.tools"].ApiExceptionDialog(e)
def microsoft_signin(self, **kw): pool = request.env root_url = request.env['ir.config_parameter'].sudo().get_param( 'web.base.url') + '/' oauth_provider_rec =\ pool['ir.model.data'].sudo().get_object_reference( 'odoo_microsoft_account', 'provider_microsoft')[1] provider = \ pool['auth.oauth.provider'].sudo().browse(oauth_provider_rec) authorization_data = \ pool['auth.oauth.provider'].sudo().oauth_token( 'authorization_code', provider, kw.get('code'), refresh_token=None) access_token = authorization_data.get('access_token') refresh_token = authorization_data.get('refresh_token') try: conn = httplib.HTTPSConnection(provider.data_endpoint) conn.request("GET", "/v1.0/me", "", { 'Authorization': access_token, 'Accept': 'application/json' }) response = conn.getresponse() data = simplejson.loads(response.read()) displayName = data.get('displayName') mail = data.get('userPrincipalName') user_id = data.get('id') conn.close() except Exception as e: print(e) try: credentials = pool['res.users'].sudo().microsoft_auth_oauth( provider.id, { 'access_token': access_token, 'user_id': user_id, 'email': mail, 'name': displayName, 'microsoft_refresh_token': refresh_token }) request.cr.commit() return login_and_redirect(*credentials, redirect_url=root_url + 'web?') except AttributeError: _logger.error("auth_signup not installed on" " database %s: oauth sign up cancelled." % (request.cr.dbname)) url = "/web/login?oauth_error=1" except odoo.exceptions.AccessDenied: _logger.info('OAuth2: access denied,' ' redirect to main page in case a valid' ' session exists, without setting cookies') url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(root_url + url)
def signin(self, **kw): msauth_state = base64.b64encode(request.session.db.encode()) if request.params.get('state').encode() != msauth_state: return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('State check failed (1). Try again.') }) if not request.params.get('code'): return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('Expected "code" param in URL, but its not there. Try again. Or contact Administrator' ) }) code = request.params.get('code') profile = self._validate(code) if not profile: return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('Profile validation failed. Try again. Or contact Administrator' ) }) # sure the user is authentic, but do they have a login for this DB? --> If user not exist in DB --> user is not allowed if 'userPrincipalName' not in profile: return request.render( 'http_routing.http_error', { 'status_code': _('msauth'), 'status_message': _('Your profile does not have an email') }) # Set User login name login = profile['userPrincipalName'] # Generate temp password so user can login password = self._ensure_password(login) # Check if password was set if not password: _logger.error("User %s tried to login but failed " % profile['userPrincipalName']) return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('You (%s) are not allowed access to this database (1)' % profile['userPrincipalName']) }) # User has login and password, try to loggin login_uid = request.session.authenticate(request.session.db, login, password) if login_uid is False: return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('You are not allowed access to this database (2)') }) # User logged in, set users token and refresh token request.env['auth.oauth.provider'].register_token( profile['access_token'], profile.get('refresh_token', False), profile['expires_in']) return set_cookie_and_redirect('/web')
def signin(self, **kw): if 'state' in kw: state = json.loads(kw['state']) else: info = self._get_threebot_info(kw) state = info['state'] kw.pop('signedhash') kw.pop('data') kw['state'] = json.dumps(state) kw['email'] = info['email'] kw['access_token']: '' dbname = state['d'] if not http.db_filter([dbname]): return BadRequest() provider = state['p'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth(provider, kw) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus( state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu request.session.authenticate(db=credentials[0], uid=credentials[1]) return set_cookie_and_redirect(redirect) # Since /web is hardcoded, verify user has right to land on it if werkzeug.urls.url_parse( resp.location ).path == '/web' and not request.env.user.has_group( 'base.group_user'): resp.location = '/' return resp except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except 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' ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def signin(self, **kw): if not request.session['msauth.msuuid']: return werkzeug.utils.redirect( '/web/login?err=Auth session expired - Try again', code=302) if request.params.get('state').replace( '%7', '|') != request.session['msauth.msuuid']: request.session['msauth.msuuid'] = None return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('State check failed (1). Try again.') }) provider_id = request.session['msauth.msuuid'].split('|')[1] if not request.params.get('code'): return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('Expected "code" param in URL, but its not there. Try again. Or contact Administrator' ) }) request.session['msauth.msuuid'] = None code = request.params.get('code') profile = self._validate(code, provider_id) if not profile: return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('Profile validation failed. Try again. Or contact Administrator' ) }) # sure the user is authentic, but do they have a login for this DB? --> If user not exist in DB --> user is not allowed if 'userPrincipalName' not in profile: return request.render( 'http_routing.http_error', { 'status_code': _('msauth'), 'status_message': _('Your profile does not have an email') }) login = profile['userPrincipalName'] # Generate temp password so user can login password = self._ensure_password(login) if not password: _logger.error("User %s tried to login but failed " % profile['userPrincipalName']) return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('You (%s) are not allowed access to this database (1)' % profile['userPrincipalName']) }) login_uid = request.session.authenticate( request.session['msauth.session_db'], login, password) if login_uid is False: return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': _('You are not allowed access to this database (2)') }) expires = request.session['msauth.expires_in'] expires_in = datetime.now() + timedelta(minutes=expires / 60) user_vals = { 'office365_access_token': request.session.get('msauth.id_token', None), 'office365_refresh_token': request.session.get('msauth.refresh_token', None), 'office365_expiration': expires_in } current_user = request.env.user current_user.sudo().write(user_vals) return set_cookie_and_redirect('/web')
def microsoft_signin(self, **kw): pool = request.env root_url = ( request.env["ir.config_parameter"].sudo().get_param("web.base.url") + "/" ) oauth_provider_rec = ( pool["ir.model.data"] .sudo() .get_object_reference("odoo_microsoft_account", "provider_microsoft")[1] ) provider = pool["auth.oauth.provider"].sudo().browse(oauth_provider_rec) authorization_data = ( pool["auth.oauth.provider"] .sudo() .oauth_token( "authorization_code", provider, kw.get("code"), refresh_token=None ) ) access_token = authorization_data.get("access_token") resource = authorization_data.get("resource") id_token = authorization_data.get("id_token") expires_in = authorization_data.get("expires_in") token_type = authorization_data.get("token_type") refresh_token = authorization_data.get("refresh_token") scope = authorization_data.get("scope") not_before = authorization_data.get("not_before") expires_on = authorization_data.get("expires_on") mail = "" user_id = None displayName = "" try: import requests # conn = httplib.HTTPSConnection(provider.data_endpoint) # conn.request("GET", "/v1.0/me", "", # {'Authorization': access_token, 'Accept': 'application/json'}) # response = conn.getresponse() # data = simplejson.loads(response.read()) headers = { "Authorization": "Bearer %s" % access_token, "Accept": "application/json", } data = requests.get(provider.data_endpoint, headers=headers) data = simplejson.loads(data.text) displayName = data.get("displayName") givenName = data.get("givenName") mail = data.get("userPrincipalName") mobilePhone = data.get("mobilePhone") surname = data.get("surname") user_id = data.get("id") userPrincipalName = data.get("userPrincipalName") conn.close() except Exception as e: pass try: credentials = ( pool["res.users"] .sudo() .microsoft_auth_oauth( provider.id, { "access_token": access_token, "user_id": user_id, "email": mail, "name": displayName, "microsoft_refresh_token": refresh_token, }, ) ) request.cr.commit() return login_and_redirect(*credentials, redirect_url=root_url + "web?") except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (request.cr.dbname,) ) url = "/web/login?oauth_error=1" except odoo.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" ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "web/login?oauth_error=2" return set_cookie_and_redirect(root_url + url)
def wxwork_qr_signin(self, **kw): code = kw.pop("code", None) corpid = request.env["ir.config_parameter"].sudo().get_param( "wxwork.corpid") secret = (request.env["ir.config_parameter"].sudo().get_param( "wxwork.auth_secret")) wxwork_api = CorpApi(corpid, secret) response = wxwork_api.httpCall( CORP_API_TYPE["GET_USER_INFO_BY_CODE"], { "code": code, }, ) state = json.loads(kw["state"].replace("M", '"')) dbname = state["d"] if not http.db_filter([dbname]): return BadRequest() provider = state["p"] context = {"no_user_creation": True} registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = (env["res.users"].sudo().auth_oauth_wxwork( provider, response)) cr.commit() action = state.get("a") menu = state.get("m") redirect = (werkzeug.url_unquote_plus(state["r"]) if state.get("r") else False) url = "/web" if redirect: url = redirect elif action: url = "/web#action=%s" % action elif menu: url = "/web#menu_id=%s" % menu resp = login_and_redirect(*credentials, redirect_url=url) if werkzeug.urls.url_parse( resp.location ).path == "/web" and not request.env.user.has_group( "base.group_user"): resp.location = "/" return resp except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except 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" ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)