Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
99
crates/scel_api/src/auth/mod.rs
Normal file
99
crates/scel_api/src/auth/mod.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
use std::env;
|
||||
|
||||
use async_session::{MemoryStore, Session, SessionStore};
|
||||
use axum::{
|
||||
extract::Query,
|
||||
http::HeaderMap,
|
||||
response::{IntoResponse, Redirect},
|
||||
Extension,
|
||||
};
|
||||
use oauth2::{
|
||||
basic::BasicClient, reqwest::async_http_client, AuthUrl, AuthorizationCode, ClientId,
|
||||
ClientSecret, CsrfToken, RedirectUrl, TokenResponse, TokenUrl,
|
||||
};
|
||||
use reqwest::header::SET_COOKIE;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{User, COOKIE_NAME};
|
||||
|
||||
pub fn oauth_client() -> BasicClient {
|
||||
let client_id = env::var("GITEA_CLIENT_ID").expect("Missing GITEA_CLIENT_ID");
|
||||
let client_secret = env::var("GITEA_CLIENT_SECRET").expect("Missing GITEA_CLIENT_SECRET");
|
||||
let redirect_url = env::var("GITEA_REDIRECT_URL")
|
||||
.unwrap_or_else(|_| "http://127.0.0.1:3000/auth/authorized".to_string());
|
||||
|
||||
let auth_url =
|
||||
env::var("GITEA_AUTH_URL").unwrap_or_else(|_| "https://git.front.kjuulh.io".to_string());
|
||||
|
||||
let token_url =
|
||||
env::var("GITEA_TOKEN_URL").unwrap_or_else(|_| "https://git.front.kjuulh.io".to_string());
|
||||
|
||||
BasicClient::new(
|
||||
ClientId::new(client_id),
|
||||
Some(ClientSecret::new(client_secret)),
|
||||
AuthUrl::new(auth_url).expect("AuthUrl was invalid"),
|
||||
Some(TokenUrl::new(token_url).expect("Token url was invalid")),
|
||||
)
|
||||
.set_redirect_uri(RedirectUrl::new(redirect_url).expect("RedirectUrl was invalid"))
|
||||
}
|
||||
|
||||
pub async fn gitea(Extension(client): Extension<BasicClient>) -> impl IntoResponse {
|
||||
let (auth_url, _crsf_token) = client.authorize_url(CsrfToken::new_random).url();
|
||||
|
||||
Redirect::to(&auth_url.to_string())
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct AuthRequest {
|
||||
code: String,
|
||||
state: String,
|
||||
}
|
||||
|
||||
pub async fn authorized(
|
||||
Query(query): Query<AuthRequest>,
|
||||
Extension(store): Extension<MemoryStore>,
|
||||
Extension(oauth_client): Extension<BasicClient>,
|
||||
) -> impl IntoResponse {
|
||||
let token = oauth_client
|
||||
.exchange_code(AuthorizationCode::new(query.code.clone()))
|
||||
.request_async(async_http_client)
|
||||
.await
|
||||
.expect("failed to get http client");
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let user_data_json = client
|
||||
.get(get_gitea_user_data_url())
|
||||
.bearer_auth(token.access_token().secret())
|
||||
.send()
|
||||
.await
|
||||
.expect("Request did not succeed");
|
||||
// .text()
|
||||
// .await
|
||||
// .unwrap();
|
||||
|
||||
let user_data: User = user_data_json
|
||||
.json::<User>()
|
||||
.await
|
||||
.expect("could not parse user");
|
||||
|
||||
let mut session = Session::new();
|
||||
session
|
||||
.insert("user", &user_data)
|
||||
.expect("could not insert user data");
|
||||
|
||||
let cookie = store
|
||||
.store_session(session)
|
||||
.await
|
||||
.expect("could not insert session")
|
||||
.expect("session was not valid");
|
||||
|
||||
let cookie = format!("{}={}; SameSite=Lax; Path=/", COOKIE_NAME, cookie);
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(SET_COOKIE, cookie.parse().expect("Cookie is not valid"));
|
||||
(headers, Redirect::to("/"))
|
||||
}
|
||||
|
||||
fn get_gitea_user_data_url() -> String {
|
||||
env::var("GITEA_USER_INFO_URL").expect("Missing GITEA_USER_INFO_URL")
|
||||
}
|
Reference in New Issue
Block a user