support github login
This commit is contained in:
125
src/login.rs
125
src/login.rs
@@ -69,7 +69,20 @@ struct Account {
|
||||
pub id: String,
|
||||
}
|
||||
#[get("/cs/auth?<code>&<redirect_url>&<jump_to_url>")]
|
||||
pub async fn cs_auth(code: String, redirect_url: String, jump_to_url: String, db: Db) -> Redirect {
|
||||
pub async fn cs_auth(
|
||||
code: String,
|
||||
redirect_url: String,
|
||||
jump_to_url: String,
|
||||
db: Db,
|
||||
) -> Result<Redirect, &'static str> {
|
||||
if !env::var("FRONTEND_WHITELIST")
|
||||
.unwrap_or_default()
|
||||
.split(',')
|
||||
.any(|url| jump_to_url.starts_with(url))
|
||||
{
|
||||
return Err("前端地址不在白名单内");
|
||||
}
|
||||
|
||||
let mast_url = env::var("MAST_BASE_URL").unwrap();
|
||||
let mast_cli = env::var("MAST_CLIENT").unwrap();
|
||||
let mast_sec = env::var("MAST_SECRET").unwrap();
|
||||
@@ -121,19 +134,109 @@ pub async fn cs_auth(code: String, redirect_url: String, jump_to_url: String, db
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Redirect::to(format!(
|
||||
"{}?token={}",
|
||||
{
|
||||
if env::var("FRONTEND_WHITELIST")
|
||||
Ok(Redirect::to(format!("{}?token={}", &jump_to_url, &tk)))
|
||||
}
|
||||
|
||||
#[get("/gh")]
|
||||
pub fn gh_login(r: RefHeader) -> Redirect {
|
||||
let gh_url = "https://github.com/login/oauth/authorize";
|
||||
let gh_cli = env::var("GH_CLIENT").unwrap();
|
||||
let gh_scope = "user:email";
|
||||
|
||||
let jump_to_url = Url::parse(&r.0).unwrap();
|
||||
|
||||
let mut redirect_url = env::var("AUTH_BACKEND_URL")
|
||||
.map(|url| Url::parse(&url).unwrap())
|
||||
.unwrap_or_else(|_| jump_to_url.clone());
|
||||
redirect_url.set_path("/_login/gh/auth");
|
||||
|
||||
redirect_url = Url::parse_with_params(
|
||||
redirect_url.as_str(),
|
||||
&[("jump_to_url", jump_to_url.as_str())],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let url = Url::parse_with_params(
|
||||
gh_url,
|
||||
&[
|
||||
("redirect_uri", redirect_url.as_str()),
|
||||
("client_id", &gh_cli),
|
||||
("scope", gh_scope),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Redirect::to(url.to_string())
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
struct GithubEmail {
|
||||
pub email: String,
|
||||
pub verified: bool,
|
||||
}
|
||||
|
||||
#[get("/gh/auth?<code>&<jump_to_url>")]
|
||||
pub async fn gh_auth(code: String, jump_to_url: String, db: Db) -> Result<Redirect, &'static str> {
|
||||
if !env::var("FRONTEND_WHITELIST")
|
||||
.unwrap_or_default()
|
||||
.split(',')
|
||||
.any(|url| jump_to_url.starts_with(url))
|
||||
{
|
||||
&jump_to_url
|
||||
} else {
|
||||
"/"
|
||||
return Err("前端地址不在白名单内");
|
||||
}
|
||||
},
|
||||
&tk
|
||||
))
|
||||
|
||||
let gh_cli = env::var("GH_CLIENT").unwrap();
|
||||
let gh_sec = env::var("GH_SECRET").unwrap();
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let r = client
|
||||
.post("https://github.com/login/oauth/access_token")
|
||||
.header(reqwest::header::ACCEPT, "application/json")
|
||||
.form(&[
|
||||
("client_id", gh_cli.as_str()),
|
||||
("client_secret", gh_sec.as_str()),
|
||||
("code", code.as_str()),
|
||||
])
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
//let token: rocket::serde::json::Value = r.json().await.unwrap();
|
||||
let token: Token = r.json().await.unwrap();
|
||||
|
||||
dbg!(&token);
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let r = client
|
||||
.get("https://api.github.com/user/emails")
|
||||
.bearer_auth(token.access_token)
|
||||
.header(reqwest::header::USER_AGENT, "hole_thu LoginBot")
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
// dbg!(&r);
|
||||
let emails = r
|
||||
.json::<Vec<GithubEmail>>()
|
||||
//.json::<rocket::serde::json::Value>()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
//dbg!(&emails);
|
||||
|
||||
for email in emails {
|
||||
if let Some(email_name) = email
|
||||
.email
|
||||
.strip_suffix("@mails.tsinghua.edu.cn")
|
||||
.and_then(|name| email.verified.then_some(name))
|
||||
{
|
||||
let tk = User::find_or_create_token(&db, &format!("gh_{}", email_name), false)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
return Ok(Redirect::to(format!("{}?token={}", &jump_to_url, &tk)));
|
||||
}
|
||||
}
|
||||
|
||||
Err("没有找到已验证的清华邮箱")
|
||||
}
|
||||
|
||||
@@ -99,7 +99,12 @@ async fn main() {
|
||||
"/_login",
|
||||
[
|
||||
#[cfg(feature = "mastlogin")]
|
||||
routes![login::cs_login, login::cs_auth],
|
||||
routes![
|
||||
login::cs_login,
|
||||
login::cs_auth,
|
||||
login::gh_login,
|
||||
login::gh_auth
|
||||
],
|
||||
routes![],
|
||||
]
|
||||
.concat(),
|
||||
|
||||
Reference in New Issue
Block a user