Skip to content

Commit

Permalink
local server bind address (#202)
Browse files Browse the repository at this point in the history
This PR adds the bind_addr parameter to run_local_server. When using localhost inside of a container this is needed to allow the redirect server to bind to an address to which response will return. In a container this address is not the same as the host address of localhost.

- [x] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-auth-library-python-oauthlib/issues/new/choose) before writing your code!  That way we can discuss the change, evaluate designs, and agree on the general idea
- [x] Ensure the tests and linter pass
- [x] Code coverage does not decrease (if any source code was changed)
- [x] Appropriate docs were updated (if necessary)

Fixes #201 🦕
  • Loading branch information
gilesknap committed Aug 12, 2022
1 parent 0ec54e6 commit b081043
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
8 changes: 7 additions & 1 deletion google_auth_oauthlib/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ def run_console(
def run_local_server(
self,
host="localhost",
bind_addr=None,
port=8080,
authorization_prompt_message=_DEFAULT_AUTH_PROMPT_MESSAGE,
success_message=_DEFAULT_WEB_SUCCESS_MESSAGE,
Expand All @@ -463,6 +464,11 @@ def run_local_server(
Args:
host (str): The hostname for the local redirect server. This will
be served over http, not https.
bind_addr (str): Optionally provide an ip address for the redirect
server to listen on when it is not the same as host
(e.g. in a container). Default value is None,
which means that the redirect server will listen
on the ip address specified in the host parameter.
port (int): The port for the local redirect server.
authorization_prompt_message (str): The message to display to tell
the user to navigate to the authorization URL.
Expand All @@ -483,7 +489,7 @@ def run_local_server(
# Fail fast if the address is occupied
wsgiref.simple_server.WSGIServer.allow_reuse_address = False
local_server = wsgiref.simple_server.make_server(
host, port, wsgi_app, handler_class=_WSGIRequestHandler
bind_addr or host, port, wsgi_app, handler_class=_WSGIRequestHandler
)

redirect_uri_format = (
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/test_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,24 @@ def assign_last_request_uri(host, port, wsgi_app, **kwargs):

assert not webbrowser_mock.open.called

@mock.patch("google_auth_oauthlib.flow.webbrowser", autospec=True)
@mock.patch("wsgiref.simple_server.make_server", autospec=True)
def test_run_local_server_bind_addr(
self, make_server_mock, webbrowser_mock, instance, mock_fetch_token
):
def assign_last_request_uri(host, port, wsgi_app, **kwargs):
wsgi_app.last_request_uri = self.REDIRECT_REQUEST_PATH
return mock.Mock()

make_server_mock.side_effect = assign_last_request_uri

my_ip = socket.gethostbyname(socket.gethostname())
instance.run_local_server(bind_addr=my_ip, host="localhost")

assert webbrowser_mock.open.called
name, args, kwargs = make_server_mock.mock_calls[0]
assert args[0] == my_ip

@pytest.mark.webtest
@mock.patch("google_auth_oauthlib.flow.webbrowser", autospec=True)
def test_run_local_server_occupied_port(
Expand Down

0 comments on commit b081043

Please sign in to comment.