diff --git a/CHANGELOG.md b/CHANGELOG.md index 316c1036d..515183696 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 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) diff --git a/tiled/client/context.py b/tiled/client/context.py index e907efee0..a5ae197d9 100644 --- a/tiled/client/context.py +++ b/tiled/client/context.py @@ -159,6 +159,25 @@ 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") + if self.server_info["authentication"].get("links"): + whoami = self.whoami() + auth_info.append("as") + auth_info.append( + ",".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_repr = " ".join(auth_info) + return f"<{type(self).__name__} {auth_repr}>" + def __enter__(self): return self