impl auth
This commit is contained in:
parent
1e31d74904
commit
e47b29da21
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1668,6 +1668,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -17,3 +17,4 @@ reqwest = { version = "0.12.5", features = ["json"] }
|
|||||||
serde = { version = "1.0.204", features = ["derive"] }
|
serde = { version = "1.0.204", features = ["derive"] }
|
||||||
serde_json = "1.0.120"
|
serde_json = "1.0.120"
|
||||||
tokio = { version = "1.38.0", features = ["full"] }
|
tokio = { version = "1.38.0", features = ["full"] }
|
||||||
|
url = "2.5.2"
|
||||||
|
@ -79,7 +79,9 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_upload_token(&self) -> anyhow::Result<types::response::GetFileLinkTokenResponse> {
|
pub async fn get_upload_token(
|
||||||
|
&self,
|
||||||
|
) -> anyhow::Result<types::response::GetFileLinkTokenResponse> {
|
||||||
if self.last_refresh.read().await.elapsed().as_secs() > self.token_valid_time.into() {
|
if self.last_refresh.read().await.elapsed().as_secs() > self.token_valid_time.into() {
|
||||||
self.refresh_token().await?;
|
self.refresh_token().await?;
|
||||||
}
|
}
|
||||||
@ -162,12 +164,10 @@ impl Client {
|
|||||||
|
|
||||||
match serde_json::from_str(&text) {
|
match serde_json::from_str(&text) {
|
||||||
std::result::Result::Ok(json) => Ok(json),
|
std::result::Result::Ok(json) => Ok(json),
|
||||||
Err(err) => {
|
Err(err) => match serde_json::from_str::<types::response::SendyError>(&text) {
|
||||||
match serde_json::from_str::<types::response::SendyError>(&text) {
|
|
||||||
std::result::Result::Ok(json) => Err(anyhow::anyhow!("{:?}", json)),
|
std::result::Result::Ok(json) => Err(anyhow::anyhow!("{:?}", json)),
|
||||||
Err(_) => Err(anyhow::Error::new(err).context(text.trim().to_string())),
|
Err(_) => Err(anyhow::Error::new(err).context(text.trim().to_string())),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +302,39 @@ pub async fn refresh_token(
|
|||||||
// .map_err(Into::into)
|
// .map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn rid_token_auth(rid_code: &str) -> anyhow::Result<types::response::RIDTokenResponse> {
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let request = client
|
||||||
|
.get(format!("https://www.rakuten-drive.com/api/v1/auth/rd/custom/token?rid_code={}&is_extension=false", rid_code))
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let text = request.text().await?;
|
||||||
|
|
||||||
|
let json: types::response::RIDTokenResponse = serde_json::from_str(&text)?;
|
||||||
|
Ok(json)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_refresh_token(
|
||||||
|
token: &str,
|
||||||
|
) -> anyhow::Result<types::response::VerifyCustomTokenResponse> {
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let req = types::request::VerifyCustomTokenRequest {
|
||||||
|
token: token.to_string(),
|
||||||
|
return_secure_token: true,
|
||||||
|
};
|
||||||
|
let request = client
|
||||||
|
.post("https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=AIzaSyDyp5IGr4nXbYin_oduNGi6ci-AnWcuAYE")
|
||||||
|
.json(&req)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let text = request.text().await?;
|
||||||
|
|
||||||
|
let json: types::response::VerifyCustomTokenResponse = serde_json::from_str(&text)?;
|
||||||
|
Ok(json)
|
||||||
|
}
|
||||||
|
|
||||||
// https://www.rakuten-drive.com/api/account/refreshtoken POST RefreshTokenRequest RefreshTokenResponse
|
// https://www.rakuten-drive.com/api/account/refreshtoken POST RefreshTokenRequest RefreshTokenResponse
|
||||||
// https://forest.sendy.jp/cloud/service/file/v1/file POST FileDetailRequest FileDetailResponse
|
// https://forest.sendy.jp/cloud/service/file/v1/file POST FileDetailRequest FileDetailResponse
|
||||||
// https://forest.sendy.jp/cloud/service/file/v1/files POST ListFilesRequest ListFilesResponse
|
// https://forest.sendy.jp/cloud/service/file/v1/files POST ListFilesRequest ListFilesResponse
|
||||||
|
28
src/main.rs
28
src/main.rs
@ -106,6 +106,7 @@ enum Commands {
|
|||||||
},
|
},
|
||||||
#[clap(about = "Print file detail")]
|
#[clap(about = "Print file detail")]
|
||||||
Info { path: String },
|
Info { path: String },
|
||||||
|
Auth {},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@ -140,8 +141,8 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Commands::Mkdir { name, path } => {
|
Commands::Mkdir { name, path } => {
|
||||||
client.mkdir(name, path.as_deref()).await.unwrap();
|
client.mkdir(name, path.as_deref()).await.unwrap();
|
||||||
}
|
}
|
||||||
Commands::Copy { src: _, dest: _ } => {
|
Commands::Copy { src, dest } => {
|
||||||
todo!("Copy");
|
client.copy(src, dest).await.unwrap();
|
||||||
}
|
}
|
||||||
Commands::Rename { path, name } => {
|
Commands::Rename { path, name } => {
|
||||||
client.rename(path, name).await.unwrap();
|
client.rename(path, name).await.unwrap();
|
||||||
@ -149,6 +150,29 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Commands::Info { path } => {
|
Commands::Info { path } => {
|
||||||
client.info(path).await.unwrap();
|
client.info(path).await.unwrap();
|
||||||
}
|
}
|
||||||
|
Commands::Auth {} => {
|
||||||
|
println!("Click the link below to authorize the app:\n");
|
||||||
|
let link = "https://login.account.rakuten.com/sso/authorize?response_type=code&client_id=rakuten_drive_web&redirect_uri=https://www.rakuten-drive.com/oauth-callback&scope=openid+profile+email&prompt=login&ui_locales=en";
|
||||||
|
println!("{}\n", link);
|
||||||
|
|
||||||
|
println!("Paste the URL you were redirected to:");
|
||||||
|
let mut auth_url = String::new();
|
||||||
|
std::io::stdin().read_line(&mut auth_url).unwrap();
|
||||||
|
let auth_url = url::Url::parse(auth_url.trim())?;
|
||||||
|
|
||||||
|
let params = auth_url.query_pairs().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let rid_code = params
|
||||||
|
.iter()
|
||||||
|
.find(|(key, _)| key == "code")
|
||||||
|
.map(|(_, value)| value.to_string())
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("Code not found in URL"))?;
|
||||||
|
|
||||||
|
let rid_token_auth_res = client::rid_token_auth(rid_code.as_str()).await?;
|
||||||
|
let token_verify_res = client::get_refresh_token(&rid_token_auth_res.custom_token).await?;
|
||||||
|
|
||||||
|
println!("Refresh token: {}", token_verify_res.refresh_token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -152,3 +152,10 @@ pub struct CopyFileRequestFile {
|
|||||||
pub size: i64,
|
pub size: i64,
|
||||||
pub version_id: String,
|
pub version_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct VerifyCustomTokenRequest {
|
||||||
|
pub return_secure_token: bool,
|
||||||
|
pub token: String,
|
||||||
|
}
|
@ -176,3 +176,20 @@ pub enum SendyErrorType {
|
|||||||
SendyErrShareUpwardShareExist,
|
SendyErrShareUpwardShareExist,
|
||||||
SendyErrShareFolderIncludedOrInclude,
|
SendyErrShareFolderIncludedOrInclude,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct RIDTokenResponse {
|
||||||
|
pub custom_token: String,
|
||||||
|
pub is_new_user: String, // "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct VerifyCustomTokenResponse {
|
||||||
|
pub kind: String,
|
||||||
|
pub id_token: String,
|
||||||
|
pub refresh_token: String,
|
||||||
|
pub expires_in: String,
|
||||||
|
pub is_new_user: bool,
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user