Skip to content

Commit

Permalink
Merge pull request messense#449 from messense/login
Browse files Browse the repository at this point in the history
Add qrcode scan login to CLI
  • Loading branch information
messense authored Jun 3, 2022
2 parents c07c203 + a7acecf commit 562c458
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 106 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/Release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -342,25 +342,25 @@ jobs:
matrix:
target:
- arch: "aarch64_generic"
sdk: "https://downloads.openwrt.org/snapshots/targets/rockchip/armv8/openwrt-sdk-rockchip-armv8_gcc-11.2.0_musl.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/rockchip/armv8/openwrt-sdk-rockchip-armv8_gcc-11.3.0_musl.Linux-x86_64.tar.xz"
- arch: "arm_cortex-a9"
sdk: "https://downloads.openwrt.org/snapshots/targets/bcm53xx/generic/openwrt-sdk-bcm53xx-generic_gcc-11.2.0_musl_eabi.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/bcm53xx/generic/openwrt-sdk-bcm53xx-generic_gcc-11.3.0_musl_eabi.Linux-x86_64.tar.xz"
- arch: "aarch64_cortex-a53"
sdk: "https://downloads.openwrt.org/snapshots/targets/bcm27xx/bcm2710/openwrt-sdk-bcm27xx-bcm2710_gcc-11.2.0_musl.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/bcm27xx/bcm2710/openwrt-sdk-bcm27xx-bcm2710_gcc-11.3.0_musl.Linux-x86_64.tar.xz"
- arch: "aarch64_cortex-a72"
sdk: "https://downloads.openwrt.org/snapshots/targets/bcm27xx/bcm2711/openwrt-sdk-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/bcm27xx/bcm2711/openwrt-sdk-bcm27xx-bcm2711_gcc-11.3.0_musl.Linux-x86_64.tar.xz"
- arch: "x86_64"
sdk: "https://downloads.openwrt.org/snapshots/targets/x86/64/openwrt-sdk-x86-64_gcc-11.2.0_musl.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/x86/64/openwrt-sdk-x86-64_gcc-11.3.0_musl.Linux-x86_64.tar.xz"
- arch: "i386_pentium4"
sdk: "https://downloads.openwrt.org/snapshots/targets/x86/generic/openwrt-sdk-x86-generic_gcc-11.2.0_musl.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/x86/generic/openwrt-sdk-x86-generic_gcc-11.3.0_musl.Linux-x86_64.tar.xz"
- arch: "arm_mpcore"
sdk: "https://downloads.openwrt.org/snapshots/targets/oxnas/ox820/openwrt-sdk-oxnas-ox820_gcc-11.2.0_musl_eabi.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/oxnas/ox820/openwrt-sdk-oxnas-ox820_gcc-11.3.0_musl_eabi.Linux-x86_64.tar.xz"
- arch: "arm_cortex-a5_vfpv4"
sdk: "https://downloads.openwrt.org/snapshots/targets/at91/sama5/openwrt-sdk-at91-sama5_gcc-11.2.0_musl_eabi.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/at91/sama5/openwrt-sdk-at91-sama5_gcc-11.3.0_musl_eabi.Linux-x86_64.tar.xz"
- arch: "arm_cortex-a7_neon-vfpv4"
sdk: "https://downloads.openwrt.org/snapshots/targets/ipq40xx/generic/openwrt-sdk-ipq40xx-generic_gcc-11.2.0_musl_eabi.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/ipq40xx/generic/openwrt-sdk-ipq40xx-generic_gcc-11.3.0_musl_eabi.Linux-x86_64.tar.xz"
- arch: "mipsel_24kc"
sdk: "https://downloads.openwrt.org/snapshots/targets/ramips/mt7621/openwrt-sdk-ramips-mt7621_gcc-11.2.0_musl.Linux-x86_64.tar.xz"
sdk: "https://downloads.openwrt.org/snapshots/targets/ramips/mt7621/openwrt-sdk-ramips-mt7621_gcc-11.3.0_musl.Linux-x86_64.tar.xz"
- arch: "mips_24kc"
sdk: "https://archive.openwrt.org/releases/19.07.7/targets/ar71xx/nand/openwrt-sdk-19.07.7-ar71xx-nand_gcc-7.5.0_musl.Linux-x86_64.tar.xz"
steps:
Expand Down
32 changes: 32 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ bytes = "1.0.1"
clap = { version = "3.1.14", features = ["derive", "env", "wrap_help"] }
dashmap = "5.3.2"
dav-server = { version = "0.3.3", default-features = false, features = ["hyper"] }
dirs = "4.0.0"
futures-util = "0.3"
headers = "0.3.6"
hyper = { version = "0.14.18", features = ["server", "http2"] }
Expand Down
6 changes: 1 addition & 5 deletions src/drive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ pub struct AliyunDrive {

impl AliyunDrive {
pub async fn new(config: DriveConfig, refresh_token: String) -> Result<Self> {
let refresh_token_is_empty = refresh_token.is_empty();
let credentials = Credentials {
refresh_token,
access_token: None,
Expand Down Expand Up @@ -91,9 +90,6 @@ impl AliyunDrive {
} else {
None
};
if refresh_token_is_empty && refresh_token_from_file.is_none() {
bail!("No refresh token provided! \n📝 Please specify refresh token from `--refresh-token` CLI option.");
}
tokio::spawn(async move {
let mut delay_seconds = 7000;
match client
Expand Down Expand Up @@ -231,7 +227,7 @@ impl AliyunDrive {

async fn access_token(&self) -> Result<String> {
let cred = self.credentials.read().await;
Ok(cred.access_token.clone().context("missing access_token")?)
cred.access_token.clone().context("missing access_token")
}

fn drive_id(&self) -> Result<&str> {
Expand Down
76 changes: 10 additions & 66 deletions src/login/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::login::model::{
AuthorizationCode, CkForm, GeneratorQrCodeResult, GotoResult, QueryQrCodeResult, Token,
WebLoginResult,
};
use crate::login::State::{CONFIRMED, EXPIRED, NEW};
use anyhow::anyhow;
use reqwest::Response;
use serde::de::DeserializeOwned;
Expand All @@ -27,20 +26,22 @@ const SESSION_ID_KEY: &str = "SESSIONID";

#[derive(Eq, PartialEq, Clone)]
pub enum State {
CONFIRMED,
EXPIRED,
NEW,
Confirmed,
Expired,
New,
}

impl FromStr for State {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
use State::*;

match s {
"NEW" => Ok(NEW),
"EXPIRED" => Ok(EXPIRED),
"CONFIRMED" => Ok(CONFIRMED),
_ => Ok(EXPIRED),
"NEW" => Ok(New),
"EXPIRED" => Ok(Expired),
"CONFIRMED" => Ok(Confirmed),
_ => Ok(Expired),
}
}
}
Expand Down Expand Up @@ -146,63 +147,6 @@ impl ResponseHandler {
async fn response_error_msg_handler(resp: Response) -> String {
resp.text()
.await
.unwrap_or(String::from("An error occurred while extracting the body."))
}
}

#[cfg(test)]
mod tests {
use crate::login;
use crate::login::model::{
AuthorizationCode, AuthorizationToken, Ok, QueryQrCodeCkForm, Token,
};

#[tokio::test]
async fn test() {
let scan = login::QrCodeScanner::new().await.unwrap();
// 返回二维码内容结果集
let generator_qr_code_result = scan.generator().await.unwrap();
// 需要生成二维码的内容
let qrcode_content = generator_qr_code_result.get_content();
let ck_form = QueryQrCodeCkForm::from(generator_qr_code_result);
// 打印二维码
qr2term::print_qr(&qrcode_content).unwrap();
for _i in 0..10 {
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
// 模拟轮训查询二维码状态
let query_result = scan.query(&ck_form).await.unwrap();
if query_result.ok() {
// query_result.is_new() 表示未扫码状态
if query_result.is_new() {
println!("new");
// 做点什么..
continue;
}
// query_result.is_expired() 表示扫码成功,但未点击确认登陆
if query_result.is_expired() {
// 做点什么..
println!("expired");
continue;
}
// 移动端APP扫码成功并确认登陆
if query_result.is_confirmed() {
// 获取移动端登陆Result
let mobile_login_result = query_result.get_mobile_login_result().unwrap();
// 移动端access-token
let access_token = mobile_login_result.access_token().unwrap_or(String::new());
// 根据移动端access-token获取authorization code(授权码)
let goto_result = scan.token_login(Token::from(&access_token)).await.unwrap();
// 根据授权码登陆获取Web端登陆结果集
let web_login_result = scan
.get_token(AuthorizationCode::from(&goto_result))
.await
.unwrap();
// 获取Web端refresh token
let refresh_token = web_login_result.refresh_token().unwrap();
println!("refresh-token: {:?}", refresh_token);
break;
}
}
}
.unwrap_or_else(|e| format!("An error occurred while extracting the body: {:?}", e))
}
}
27 changes: 11 additions & 16 deletions src/login/model.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use anyhow::anyhow;
use std::fmt::Debug;
use anyhow::{bail, Context};

use crate::login::State;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -150,7 +149,7 @@ impl Ok for QueryQrCodeResult {
impl QueryQrCodeResult {
pub fn is_new(&self) -> bool {
if let Some(ref state) = self.get_status() {
if State::NEW.eq(state) {
if State::New.eq(state) {
return true;
}
}
Expand All @@ -159,7 +158,7 @@ impl QueryQrCodeResult {

pub fn is_expired(&self) -> bool {
if let Some(ref state) = self.get_status() {
if State::EXPIRED.eq(state) {
if State::Expired.eq(state) {
return true;
}
}
Expand All @@ -168,7 +167,7 @@ impl QueryQrCodeResult {

pub fn is_confirmed(&self) -> bool {
if let Some(ref state) = self.get_status() {
if State::CONFIRMED.eq(state) {
if State::Confirmed.eq(state) {
return true;
}
}
Expand Down Expand Up @@ -293,24 +292,20 @@ impl From<&String> for GotoResult {

impl GotoResult {
pub fn extract_authorization_code(&self) -> anyhow::Result<String> {
let goto = self.goto.as_ref().ok_or(anyhow!("goto value is None"))?;
let goto = self.goto.as_ref().context("goto value is None")?;
let url = Url::parse(goto.as_str())?;
let query = url.query().ok_or(anyhow!("goto query is None"))?;
let param_array = query.split("&").collect::<Vec<&str>>();
let query = url.query().context("goto query is None")?;
let param_array = query.split('&').collect::<Vec<&str>>();
for param in param_array {
let param = param.to_string();
let k_v_array = param.split("=").collect::<Vec<&str>>();
let key = k_v_array
.get(0)
.ok_or(anyhow!("goto query param key is None"))?;
let k_v_array = param.split('=').collect::<Vec<&str>>();
let key = k_v_array.get(0).context("goto query param key is None")?;
if *key == CODE_KEY {
let value = k_v_array
.get(1)
.ok_or(anyhow!("goto query param value is None"))?;
let value = k_v_array.get(1).context("goto query param value is None")?;
return Ok(String::from(*value));
}
}
Err(anyhow!("Failed to get authorization code"))
bail!("Failed to get authorization code")
}
}

Expand Down
Loading

0 comments on commit 562c458

Please sign in to comment.