Skip to content

Commit

Permalink
Merge pull request #19 from scivisum/http_auth
Browse files Browse the repository at this point in the history
Http auth
  • Loading branch information
earendil committed Aug 15, 2019
2 parents f9ed1cb + 6c4c342 commit 2ffee9e
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
17 changes: 16 additions & 1 deletion browserdebuggertools/chrome/interface.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import contextlib
import time
import logging
from base64 import b64decode
from base64 import b64decode, b64encode

from browserdebuggertools.sockethandler import SocketHandler
from browserdebuggertools.exceptions import (
Expand Down Expand Up @@ -215,3 +215,18 @@ def emulate_network_conditions(self, latency, download, upload, offline=False):
}

return self.execute("Network", "emulateNetworkConditions", network_conditions)

def set_basic_auth(self, username, password):
"""
Creates a basic type Authorization header from the username and password strings
and applies it to all requests
"""
auth = "Basic " + b64encode("%s:%s" % (username, password))
self.set_request_headers({"Authorization": auth})

def set_request_headers(self, headers):
"""
The specified headers are applied to all requests
:param headers: A dictionary of the form {"headerKey": "headerValue"}
"""
self.execute("Network", "setExtraHTTPHeaders", {"headers": headers})
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

setup(
name="browserdebuggertools",
version="3.1.0",
version="3.2.0",
packages=PACKAGES,
install_requires=requires,
license="GNU General Public License v3",
Expand Down
33 changes: 32 additions & 1 deletion tests/e2etests/chrome/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def test_took_expected_time(self):
start = time.time()
self.assertTrue(self.waitForEventWithMethod("Network.loadingFinished"))
time_taken = time.time() - start
self.assertEqual(10, int(round(time_taken)))
self.assertIn(int(round(time_taken)), [10, 11]) # Headed browser is a bit slower


class Test_ChromeInterface_emulate_network_conditions_headed(
Expand All @@ -236,3 +236,34 @@ class Test_ChromeInterface_emulate_network_conditions_headless(
HeadlessChromeInterfaceTest, ChromeInterface_emulate_network_conditions, TestCase
):
pass


class ChromeInterface_set_basic_auth(object):

def test_standard_auth_page(self):

self.devtools_client.enable_domain("Network")
url = "http://username:password@localhost:%s/auth_challenge" % self.testSite.port
self.devtools_client.navigate(url=url)
self._assert_dom_complete()

responses_received = []
for event in self.devtools_client.get_events("Network"):
if event.get("method") == "Network.responseReceived":
responses_received.append(event["params"]["response"]["status"])

self.assertTrue(len(responses_received) >= 2) # Headed browser creates extra requests
self.assertIn(200, responses_received)
self.assertNotIn(401, responses_received) # Devtools genuinely doesn't report these


class Test_ChromeInterface_set_baic_auth_headed(
HeadedChromeInterfaceTest, ChromeInterface_set_basic_auth, TestCase
):
pass


class Test_ChromeInterface_set_baic_auth_headless(
HeadlessChromeInterfaceTest, ChromeInterface_set_basic_auth, TestCase
):
pass
35 changes: 35 additions & 0 deletions tests/e2etests/testsite/start.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import multiprocessing
import time
from base64 import b64decode

import cherrypy

Expand Down Expand Up @@ -35,6 +36,40 @@ def javascript_file(self, response_time=None):
def big_body(self, size=1000000):
return "T" * size

@cherrypy.expose
def auth_challenge(self, authorized_username="username", authorized_password="password",
response_body=None):

if self.is_authenticated(authorized_username, authorized_password):

if response_body:
return response_body

return """
<html>
<head><script src="/auth_challenge?response_body=null"></script></head>
<body>
Authorized
</body>
</html>
"""
cherrypy.response.headers["WWW-Authenticate"] = "basic"
cherrypy.response.status = 401
return "Need to authorize"

@staticmethod
def is_authenticated(authorized_username, authorized_password):

if "Authorization" in cherrypy.request.headers:

auth_string = str(cherrypy.request.headers["Authorization"])
secret = auth_string.split("Basic ")[1]
credentials = b64decode(secret).decode()
this_username, this_password = tuple(credentials.split(":"))
if (this_username == authorized_username) and (this_password == authorized_password):
return True
return False


class Server(object):

Expand Down

0 comments on commit 2ffee9e

Please sign in to comment.