@@ -291,19 +291,27 @@ def _vk_login(self, captcha_sid=None, captcha_key=None):
291291 }
292292 )
293293
294+ if 'sid' not in account :
295+ raise AuthError ('Account not exists' )
296+
294297 credentials .sid = account ['sid' ]
295298 next_step = account .get ('next_step' )
296299
297300 if next_step is not None and next_step ['verification_method' ] != VerificationMethod .PASSWORD :
298- self .logger .info ('Confirmation code is required' )
299- self ._pass_confirmation_code (next_step ['verification_method' ], credentials )
301+ if (
302+ not next_step .get ('has_another_verification_methods' )
303+ or
304+ VerificationMethod .PASSWORD not in self ._get_allowed_verification_methods (credentials )
305+ ):
306+ self .logger .info ('Confirmation code is required' )
307+ self ._pass_confirmation_code (next_step ['verification_method' ], credentials )
300308
301309 if not credentials .can_skip_password and not self .password :
302310 raise PasswordRequired ('Password is required to login' )
303311
304312 response_dict = self .vk_login_method (
305313 action = 'connect_authorize' ,
306- data = {
314+ values = {
307315 'username' : self .login ,
308316 'password' : self .password ,
309317 'auth_token' : credentials .access_token ,
@@ -323,12 +331,7 @@ def _vk_login(self, captcha_sid=None, captcha_key=None):
323331 },
324332 )
325333
326- if response_dict ['type' ] != 'okay' :
327- if response_dict ['error_code' ] == 'incorrect_password' :
328- raise BadPassword ('Bad password' )
329- raise AuthorizeError (response_dict )
330-
331- if response_dict ['data' ]['is_user_banned' ]:
334+ if response_dict ['is_user_banned' ]:
332335 raise AccountBlocked ('Account is blocked' )
333336
334337 if not self ._sid :
@@ -437,6 +440,23 @@ def _vk_login_legacy(self, response, captcha_sid=None, captcha_key=None):
437440 if 'act=blocked' in response .url :
438441 raise AccountBlocked ('Account is blocked' )
439442
443+ def _get_allowed_verification_methods (self , credentials : WebLoginCredentials ) -> t .Set [VerificationMethod ]:
444+ """Возвращает множество доступных для подтверждения входа методов."""
445+ verification_methods = set (VerificationMethod )
446+ response = self .method (
447+ with_cookies = True ,
448+ method = 'ecosystem.getVerificationMethods' ,
449+ values = {
450+ 'v' : credentials .api_version ,
451+ 'client_id' : credentials .app_id ,
452+ 'sid' : credentials .sid ,
453+ 'device_id' : credentials .device_id ,
454+ 'anonymous_token' : credentials .anonymous_token ,
455+ 'access_token' : '' ,
456+ },
457+ )
458+ return {VerificationMethod (m ['name' ]) for m in response ['methods' ] if m ['name' ] in verification_methods }
459+
440460 def _pass_confirmation_code (
441461 self ,
442462 verification_method : str ,
@@ -918,7 +938,7 @@ def method(
918938 def vk_login_method (
919939 self ,
920940 action : str ,
921- data : t .Dict [str , t .Any ],
941+ values : t .Dict [str , t .Any ],
922942 headers : t .Optional [t .Dict [str , t .Any ]] = None ,
923943 captcha_sid : t .Optional [str ] = None ,
924944 captcha_key : t .Optional [str ] = None ,
@@ -929,8 +949,8 @@ def vk_login_method(
929949 :param action: имя действия, например, connect_authorize или connect_internal
930950 :type action: str
931951
932- :param data : данные/поля формы
933- :type data : dict
952+ :param values : данные/поля формы
953+ :type values : dict
934954
935955 :param headers: HTTP заголовки
936956 :type headers: dict
@@ -943,16 +963,15 @@ def vk_login_method(
943963 """
944964 if captcha_sid and captcha_key :
945965 self .logger .info (f'Using captcha code: { captcha_sid } : { captcha_key } ' )
946- data ['captcha_sid' ] = captcha_sid
947- data ['captcha_key' ] = captcha_key
966+ values ['captcha_sid' ] = captcha_sid
967+ values ['captcha_key' ] = captcha_key
948968
949969 response = self .http .post (
950970 url = f'https://login.vk.com/?act={ action } ' ,
951- data = data ,
971+ data = values ,
952972 headers = headers ,
953973 )
954974 response_dict = response .json ()
955- self .logger .debug (response_dict )
956975
957976 if response_dict ['type' ] == 'captcha' :
958977 captcha_type = response_dict ['captcha_type' ]
@@ -965,14 +984,25 @@ def vk_login_method(
965984 func = self .vk_login_method ,
966985 kwargs = {
967986 'action' : action ,
968- 'data ' : data ,
987+ 'values ' : values ,
969988 'headers' : headers ,
970989 },
971990 )
972991
973992 return self .error_handlers [CAPTCHA_ERROR_CODE ](captcha )
974993
975- return response_dict
994+ if response_dict ['type' ] != 'okay' :
995+ if response_dict ['error_code' ] == 'incorrect_password' :
996+ raise BadPassword (response_dict ['error_info' ])
997+
998+ if response_dict ['error_code' ]:
999+ error_message = '[{error_code}] {error_info}' .format (** response_dict )
1000+ else :
1001+ error_message = response_dict ['error_info' ]
1002+
1003+ raise AuthError (error_message )
1004+
1005+ return response_dict .get ('data' , response_dict )
9761006
9771007
9781008class VkApiGroup (VkApi ):
0 commit comments