Unreleased changes are documented in files in the changelog.d directory.
Remove the
globus_action_provider_tools.flask.api_helpers
module, and the helpers it provided.If possible, it is recommended to immediately migrate Action Providers off of the code in the Flask API helpers module.
If this cannot be done immediately, it is recommended to pin the Action Provider Tools dependency to
0.19.1
.
The
required_authorizer_expiration_time
parameter toget_authorizer_for_scope
is deprecated.Given token expiration and caching lifetimes, it was not possible for this parameter to have any effect based on its prior documented usage.
- Action Provider Tools no longer requests Dependent Refresh Tokens if Access Tokens are sufficient. As a result of this fix, the AuthState dependent token cache will never contain dependent refresh tokens.
AuthState.introspect_token()
will no longer returnNone
if the token is not active.Instead, a new exception,
InactiveTokenError
, will be raised.InactiveTokenError
is a subclass ofValueError
.Code that calls
AuthState.introspect_token()
no longer returnsNone
, either, but will instead raiseValueError
(or a subclass) or aglobus_sdk.GlobusAPIError
:AuthState.get_authorizer_for_scope
AuthState.effective_identity
AuthState.identities
Group caching behavior in the
AuthState
class has been improved to ensure that the cache is checked before any external operations (e.g., dependent token callouts) are required. The cache now uses the token hash as its key, rather than a dependent token.
- Remove examples from documentation which relied upon the
api_helpers
module.
Introduce new scriv categories to better communicate how the project evolves.
The categories are also re-ordered, which defines how fragments will be ordered in the CHANGELOG.
Add a changelog fragment template.
When introspecting tokens, allow the introspected scopes to be a superset of required scopes.
A bug in the scope comparison code flipped the logic; if a user consented to scopes A and B and the action provider required only scope A, the comparison would fail as if A and B were required but only A had been consented to.
This is now fixed.
YANKED
- The token introspect checking and caching performed in
AuthState
has been improved.- The cache is keyed off of token hashes, rather than raw token strings.
- The
exp
andnbf
values are no longer verified, removing the possibility of incorrect treatment of valid tokens as invalid due to clock drift. - Introspect response caching caches the raw response even for invalid tokens, meaning that Action Providers will no longer repeatedly introspect a token once it is known to be invalid.
- Scope validation raises a new, dedicated error class,
globus_action_provider_tools.authentication.InvalidTokenScopesError
, on failure.
- The
TokenChecker
class has been removed and replaced in all cases with anAuthStateBuilder
which better matches the purpose of this class. - The
check_token
flask-specific helper has been replaced with aFlaskAuthStateBuilder
which subclassesAuthStateBuilder
and specializes it to handle aflask.Request
object. - The
aud
field of token introspect responses is no longer validated and fields associated with it have been removed. This includes changes to function and class initializer signatures.- The
expected_audience
field is no longer supported inAuthState
andTokenChecker
. It has been removed from the initializers for these classes. globus_auth_client_name
has been removed fromActionProviderBlueprint
.client_name
has been removed fromadd_action_routes_to_blueprint
.
- The
- Move to src/ tree layout
- Refactor
AuthState.get_authorizer_for_scope
without changing its primary outward semantics. Thebypass_dependent_token_cache
argument has been removed from its interface, as it is not necessary to expose with the improved implementation.
globus_action_provider_tools.testing
has been removed. Users who were relying on these components should make use of their own fixtures and mocks.
- Added a new configuration class
ActionProviderConfig
with the initial option toscrub_validation_errors
(default: True).- If disabled, user-provided data may be included in library raised validation errors.
Use UUIDs as action IDs.
Scrubbed and non-scrubbed jsonschema errors have been enhanced. They now follow the format
Field '<jsonpath>' (category: '<error_category>'): Input failed schema validation
Sample:
Field 'data.attributes.name' (category: 'required'): Input failed schema validation
Pydantic errors will similarly include a category in their error messages.
- Remove
pybase62
as a project dependency.
Allow package consumers to run with Python optimizations enabled.
This is supported by replacing
assert
statements withraise AssertionError
.
- Remove references to web browsers from HTTP 401 Unauthorized responses.
- Reduce I/O with Globus Auth when possible.
- If the action provider is visible to
"public"
, introspection requests are allowed without checking tokens. - If the bearer token is missing, malformed, or is too short or long, the incoming request is summarily rejected with HTTP 401 without introspecting the token.
- If the action provider is visible to
- Support CORS requests to introspection routes.
Prevent
TypeError
s from occurring during pydantic error formatting.This was caused by integer list indexes in pydantic error locations.
- Fix failing documentation builds (locally, and in Read the Docs).
- Enforce reproducible documentation builds using full dependency locking.
- Bump the OpenAPI documentation version and build the documentation.
- Test documentation builds in GitHub CI.
- Update
make install
so it can get developers up and running. - Document that
make install
can get developers up and running.
- Manage test, mypy, and doc dependencies using a consistent framework.
- Introduce a standard command,
tox run -m update
, that can update dependencies.
- Groups were not being properly considered in authorization checks.
- Error descriptions in responses are now always strings (previously they could also be lists of strings or lists of dictionaries).
- Input validation errors now use an HTTP response status code of 422.
- Validation errors no longer return input data in their description.
- Change the way that dependent token caching computes cache keys to improve upstream cache busting
- Added a CloudWatchEMFLogger
RequestLifecycleHook
class. When attached to anActionProviderBlueprint
, it will emit request count, latency, and response category (2xxs, 4xxs, 5xxs) count metrics through CloudWatch EMF. Metrics are emitted both for the aggregate AP dimension set and the individual route dimension set.- Classes may be provided at Blueprint instantiation time to register before, after, and/or teardown functionality wrapping route invocation.
- Support Python 3.12.
- Drop support for Python 3.7.
- Remove unused dependencies.
- Raise the minimum Flask version to 2.3.0, which dropped support for Python 3.7.
- The minimum pyyaml version is now 6.0
- Imports from
globus_action_provider_tools.flask
will no longer emit aDeprecationWarning
During local testing, build a shared wheel.
Previously, a shared
.tar.gz
file was created. However, in each tox environment, pip would convert this to a wheel during installation.This change decreases local test times from ~20 seconds to ~12 seconds.
Support running tox test environments in parallel (run
tox p
).This change decreases local test times to only ~3 seconds.
Overhaul CI.
Introduce caching of the
.tox/
and.venv/
directories.The cache is invalidated once each week (
date %U
rolls the week on Sundays).Build a shared wheel once as an artifact and reuse it across all test environments.
Consolidate standard testing and testing of minimum Flask versions.
- Remove an unused parameter from
TokenChecker
:cache_config
. - Remove a no-op call to Globus Auth during
TokenChecker
instantiation. - Remove the
ConfigurationError
class.
- Add support for Python 3.11.
- Drop support for Python 3.6.
Fix a crash that will occur if a non-object JSON document is submitted. For example, this will happen if the incoming JSON document is
"string"
or["array"]
.Fix a crash that occurs when an HTTP 400 "invalid grant" error is received from Globus Auth while getting an authorizer for a given scope.
This is now caught by
AuthState.get_authorizer_for_scope()
andNone
is returned.
Remove the
__version__
attribute.The
importlib.metadata
module in Python 3.8 and higher (or the backportedimportlib_metadata
package) can be used to query the version of installed packages if needed.jsonschema>=4.17,<5
is now required by action-provider-tools.Consumers of the library will have to update to a more recent version of
jsonschema
if they are using it explicitly.
No changes from 0.12.0b1.
- Upgrade to use major version 3 of the Globus SDK. If you are using Action Provider Tools in an environment which is currently using an earlier version of the Globus SDK, then you will need to upgrade first in order for this version to be compatible.
- Fixes an issue where the ActionProviderBlueprint decorators were not returning the decorated functions. This meant that the registered functions were loaded onto the Action Provider correctly but were None in the module in which they were defined.
- Add a CHANGELOG and include it in the documentation.
- Use scriv for CHANGELOG management.
- Improved logging around the authentication module's cache hits and misses.
- Fixed handling of missing refresh tokens in dependent token grants. Now, even if a refresh token is expected in a dependent grant, it falls back to just using the access token up until the time the access token expires. We also shorten the dependent token grant cache to be less than the expected lifetime of an access token and, thus, from cache, we should not retrieve an access token which is already expired.
- Adds caching to the following Globus Auth operations: token introspection, group membership, dependent token grants.
- Adds documentation around the new caching behavior: https://action-provider-tools.readthedocs.io/en/latest/toolkit/caching.html
- Bumps globus-sdk version dependency.
- Logs authentication errors when a token fails introspection or token validation.
- Updates pydantic version to address CVE-2021-29510
- Allows the detail field to be a string.
- Improves logging output in the case where there is an Action Provider throws Exceptions or an authentication issue.
- Allows for environment variable configuration.
- Bundles Flask an an optional dependency. See the README.md for information on installing the toolkit with Flask.
- Stabilizes package API.
- Updates serialization to output timezone aware datatime objects
- Updates the return type for Action Resume operations to allow for status codes to be returned from the route.
- Cleanly separates the Flask HTTP components from the plain Python components.
- The Flask Callback Loader Helper is now deprecated in favor of the Flask Blueprint Helper.
- Provide helpers to standardize output formats for INACTIVE and FAILED states
- Adds a new resume operation to the helpers which is used to signal that an INACTIVE Action may be resumed.
- Adds exceptions that can be raised from Flask views to return standardized JSON responses.
- Adds support for Action Provider schema definitions based on Pydantic.
- Migrates ActionStatus, ActionRequest, and ActionProviderDescription to Pydantic classes.
- Modifies ActionProvider introspection endpoint creation on the ActionProviderBlueprint so that HTTP requests with and without trailing slashes receive the same results.
- Action Provider Pydantic classes: https://action-provider-tools.readthedocs.io/en/latest/toolkit/validation.html
- Action Provider Pydantic input schema support: https://action-provider-tools.readthedocs.io/en/latest/examples/input_schemas.html#pydantic
- Improves testing tools for isolating tests between different instances of ActionProviderBlueprints and the Flask helpers.
- Adds a shared patch to the testing library to mock out an ActionProviderBlueprints TokenChecker
- Users can now specify a Globus Auth Client Name (legacy) when creating an instance of the ActionProviderBlueprint
- Users can now specify multiple acceptable scopes when creating an instance of the ActionProviderBlueprint
- Fixes an issue in the ActionProviderBlueprint where registering multiple Blueprints on a Flask app would only register one set of routes