feature: Serializable Credentials for auth

This commit is contained in:
gak 2022-07-25 14:17:49 +10:00
parent e405ef83f8
commit 050b9da48a
2 changed files with 33 additions and 0 deletions

View file

@ -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> {

View file

@ -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,
} }