blob: 4693cc60ef31862be4f240c8fcfc7243ad0da4d9 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
//! This module provides low-level generated gRPC clients for the
//! Yandex Cloud APIs.
//!
//! The clients are generated using the [tonic][] and [prost][]
//! crates and have default configuration.
//!
//! Documentation present in the protos is retained into the generated
//! Rust types, but for detailed API information you should visit the
//! official Yandex Cloud Documentation pages:
//!
//! * [in English](https://cloud.yandex.com/en-ru/docs/overview/api)
//! * [in Russian](https://cloud.yandex.ru/docs/overview/api)
//!
//! The proto sources are available on the [Yandex Cloud GitHub][protos].
//!
//! [tonic]: https://docs.rs/tonic/latest/tonic/
//! [prost]: https://docs.rs/prost/latest/prost/
//! [protos]: https://github.com/yandex-cloud/cloudapi
//!
//! The majority of user-facing structures can be found in the
//! [`yandex::cloud`] module.
//!
//! ## Usage
//!
//! Typically to use these APIs, you need to provide an authentication
//! credential and an endpoint to connect to. The full list of
//! Yandex's endpoints is [available online][endpoints] and you should
//! look up the service you plan to use and pick the correct endpoint
//! from the list.
//!
//! Authentication is done via an HTTP header using an IAM token,
//! which can be done in Tonic using [interceptors][]. The
//! [`AuthInterceptor`] provided by this crate can be used for that
//! purpose.
//!
//! [endpoints]: https://cloud.yandex.com/en/docs/api-design-guide/concepts/endpoints
//! [interceptors]: https://docs.rs/tonic/latest/tonic/service/trait.Interceptor.html
use tonic::metadata::{Ascii, MetadataValue};
use tonic::service::Interceptor;
/// Helper trait for types or closures that can provide authentication
/// tokens for Yandex Cloud.
pub trait TokenProvider {
/// Fetch a currently valid authentication token for Yandex Cloud.
fn get_token<'a>(&'a mut self) -> &'a str;
}
impl TokenProvider for String {
fn get_token<'a>(&'a mut self) -> &'a str {
self.as_str()
}
}
impl TokenProvider for &'static str {
fn get_token(&mut self) -> &'static str {
*self
}
}
/// Interceptor for adding authentication headers to gRPC requests.
/// This is constructed with a callable that returns authentication
/// tokens.
///
/// This callable is responsible for ensuring that the returned tokens
/// are valid at the given time, i.e. it should take care of
/// refreshing and so on.
pub struct AuthInterceptor<T: TokenProvider> {
token_provider: T,
}
impl<T: TokenProvider> AuthInterceptor<T> {
pub fn new(token_provider: T) -> Self {
Self { token_provider }
}
}
impl<T: TokenProvider> Interceptor for AuthInterceptor<T> {
fn call(
&mut self,
mut request: tonic::Request<()>,
) -> Result<tonic::Request<()>, tonic::Status> {
let token: MetadataValue<Ascii> = format!("Bearer {}", self.token_provider.get_token())
.try_into()
.map_err(|_| {
tonic::Status::invalid_argument("authorization token contained invalid characters")
})?;
request.metadata_mut().insert("authorization", token);
Ok(request)
}
}
// The rest of this file is generated by the build script at ../build.rs.
include!("includes.rs");
|