feature: Serializable Credentials for auth
This commit is contained in:
parent
e405ef83f8
commit
050b9da48a
30
src/auth.rs
30
src/auth.rs
|
@ -17,6 +17,12 @@ pub struct AccessToken(pub String);
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, FromStr, Display)]
|
#[derive(Debug, Clone, Serialize, Deserialize, FromStr, Display)]
|
||||||
pub struct RefreshToken(pub String);
|
pub struct RefreshToken(pub String);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Credentials {
|
||||||
|
pub access_token: AccessToken,
|
||||||
|
pub refresh_token: Option<RefreshToken>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Api {
|
impl Api {
|
||||||
/// Currently the only way to "authenticate" to an access token for this library.
|
/// Currently the only way to "authenticate" to an access token for this library.
|
||||||
pub async fn from_interactive_url() -> Result<Api, TeslatteError> {
|
pub async fn from_interactive_url() -> Result<Api, TeslatteError> {
|
||||||
|
@ -39,6 +45,17 @@ impl Api {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_credentials(credentials: Credentials) -> Api {
|
||||||
|
Api::new(credentials.access_token, credentials.refresh_token)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn credentials(&self) -> Credentials {
|
||||||
|
Credentials {
|
||||||
|
access_token: self.access_token.clone(),
|
||||||
|
refresh_token: self.refresh_token.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_login_url_for_user() -> LoginForm {
|
pub async fn get_login_url_for_user() -> LoginForm {
|
||||||
let code = Code::new();
|
let code = Code::new();
|
||||||
let state = random_string(8);
|
let state = random_string(8);
|
||||||
|
@ -61,6 +78,19 @@ impl Api {
|
||||||
Self::auth_post(url, &payload).await
|
Self::auth_post(url, &payload).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Refresh the internally stored access token using the known refresh token.
|
||||||
|
pub async fn refresh(&mut self) -> Result<(), TeslatteError> {
|
||||||
|
match &self.refresh_token {
|
||||||
|
None => Err(TeslatteError::NoRefreshToken),
|
||||||
|
Some(refresh_token) => {
|
||||||
|
let response = Self::refresh_token(&refresh_token).await?;
|
||||||
|
self.access_token = response.access_token;
|
||||||
|
self.refresh_token = Some(response.refresh_token);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn refresh_token(
|
pub async fn refresh_token(
|
||||||
refresh_token: &RefreshToken,
|
refresh_token: &RefreshToken,
|
||||||
) -> Result<RefreshTokenResponse, TeslatteError> {
|
) -> Result<RefreshTokenResponse, TeslatteError> {
|
||||||
|
|
|
@ -38,4 +38,7 @@ pub enum TeslatteError {
|
||||||
|
|
||||||
#[error("Could not convert \"{0}\" to an EnergySiteId.")]
|
#[error("Could not convert \"{0}\" to an EnergySiteId.")]
|
||||||
DecodeEnergySiteIdError(String),
|
DecodeEnergySiteIdError(String),
|
||||||
|
|
||||||
|
#[error("No refresh token available.")]
|
||||||
|
NoRefreshToken,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue