Skip to content

Commit

Permalink
Merge pull request #46 from mdsol/include-asgi-root-path
Browse files Browse the repository at this point in the history
Include ASGI scope root_path in url used to validate mAuth signature
  • Loading branch information
ejinotti-mdsol authored Oct 31, 2023
2 parents a6e8330 + 80c9ece commit 7381959
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.6.2
- Fix `MAuthASGIMiddleware` signature validation when the full URL path is split
between `root_path` and `path` in the request scope.

# 1.6.1
- Fix `MAuthWSGIMiddleware` to return a string for "status" and to properly set
content-length header.
Expand Down
3 changes: 2 additions & 1 deletion mauth_client/middlewares/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ async def __call__(
if scope["type"] != "http" or path in self.exempt:
return await self.app(scope, receive, send)

root_path = scope["root_path"]
query_string = scope["query_string"]
url = f"{path}?{decode(query_string)}" if query_string else path
url = f"{root_path}{path}?{decode(query_string)}" if query_string else f"{root_path}{path}"
headers = {decode(k): decode(v) for k, v in scope["headers"]}

events, body = await self._get_body(receive)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "mauth-client"
version = "1.6.1"
version = "1.6.2"
description = "MAuth Client for Python"
repository = "https://github.com/mdsol/mauth-client-python"
authors = ["Medidata Solutions <support@mdsol.com>"]
Expand Down
36 changes: 36 additions & 0 deletions tests/middlewares/asgi_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,39 @@ async def ws(websocket: WebSocket):
with self.client.websocket_connect("/ws") as websocket:
data = websocket.receive_json()
self.assertEqual(data, {"msg": "helloes"})


class TestMAuthASGIMiddlewareInSubApplication(unittest.TestCase):
def setUp(self):
self.app_uuid = str(uuid4())
Config.APP_UUID = self.app_uuid
Config.MAUTH_URL = "https://mauth.com"
Config.MAUTH_API_VERSION = "v1"
Config.PRIVATE_KEY = "key"

self.app = FastAPI()
sub_app = FastAPI()
sub_app.add_middleware(MAuthASGIMiddleware)

@sub_app.get("/path")
async def sub_app_path():
return {"msg": "sub app path"}

self.app.mount("/sub_app", sub_app)

self.client = TestClient(self.app)

@patch.object(LocalAuthenticator, "is_authentic", autospec=True)
def test_includes_base_application_path_in_signature_verification(self, is_authentic_mock):
request_url = None

def is_authentic_effect(self):
nonlocal request_url
request_url = self.signable.attributes_for_signing["request_url"]
return True, 200, ""

is_authentic_mock.side_effect = is_authentic_effect

self.client.get("/sub_app/path")

self.assertEqual(request_url, "/sub_app/path")

0 comments on commit 7381959

Please sign in to comment.