From 8a7676945cf10f61083566e9343c792871116eee Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Wed, 06 Oct 2021 02:34:39 +0100 Subject: [PATCH] Quick little user info page --- chartered-frontend/src/index.tsx | 6 ++++++ chartered-frontend/src/pages/User.tsx | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ chartered-web/src/endpoints/web_api/mod.rs | 4 ++-- chartered-web/src/endpoints/web_api/search_users.rs | 54 ------------------------------------------------------ chartered-web/src/endpoints/web_api/users/info.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ chartered-web/src/endpoints/web_api/users/mod.rs | 25 +++++++++++++++++++++++++ chartered-web/src/endpoints/web_api/users/search.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 237 insertions(+), 56 deletions(-) diff --git a/chartered-frontend/src/index.tsx b/chartered-frontend/src/index.tsx index 0e800f6..940f619 100644 --- a/chartered-frontend/src/index.tsx +++ a/chartered-frontend/src/index.tsx @@ -22,6 +22,7 @@ import ListOrganisations from "./pages/organisations/ListOrganisations"; import OrganisationView from "./pages/crate/OrganisationView"; import CreateOrganisation from "./pages/organisations/CreateOrganisation"; +import User from "./pages/User"; function App() { return ( @@ -60,6 +61,11 @@ exact path="/crates/:organisation/:crate/:subview?" component={() => } + /> + } /> ({ + auth, + endpoint: "users/info/" + uuid, + }); + + if (error) { + return ; + } + + const ready = !!user; + + console.log(user); + + return ( +
+
+ ); + } diff --git a/chartered-web/src/endpoints/web_api/mod.rs b/chartered-web/src/endpoints/web_api/mod.rs index 5e80e62..407d039 100644 --- a/chartered-web/src/endpoints/web_api/mod.rs +++ a/chartered-web/src/endpoints/web_api/mod.rs @@ -1,8 +1,8 @@ mod auth; mod crates; mod organisations; -mod search_users; mod ssh_key; +mod users; use axum::{ body::{Body, BoxBody}, @@ -25,7 +25,7 @@ crate::axum_box_after_every_route!(Router::new() .nest("/organisations", organisations::routes()) .nest("/crates", crates::routes()) - .route("/users/search", get(search_users::handle)) + .nest("/users", users::routes()) .route("/ssh-key", get(ssh_key::handle_get)) .route("/ssh-key", put(ssh_key::handle_put)) .route("/ssh-key/:id", delete(ssh_key::handle_delete))) diff --git a/chartered-web/src/endpoints/web_api/search_users.rs b/chartered-web/src/endpoints/web_api/search_users.rs deleted file mode 100644 index 9278150..0000000 100644 --- a/chartered-web/src/endpoints/web_api/search_users.rs +++ /dev/null @@ -1,54 +1,0 @@ -use axum::{extract, Json}; -use chartered_db::{users::User, ConnectionPool}; -use serde::{Deserialize, Serialize}; -use thiserror::Error; - -#[derive(Deserialize)] -pub struct RequestParams { - q: String, -} - -#[derive(Serialize)] -pub struct Response { - users: Vec, -} - -#[derive(Serialize)] -pub struct ResponseUser { - user_uuid: chartered_db::uuid::Uuid, - username: String, -} - -pub async fn handle( - extract::Extension(db): extract::Extension, - extract::Query(req): extract::Query, -) -> Result, Error> { - let users = User::search(db, req.q, 5) - .await? - .into_iter() - .map(|user| ResponseUser { - user_uuid: user.uuid.0, - username: user.username, - }) - .collect(); - - Ok(Json(Response { users })) -} - -#[derive(Error, Debug)] -pub enum Error { - #[error("Failed to query database")] - Database(#[from] chartered_db::Error), -} - -impl Error { - pub fn status_code(&self) -> axum::http::StatusCode { - use axum::http::StatusCode; - - match self { - Self::Database(_) => StatusCode::INTERNAL_SERVER_ERROR, - } - } -} - -define_error_response!(Error); diff --git a/chartered-web/src/endpoints/web_api/users/info.rs b/chartered-web/src/endpoints/web_api/users/info.rs new file mode 100644 index 0000000..c8870bb 100644 --- /dev/null +++ a/chartered-web/src/endpoints/web_api/users/info.rs @@ -1,0 +1,59 @@ +use axum::{extract, Json}; +use chartered_db::{users::User, ConnectionPool}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +#[derive(Serialize)] +pub struct Response { + uuid: chartered_db::uuid::Uuid, + username: String, + name: Option, + nick: Option, + email: Option, + external_profile_url: Option, + picture_url: Option, +} + +impl From for Response { + fn from(user: chartered_db::users::User) -> Self { + Self { + uuid: user.uuid.0, + username: user.username, + name: user.name, + nick: user.nick, + email: user.email, + external_profile_url: user.external_profile_url, + picture_url: user.picture_url, + } + } +} + +pub async fn handle( + extract::Path((_session_key, uuid)): extract::Path<(String, chartered_db::uuid::Uuid)>, + extract::Extension(db): extract::Extension, +) -> Result, Error> { + let user = User::find_by_uuid(db, uuid).await?.ok_or(Error::NotFound)?; + + Ok(Json(user.into())) +} + +#[derive(Error, Debug)] +pub enum Error { + #[error("Failed to query database")] + Database(#[from] chartered_db::Error), + #[error("User doesn't exist")] + NotFound, +} + +impl Error { + pub fn status_code(&self) -> axum::http::StatusCode { + use axum::http::StatusCode; + + match self { + Self::Database(_) => StatusCode::INTERNAL_SERVER_ERROR, + Self::NotFound => StatusCode::NOT_FOUND, + } + } +} + +define_error_response!(Error); diff --git a/chartered-web/src/endpoints/web_api/users/mod.rs b/chartered-web/src/endpoints/web_api/users/mod.rs new file mode 100644 index 0000000..256bbb5 100644 --- /dev/null +++ a/chartered-web/src/endpoints/web_api/users/mod.rs @@ -1,0 +1,25 @@ +mod search; +mod info; + +use axum::{ + body::{Body, BoxBody}, + handler::get, + http::{Request, Response}, + Router, +}; +use futures::future::Future; +use std::convert::Infallible; + +pub fn routes() -> Router< + impl tower::Service< + Request, + Response = Response, + Error = Infallible, + Future = impl Future, Infallible>> + Send, + > + Clone + + Send, +> { + crate::axum_box_after_every_route!(Router::new() + .route("/search", get(search::handle)) + .route("/info/:uuid", get(info::handle))) +} diff --git a/chartered-web/src/endpoints/web_api/users/search.rs b/chartered-web/src/endpoints/web_api/users/search.rs new file mode 100644 index 0000000..9278150 100644 --- /dev/null +++ a/chartered-web/src/endpoints/web_api/users/search.rs @@ -1,0 +1,54 @@ +use axum::{extract, Json}; +use chartered_db::{users::User, ConnectionPool}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +#[derive(Deserialize)] +pub struct RequestParams { + q: String, +} + +#[derive(Serialize)] +pub struct Response { + users: Vec, +} + +#[derive(Serialize)] +pub struct ResponseUser { + user_uuid: chartered_db::uuid::Uuid, + username: String, +} + +pub async fn handle( + extract::Extension(db): extract::Extension, + extract::Query(req): extract::Query, +) -> Result, Error> { + let users = User::search(db, req.q, 5) + .await? + .into_iter() + .map(|user| ResponseUser { + user_uuid: user.uuid.0, + username: user.username, + }) + .collect(); + + Ok(Json(Response { users })) +} + +#[derive(Error, Debug)] +pub enum Error { + #[error("Failed to query database")] + Database(#[from] chartered_db::Error), +} + +impl Error { + pub fn status_code(&self) -> axum::http::StatusCode { + use axum::http::StatusCode; + + match self { + Self::Database(_) => StatusCode::INTERNAL_SERVER_ERROR, + } + } +} + +define_error_response!(Error); -- rgit 0.1.3