diff --git a/crates/server/src/api.rs b/crates/server/src/api.rs index 9f8e62d51f..9510c2fc10 100644 --- a/crates/server/src/api.rs +++ b/crates/server/src/api.rs @@ -1,4 +1,4 @@ -use crate::{auth, AppState, Request, RequestExt as _}; +use crate::{auth, db::UserId, AppState, Request, RequestExt as _}; use async_trait::async_trait; use serde::Deserialize; use serde_json::json; @@ -6,6 +6,9 @@ use std::sync::Arc; use surf::StatusCode; pub fn add_routes(app: &mut tide::Server>) { + app.at("/users").get(get_users); + app.at("/users").post(create_user); + app.at("/users/:id").put(update_user); app.at("/users/:github_login").get(get_user); app.at("/users/:github_login/access_tokens") .post(create_access_token); @@ -25,6 +28,66 @@ async fn get_user(request: Request) -> tide::Result { .build()) } +async fn get_users(request: Request) -> tide::Result { + request.require_token().await?; + + let users = request.db().get_all_users().await?; + + Ok(tide::Response::builder(StatusCode::Ok) + .body(tide::Body::from_json(&users)?) + .build()) +} + +async fn create_user(mut request: Request) -> tide::Result { + request.require_token().await?; + + #[derive(Deserialize)] + struct Params { + github_login: String, + admin: bool, + } + let params = request.body_json::().await?; + + let user_id = request + .db() + .create_user(¶ms.github_login, params.admin) + .await?; + + let user = request.db().get_user_by_id(user_id).await?.ok_or_else(|| { + surf::Error::from_str( + StatusCode::InternalServerError, + "couldn't find the user we just created", + ) + })?; + + Ok(tide::Response::builder(StatusCode::Ok) + .body(tide::Body::from_json(&user)?) + .build()) +} + +async fn update_user(mut request: Request) -> tide::Result { + request.require_token().await?; + + #[derive(Deserialize)] + struct Params { + admin: bool, + } + let user_id = UserId( + request + .param("id")? + .parse::() + .map_err(|error| surf::Error::from_str(StatusCode::BadRequest, error.to_string()))?, + ); + let params = request.body_json::().await?; + + request + .db() + .set_user_is_admin(user_id, params.admin) + .await?; + + Ok(tide::Response::builder(StatusCode::Ok).build()) +} + async fn create_access_token(request: Request) -> tide::Result { request.require_token().await?; diff --git a/crates/server/src/db.rs b/crates/server/src/db.rs index e3267bad0e..e8a1023a92 100644 --- a/crates/server/src/db.rs +++ b/crates/server/src/db.rs @@ -121,6 +121,11 @@ impl Db { }) } + pub async fn get_user_by_id(&self, id: UserId) -> Result> { + let users = self.get_users_by_ids([id]).await?; + Ok(users.into_iter().next()) + } + pub async fn get_users_by_ids( &self, ids: impl IntoIterator,