Merge pull request #366 from cjmayo/userorpwd

Support login forms with user and/or password
This commit is contained in:
Chris Mayo 2020-05-13 19:37:44 +01:00 committed by GitHub
commit 08ddf658bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 12 deletions

View file

@ -83,19 +83,24 @@ class Aggregate:
if not url:
return
user, password = self.config.get_user_password(url)
if not user and not password:
raise LinkCheckerError(
"loginurl is configured but neither user nor password are set")
session = requests.Session()
# XXX user-agent header
# XXX timeout
log.debug(LOG_CHECK, "Getting login form %s", url)
response = session.get(url)
response.raise_for_status()
cgiuser = self.config["loginuserfield"]
cgipassword = self.config["loginpasswordfield"]
cgiuser = self.config["loginuserfield"] if user else None
cgipassword = self.config["loginpasswordfield"] if password else None
form = loginformsearch.search_form(response.text, cgiuser, cgipassword)
if not form:
raise LinkCheckerError("Login form not found at %s" % url)
form.data[cgiuser] = user
form.data[cgipassword] = password
if user:
form.data[cgiuser] = user
if password:
form.data[cgipassword] = password
for key, value in self.config["loginextrafields"].items():
form.data[key] = value
formurl = parse.urljoin(url, form.url)

View file

@ -41,7 +41,7 @@ def search_form(content, cgiuser, cgipassword):
CGI fields. If no form is found return None.
"""
soup = htmlsoup.make_soup(content)
cginames = {cgiuser, cgipassword}
cginames = {cgiuser, cgipassword} - {None}
for form_element in soup.find_all("form", action=True):
form = Form(form_element["action"])
for input_element in form_element.find_all("input",

View file

@ -0,0 +1,3 @@
<form action="/tests/checker/cgi-bin/input2cookies.py">
<input name="password">
</form>

View file

@ -0,0 +1,3 @@
<form action="/tests/checker/cgi-bin/input2cookies.py">
<input name="login">
</form>

View file

@ -29,18 +29,36 @@ class TestLoginUrl(HttpServerTest):
super().__init__(methodName=methodName)
self.handler = CGIHandler
def test_loginurl(self):
def visit_loginurl(self, page, user=None, password=None, extrafields=False):
confargs = {}
confargs["loginurl"] = self.get_url("loginform.html")
confargs["loginextrafields"] = {"extra_field": "default"}
confargs["loginurl"] = self.get_url(page)
if extrafields:
confargs["loginextrafields"] = {"extra_field": "default"}
confargs["authentication"] = [{
"user": "test_user", "password": "test_password",
"user": user, "password": password,
"pattern": re.compile("^http://localhost.*")
}]
aggregate = get_test_aggregate(confargs, {"expected": ""})
aggregate.visit_loginurl()
self.assertEqual(aggregate.cookies["login"], "test_user")
self.assertEqual(aggregate.cookies["password"], "test_password")
self.assertEqual(aggregate.cookies["extra_field"], "default")
return aggregate.cookies
def test_loginurl(self):
cookies = self.visit_loginurl("loginform.html", "test_user",
"test_password", True)
self.assertEqual(cookies["login"], "test_user")
self.assertEqual(cookies["password"], "test_password")
self.assertEqual(cookies["extra_field"], "default")
def test_loginurl_user(self):
cookies = self.visit_loginurl("loginform_user.html", "test_user")
self.assertEqual(cookies["login"], "test_user")
def test_login_password(self):
cookies = self.visit_loginurl("loginform_password.html",
password="test_password")
self.assertEqual(cookies["password"], "test_password")