-
-
Save Sapistudio/670dbf715e47860316bccdc9431e439c to your computer and use it in GitHub Desktop.
Yahoo email validation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import time | |
import urllib | |
import requests | |
class Yahoo(object): | |
""" | |
Hokey way of Yahoo validation since their SMTP check returns | |
250 for every request. | |
""" | |
def __init__(self): | |
""" | |
Putting together some constants needed or maybe for PEP8 fashion. | |
""" | |
ua = [] | |
ua.append('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1)') | |
ua.append('AppleWebKit/537.36 (KHTML, like Gecko)') | |
ua.append('Chrome/63.0.3239.108 Safari/537.36') | |
content_type = 'application/x-www-form-urlencoded; charset=UTF-8' | |
url = 'https://login.yahoo.com/account/module/create' | |
params = 'validateField=yid' | |
self.url = '{0}?{1}'.format(url, params) | |
self.headers = {'origin': 'https://login.yahoo.com', | |
'accept-encoding': 'gzip, deflate, br', | |
'accept-language': 'en-US,en;q=0.9', | |
'user-agent': ' '.join(ua), | |
'content-type': content_type, | |
'accept': '*/*', | |
'referer': self.url, | |
'authority': 'login.yahoo.com', | |
'x-requested-with': 'XMLHttpRequest'} | |
def _valid_response_(self, response): | |
""" Internal function for checking the response code. | |
Args: | |
response (:obj:): Requests response object. | |
Returns: | |
bool: True or False based on if 2xx status code. | |
""" | |
if response and response.status_code: | |
if response.status_code in range(200, 299): | |
return True | |
return False | |
def _extract_crumb(self, cookies): | |
""" Crumb needed for the post body element. | |
Args: | |
cookies (:obj:): Requests.cookies response object. | |
Returns: | |
acrumb (str): Parsed out string from AS cookie for body. | |
""" | |
acrumb = None | |
for cookie in cookies: | |
if cookie.name == 'AS': | |
dataset = cookie.value.split('&') | |
for data in dataset: | |
if data.startswith('s='): | |
acrumb = data[len('s='):] | |
return acrumb | |
def _browser_data(self, acrumb, mailbox): | |
""" Construct of the post return data for second request. | |
Args: | |
acrumb (str): Hash value returned to post body. | |
mailbox (str): {mailbox}@yahoo.com also needed for post body. | |
Returns: | |
browser, dict_args (tuple): 2 sets of prepared data for response. | |
""" | |
ftime_start = int(time.time()) | |
ftime_end = ftime_start + 10 | |
hash1 = '24700f9f1986800ab4fcc880530dd0ed' | |
hash2 = 'd52a1516cfb5f1c2d8a427c14bc3645f' | |
browser_fp_data = {"language": "en-US", | |
"colorDepth": 24, | |
"deviceMemory": 8, | |
"pixelRatio": 2, | |
"hardwareConcurrency": 8, | |
"resolution": {"w": 1440, | |
"h": 900}, | |
"availableResolution": {"w": 1440, | |
"h": 846}, | |
"timezoneOffset": 300, | |
"timezone": "America/Chicago", | |
"sessionStorage": 1, | |
"localStorage": 1, | |
"indexedDb": 1, | |
"openDatabase": 1, | |
"cpuClass": "unknown", | |
"platform": "MacIntel", | |
"doNotTrack": 1, | |
"canvas": "canvas winding:yes~canvas", | |
"webgl": 1, | |
"webglVendorAndRenderer": "Google Inc. (ATI Technologies Inc.)~ANGLE (ATI Technologies Inc., AMD Radeon Pro 555 OpenGL Engine, OpenGL 4.1)", | |
"adblock": 0, | |
"hasLiedLanguages": 0, | |
"hasLiedResolution": 0, | |
"hasLiedOs": 0, | |
"hasLiedBrowser": 0, | |
"touch_support": {"points": 0, | |
"event": 0, | |
"start": 0}, | |
"plugins": {"count": 0, | |
"hash": hash1}, | |
"fonts": {"count": 27, | |
"hash": hash2}, | |
"audio": "124.04347657808103", | |
"ts": {"serve": ftime_start, | |
"render": ftime_end}} | |
dict_args = {'specId': 'yidregsimplified', | |
'cacheStored': 'true', | |
'crumb': 'QFM5cNikkUV', | |
'acrumb': acrumb, | |
'sessionIndex': 'QQ--', | |
'done': 'https%3A%2F%2Fwww.yahoo.com', | |
'attrSetIndex': 0, | |
'googleIdToken': '', | |
'authCode': '', | |
'tos0': 'oath_freereg|us|en-US', | |
'firstName': '', | |
'lastName': '', | |
'attrSetIndex': 0, | |
'userid-domain': 'yahoo', | |
'userId': mailbox, | |
'yidDomainDefault': 'yahoo.com', | |
'yidDomain': 'yahoo.com', | |
'password': '', | |
'shortCountryCode': 'US', | |
'phone': '', | |
'mm': '', | |
'dd': '', | |
'yyyy': '', | |
'multiDomain': '', | |
'signup': '', | |
'freeformGender': ''} | |
return browser_fp_data, dict_args | |
def _reshape_cookie(self, cookies): | |
""" Returns string representation of cookie body | |
Args: | |
cookies (:obj:`list`): List of cookies | |
Returns: | |
string: Concatenated string of cookie name+body | |
""" | |
string = [] | |
for cookie in cookies: | |
string.append('{0}={1}'.format(cookie.name, cookie.value)) | |
return ';'.join(string) | |
def _digest_response(self, response): | |
""" Tests response output if mailbox exists. | |
Args: | |
response (:obj:): Requests response object.json() | |
Returns: | |
string: "exists" or "does not exist" | |
""" | |
output = None | |
if 'errors' in response: | |
for error in response['errors']: | |
if error['name'] == 'userId': | |
output = error['error'] | |
if output == 'IDENTIFIER_EXISTS': | |
return 'exists' | |
return 'does not exist' | |
def _clean_mailbox(self, mailbox): | |
""" Incase someone passes in a full email in instead of a mailbox | |
Args: | |
mailbox (str): "[email protected]" | |
Returns: | |
mailbox (str): "test" without the "@yahoo.com" | |
""" | |
if '@' in mailbox: | |
return mailbox[:mailbox.find("@") - 1] | |
return mailbox | |
def validate(self, mailbox): | |
""" Validation method that runs the check against the validation. | |
Args: | |
mailbox (str): mailbox to check validation against. | |
Returns: | |
string: "{mailbox} exists" or "{mailbox} does not exist" | |
""" | |
mailbox = self._clean_mailbox(mailbox) | |
r = requests.get(self.url) | |
if not self._valid_response_(r): | |
return {'Error': 'Initial request error'} | |
acrumb = self._extract_crumb(r.cookies) | |
self.headers['cookie'] = self._reshape_cookie(r.cookies) | |
browser_fp_data, dict_args = self._browser_data(acrumb, mailbox) | |
payload = {'browser-fp-data': browser_fp_data} | |
payload.update(dict_args) | |
params = {'validateField': 'userId'} | |
req = requests.post(self.url, headers=self.headers, cookies=r.cookies, | |
data=payload, params=params) | |
if not self._valid_response_(r): | |
return {'Error': 'Validation call error'} | |
return '{0} {1}'.format(mailbox, self._digest_response(req.json())) | |
if __name__ == '__main__': | |
yahoo = Yahoo() | |
mailbox = 'krazybean1' | |
if len(sys.argv) == 2: | |
mailbox = sys.argv[1] | |
print(yahoo.validate(mailbox)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment