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