예제 #1
0
    def login(self):
        """
        Login
        """

        response = self.auth_session.get(self.LOGIN_URL)
        login_form_action = get_form_action(response.text)
        if not login_form_action:
            raise VkAuthError('VK changed login flow')

        login_form_data = {
            'email': self.user_login,
            'pass': self.user_password,
        }
        response = self.auth_session.post(login_form_action, login_form_data)
        logger.debug('Cookies: %s', self.auth_session.cookies)

        response_url_query = get_url_query(response.url)

        if 'remixsid' in self.auth_session.cookies or 'remixsid6' in self.auth_session.cookies:
            return

        if 'sid' in response_url_query:
            self.auth_captcha_is_needed(response, login_form_data)
        elif response_url_query.get('act') == 'authcheck':
            self.auth_check_is_needed(response.text)
        elif 'security_check' in response_url_query:
            self.phone_number_is_needed(response.text)
        else:
            message = 'Authorization error (incorrect password)'
            logger.error(message)
            raise VkAuthError(message)
예제 #2
0
 def phone_number_is_needed(self, content, session):
     """
     Default behavior on PHONE NUMBER is to raise exception
     Reload this in child
     """
     # logger.error('Authorization error (phone number is needed)')
     raise VkAuthError('Authorization error (phone number is needed)')
예제 #3
0
    async def _process_auth_form(self, html: str) -> typing.Tuple[URL, str]:
        """
        Parsing data from authorization page and filling the form and submitting the form

        :param html: html page
        :return: url and  html from redirected page
        """
        parser = AuthPageParser()
        parser.feed(html)
        parser.close()

        form_data = dict(parser.inputs)
        form_url = parser.url
        form_data["email"] = self.login
        form_data["pass"] = self.password
        if parser.message:
            raise VkAuthError("invalid_data", parser.message, form_url,
                              form_data)
        if parser.captcha_url:
            form_data["captcha_key"] = await self.enter_captcha(
                "https://m.vk.com{}".format(parser.captcha_url),
                form_data["captcha_sid"],
            )
            form_url = "https://m.vk.com{}".format(form_url)

        url, html = await self._get_data_from_form(form_url, form_data)
        return url, html
예제 #4
0
    async def _get_auth_page(self) -> str:
        """
        Get authorization mobile page without js
        :return: html page
        """
        params = {
            "client_id": self.app_id,
            "redirect_uri": "https://oauth.vk.com/blank.html",
            "display": "mobile",
            "response_type": "token",
            "v": self.API_VERSION,
        }
        if self.scope:
            params["scope"] = self.scope

        async with self.session.get(url=self.AUTH_URL, params=params) as resp:
            response = await resp.text()
            status = resp.status

        if status != 200:
            error_dict = JSON_LIBRARY.loads(response)
            raise VkAuthError(
                error_dict["error"],
                error_dict["error_description"],
                self.AUTH_URL,
                params,
            )
        return response
예제 #5
0
 async def authorize(self) -> None:
     """Getting a new token from server"""
     html = await self._get_auth_page()
     url = URL("/authorize?email")
     for _ in range(self.num_of_attempts):
         if url.path == "/authorize" and "email" in url.query:
             url, html = await self._process_auth_form(html)
         if (
             url.path == "/login"
             and url.query.get("act", "") == "authcheck"
         ):
             url, html = await self._process_2auth_form(html)
         if (
             url.path == "/login"
             and url.query.get("act", "") == "authcheck_code"
         ):
             url, html = await self._process_auth_form(html)
         if url.path == "/authorize" and "__q_hash" in url.query:
             url, html = await self._process_access_form(html)
         if url.path == "/blank.html":
             parsed_fragments = dict(parse_qsl(url.fragment))
             self.access_token = parsed_fragments["access_token"]
             await self.session.close()
             return None
     raise VkAuthError(
         "Something went wrong", "Exceeded the number of attempts to log in"
     )
예제 #6
0
    def oauth2_authorization(self):
        """
        OAuth2
        """
        auth_data = {
            'client_id': self.app_id,
            'display': 'mobile',
            'response_type': 'token',
            'scope': self.scope,
            'v': '5.28',
        }
        response = self.auth_session.post(self.AUTHORIZE_URL, auth_data)
        response_url_query = get_url_query(response.url)
        if 'access_token' in response_url_query:
            return response_url_query

        # Permissions is needed
        logger.info('Getting permissions')
        # form_action = re.findall(r'<form method="post" action="(.+?)">', auth_response.text)[0]
        form_action = get_form_action(response.text)
        logger.debug('Response form action: %s', form_action)
        if form_action:
            response = self.auth_session.get(form_action)
            response_url_query = get_url_query(response.url)
            return response_url_query

        try:
            response_json = response.json()
        except ValueError:  # not JSON in response
            error_message = 'OAuth2 grant access error'
        else:
            error_message = 'VK error: [{}] {}'.format(response_json['error'], response_json['error_description'])
        logger.error('Permissions obtained')
        raise VkAuthError(error_message)
예제 #7
0
    def get_access_token(self):
        """
        Get access token using app id and user login and password.
        """
        logger.debug('AuthMixin.get_access_token()')

        auth_session = LoggingSession()
        with auth_session as self.auth_session:
            self.auth_session = auth_session
            self.login()
            auth_response_url_query = self.oauth2_authorization()

        if 'access_token' in auth_response_url_query:
            return auth_response_url_query['access_token']
        else:
            raise VkAuthError('OAuth2 authorization error')
예제 #8
0
    def auth_captcha_is_needed(self, response, login_form_data):
        logger.info('Captcha is needed')

        response_url_dict = get_url_query(response.url)

        captcha_form_action = get_form_action(response.text)
        logger.debug('form_url %s', captcha_form_action)
        if not captcha_form_action:
            raise VkAuthError('Cannot find form url')

        # todo Are we sure that `response_url_dict` doesn't contain CAPTCHA image url?
        captcha_url = '%s?s=%s&sid=%s' % (
            self.CAPTCHA_URI, response_url_dict['s'], response_url_dict['sid'])

        login_form_data['captcha_sid'] = response_url_dict['sid']
        login_form_data['captcha_key'] = self.get_captcha_key(captcha_url)

        self.auth_session.post(captcha_form_action, login_form_data)
예제 #9
0
파일: mixins.py 프로젝트: itJunky/vk
    def auth_captcha_is_needed(self, response, login_form_data):
        logger.info('Captcha is needed')

        response_url_dict = get_url_query(response.url)

        # form_url = re.findall(r'<form method="post" action="(.+)" novalidate>', response.text)
        captcha_form_action = get_form_action(response.text)
        logger.debug('form_url %s', captcha_form_action)
        if not captcha_form_action:
            raise VkAuthError('Cannot find form url')

        captcha_url = '%s?s=%s&sid=%s' % (self.CAPTCHA_URI, response_url_dict['s'], response_url_dict['sid'])
        # logger.debug('Captcha url %s', captcha_url)

        login_form_data['captcha_sid'] = response_url_dict['sid']
        login_form_data['captcha_key'] = self.on_captcha_is_needed(captcha_url)

        response = self.auth_session.post(captcha_form_action, login_form_data)
예제 #10
0
    async def _process_2auth_form(self, html: str) -> typing.Tuple[URL, str]:
        """
        Parsing two-factor authorization page and filling the code

        :param html: html page
        :return: url and  html from redirected page
        """
        parser = TwoFactorCodePageParser()
        parser.feed(html)
        parser.close()

        form_url = parser.url
        form_data = dict(parser.inputs)
        form_data["remember"] = 0
        if parser.message:
            raise VkAuthError("invalid_data", parser.message, form_url, form_data)
        form_data["code"] = await self.enter_confirmation_code()

        url, html = await self._get_data_from_form(form_url, form_data)
        return url, html
예제 #11
0
 def auth_captcha_is_needed(self, content, session):
     """
     Default behavior on CAPTCHA is to raise exception
     Reload this in child
     """              
     raise VkAuthError('Authorization error (captcha)')
예제 #12
0
 def auth_code_is_needed(self, content, session):
     """
     Default behavior on 2-AUTH CODE is to raise exception
     Reload this in child
     """           
     raise VkAuthError('Authorization error (2-factor code is needed)')
예제 #13
0
 def get_auth_check_code(self):
     raise VkAuthError('Auth check code is needed')
예제 #14
0
 def phone_number_is_needed(self, text):
     raise VkAuthError('Phone number is needed')