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 _do_post_login(self, employee, redirect): """ 所有的验证都结束并正确后,需要界面跳转到主界面 :param employee: employee :param redirect: :return: """ ensure_db() dbname = request.session.db if not http.db_filter([dbname]): return BadRequest() context = {} registry = registry_get(dbname) oauth_uid = employee.sudo().ding_id with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth_dingtalk( "dingtalk", oauth_uid) cr.commit() url = '/web' if not redirect else redirect uid = request.session.authenticate(*credentials) if uid: return http.redirect_with_hash(url) else: self._do_err_redirect("登录失败") except Exception as e: self._do_err_redirect("登录失败,原因为:{}".format(str(e)))
def view(self, db, token, action, id, view='calendar'): registry = registry_get(db) with registry.cursor() as cr: # Since we are in auth=none, create an env with SUPERUSER_ID env = Environment(cr, SUPERUSER_ID, {}) attendee = env['calendar.attendee'].search([('access_token', '=', token), ('event_id', '=', int(id))]) if not attendee: return request.not_found() timezone = attendee.partner_id.tz lang = attendee.partner_id.lang or get_lang(request.env).code event = env['calendar.event'].with_context(tz=timezone, lang=lang).browse(int(id)) # If user is internal and logged, redirect to form view of event # otherwise, display the simplifyed web page with event informations if request.session.uid and request.env['res.users'].browse(request.session.uid).user_has_groups('base.group_user'): return werkzeug.utils.redirect('/web?db=%s#id=%s&view_type=form&model=calendar.event' % (db, id)) # NOTE : we don't use request.render() since: # - we need a template rendering which is not lazy, to render before cursor closing # - we need to display the template in the language of the user (not possible with # request.render()) response_content = env['ir.ui.view'].with_context(lang=lang).render_template( 'calendar.invitation_page_anonymous', { 'event': event, 'attendee': attendee, }) return request.make_response(response_content, headers=[('Content-Type', 'text/html')])
def _wxent_do_post_login(self, user_id, redirect): """ 所有的验证都结束并正确后,需要界面跳转到主界面 :param user_id: user_id :param redirect: :return: """ ensure_db() 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_weixin_ent( "weixin_ent", user_id) cr.commit() url = '/web' if not redirect else redirect uid = request.session.authenticate(*credentials) if uid: return http.redirect_with_hash(url) else: return self._do_err_redirect("Oauth认证失败!请使用账号登录") except Exception as e: return self._do_err_redirect("登录失败,原因为:{}".format(str(e)))
def view(self, db, token, action, id, view='calendar'): registry = registry_get(db) with registry.cursor() as cr: # Since we are in auth=none, create an env with SUPERUSER_ID env = Environment(cr, SUPERUSER_ID, {}) attendee = env['calendar.attendee'].search([('access_token', '=', token)]) timezone = attendee.partner_id.tz lang = attendee.partner_id.lang or 'en_US' event = env['calendar.event'].with_context(tz=timezone, lang=lang).browse( int(id)) # If user is logged, redirect to form view of event # otherwise, display the simplifyed web page with event informations if request.session.uid: return werkzeug.utils.redirect( '/web?db=%s#id=%s&view_type=form&model=calendar.event' % (db, id)) # NOTE : we don't use request.render() since: # - we need a template rendering which is not lazy, to render before cursor closing # - we need to display the template in the language of the user (not possible with # request.render()) return env['ir.ui.view'].with_context(lang=lang).render_template( 'calendar.invitation_page_anonymous', { 'event': event, 'attendee': attendee, })
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 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 web_phone_login(self, redirect=None, **kw): ensure_db() request.params['login_success'] = False values = request.params.copy() try: values['databases'] = http.db_list() except odoo.exceptions.AccessDenied: values['databases'] = None if request.httprequest.method == 'POST': with registry_get(request.params['phone_db']).cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) expiration_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S') users = env['res.users'].sudo().search([ ('partner_id.mobile', '=', request.params['phone']), ('verify_code', '=', request.params['checkCode']), ('expiration_date', '>', expiration_date) ]) if users: # request.httprequest.environ['phone'] = request.params['phone'] # request.httprequest.environ['checkCode'] = request.params['checkCode'] request.session.authenticate(request.params['phone_db'], users[0].login, users[0].password_crypt) request.params['login_success'] = True if not redirect: redirect = '/web' return http.redirect_with_hash( self._login_redirect(users[0].id, redirect=redirect)) else: values['phone_error'] = _("check code is not correct!") return request.render('web.login', values)
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 view(self, db, token, action, id, view='calendar'): registry = registry_get(db) with registry.cursor() as cr: # Since we are in auth=none, create an env with SUPERUSER_ID env = Environment(cr, SUPERUSER_ID, {}) attendee = env['calendar.attendee'].search([('access_token', '=', token)]) timezone = attendee.partner_id.tz event = env['calendar.event'].with_context(tz=timezone).browse( int(id)) # If user is logged, redirect to form view of event # otherwise, display the simplifyed web page with event informations if request.session.uid: return werkzeug.utils.redirect( '/web?db=%s#id=%s&view_type=form&model=calendar.event' % (db, id)) # NOTE : calling render return a lazy response. The rendering result will be done when the # cursor will be closed. So it is requried to call `flatten` to make the redering before # existing the `with` clause response = request.render('calendar.invitation_page_anonymous', { 'event': event, 'attendee': attendee, }) response.flatten() return response
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 oea(self, **kw): """login user via Odoo Account provider""" dbname = kw.pop('db', None) if not dbname: dbname = request.db if not dbname: raise BadRequest() if not http.db_filter([dbname]): raise 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: redirect = request.redirect(f'/web?db={dbname}', 303) redirect.autocorrect_location_header = False return redirect 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 digit_authenticate(self, data): user_num = data['phone_number'][-10:] dbname = request.session.db key = request.session.loginKey del request.session['loginKey'] registry = registry_get(dbname) with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) user_ids = env['res.users'].sudo().search([("partner_id.mobile", "ilike", user_num)]) if not user_ids: return False else: for userData in user_ids: if request.session.user_identity == userData.id: if userData.digits_access_token: if userData.digits_access_token == data[ 'access_token']: return (dbname, userData.login, key) else: return False else: updatedUserId = userData.write({ 'digits_access_token': data['access_token'], 'user_2f_enable_status': True }) cr.commit() return (dbname, userData.login, key)
def oauth(self, **kw): '''企业微信oauth验证''' code = request.params.get('code') dbname = request.session.db registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) config = env['wechat.corp.config'].sudo().search([('id', '=', 1)])[0] if config: corp_id = config.corp_id corp_agent_secret = config.corp_agent_secret except Exception as e: _logger.exception("oauth: %s" % str(e)) # 调用企业微信api if code and corp_id and corp_agent_secret: wxapi = CorpApi(corp_id, corp_agent_secret) try: accesstoken = wxapi.getAccessToken() response = wxapi.httpCall( CORP_API_TYPE['GET_USER_INFO_BY_CODE'], {"code": code}) _logger.info(u'UserId:%s' % response['UserId']) if response['UserId']: with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) wechat_corp_users_id = env[ 'wechat.corp.users'].sudo().search([ ('userid', '=', response['UserId']) ])[0] res_users_id = env['res.users'].sudo().search([ ('wxcorp_users_id', '=', wechat_corp_users_id.id) ])[0] login = res_users_id.login if login: # 更新访问令牌 res_users_id.write( {"oauth_access_token": accesstoken}) cr.commit() # 验证核心函数authenticate:数据库名,登录名,密码或访问令牌 request.session.authenticate( dbname, login, accesstoken) url = '/web' else: url = '/web/login?oauth_error=2' except Exception as e: _logger.exception("oauth_res_users: %s" % str(e)) url = '/web/login?oauth_error=2' except ApiException as e: # print e.errCode, e.errMsg _logger.info(u'errMsg:%s' % e.errMsg) url = '/web/login?oauth_error=2' else: url = '/web/login?oauth_error=2' return self.set_cookie_and_redirect(url)
def web_dingtalk_auto_signin_action(self, **kw): """ 通过获得的【免登授权码或者临时授权码】获取用户信息 :param kw: :return: """ auth_code = kw.get('authCode') logging.info(">>>免登授权码: %s", auth_code) config = request.env['dingtalk.mc.config'].sudo().search( [('m_login', '=', True)], limit=1) client = dt.get_client( request, dt.get_dingtalk_config(request, config.company_id)) result = client.user.getuserinfo(auth_code) domain = [('ding_id', '=', result.userid), ('company_id', '=', config.company_id.id)] employee = request.env['hr.employee'].sudo().search(domain, limit=1) if not employee: _logger.info(_("系统对应员工不存在!")) return self._do_err_redirect(_("系统对应员工不存在!")) _logger.info(">>>员工:{}正在尝试登录系统".format(employee.name)) if not employee.ding_id: _logger.info(_("员工不存在钉钉ID,请维护后再试!")) return self._do_err_redirect(_("员工不存在钉钉ID,请维护后再试!")) if not employee.user_id: return self._do_err_redirect(_("你还没有关联系统用户,请联系管理员处理!")) ensure_db() dbname = request.session.db if not http.db_filter([dbname]): return BadRequest() registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) credentials = env['res.users'].sudo().auth_oauth( 'dingtalk', employee.ding_id) cr.commit() url = '/web' 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: _logger.error(">>>未在数据库'%s'上安装auth_signup:oauth注册已取消。" % (dbname, )) url = "/web/login?oauth_error=1" except AccessDenied: _logger.info( '>>>DingTalk-OAuth2: 访问被拒绝,在存在有效会话的情况下重定向到主页,而未设置Cookie') 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 http.redirect_with_hash(url)
def declined(self, db, token, action, id): registry = registry_get(db) with registry.cursor() as cr: env = Environment(cr, SUPERUSER_ID, {}) attendee = env["calendar.attendee"].search([("access_token", "=", token), ("state", "!=", "declined")]) if attendee: attendee.do_decline() return self.view(db, token, action, id, view="form")
def declined(self, db, token, action, id): registry = registry_get(db) with registry.cursor() as cr: env = Environment(cr, SUPERUSER_ID, {}) attendee = env['calendar.attendee'].search([('access_token', '=', token), ('state', '!=', 'declined')]) if attendee: attendee.do_decline() return self.view(db, token, action, id, view='form')
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 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.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)
def token(self, db, admin_passwd, login): if not config.verify_admin_password(admin_passwd): raise AccessDenied() registry = registry_get(db) with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) token = uuid.uuid4() user = env['res.users'].sudo().search([('login', '=', login)]) user.write({ 'authenticator_token': token, 'authenticator_expire_in': datetime.now() + timedelta(seconds=30) }) return token
def get_maintenance_requests(self, db, ticket_id, token=None): registry = registry_get(db) with registry.cursor() as cr: env = Environment(cr, SUPERUSER_ID, {}) Ticket = False if token: Ticket = env['maintenance.request'].sudo().search([ ('id', '=', ticket_id), ('access_token', '=', token) ]) else: Ticket = env['maintenance.request'].browse(ticket_id) if not Ticket: return request.not_found() return werkzeug.utils.redirect( '/web?db=%s#id=%s&view_type=form&model=maintenance.request' % (db, ticket_id))
def info(self, db, admin_passwd): if not config.verify_admin_password(admin_passwd): raise AccessDenied() registry = registry_get(db) with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) users = env['res.users'].sudo().search_read( [('share', '=', False)], ['id', 'login', 'name', 'groups_id']) ResGroups = env['res.groups'] IrModelData = env['ir.model.data'] admin_group_id = env.ref('base.group_erp_manager').id group_ids = [] for app, kind, gs, category_name in ResGroups.sudo( ).get_groups_by_application(): if kind == 'selection': group_ids.extend(gs.ids) for user in users: # TODO: Implement user lang to translate groups names category_ids = [] user['groups_id'] = ResGroups.sudo().search_read( [('id', 'in', [g for g in user['groups_id'] if g in group_ids])], ['id', 'full_name', 'category_id'], order='id desc') user['is_admin'] = True if admin_group_id in [ g['id'] for g in user['groups_id'] ] else False user_groups_id = [] for group in user['groups_id']: if group['category_id'][0] not in category_ids: group_info = IrModelData.sudo().search_read( [('model', '=', 'res.groups'), ('res_id', '=', group.get('id'))], ['module', 'name'], order='id', limit=1) group['external_id'] = '{}.{}'.format( group_info[0]['module'], group_info[0]['name']) if group_info else False category_ids.append(group['category_id'][0]) user_groups_id.append(group) user['groups_id'] = user_groups_id return users
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 qywx_open(self,*args,**kwargs): '''企业微信oauth_url''' dbname = request.session.db registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) config = env['wx.corp.config'].sudo().search([('id', '=', 1)])[0] if config: corp_id = config.Corp_Id host = config.wexin_login_url url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s/wechat/wechat&response_type=code&scope=SCOPE&connect_redirect=1#wechat_redirect'%(corp_id,host) #url = 'https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%s&&redirect_uri=%s/wechat/wechat&state=STATE'%(corp_id,corp_agent,host) except Exception as e: _logger.exception("open: %s" % str(e)) url = "/web/login?oauth_error=2" return self.set_cookie_and_redirect(url)
def _auth_method_jwt(cls, validator_name=None): assert request.db assert not request.uid assert not request.session.uid token = cls._get_bearer_token() assert token registry = registry_get(request.db) with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) validator = env["auth.jwt.validator"]._get_validator_by_name( validator_name) assert len(validator) == 1 payload = validator._decode(token) uid = validator._get_and_check_uid(payload) assert uid partner_id = validator._get_and_check_partner_id(payload) request.uid = uid # this resets request.env request.jwt_payload = payload request.jwt_partner_id = partner_id
def open(self): '''企业微信oauth_url''' dbname = request.session.db registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) config = env['wechat.corp.config'].sudo().search([('id', '=', 1)])[0] if config: corp_id = config.corp_id host = request.httprequest.environ.get('HTTP_HOST', '') url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=http://%s/wechat/wechat&response_type=code&scope=SCOPE&connect_redirect=1#wechat_redirect' % ( corp_id, host) except Exception as e: _logger.exception("open: %s" % str(e)) url = "/web/login?oauth_error=2" return self.set_cookie_and_redirect(url)
def view(self, db, token, action, id, view="calendar"): registry = registry_get(db) with registry.cursor() as cr: # Since we are in auth=none, create an env with SUPERUSER_ID env = Environment(cr, SUPERUSER_ID, {}) attendee = env["calendar.attendee"].search([("access_token", "=", token)]) timezone = attendee.partner_id.tz event = env["calendar.event"].with_context(tz=timezone).browse(int(id)) # If user is logged, redirect to form view of event # otherwise, display the simplifyed web page with event informations if request.session.uid: return werkzeug.utils.redirect("/web?db=%s#id=%s&view_type=form&model=calendar.event" % (db, id)) # NOTE : calling render return a lazy response. The rendering result will be done when the # cursor will be closed. So it is requried to call `flatten` to make the redering before # existing the `with` clause response = request.render("calendar.invitation_page_anonymous", {"event": event, "attendee": attendee}) response.flatten() return response
def get_verify_code(self, phone=None, **kw): _logger.info('phone is %s', phone) result = {} with registry_get(request.session.db).cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) users = env['res.users'].sudo().search([('partner_id.mobile', '=', phone)]) if users: expiration_date = datetime.now() + timedelta(minutes=5) users[0].write({ 'verify_code': self.generate_verify_code(), 'expiration_date': expiration_date }) cr.commit() result['is_success'] = True result['phone_message'] = 'we send it to you' else: result['is_success'] = False result['phone_message'] = 'your phone no exist' return result
def web_login(self, redirect=None, **kw): ensure_db() request.params['login_success'] = False if request.httprequest.method == 'GET' and redirect and request.session.uid: return http.redirect_with_hash(redirect) if not request.uid: request.uid = odoo.SUPERUSER_ID values = request.params.copy() try: values['databases'] = http.db_list() except odoo.exceptions.AccessDenied: values['databases'] = None if request.httprequest.method == 'POST': old_uid = request.uid uid = request.session.authenticate(request.session.db, request.params['login'], request.params['password']) if uid is not False: with registry_get(request.session.db).cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) getDigitsConfigSearch=http.request.env['digits.configuration'].search([]) if getDigitsConfigSearch: getUserBrowse = env['res.users'].sudo().browse(uid) user_2f_enable_status = getUserBrowse[0].user_2f_enable_status if user_2f_enable_status: logout=request.session.logout(keep_db=True) request.session['loginKey'] = kw['password'] request.session['user_identity'] = uid userMobileNumber = getUserBrowse[0].partner_id.mobile if userMobileNumber: ir_config_id=env['ir.config_parameter'].sudo().search([('key','=','web.base.url')]) base_url=env['ir.config_parameter'].sudo().browse(int(ir_config_id))[0].value return http.request.render('allip_digits_2f_authentication.digit_confirmation_template',{'userMobileNumber':userMobileNumber,'callbackUrl' : base_url+'/verify/login'}) else: values['error'] = _("You may have enabled two factor authentication using mobile number, but your mobile number is not setup under your profile. Please contact your Administrator!") return request.render('web.login', values) request.params['login_success'] = True if not redirect: redirect = '/web' return http.redirect_with_hash(redirect) request.uid = old_uid values['error'] = _("Wrong login/password") return request.render('web.login', values)
def user_login_by_emp(self, employee): """ :param employee: employee :return: """ ensure_db() dbname = request.session.db if not http.db_filter([dbname]): return BadRequest() registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) credentials = env['res.users'].sudo().auth_oauth( 'dingtalk', employee.ding_id) cr.commit() url = '/web' 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: _logger.error(">>>未在数据库'%s'上安装auth_signup:oauth注册已取消。" % (dbname, )) url = "/web/login?oauth_error=1" except AccessDenied: _logger.info( '>>>DingTalk-OAuth2: 访问被拒绝,在存在有效会话的情况下重定向到主页,而未设置Cookie') url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: err_str = "OAuth2: %s" % str(e) _logger.exception(err_str) return self.do_error_redirect(err_str) return http.redirect_with_hash(url)
def linkedin_authorized(self, code, **kw): Oauth = request.env['oauth.oauth'] linkedin = Oauth.sudo().get_provider('Linkedin') callback_uri = self.get_callback_url('linkedin') oauth_session = OAuth2Session(linkedin.client_id, redirect_uri=callback_uri) oauth_session.fetch_token(linkedin.access_token_endpoint, code=code, client_secret=linkedin.client_secret) user_response = oauth_session.get( 'https://api.linkedin.com/v1/people/~:(id,email-address,first-name,last-name,picture-urls::(original))?format=json' ) user_info = user_response.json() url = user_info.get('pictureUrls', {}).get('values', [False])[0] image = self.fetch_image(url) name = user_info['firstName'] + ' ' + user_info['lastName'] email = user_info['emailAddress'] oauth_uid = access_token = user_info['id'] vals = { 'oauth_access_token': access_token, 'name': name, 'oauth_uid': oauth_uid, 'email': email, 'image': image, } provider_id = linkedin.id db = request.session['db'] registry = registry_get(db) after_login_url = linkedin.after_login_url with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) try: login = env['res.users'].sudo()._singup_user(provider_id, vals) except Exception as e: return request.render('web.login', {'error': e.message}) cr.commit() request._cr.commit() res = login_and_redirect(db, login, access_token, after_login_url) return res
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)
def facebook_authorized(self, state, code, **kw): Oauth = request.env['oauth.oauth'] facebook = Oauth.sudo().get_provider('Facebook') callback_uri = self.get_callback_url('facebook') oauth_session = OAuth2Session(facebook.client_id, redirect_uri=callback_uri) oauth_session.fetch_token(facebook.access_token_endpoint, code=code, client_secret=facebook.client_secret) user_response = oauth_session.get( 'https://graph.facebook.com/me?fields=id,name,email') user_info = user_response.json() url = 'https://graph.facebook.com/%s/picture?type=large' % user_info[ 'id'] image = self.fetch_image(url) access_token = user_info['id'] vals = { 'oauth_access_token': access_token, 'name': user_info['name'], 'oauth_uid': user_info['id'], 'email': user_info['email'], 'image': image } provider_id = facebook.id db = request.session['db'] registry = registry_get(db) after_login_url = facebook.after_login_url with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) try: login = env['res.users'].sudo()._singup_user(provider_id, vals) except Exception as e: return request.render('web.login', {'error': e.message}) cr.commit() request._cr.commit() res = login_and_redirect(db, login, access_token, after_login_url) return res
def view(self, db, token, action, id, view='calendar', **kwargs): """ Redirect the user to the website page of the calendar.event, only if it is an appointment """ super(WebsiteCalendarController, self).view(db, token, action, id, view='calendar', **kwargs) registry = registry_get(db) with registry.cursor() as cr: env = Environment(cr, SUPERUSER_ID, {}) attendee = env['calendar.attendee'].search([ ('access_token', '=', token), ('event_id', '=', int(id)) ]) if attendee: request.session['timezone'] = attendee.partner_id.tz if not attendee.event_id.access_token: attendee.event_id._generate_access_token() return redirect('/website/calendar/view/' + str(attendee.event_id.access_token)) else: return request.render("website_calendar.appointment_invalid", {})
def view(self, db, token, action, id, view='calendar'): registry = registry_get(db) with registry.cursor() as cr: # Since we are in auth=none, create an env with SUPERUSER_ID env = Environment(cr, SUPERUSER_ID, {}) attendee = env['calendar.attendee'].search([('access_token', '=', token)]) timezone = attendee.partner_id.tz lang = attendee.partner_id.lang or 'en_US' event = env['calendar.event'].with_context(tz=timezone, lang=lang).browse(int(id)) # If user is logged, redirect to form view of event # otherwise, display the simplifyed web page with event informations if request.session.uid: return werkzeug.utils.redirect('/web?db=%s#id=%s&view_type=form&model=calendar.event' % (db, id)) # NOTE : we don't use request.render() since: # - we need a template rendering which is not lazy, to render before cursor closing # - we need to display the template in the language of the user (not possible with # request.render()) return env['ir.ui.view'].with_context(lang=lang).render_template( 'calendar.invitation_page_anonymous', { 'event': event, 'attendee': attendee, })