osauth/basic.rs
1// Copyright 2020 Dmitry Tantsur <dtantsur@protonmail.com>
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! HTTP basic authentication.
16
17use async_trait::async_trait;
18use reqwest::{Client, RequestBuilder, Url};
19use static_assertions::assert_impl_all;
20
21use super::{AuthType, EndpointFilters, Error, ErrorKind};
22
23/// Authentication type that uses HTTP basic authentication.
24///
25/// This type always uses a pre-defined endpoint:
26/// ```rust,no_run
27/// let auth = osauth::BasicAuth::new("https://cloud.local/baremetal",
28/// "username", "password")
29/// .expect("Invalid endpoint URL");
30/// let session = osauth::Session::new(auth);
31/// ```
32#[derive(Clone, Debug)]
33pub struct BasicAuth {
34 endpoint: Url,
35 username: String,
36 password: String,
37}
38
39assert_impl_all!(BasicAuth: Send, Sync);
40
41impl BasicAuth {
42 /// Create a new HTTP basic authentication method using a fixed endpoint.
43 ///
44 /// This endpoint will be returned in response to all `get_endpoint` calls
45 /// of the [AuthType](trait.AuthType.html) trait.
46 pub fn new<U, S1, S2>(endpoint: U, username: S1, password: S2) -> Result<BasicAuth, Error>
47 where
48 U: AsRef<str>,
49 S1: Into<String>,
50 S2: Into<String>,
51 {
52 let endpoint = Url::parse(endpoint.as_ref())
53 .map_err(|e| Error::new(ErrorKind::InvalidInput, e.to_string()))?;
54 Ok(BasicAuth {
55 endpoint,
56 username: username.into(),
57 password: password.into(),
58 })
59 }
60}
61
62#[async_trait]
63impl AuthType for BasicAuth {
64 /// Authenticate a request.
65 async fn authenticate(
66 &self,
67 _client: &Client,
68 request: RequestBuilder,
69 ) -> Result<RequestBuilder, Error> {
70 Ok(request.basic_auth(&self.username, Some(&self.password)))
71 }
72
73 /// Get a predefined endpoint for all service types
74 async fn get_endpoint(
75 &self,
76 _client: &Client,
77 _service_type: &str,
78 _filters: &EndpointFilters,
79 ) -> Result<Url, Error> {
80 Ok(self.endpoint.clone())
81 }
82
83 /// This call does nothing for `BasicAuth`.
84 async fn refresh(&self, _client: &Client) -> Result<(), Error> {
85 Ok(())
86 }
87}