1 1 | /*
|
2 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3 3 | * SPDX-License-Identifier: Apache-2.0
|
4 4 | */
|
5 5 |
|
6 6 | //! The [`NoAuthRuntimePlugin`] and supporting code.
|
7 7 |
|
8 8 | use crate::client::identity::no_auth::NoAuthIdentityResolver;
|
9 9 | use aws_smithy_runtime_api::box_error::BoxError;
|
10 + | use aws_smithy_runtime_api::client::auth::static_resolver::StaticAuthSchemeOptionResolver;
|
10 11 | use aws_smithy_runtime_api::client::auth::{
|
11 - | AuthScheme, AuthSchemeEndpointConfig, AuthSchemeId, SharedAuthScheme, Sign,
|
12 + | AuthScheme, AuthSchemeEndpointConfig, AuthSchemeId, AuthSchemeOption,
|
13 + | AuthSchemeOptionResolverParams, AuthSchemeOptionsFuture, ResolveAuthSchemeOptions,
|
14 + | SharedAuthScheme, SharedAuthSchemeOptionResolver, Sign,
|
12 15 | };
|
13 16 | use aws_smithy_runtime_api::client::identity::{Identity, SharedIdentityResolver};
|
14 17 | use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
|
15 18 | use aws_smithy_runtime_api::client::runtime_components::{
|
16 19 | GetIdentityResolver, RuntimeComponents, RuntimeComponentsBuilder,
|
17 20 | };
|
18 21 | use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
|
22 + | use aws_smithy_runtime_api::shared::IntoShared;
|
19 23 | use aws_smithy_types::config_bag::ConfigBag;
|
20 24 | use std::borrow::Cow;
|
21 25 |
|
22 26 | /// Auth scheme ID for "no auth".
|
23 27 | pub const NO_AUTH_SCHEME_ID: AuthSchemeId = AuthSchemeId::new("noAuth");
|
24 28 |
|
25 29 | /// A [`RuntimePlugin`] that registers a "no auth" identity resolver and auth scheme.
|
26 30 | ///
|
27 31 | /// This plugin can be used to disable authentication in certain cases, such as when there is
|
28 32 | /// a Smithy `@optionalAuth` trait.
|
33 + | ///
|
34 + | /// Note: This plugin does not work out of the box because it does not configure an auth scheme option resolver
|
35 + | /// that recognizes the `noAuth` scheme.
|
36 + | #[doc(hidden)]
|
29 37 | #[non_exhaustive]
|
30 38 | #[derive(Debug)]
|
39 + | #[deprecated(since = "1.9.5", note = "Use `NoAuthRuntimePluginV2` instead")]
|
31 40 | pub struct NoAuthRuntimePlugin(RuntimeComponentsBuilder);
|
32 41 |
|
42 + | #[allow(deprecated)]
|
33 43 | impl Default for NoAuthRuntimePlugin {
|
34 44 | fn default() -> Self {
|
35 45 | Self::new()
|
36 46 | }
|
37 47 | }
|
38 48 |
|
49 + | #[allow(deprecated)]
|
39 50 | impl NoAuthRuntimePlugin {
|
40 51 | /// Creates a new `NoAuthRuntimePlugin`.
|
41 52 | pub fn new() -> Self {
|
42 53 | Self(
|
43 54 | RuntimeComponentsBuilder::new("NoAuthRuntimePlugin")
|
44 55 | .with_identity_resolver(
|
45 56 | NO_AUTH_SCHEME_ID,
|
46 57 | SharedIdentityResolver::new(NoAuthIdentityResolver::new()),
|
47 58 | )
|
48 59 | .with_auth_scheme(SharedAuthScheme::new(NoAuthScheme::new())),
|
49 60 | )
|
50 61 | }
|
51 62 | }
|
52 63 |
|
64 + | #[allow(deprecated)]
|
53 65 | impl RuntimePlugin for NoAuthRuntimePlugin {
|
54 66 | fn runtime_components(
|
55 67 | &self,
|
56 68 | _: &RuntimeComponentsBuilder,
|
57 69 | ) -> Cow<'_, RuntimeComponentsBuilder> {
|
58 70 | Cow::Borrowed(&self.0)
|
59 71 | }
|
60 72 | }
|
61 73 |
|
74 + | /// A [`RuntimePlugin`] that registers a "no auth" identity resolver, auth scheme, and auth scheme option resolver.
|
75 + | ///
|
76 + | /// Ideally, a Smithy model should use `@optionalAuth` or `@auth([])` on operations so that:
|
77 + | /// - The Smithy runtime supports the no-auth scheme
|
78 + | /// - The code-generated default auth scheme option resolver includes the no-auth scheme for those operations
|
79 + | ///
|
80 + | /// When that is not possible, this plugin can be used to achieve the same effect.
|
81 + | #[derive(Debug)]
|
82 + | pub struct NoAuthRuntimePluginV2(RuntimeComponentsBuilder);
|
83 + |
|
84 + | impl Default for NoAuthRuntimePluginV2 {
|
85 + | fn default() -> Self {
|
86 + | Self::new()
|
87 + | }
|
88 + | }
|
89 + |
|
90 + | impl NoAuthRuntimePluginV2 {
|
91 + | /// Creates a new `NoAuthRuntimePluginV2`.
|
92 + | pub fn new() -> Self {
|
93 + | Self(
|
94 + | RuntimeComponentsBuilder::new("NoAuthRuntimePluginV2")
|
95 + | .with_identity_resolver(
|
96 + | NO_AUTH_SCHEME_ID,
|
97 + | SharedIdentityResolver::new(NoAuthIdentityResolver::new()),
|
98 + | )
|
99 + | .with_auth_scheme(SharedAuthScheme::new(NoAuthScheme::new())),
|
100 + | )
|
101 + | }
|
102 + | }
|
103 + |
|
104 + | impl RuntimePlugin for NoAuthRuntimePluginV2 {
|
105 + | fn runtime_components(
|
106 + | &self,
|
107 + | current_components: &RuntimeComponentsBuilder,
|
108 + | ) -> Cow<'_, RuntimeComponentsBuilder> {
|
109 + | // No auth scheme option resolver is configured here because it needs to access
|
110 + | // the existing resolver (likely the code-generated default) stored in the
|
111 + | // current runtime components builder.
|
112 + | let auth_scheme_option_resolver: SharedAuthSchemeOptionResolver =
|
113 + | match current_components.auth_scheme_option_resolver() {
|
114 + | Some(current_resolver) => {
|
115 + | NoAuthSchemeOptionResolver::new(current_resolver.clone()).into_shared()
|
116 + | }
|
117 + | None => StaticAuthSchemeOptionResolver::new(vec![NO_AUTH_SCHEME_ID]).into_shared(),
|
118 + | };
|
119 + | Cow::Owned(
|
120 + | self.0
|
121 + | .clone()
|
122 + | .with_auth_scheme_option_resolver(Some(auth_scheme_option_resolver)),
|
123 + | )
|
124 + | }
|
125 + | }
|
126 + |
|
127 + | #[derive(Debug)]
|
128 + | struct NoAuthSchemeOptionResolver<R> {
|
129 + | inner: R,
|
130 + | }
|
131 + |
|
132 + | impl<R> NoAuthSchemeOptionResolver<R> {
|
133 + | fn new(inner: R) -> Self {
|
134 + | Self { inner }
|
135 + | }
|
136 + | }
|
137 + |
|
138 + | impl<R> ResolveAuthSchemeOptions for NoAuthSchemeOptionResolver<R>
|
139 + | where
|
140 + | R: ResolveAuthSchemeOptions,
|
141 + | {
|
142 + | fn resolve_auth_scheme_options_v2<'a>(
|
143 + | &'a self,
|
144 + | params: &'a AuthSchemeOptionResolverParams,
|
145 + | cfg: &'a ConfigBag,
|
146 + | runtime_components: &'a RuntimeComponents,
|
147 + | ) -> AuthSchemeOptionsFuture<'a> {
|
148 + | let inner_future =
|
149 + | self.inner
|
150 + | .resolve_auth_scheme_options_v2(params, cfg, runtime_components);
|
151 + |
|
152 + | AuthSchemeOptionsFuture::new(async move {
|
153 + | let mut options = inner_future.await?;
|
154 + | options.push(AuthSchemeOption::from(NO_AUTH_SCHEME_ID));
|
155 + | Ok(options)
|
156 + | })
|
157 + | }
|
158 + | }
|
159 + |
|
62 160 | /// The "no auth" auth scheme.
|
63 161 | ///
|
64 162 | /// The orchestrator requires an auth scheme, so Smithy's `@optionalAuth` trait is implemented
|
65 163 | /// by placing a "no auth" auth scheme at the end of the auth scheme options list so that it is
|
66 164 | /// used if there's no identity resolver available for the other auth schemes. It's also used
|
67 165 | /// for models that don't have auth at all.
|
68 166 | #[derive(Debug, Default)]
|
69 167 | pub struct NoAuthScheme {
|
70 168 | signer: NoAuthSigner,
|
71 169 | }
|