Beispiel #1
0
 async def authorize(self) -> None:
     """Getting a new token from server"""
     html = await self._get_auth_page()
     url = URL('/authorize?email')
     for step in range(self.num_of_attempts):
         if url.path == '/authorize' and 'email' in url.query:
             # Invalid login or password  and 'email' in q.query
             url, html = await self._process_auth_form(html)
         if url.path == '/login' and url.query.get('act',
                                                   '') == 'authcheck':
             # Entering 2auth code
             url, html = await self._process_2auth_form(html)
         if url.path == '/login' and url.query.get('act',
                                                   '') == 'authcheck_code':
             # Need captcha
             url, html = await self._process_auth_form(html)
         if url.path == '/authorize' and '__q_hash' in url.query:
             # Give rights for app
             url, html = await self._process_access_form(html)
         if url.path == '/blank.html':
             # Success
             self.access_token = url.query['access_token']
             return
     raise VkAuthError('Something went wrong',
                       'Exceeded the number of attempts to log in')
Beispiel #2
0
    async def _get_auth_page(self) -> str:
        """
        Get authorization mobile page without js
        :return: html page
        """
        # Prepare request
        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

        # Send request
        status, response = await self.driver.get_text(self.AUTH_URL, params)

        # Process response
        if status != 200:
            error_dict = json.loads(response)
            raise VkAuthError(error_dict['error'],
                              error_dict['error_description'], self.AUTH_URL,
                              params)
        return response
Beispiel #3
0
    async def _process_auth_form(self, html: str) -> (str, 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
        """
        # Parse page
        p = AuthPageParser()
        p.feed(html)
        p.close()

        # Get data from hidden inputs
        form_data = dict(p.inputs)
        form_url = p.url
        form_data['email'] = self.login
        form_data['pass'] = self.password
        if p.message:
            # Show form errors
            raise VkAuthError('invalid_data', p.message, form_url, form_data)
        elif p.captcha_url:
            form_data['captcha_key'] = await self.enter_captcha(
                "https://m.vk.com{}".format(p.captcha_url),
                form_data['captcha_sid'])
            form_url = "https://m.vk.com{}".format(form_url)

        # Send request
        url, html = await self.driver.post_text(form_url, form_data)
        return url, html
Beispiel #4
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)')
Beispiel #5
0
 async def authorize(self, code=None):
     code = await self.get_code(code)
     params = {
         'client_id': self.app_id,
         'client_secret': self.app_secret,
         'redirect_uri': self.redirect_uri,
         'code': code
     }
     response = await self.driver.json(self.CODE_URL, params, self.timeout)
     if 'error' in response:
         raise VkAuthError(response['error'], response['error_description'], self.CODE_URL, params)
     self.access_token = response['access_token']
Beispiel #6
0
 async def process_2auth_form(self, html):
     p = TwoFactorCodePageParser()
     p.feed(html)
     p.close()
     form_url = p.url
     form_data = dict(p.inputs)
     form_data['remember'] = 0
     if p.message:
         raise VkAuthError('invalid_data', p.message, form_url, form_data)
     form_data['code'] = await self.enter_confirmation_сode()
     url, html = await self.driver.post_text(form_url, form_data)
     return url, html
Beispiel #7
0
 async def process_auth_form(self, html):
     p = AuthPageParser()
     p.feed(html)
     p.close()
     form_data = dict(p.inputs)
     form_url = p.url
     form_data['email'] = self.login
     form_data['pass'] = self.password
     if p.message:
         raise VkAuthError('invalid_data', p.message, form_url, form_data)
     elif p.captcha_url:
         form_data['captcha_key'] = await self.enter_captcha(p.captcha_url, form_data['captcha_sid'])
     url, html = await self.driver.post_text(form_url, form_data)
     return url, html
Beispiel #8
0
    def login(self):
        """
        Login
        """

        response = yield from self.auth_session.get(self.LOGIN_URL)
        response = RequestsLikeResponse(response)
        login_form_action = get_form_action((yield from 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 = yield from self.auth_session.post(login_form_action,
                                                     data=login_form_data)
        response = RequestsLikeResponse(response)
        yield from response.text()
        # logger.info('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:
            # if 'remixsid' in response_url_query or 'remixsid6' in response_url_query:
            return

        if 'sid' in response_url_query:
            yield from self.auth_captcha_is_needed(response, login_form_data)
        elif response_url_query.get('act') == 'authcheck':
            self.auth_check_is_needed((yield from response.text()))
        elif 'security_check' in response_url_query:
            self.phone_number_is_needed((yield from response.text()))
        else:
            message = 'Authorization error (incorrect password)'
            logger.error(message)
            raise VkAuthError(message)
Beispiel #9
0
    async def get_auth_page(self):
        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
        status, response = await self.driver.get_text(self.AUTH_URL, params)
        if status != 200:
            error_dict = json.loads(response)
            raise VkAuthError(error_dict['error'], error_dict['error_description'], self.AUTH_URL, params)
        return response
Beispiel #10
0
 async def authorize(self, code: str = None) -> None:
     """Getting a new token from server"""
     code = await self.get_code(code)
     params = {
         'client_id': self.app_id,
         'client_secret': self.app_secret,
         'redirect_uri': self.redirect_uri,
         'code': code
     }
     _, response = await self.driver.post_json(self.CODE_URL, params,
                                               self.timeout)
     if 'error' in response:
         raise VkAuthError(response['error'], response['error_description'],
                           self.CODE_URL, params)
     self.access_token = response['access_token']
Beispiel #11
0
    def get_access_token(self):
        """
        Get access token using app id and user login and password.
        """
        logger.info('AuthMixin.get_access_token()')

        auth_session = aiohttp.ClientSession()
        with auth_session as self.auth_session:
            self.auth_session = auth_session
            yield from self.login()
            auth_response_url_query = yield from self.oauth2_authorization()

        if 'access_token' in auth_response_url_query:
            return auth_response_url_query[
                'access_token'], auth_response_url_query['expires_in']
        else:
            raise VkAuthError('OAuth2 authorization error')
Beispiel #12
0
 async def authorize(self):
     html = await self.get_auth_page()
     q = urllib.parse.urlparse('/authorize?email')
     for step in range(self.num_of_attempts):
         if q.path == '/authorize'and 'email' in q.query:  # invalid login or password  and 'email' in q.query
             url, html = await self.process_auth_form(html)
             q = urllib.parse.urlparse(url)
         if q.path == '/login':  # entering 2auth code
             url, html = await self.process_2auth_form(html)
             q = urllib.parse.urlparse(url)
         if q.path == '/authorize' and '__q_hash' in q.query:  # give rights for app
             url, html = await self.process_access_form(html)
             q = urllib.parse.urlparse(url)
         if q.path == '/blank.html':
             qs = dict(urllib.parse.parse_qsl(q.query))
             self.access_token = qs['access_token']
             return
     raise VkAuthError('Something went wrong', 'Exceeded the number of attempts to log in')
Beispiel #13
0
    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((yield from response.text()))
        logger.info('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.info('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 = yield from self.auth_session.post(captcha_form_action,
                                                     data=login_form_data)
Beispiel #14
0
    def oauth2_authorization(self):
        """
        OAuth2
        """
        auth_data = {
            'client_id': self.app_id,
            'display': 'mobile',
            'response_type': 'token',
            'scope': self.scope,
            'v': '5.37',
            # "redirect_uri": "https://oauth.vk.com/blank.html",
        }
        response = yield from self.auth_session.post(self.AUTHORIZE_URL,
                                                     data=auth_data)
        response = RequestsLikeResponse(response)
        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((yield from response.text()))
        logger.info('Response form action: %s', form_action)
        if form_action:
            response = yield from self.auth_session.get(form_action)
            response = RequestsLikeResponse(response)
            response_url_query = get_url_query(response.url)
            return response_url_query

        try:
            response_json = yield from 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)
Beispiel #15
0
    async def _process_2auth_form(self, html: str) -> (str, str):
        """
        Parsing two-factor authorization page and filling the code

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

        # Prepare request data
        form_url = p.url
        form_data = dict(p.inputs)
        form_data['remember'] = 0
        if p.message:
            raise VkAuthError('invalid_data', p.message, form_url, form_data)
        form_data['code'] = await self.enter_confirmation_code()

        # Send request
        url, html = await self.driver.post_text(form_url, form_data)
        return url, html
Beispiel #16
0
 def get_auth_check_code(self):
     raise VkAuthError('Auth check code is needed')
Beispiel #17
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)')
Beispiel #18
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)')
Beispiel #19
0
 async def authorize(self):
     raise VkAuthError('invalid_token', 'User authorization failed')
Beispiel #20
0
 async def authorize(self) -> None:
     """Getting a new token from server"""
     # For `TokenSession` we have not credentials for getting new token
     raise VkAuthError('invalid_token', 'User authorization failed')
Beispiel #21
0
 def phone_number_is_needed(self, text):
     raise VkAuthError('Phone number is needed')