summaryrefslogtreecommitdiffstats
path: root/crates/auth/src/server
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2025-07-23 13:39:40 +0200
committerrtkay123 <dev@kanjala.com>2025-07-23 13:39:40 +0200
commit089efa225cc0a4e7be12608129ddbff28d11f320 (patch)
treed5d27ba5f5056c7a539365fd314e6d7ce7529523 /crates/auth/src/server
parent0a48abb0f0d4752b639fb89dd2db32a3db0eebb8 (diff)
downloadsellershut-089efa225cc0a4e7be12608129ddbff28d11f320.tar.bz2
sellershut-089efa225cc0a4e7be12608129ddbff28d11f320.zip
feat(auth): discord oauth
Diffstat (limited to 'crates/auth/src/server')
-rw-r--r--crates/auth/src/server/routes.rs47
-rw-r--r--crates/auth/src/server/routes/authorised.rs23
-rw-r--r--crates/auth/src/server/routes/discord.rs10
-rw-r--r--crates/auth/src/server/routes/discord/discord_auth.rs20
4 files changed, 100 insertions, 0 deletions
diff --git a/crates/auth/src/server/routes.rs b/crates/auth/src/server/routes.rs
new file mode 100644
index 0000000..7a25e70
--- /dev/null
+++ b/crates/auth/src/server/routes.rs
@@ -0,0 +1,47 @@
+pub mod authorised;
+pub mod discord;
+use axum::response::IntoResponse;
+use serde::Deserialize;
+
+#[derive(Debug, Clone, Copy, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum Provider {
+ Discord,
+}
+
+pub async fn health_check() -> impl IntoResponse {
+ let name = env!("CARGO_PKG_NAME");
+ let ver = env!("CARGO_PKG_VERSION");
+
+ format!("{name} v{ver} is live")
+}
+
+#[cfg(test)]
+mod tests {
+ use axum::{
+ body::Body,
+ http::{Request, StatusCode},
+ };
+ use sqlx::PgPool;
+ use stack_up::Services;
+ use tower::ServiceExt;
+
+ use crate::{
+ server::{self, test_config},
+ state::AppState,
+ };
+
+ #[sqlx::test]
+ async fn health_check(pool: PgPool) {
+ let services = Services { postgres: pool };
+ let state = AppState::create(services, &test_config()).await.unwrap();
+ let app = server::router(state);
+
+ let response = app
+ .oneshot(Request::builder().uri("/").body(Body::empty()).unwrap())
+ .await
+ .unwrap();
+
+ assert_eq!(response.status(), StatusCode::OK);
+ }
+}
diff --git a/crates/auth/src/server/routes/authorised.rs b/crates/auth/src/server/routes/authorised.rs
new file mode 100644
index 0000000..ddf048d
--- /dev/null
+++ b/crates/auth/src/server/routes/authorised.rs
@@ -0,0 +1,23 @@
+use axum::{
+ extract::{Query, State},
+ response::IntoResponse,
+};
+use axum_extra::{TypedHeader, headers};
+use serde::Deserialize;
+
+use crate::{error::AppError, server::routes::Provider, state::AppHandle};
+
+#[derive(Debug, Deserialize)]
+pub struct AuthRequest {
+ provider: Provider,
+ code: String,
+ state: String,
+}
+
+async fn login_authorized(
+ Query(query): Query<AuthRequest>,
+ State(state): State<AppHandle>,
+ TypedHeader(cookies): TypedHeader<headers::Cookie>,
+) -> Result<impl IntoResponse, AppError> {
+ Ok("")
+}
diff --git a/crates/auth/src/server/routes/discord.rs b/crates/auth/src/server/routes/discord.rs
new file mode 100644
index 0000000..e1a834f
--- /dev/null
+++ b/crates/auth/src/server/routes/discord.rs
@@ -0,0 +1,10 @@
+mod discord_auth;
+use axum::{Router, routing::get};
+
+use crate::state::AppHandle;
+
+pub fn discord_router(state: AppHandle) -> Router {
+ Router::new()
+ .route("/auth/discord", get(discord_auth::discord_auth))
+ .with_state(state)
+}
diff --git a/crates/auth/src/server/routes/discord/discord_auth.rs b/crates/auth/src/server/routes/discord/discord_auth.rs
new file mode 100644
index 0000000..b07fa7a
--- /dev/null
+++ b/crates/auth/src/server/routes/discord/discord_auth.rs
@@ -0,0 +1,20 @@
+use axum::{
+ extract::State,
+ http::HeaderMap,
+ response::{IntoResponse, Redirect},
+};
+use oauth2::{CsrfToken, Scope};
+
+use crate::{error::AppError, state::AppHandle};
+
+pub async fn discord_auth(State(state): State<AppHandle>) -> Result<impl IntoResponse, AppError> {
+ let (auth_url, csrf_token) = state
+ .discord_client
+ .authorize_url(CsrfToken::new_random)
+ .add_scope(Scope::new("identify".to_string()))
+ .url();
+
+ let mut headers = HeaderMap::new();
+
+ Ok((headers, Redirect::to(auth_url.as_ref())))
+}