From 545f05572c7a50e7d2f630a5abcd5a9fed02e62a Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Thu, 16 May 2024 17:26:52 -0400 Subject: [PATCH 1/6] Show auth state in Context repr. --- tiled/client/context.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tiled/client/context.py b/tiled/client/context.py index e907efee0..840f97cde 100644 --- a/tiled/client/context.py +++ b/tiled/client/context.py @@ -159,6 +159,23 @@ def __init__( self.api_key = api_key # property setter sets Authorization header self.admin = Admin(self) # accessor for admin-related requests + def __repr__(self): + auth_info = [] + if (self.api_key is None) and (self.http_client.auth is None): + auth_info.append("(unauthenticated)") + else: + auth_info.append("authenticated") + identities = self.whoami()["identities"] + if identities: + auth_info.append("as") + auth_info.append( + ",".join(f"'{identity['id']}'" for identity in identities) + ) + if self.api_key is not None: + auth_info.append(f"with API key '{self.api_key[:8]}...'") + auth_repr = " ".join(auth_info) + return f"<{type(self).__name__} {auth_repr}>" + def __enter__(self): return self From 01a4db45d1c5bab31b4cf2ca83f332cefc6e0f66 Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Thu, 16 May 2024 17:27:27 -0400 Subject: [PATCH 2/6] Add CHANGELOG entry. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbad59cc3..48796f2c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Write the date in place of the "Unreleased" in the case a new version is release that the data in it can be read. - Added `tiled.client.sync` with a utility for copying nodes between two Tiled instances. +- Show authentication state in `Context` repr. ### Changed From 13e38f00e54583c693985ab48c38579ffbcab8e9 Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Fri, 17 May 2024 09:12:50 -0400 Subject: [PATCH 3/6] Handle case of short manually set single-user API keys Co-authored-by: Padraic Shafer <76011594+padraic-shafer@users.noreply.github.com> --- tiled/client/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tiled/client/context.py b/tiled/client/context.py index 840f97cde..bf667f662 100644 --- a/tiled/client/context.py +++ b/tiled/client/context.py @@ -172,7 +172,7 @@ def __repr__(self): ",".join(f"'{identity['id']}'" for identity in identities) ) if self.api_key is not None: - auth_info.append(f"with API key '{self.api_key[:8]}...'") + auth_info.append(f"with API key '{self.api_key[:min(len(self.api_key)//2, 8)]}...'") auth_repr = " ".join(auth_info) return f"<{type(self).__name__} {auth_repr}>" From b07061322f3640248c197061fbe04ba6b9f0dce8 Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Fri, 17 May 2024 09:19:55 -0400 Subject: [PATCH 4/6] Fix single-user server conditional --- tiled/client/context.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tiled/client/context.py b/tiled/client/context.py index bf667f662..0241fc279 100644 --- a/tiled/client/context.py +++ b/tiled/client/context.py @@ -165,11 +165,11 @@ def __repr__(self): auth_info.append("(unauthenticated)") else: auth_info.append("authenticated") - identities = self.whoami()["identities"] - if identities: + if self.server_info["authentication"].get("links"): + whoami = self.whoami() auth_info.append("as") auth_info.append( - ",".join(f"'{identity['id']}'" for identity in identities) + ",".join(f"'{identity['id']}'" for identity in whoami["identities"]) ) if self.api_key is not None: auth_info.append(f"with API key '{self.api_key[:min(len(self.api_key)//2, 8)]}...'") From 94c07dd0b9b09ccf603f97a3db5c5872b290bf3f Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Fri, 17 May 2024 09:20:09 -0400 Subject: [PATCH 5/6] Test Context repr --- tiled/_tests/test_authentication.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tiled/_tests/test_authentication.py b/tiled/_tests/test_authentication.py index 8d7a61d1f..5ad3fd3a1 100644 --- a/tiled/_tests/test_authentication.py +++ b/tiled/_tests/test_authentication.py @@ -77,11 +77,14 @@ def test_password_auth(enter_password, config): from_context(context, username="alice") # Reuse token from cache. client = from_context(context, username="alice") + assert "authenticated as 'alice'" in repr(client.context) client.logout() + assert "unauthenticated" in repr(client.context) # Log in as Bob. with enter_password("secret2"): client = from_context(context, username="bob") + assert "authenticated as 'bob'" in repr(client.context) client.logout() # Bob's password should not work for Alice. @@ -333,6 +336,10 @@ def test_api_key_activity(enter_password, config): context.logout() assert key_info["latest_activity"] is None # never used context.api_key = key_info["secret"] + assert "authenticated as 'alice'" in repr(context) + assert "with API key" in repr(context) + assert key_info["secret"][:8] in repr(context) + assert key_info["secret"][8:] not in repr(context) # Use the key for a couple requests and see that latest_activity becomes set and then increases. client = from_context(context) From 4c377c8a66eabd7f98b990061d941e6320ab3cda Mon Sep 17 00:00:00 2001 From: Dan Allan Date: Fri, 17 May 2024 09:42:12 -0400 Subject: [PATCH 6/6] whitespace --- tiled/client/context.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tiled/client/context.py b/tiled/client/context.py index 0241fc279..a5ae197d9 100644 --- a/tiled/client/context.py +++ b/tiled/client/context.py @@ -172,7 +172,9 @@ def __repr__(self): ",".join(f"'{identity['id']}'" for identity in whoami["identities"]) ) if self.api_key is not None: - auth_info.append(f"with API key '{self.api_key[:min(len(self.api_key)//2, 8)]}...'") + auth_info.append( + f"with API key '{self.api_key[:min(len(self.api_key)//2, 8)]}...'" + ) auth_repr = " ".join(auth_info) return f"<{type(self).__name__} {auth_repr}>"