feat(server >> api): implemented an endpoint that gives the client information about their authenticated account
This commit is contained in:
parent
8f8e2c5665
commit
5db4d4869c
|
@ -19,6 +19,7 @@ env_logger = "0.11.3"
|
|||
log = "0.4.21"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.197", features = ["default"] }
|
||||
strum = { version = "0.26.2", features = ["derive"] }
|
||||
thiserror = "1.0.58"
|
||||
uuid = { version = "1.7.0", features = ["v4"] }
|
||||
tokio = { version = "1.36.0", features = ["sync"] }
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
pub mod invite;
|
||||
|
||||
use crate::backend::Backend;
|
||||
use actix_web::{post, web, HttpResponse, Responder};
|
||||
use crate::backend::{permissions::Permission, Backend};
|
||||
use actix_web::{get, post, web, HttpResponse, Responder};
|
||||
use actix_web_httpauth::extractors::bearer::BearerAuth;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use uuid::Uuid;
|
||||
|
@ -67,3 +68,26 @@ pub async fn auth(backend: web::Data<Backend>, body: web::Json<AuthRequest>) ->
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct InfoResponse {
|
||||
userid: String,
|
||||
permissions: Vec<Permission>,
|
||||
}
|
||||
|
||||
#[get("/account/info")]
|
||||
pub async fn info(backend: web::Data<Backend>, bearer_auth: BearerAuth) -> impl Responder {
|
||||
match backend.account_info(bearer_auth.token()).await {
|
||||
Err(e) => {
|
||||
log::error!("{e}");
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
Ok(res) => match res {
|
||||
Err(e) => e.into(),
|
||||
Ok((userid, permissions)) => HttpResponse::Ok().json(InfoResponse {
|
||||
userid: userid.to_string(),
|
||||
permissions,
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ pub async fn start(config: &Config, backend: Backend) -> Result<()> {
|
|||
.app_data(data.clone())
|
||||
.service(endpoints::account::register)
|
||||
.service(endpoints::account::auth)
|
||||
.service(endpoints::account::info)
|
||||
.service(endpoints::account::invite::new)
|
||||
.service(endpoints::relay::create)
|
||||
.service(endpoints::relay::relay_id::user::user_id::public_key)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
mod db_structures;
|
||||
pub mod error;
|
||||
mod permissions;
|
||||
pub mod permissions;
|
||||
mod relay;
|
||||
mod tokens;
|
||||
mod user;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
use serde::Serialize;
|
||||
use strum::{EnumIter, IntoEnumIterator};
|
||||
|
||||
#[derive(EnumIter, Debug, Serialize)]
|
||||
pub enum Permission {
|
||||
GenerateInviteTokens,
|
||||
PromoteUsers,
|
||||
|
@ -11,3 +15,19 @@ impl Permission {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Permissions(pub u16);
|
||||
|
||||
impl Into<Vec<Permission>> for Permissions {
|
||||
fn into(self) -> Vec<Permission> {
|
||||
Permission::iter()
|
||||
.filter_map(|permission| {
|
||||
if (self.0 & permission.as_u16()) > 0 {
|
||||
Some(permission)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::backend::{
|
||||
db_structures::UsersRow, error::Error, permissions::Permission, tokens::resolve_auth_token,
|
||||
db_structures::UsersRow,
|
||||
error::Error,
|
||||
permissions::{Permission, Permissions},
|
||||
tokens::resolve_auth_token,
|
||||
Backend,
|
||||
};
|
||||
use anyhow::{bail, Result};
|
||||
|
@ -35,6 +38,10 @@ impl User {
|
|||
(self.permissions & permission.as_u16()) > 0
|
||||
}
|
||||
|
||||
pub fn permissions(&self) -> Vec<Permission> {
|
||||
Permissions(self.permissions).into()
|
||||
}
|
||||
|
||||
pub fn verify_password(&self, password: &str) -> Result<bool> {
|
||||
let hash = argon2::PasswordHash::new(self.password.as_str()).map_err(|_| {
|
||||
anyhow::Error::msg(format!(
|
||||
|
@ -173,4 +180,16 @@ impl Backend {
|
|||
|
||||
Ok(Ok(token))
|
||||
}
|
||||
|
||||
pub async fn account_info(
|
||||
&self,
|
||||
requester: impl IntoUser,
|
||||
) -> Result<Result<(Uuid, Vec<Permission>), Error>> {
|
||||
let requester = match requester.into_user(&self.pool).await? {
|
||||
Err(e) => return Ok(Err(e)),
|
||||
Ok(user) => user,
|
||||
};
|
||||
|
||||
Ok(Ok((requester.uuid, requester.permissions())))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue