Skip to content

Instantly share code, notes, and snippets.

@Taiiwo
Created July 19, 2015 18:01
Show Gist options
  • Save Taiiwo/0a718f09d894553f2be2 to your computer and use it in GitHub Desktop.
Save Taiiwo/0a718f09d894553f2be2 to your computer and use it in GitHub Desktop.
A python class for verifying login details for any website
import mechanize
import cookielib
import re
class Login:
def __init__(self):
# set a bunch of properties as default settings
self.url = False
self.formIndex = 0
self.dualPage = False
self.userField = "email"
self.passField = "pass"
self.success = False
self.invalid = False
self.rateLimited = False
# set up the /browser/
self.br = mechanize.Browser()
cj = cookielib.LWPCookieJar()
self.br.set_cookiejar(cj)
self.br.set_handle_equiv(True)
self.br.set_handle_redirect(True)
self.br.set_handle_referer(True)
self.br.set_handle_robots(False)
self.br.set_handle_refresh(
mechanize._http.HTTPRefreshProcessor(),
max_time=1
)
# Google says we're using an outdated browser ;_;
self.br.addheaders = [(
'User-agent',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) '
'Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1'
)]
# this function uses our browsers instance to log into the page
def login(self, username, password):
# make sure all of the required arguments are set
if not self.url or not self.userField or not self.passField:
raise ArgumentError('Specify properties: url, userField, passField')
else:
if not (self.success or self.invalid):
raise ArgumentError('Specify atleast one of properties'
' `success` of ` invalid`')
else:
# we definitely have all of values we need, let's get to work
# renamed for simplicity
br = self.br
# browse to the page
r = br.open(self.url)
# check if the username and password are on different pages
if self.dualPage:
# we're making a bunch of assumtions here mainly to support
# google.
#
# this checks if the form index is a list, and if it is, it
# uses both values; one for each page. See also comment !1
if type(self.formIndex) == int:
formIndex = self.formIndex
indexIsList = False
else:
formIndex = self.formIndex[0]
indexIsList = True
# select the NRth form on the page, the first if there's one
br.select_form(nr=formIndex)
# put the username in the username field
br.form[self.userField] = username
# submit the form, and wait until the next page loads
br.submit()
# !1
if indexIsList:
formIndex = self.formIndex[1]
# select the correct form on the next page
br.select_form(nr=formIndex)
# enter the password into the passowrd field
br.form[self.passField] = password
# submit the form, hopefully logging us in
br.submit()
else:
# all the fields are on the same page
# select the NRth form on the page, the first if there's one
br.select_form(nr=self.formIndex)
# put the username and password into their respective field
br.form[self.userField] = username
br.form[self.passField] = password
# submit the form
br.submit()
# get the HTML of the resulting page
html = br.response().read()
# check to see if it was the response we were looking for
return self.verify(
html,
self.success,
self.invalid,
self.rateLimited
)
# tries to work out if html is of a success, invalid, or rate limited page
def verify(self, html, success, invalid, rateLimited):
# make a blank object, just to keep things pretty
r = ReturnObject()
# add the html to the object so the developer can use it for debugging
r.html = html
# prioritize rate limiting message, as it's the least likely to appear
if rateLimited and re.search(rateLimited, html):
r.valid = False
r.desc = "The rateLimited regex matched in the page."
r.rateLimited = True
# check if the invalid regex matches
elif invalid and re.search(invalid, html):
r.valid = False
r.desc = "The invalid regex matched in the page."
r.rateLimited = False
# check if the success regex matches
elif success and re.search(success, html):
r.valid = True
r.desc = "The success regex matched in the page."
r.rateLimited = False
# if only invalid is specified, and it didn't match, then we're probably
# authenticated
elif invalid and not success:
r.valid = True
r.desc = "Success. The invalid regex was not found in the page."
r.rateLimited = False
# nothing we provided matched, so it prbably failed to authenticate
else:
r.valid = False
r.desc = "None of the regexes matched the page"
r.rateLimited = False
return r
# just something to allow us to return an object instead of a dict
class ReturnObject:
pass
# a custom error to raise when insufficuent parameters are supplied
class ArgumentError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
if __name__ == "__main__":
# a test script that logs into google
# instantiate the class
l = Login()
# supply all of the required parameters
l.url = "https://accounts.google.com/ServiceLogin"
l.dualPage = True
l.userField = "Email"
l.passField = "Passwd"
l.success = "To access all of your Google account settings, upgrade to " \
"the latest version of any of the following browsers"
# print the description of a login attempt
print l.login('[email protected]', 'notanactualpassword').desc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment