feat(api): implemented /relay/create

This commit is contained in:
antifallobst 2024-03-22 21:20:21 +01:00
parent eb6aa532ff
commit b5f948a95e
Signed by: antifallobst
GPG Key ID: 2B4F402172791BAF
5 changed files with 58 additions and 1 deletions

View File

@ -12,6 +12,6 @@
- [X] `POST` /new - [X] `POST` /new
- [ ] `GET` /list - [ ] `GET` /list
- /relay - /relay
- [ ] `POST` /create - [X] `POST` /create
- [ ] `POST` /join - [ ] `POST` /join
- [ ] `POST` /leave - [ ] `POST` /leave

View File

@ -1 +1,2 @@
pub mod account; pub mod account;
pub mod relay;

View File

@ -0,0 +1,28 @@
use crate::backend::Backend;
use actix_web::{post, web, HttpResponse, Responder};
use actix_web_httpauth::extractors::bearer::BearerAuth;
use log::error;
use serde::Serialize;
#[derive(Debug, Serialize)]
struct CreateResponse {
id: String,
secret: String,
}
#[post("/relay/create")]
pub async fn create(backend: web::Data<Backend>, auth: BearerAuth) -> impl Responder {
match backend.create_relay(auth.token()).await {
Err(e) => {
error!("{e}");
HttpResponse::InternalServerError().finish()
}
Ok(res) => match res {
Err(e) => e.into(),
Ok((uuid, secret)) => HttpResponse::Ok().json(CreateResponse {
id: uuid.to_string(),
secret,
}),
},
}
}

View File

@ -13,6 +13,7 @@ pub async fn start(config: &Config, backend: Backend) -> Result<()> {
.service(endpoints::account::register) .service(endpoints::account::register)
.service(endpoints::account::auth) .service(endpoints::account::auth)
.service(endpoints::account::invite::new) .service(endpoints::account::invite::new)
.service(endpoints::relay::create)
}) })
.bind((config.addr.as_str(), config.port))?; .bind((config.addr.as_str(), config.port))?;

View File

@ -235,4 +235,31 @@ impl Backend {
Ok(Ok(token)) Ok(Ok(token))
} }
pub async fn create_relay(&self, user: impl IntoUser) -> Result<Result<(Uuid, String), Error>> {
let _user = match user.into_user(&self).await? {
Ok(user) => user,
Err(e) => return Ok(Err(e)),
};
let relay_id = Uuid::new_v4();
let secret = rand::distributions::Alphanumeric.sample_string(&mut OsRng, 48);
let salt = SaltString::generate(&mut OsRng);
let secret_hash = Argon2::default()
.hash_password(secret.as_bytes(), &salt)
.map_err(|_| anyhow::Error::msg("Failed to hash the relay secret"))?
.to_string();
sqlx::query!(
r#"INSERT INTO Relays VALUES (?, ?);"#,
relay_id.as_bytes().as_slice(),
secret_hash
)
.execute(&self.pool)
.await?;
Ok(Ok((relay_id, secret)))
}
} }