aws_smithy_runtime_api/client/identity/
http.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! Identity types for HTTP auth
7
8use crate::client::identity::{Identity, IdentityFuture, ResolveIdentity};
9use crate::client::runtime_components::RuntimeComponents;
10use aws_smithy_types::config_bag::ConfigBag;
11use std::fmt::Debug;
12use std::sync::Arc;
13use std::time::SystemTime;
14use zeroize::Zeroizing;
15
16/// Identity type required to sign requests using Smithy's token-based HTTP auth schemes
17///
18/// This `Token` type is used with Smithy's `@httpApiKeyAuth` and `@httpBearerAuth`
19/// auth traits.
20#[derive(Clone, Eq, PartialEq)]
21pub struct Token(Arc<TokenInner>);
22
23#[derive(Eq, PartialEq)]
24struct TokenInner {
25    token: Zeroizing<String>,
26    expiration: Option<SystemTime>,
27}
28
29impl Debug for Token {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        f.debug_struct("Token")
32            .field("token", &"** redacted **")
33            .finish()
34    }
35}
36
37impl Token {
38    /// Constructs a new identity token for HTTP auth.
39    pub fn new(token: impl Into<String>, expiration: Option<SystemTime>) -> Self {
40        Self(Arc::new(TokenInner {
41            token: Zeroizing::new(token.into()),
42            expiration,
43        }))
44    }
45
46    /// Returns the underlying identity token.
47    pub fn token(&self) -> &str {
48        &self.0.token
49    }
50
51    /// Returns the expiration time (if any) for this token.
52    pub fn expiration(&self) -> Option<SystemTime> {
53        self.0.expiration
54    }
55
56    /// Creates a `Token` for tests.
57    #[cfg(feature = "test-util")]
58    pub fn for_tests() -> Self {
59        Self::new("test-token", None)
60    }
61}
62
63impl From<&str> for Token {
64    fn from(token: &str) -> Self {
65        Self::from(token.to_owned())
66    }
67}
68
69impl From<String> for Token {
70    fn from(api_key: String) -> Self {
71        Self(Arc::new(TokenInner {
72            token: Zeroizing::new(api_key),
73            expiration: None,
74        }))
75    }
76}
77
78impl ResolveIdentity for Token {
79    fn resolve_identity<'a>(
80        &'a self,
81        _runtime_components: &'a RuntimeComponents,
82        _config_bag: &'a ConfigBag,
83    ) -> IdentityFuture<'a> {
84        IdentityFuture::ready(Ok(self.into()))
85    }
86}
87
88impl From<&Token> for Identity {
89    fn from(value: &Token) -> Self {
90        Identity::new(value.clone(), value.0.expiration)
91    }
92}
93impl From<Token> for Identity {
94    fn from(value: Token) -> Self {
95        let expiration = value.0.expiration;
96        Identity::new(value, expiration)
97    }
98}
99
100/// Identity type required to sign requests using Smithy's login-based HTTP auth schemes
101///
102/// This `Login` type is used with Smithy's `@httpBasicAuth` and `@httpDigestAuth`
103/// auth traits.
104#[derive(Clone, Eq, PartialEq)]
105pub struct Login(Arc<LoginInner>);
106
107#[derive(Eq, PartialEq)]
108struct LoginInner {
109    user: String,
110    password: Zeroizing<String>,
111    expiration: Option<SystemTime>,
112}
113
114impl Debug for Login {
115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116        f.debug_struct("Login")
117            .field("user", &self.0.user)
118            .field("password", &"** redacted **")
119            .finish()
120    }
121}
122
123impl Login {
124    /// Constructs a new identity login for HTTP auth.
125    pub fn new(
126        user: impl Into<String>,
127        password: impl Into<String>,
128        expiration: Option<SystemTime>,
129    ) -> Self {
130        Self(Arc::new(LoginInner {
131            user: user.into(),
132            password: Zeroizing::new(password.into()),
133            expiration,
134        }))
135    }
136
137    /// Returns the login user.
138    pub fn user(&self) -> &str {
139        &self.0.user
140    }
141
142    /// Returns the login password.
143    pub fn password(&self) -> &str {
144        &self.0.password
145    }
146
147    /// Returns the expiration time of this login (if any)
148    pub fn expiration(&self) -> Option<SystemTime> {
149        self.0.expiration
150    }
151}
152
153impl ResolveIdentity for Login {
154    fn resolve_identity<'a>(
155        &'a self,
156        _runtime_components: &'a RuntimeComponents,
157        _config_bag: &'a ConfigBag,
158    ) -> IdentityFuture<'a> {
159        IdentityFuture::ready(Ok(Identity::new(self.clone(), self.0.expiration)))
160    }
161}