gets and saves keys!!

This commit is contained in:
Alex Janka 2024-02-12 11:51:50 +11:00
parent 48731f99eb
commit aeb13a83bc
4 changed files with 773 additions and 26 deletions

709
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
[package] [package]
name = "tesla-auth-callback-watcher" name = "tesla-auth-callback-watcher"
version = "0.2.2" version = "0.2.3"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,3 +13,8 @@ rand = "0.8"
lazy_static = "1.4" lazy_static = "1.4"
reqwest = "0.11" reqwest = "0.11"
alex-utils = { git = "https://git.alexjanka.com/alex/alex-utils" } alex-utils = { git = "https://git.alexjanka.com/alex/alex-utils" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
tesla-common = { git = "https://git.alexjanka.com/alex/tesla-common" }
chrono = "0.4"

View file

@ -1,7 +1,7 @@
# Maintainer: Alex Janka <alex@alexjanka.com> # Maintainer: Alex Janka <alex@alexjanka.com>
pkgname=tesla-auth-callback-watcher pkgname=tesla-auth-callback-watcher
pkgver=0.2.2 pkgver=0.2.3
pkgrel=1 pkgrel=1
pkgdesc="server for tesla auth callbacks" pkgdesc="server for tesla auth callbacks"
arch=('x86_64' 'aarch64') arch=('x86_64' 'aarch64')

View file

@ -1,3 +1,5 @@
use std::{path::PathBuf, str::FromStr};
use alex_utils::PrintErrors; use alex_utils::PrintErrors;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use rand::Rng; use rand::Rng;
@ -6,6 +8,9 @@ use rocket::{
request::Request, request::Request,
response::{Redirect, Responder}, response::{Redirect, Responder},
}; };
use serde::Deserialize;
use tesla_common::AuthInfo;
use thiserror::Error;
#[macro_use] #[macro_use]
extern crate rocket; extern crate rocket;
@ -36,19 +41,20 @@ struct Secrets {
impl Secrets { impl Secrets {
fn load() -> Option<Self> { fn load() -> Option<Self> {
let secrets = Self { Some(Self {
client_id: std::env::var("CLIENT_ID").ok()?, client_id: std::env::var("CLIENT_ID").ok()?,
client_secret: std::env::var("CLIENT_SECRET").ok()?, client_secret: std::env::var("CLIENT_SECRET").ok()?,
audience: std::env::var("AUDIENCE").ok()?, audience: std::env::var("AUDIENCE").ok()?,
redirect_uri: std::env::var("REDIRECT_URI").ok()?, redirect_uri: std::env::var("REDIRECT_URI").ok()?,
}; })
log::warn!("got secrets: {secrets:#?}");
Some(secrets)
} }
} }
lazy_static! { lazy_static! {
static ref SECRETS: Option<Secrets> = Secrets::load(); static ref SECRETS: Option<Secrets> = Secrets::load();
static ref KEY_DIR: Option<PathBuf> = std::env::var("TESLA_KEY_DIR")
.ok()
.and_then(|v| PathBuf::from_str(v.as_str()).ok());
} }
#[get("/authenticated?<locale>&<code>&<state>&<issuer>")] #[get("/authenticated?<locale>&<code>&<state>&<issuer>")]
@ -70,6 +76,50 @@ async fn authenticated(
} }
} }
#[derive(Deserialize, Debug)]
#[allow(unused)]
struct TeslaError {
error: String,
error_description: String,
#[serde(rename = "referenceID")]
reference_id: String,
}
#[derive(Debug, Error)]
enum AuthKeyError {
#[error("Error returned from Tesla")]
TeslaError(TeslaError),
#[error("Error deserialising json")]
SerdeError(#[from] serde_json::Error),
}
#[derive(Deserialize, Debug)]
#[allow(unused)]
struct AuthKeySuccess {
access_token: String,
refresh_token: String,
id_token: String,
expires_in: usize,
state: String,
token_type: String,
}
impl AuthKeySuccess {
fn get_keys(&self) -> AuthInfo {
AuthInfo {
access_token: tesla_common::AccessToken(self.access_token.clone()),
refresh_token: Some(tesla_common::RefreshToken(self.refresh_token.clone())),
}
}
}
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum AuthKeyResponse {
Ok(AuthKeySuccess),
Error(TeslaError),
}
async fn register_auth_key(code: String) -> Result<(), reqwest::Error> { async fn register_auth_key(code: String) -> Result<(), reqwest::Error> {
if let Some(secrets) = SECRETS.as_ref() { if let Some(secrets) = SECRETS.as_ref() {
let mut headers = header::HeaderMap::new(); let mut headers = header::HeaderMap::new();
@ -104,13 +154,34 @@ async fn register_auth_key(code: String) -> Result<(), reqwest::Error> {
.await? .await?
.text() .text()
.await?; .await?;
log::error!("auth response from tesla: {}", res); let d = match serde_json::from_str(&res) {
Ok(AuthKeyResponse::Ok(v)) => Ok(v),
Ok(AuthKeyResponse::Error(e)) => Err(AuthKeyError::TeslaError(e)),
Err(e) => Err(AuthKeyError::SerdeError(e)),
};
match d {
Ok(keys) => save_auth(keys),
Err(e) => log::error!("error registering keys: {e:?}"),
}
} else { } else {
log::error!("secrets not found - not registering code!!! code is {code}"); log::error!("secrets not found - not registering code!!! code is {code}");
} }
Ok(()) Ok(())
} }
fn save_auth(keys: AuthKeySuccess) {
let auth_info = keys.get_keys();
let filename = KEY_DIR
.as_ref()
.map(|v| v.join(chrono::Local::now().to_rfc3339()));
match auth_info.save(filename.as_deref()) {
Ok(Some(v)) => log::warn!("could not save keys! keys: {v:?}"),
Ok(None) => {}
Err(e) => log::error!("error saving keys: {e:?}"),
}
}
#[get("/deauthenticated/<_..>")] #[get("/deauthenticated/<_..>")]
fn deauthenticated(uri: &rocket::http::uri::Origin) -> &'static str { fn deauthenticated(uri: &rocket::http::uri::Origin) -> &'static str {
log::error!("DEAUTHENTICATED: {uri:?}"); log::error!("DEAUTHENTICATED: {uri:?}");