Skip to content

Customer feature parity: no token fetch when matching serverless content permits usage#10

Merged
nick434434 merged 2 commits into
mainfrom
feat/customer-usage-serverless-content
Apr 29, 2026
Merged

Customer feature parity: no token fetch when matching serverless content permits usage#10
nick434434 merged 2 commits into
mainfrom
feat/customer-usage-serverless-content

Conversation

@nick434434

@nick434434 nick434434 commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds customer-side feature parity for “serverless usage grants” so callers can avoid fetching a license token when a matching <content> block (without server) explicitly permits the requested usage, while also improving caching behavior around license.xml and token reuse.

Changes:

  • Introduce UsageType and extend obtain_license_token(..., usage=...) to return None when a matching serverless usage grant allows the request.
  • Cache license.xml per origin (TTL) and cache license tokens by matched pattern + token server to reuse across matching URLs.
  • Update content parsing and tests to treat serverless <content> blocks as valid (for usage grants).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
connect/customer/token.py Adds usage-based serverless bypass, license.xml caching, and updates token cache keying.
connect/customer/content_parser.py Allows parsing <content> blocks without server and normalizes license_xml output.
connect/types.py Introduces UsageType enum.
connect/customer/__init__.py Re-exports UsageType alongside obtain_license_token.
connect/__init__.py Exposes UsageType at the package top-level API.
tests/customer/test_tokens.py Adds coverage for license.xml caching, token caching by matched pattern, and serverless usage-grant behavior.
tests/customer/test_content_parser.py Updates parsing expectations and adds serverless-content test.
tests/customer/conftest.py Clears the new license.xml cache between tests.
examples/obtain_and_verify_license_token.py Adds a runtime guard for obtain_license_token now returning None.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread connect/customer/token.py
Comment on lines +361 to 363
cache_key = (client_id, matched_content.server, matched_content.url_pattern)
cached = _get_cached_token(cache_key, debug)
if cached is not None:

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token cache key no longer includes the resource origin (it’s now keyed by client_id + token server + matched url_pattern). For path-only patterns like "/" or "/articles/", this can collide across different origins and return a token minted for a different license.xml/resource set. Consider including the resource origin (or a stable identifier like the license.xml URL / a hash of the matched license XML) in the cache key to prevent cross-origin token reuse.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something for us to take into account when we think of generalizing to not only Supertab Connect. Our server URL is already unique per website's base URL

Comment thread examples/obtain_and_verify_license_token.py
Comment thread connect/customer/token.py Outdated
if _local_name(element.tag) == "permits" and element.attrib.get("type") == "usage":
permitted_usages = " ".join(element.itertext()).split()
if UsageType.ALL in permitted_usages or usage_value in permitted_usages:
return True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: There is twice the same for loop. Do you think we can do it in one go?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see an immediate simplification (or complication, depends on how you look at it :P) yesterday so I considered this to be okay, but apparently it is possible!

@filias filias left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

@nick434434 nick434434 merged commit c0aa11b into main Apr 29, 2026
1 check passed
@nick434434 nick434434 deleted the feat/customer-usage-serverless-content branch April 29, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants