pib_client/
authenticated_client.rs1use bytes::Bytes;
7use http::{HeaderValue, Method, Request, Response, header::AUTHORIZATION};
8use http_request_derive::{Error, HttpRequest};
9use url::Url;
10
11use crate::{Authorization, IsAuthenticated};
12
13#[derive(Debug)]
15pub struct AuthenticatedClient<C, A> {
16 inner: C,
17 authorization: A,
18}
19
20impl<C, A> AuthenticatedClient<C, A> {
21 pub fn new(inner: C, authorization: A) -> Self {
23 Self {
24 inner,
25 authorization,
26 }
27 }
28}
29
30impl<C: Clone, A: Clone> Clone for AuthenticatedClient<C, A> {
31 fn clone(&self) -> Self {
32 Self {
33 inner: self.inner.clone(),
34 authorization: self.authorization.clone(),
35 }
36 }
37}
38
39impl<C, A> IsAuthenticated for AuthenticatedClient<C, A> {
40 fn is_authenticated(&self) -> bool {
41 true
42 }
43}
44
45#[async_trait::async_trait(?Send)]
46impl<C: http_request_derive_client::Client, A: Authorization + Sync>
47 http_request_derive_client::Client for AuthenticatedClient<C, A>
48{
49 type ClientError = C::ClientError;
51
52 async fn execute<R: HttpRequest + Send>(
54 &self,
55 request: R,
56 ) -> Result<R::Response, Self::ClientError> {
57 let bearer_token = self.authorization.get_access_token().await.unwrap();
58
59 let request = AuthenticatedRequest {
60 request,
61 bearer_token,
62 };
63 self.inner.execute(request).await
64 }
65}
66
67struct AuthenticatedRequest<R> {
68 request: R,
69 bearer_token: String,
70}
71
72impl<R: HttpRequest> HttpRequest for AuthenticatedRequest<R> {
73 type Response = R::Response;
74 type Query = R::Query;
75 type Body = R::Body;
76
77 const METHOD: Method = R::METHOD;
78
79 fn path(&self) -> String {
80 self.request.path()
81 }
82
83 fn query(&self) -> Option<&Self::Query> {
84 self.request.query()
85 }
86
87 fn body(&self) -> Option<&Self::Body> {
88 self.request.body()
89 }
90
91 fn to_http_request(&self, base_url: &Url) -> Result<Request<Vec<u8>>, Error> {
92 let mut request = self.request.to_http_request(base_url)?;
93 _ = request.headers_mut().insert(
94 AUTHORIZATION,
95 HeaderValue::from_str(&format!("Bearer {}", self.bearer_token)).unwrap(),
96 );
97 Ok(request)
98 }
99
100 fn read_response(response: Response<Bytes>) -> Result<Self::Response, Error> {
101 R::read_response(response)
102 }
103}