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) -> 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, Extension(store): Extension, Extension(oauth_client): Extension, ) -> 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::() .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") }