Beispiel #1
0
    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')
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
 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)
Beispiel #5
0
    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)
Beispiel #6
0
    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
        }
Beispiel #8
0
    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')
Beispiel #9
0
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)
Beispiel #10
0
 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)
Beispiel #11
0
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)
Beispiel #12
0
    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)
Beispiel #13
0
 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.")
Beispiel #14
0
    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)
Beispiel #15
0
    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)
Beispiel #16
0
 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)
Beispiel #19
0
    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')
Beispiel #20
0
    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)
Beispiel #21
0
    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)