feat: add users endpoint and add me and uuid under it
Some checks failed
ci/woodpecker/push/build-and-publish Pipeline failed
Some checks failed
ci/woodpecker/push/build-and-publish Pipeline failed
Adds a users endpoint that returns all users on the server, will require instance permissions in future. Place previous user requests under users to avoid having multiple endpoints.
This commit is contained in:
parent
cc07d78325
commit
1d7cdf343b
5 changed files with 149 additions and 18 deletions
77
src/api/v1/users/mod.rs
Normal file
77
src/api/v1/users/mod.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
use actix_web::{error, post, web, Error, HttpResponse, Scope};
|
||||
use futures::StreamExt;
|
||||
use log::error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::prelude::FromRow;
|
||||
use crate::{Data, api::v1::auth::check_access_token};
|
||||
|
||||
mod me;
|
||||
mod uuid;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Request {
|
||||
access_token: String,
|
||||
start: i32,
|
||||
amount: i32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, FromRow)]
|
||||
struct Response {
|
||||
uuid: String,
|
||||
username: String,
|
||||
display_name: Option<String>,
|
||||
email: String,
|
||||
}
|
||||
|
||||
const MAX_SIZE: usize = 262_144;
|
||||
|
||||
pub fn web() -> Scope {
|
||||
web::scope("/users")
|
||||
.service(res)
|
||||
.service(me::res)
|
||||
.service(uuid::res)
|
||||
}
|
||||
|
||||
#[post("")]
|
||||
pub async fn res(
|
||||
mut payload: web::Payload,
|
||||
data: web::Data<Data>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let mut body = web::BytesMut::new();
|
||||
while let Some(chunk) = payload.next().await {
|
||||
let chunk = chunk?;
|
||||
// limit max size of in-memory payload
|
||||
if (body.len() + chunk.len()) > MAX_SIZE {
|
||||
return Err(error::ErrorBadRequest("overflow"));
|
||||
}
|
||||
body.extend_from_slice(&chunk);
|
||||
}
|
||||
|
||||
let request = serde_json::from_slice::<Request>(&body)?;
|
||||
|
||||
if request.amount > 100 {
|
||||
return Ok(HttpResponse::BadRequest().finish())
|
||||
}
|
||||
|
||||
let authorized = check_access_token(request.access_token, &data.pool).await;
|
||||
|
||||
if let Err(error) = authorized {
|
||||
return Ok(error);
|
||||
}
|
||||
|
||||
let row = sqlx::query_as("SELECT CAST(uuid AS VARCHAR), username, display_name, email FROM users ORDER BY username LIMIT $1 OFFSET $2")
|
||||
.bind(request.amount)
|
||||
.bind(request.start)
|
||||
.fetch_all(&data.pool)
|
||||
.await;
|
||||
|
||||
if let Err(error) = row {
|
||||
error!("{}", error);
|
||||
return Ok(HttpResponse::InternalServerError().finish());
|
||||
}
|
||||
|
||||
let accounts: Vec<Response> = row.unwrap();
|
||||
|
||||
Ok(HttpResponse::Ok().json(accounts))
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue