forked from boto/botocore
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Multi-auth trait support (boto#3233)
* Multiauth Adds support for the new multi-auth trait that will allow a service or operation to specify a list of compatible authentication types --------- Co-authored-by: Nate Prewitt <[email protected]>
- Loading branch information
Showing
14 changed files
with
286 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"type": "feature", | ||
"category": "signing", | ||
"description": "Adds internal support for the new 'auth' trait to allow a priority list of auth types for a service or operation." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). You | ||
# may not use this file except in compliance with the License. A copy of | ||
# the License is located at | ||
# | ||
# http://aws.amazon.com/apache2.0/ | ||
# | ||
# or in the "license" file accompanying this file. This file is | ||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF | ||
# ANY KIND, either express or implied. See the License for the specific | ||
# language governing permissions and limitations under the License. | ||
import pytest | ||
|
||
from botocore.session import get_session | ||
|
||
# In the future, a service may have a list of credentials requirements where one | ||
# signature may fail and others may succeed. e.g. a service may want to use bearer | ||
# auth but fall back to sigv4 if a token isn't available. There's currently no way to do | ||
# this in botocore, so this test ensures we handle this gracefully when the need arises. | ||
|
||
|
||
# The dictionary's value here needs to be hashable to be added to the set below; any | ||
# new auth types with multiple requirements should be added in a comma-separated list | ||
AUTH_TYPE_REQUIREMENTS = { | ||
'aws.auth#sigv4': 'credentials', | ||
'aws.auth#sigv4a': 'credentials', | ||
'smithy.api#httpBearerAuth': 'bearer_token', | ||
'smithy.api#noAuth': 'none', | ||
} | ||
|
||
|
||
def _all_test_cases(): | ||
session = get_session() | ||
loader = session.get_component('data_loader') | ||
|
||
services = loader.list_available_services('service-2') | ||
auth_services = [] | ||
auth_operations = [] | ||
|
||
for service in services: | ||
service_model = session.get_service_model(service) | ||
auth_config = service_model.metadata.get('auth', {}) | ||
if auth_config: | ||
auth_services.append([service, auth_config]) | ||
for operation in service_model.operation_names: | ||
operation_model = service_model.operation_model(operation) | ||
if operation_model.auth: | ||
auth_operations.append([service, operation_model]) | ||
return auth_services, auth_operations | ||
|
||
|
||
AUTH_SERVICES, AUTH_OPERATIONS = _all_test_cases() | ||
|
||
|
||
@pytest.mark.validates_models | ||
@pytest.mark.parametrize("auth_service, auth_config", AUTH_SERVICES) | ||
def test_all_requirements_match_for_service(auth_service, auth_config): | ||
# Validates that all service-level signature types have the same requirements | ||
message = f'Found mixed signer requirements for service: {auth_service}' | ||
assert_all_requirements_match(auth_config, message) | ||
|
||
|
||
@pytest.mark.validates_models | ||
@pytest.mark.parametrize("auth_service, operation_model", AUTH_OPERATIONS) | ||
def test_all_requirements_match_for_operation(auth_service, operation_model): | ||
# Validates that all operation-level signature types have the same requirements | ||
message = f'Found mixed signer requirements for operation: {auth_service}.{operation_model.name}' | ||
auth_config = operation_model.auth | ||
assert_all_requirements_match(auth_config, message) | ||
|
||
|
||
def assert_all_requirements_match(auth_config, message): | ||
auth_requirements = set( | ||
AUTH_TYPE_REQUIREMENTS[auth_type] for auth_type in auth_config | ||
) | ||
assert len(auth_requirements) == 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). You | ||
# may not use this file except in compliance with the License. A copy of | ||
# the License is located at | ||
# | ||
# http://aws.amazon.com/apache2.0/ | ||
# | ||
# or in the "license" file accompanying this file. This file is | ||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF | ||
# ANY KIND, either express or implied. See the License for the specific | ||
# language governing permissions and limitations under the License. | ||
|
||
from botocore.auth import BaseSigner, resolve_auth_type | ||
from botocore.exceptions import ( | ||
UnknownSignatureVersionError, | ||
UnsupportedSignatureVersionError, | ||
) | ||
from tests import mock, unittest | ||
|
||
|
||
class TestAuthTraitResolution(unittest.TestCase): | ||
def test_auth_resolves_first_available(self): | ||
auth = ['aws.auth#foo', 'aws.auth#bar'] | ||
# Don't declare a signer for "foo" | ||
auth_types = {'bar': mock.Mock(spec=BaseSigner)} | ||
auth_type_conversions = {'aws.auth#foo': 'foo', 'aws.auth#bar': 'bar'} | ||
|
||
with mock.patch('botocore.auth.AUTH_TYPE_MAPS', auth_types): | ||
with mock.patch( | ||
'botocore.auth.AUTH_TYPE_TO_SIGNATURE_VERSION', | ||
auth_type_conversions, | ||
): | ||
assert resolve_auth_type(auth) == 'bar' | ||
|
||
def test_invalid_auth_type_error(self): | ||
with self.assertRaises(UnknownSignatureVersionError): | ||
resolve_auth_type(['aws.auth#invalidAuth']) | ||
|
||
def test_no_known_auth_type(self): | ||
with self.assertRaises(UnsupportedSignatureVersionError): | ||
resolve_auth_type([]) |
Oops, something went wrong.