feat: privileged user editing

This commit is contained in:
Paul Makles
2023-03-11 16:53:25 +00:00
parent b83f6da648
commit 13ed69c82a

View File

@@ -1,6 +1,6 @@
use revolt_quark::models::user::{FieldsUser, PartialUser, User}; use revolt_quark::models::user::{FieldsUser, PartialUser, User};
use revolt_quark::models::File; use revolt_quark::models::File;
use revolt_quark::{Database, Error, Result}; use revolt_quark::{Database, Error, Ref, Result};
use revolt_quark::models::user::UserStatus; use revolt_quark::models::user::UserStatus;
use rocket::serde::json::Json; use rocket::serde::json::Json;
@@ -24,6 +24,10 @@ pub struct UserProfileData {
/// # User Data /// # User Data
#[derive(Validate, Serialize, Deserialize, JsonSchema)] #[derive(Validate, Serialize, Deserialize, JsonSchema)]
pub struct DataEditUser { pub struct DataEditUser {
/// Attachment Id for avatar
#[validate(length(min = 1, max = 128))]
avatar: Option<String>,
/// New user status /// New user status
#[validate] #[validate]
status: Option<UserStatus>, status: Option<UserStatus>,
@@ -32,9 +36,14 @@ pub struct DataEditUser {
/// This is applied as a partial. /// This is applied as a partial.
#[validate] #[validate]
profile: Option<UserProfileData>, profile: Option<UserProfileData>,
/// Attachment Id for avatar
#[validate(length(min = 1, max = 128))] /// Bitfield of user badges
avatar: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
badges: Option<i32>,
/// Enum of user flags
#[serde(skip_serializing_if = "Option::is_none")]
flags: Option<i32>,
/// Fields to remove from user object /// Fields to remove from user object
#[validate(length(min = 1))] #[validate(length(min = 1))]
remove: Option<Vec<FieldsUser>>, remove: Option<Vec<FieldsUser>>,
@@ -44,19 +53,36 @@ pub struct DataEditUser {
/// ///
/// Edit currently authenticated user. /// Edit currently authenticated user.
#[openapi(tag = "User Information")] #[openapi(tag = "User Information")]
#[patch("/@me", data = "<data>")] #[patch("/<target>", data = "<data>")]
pub async fn req( pub async fn req(
db: &State<Database>, db: &State<Database>,
mut user: User, mut user: User,
target: Ref,
data: Json<DataEditUser>, data: Json<DataEditUser>,
) -> Result<Json<User>> { ) -> Result<Json<User>> {
let data = data.into_inner(); let data = data.into_inner();
data.validate() data.validate()
.map_err(|error| Error::FailedValidation { error })?; .map_err(|error| Error::FailedValidation { error })?;
// If we want to edit a different user than self, ensure we have
// permissions and subsequently replace the user in question
if target.id != "@me" {
if !user.privileged {
return Err(Error::NotPrivileged);
}
user = target.as_user(db).await?;
// Otherwise, filter out invalid edit fields
} else if data.badges.is_some() || data.flags.is_some() {
return Err(Error::NotPrivileged);
}
// Exit out early if nothing is changed
if data.status.is_none() if data.status.is_none()
&& data.profile.is_none() && data.profile.is_none()
&& data.avatar.is_none() && data.avatar.is_none()
&& data.badges.is_none()
&& data.flags.is_none()
&& data.remove.is_none() && data.remove.is_none()
{ {
return Ok(Json(user)); return Ok(Json(user));
@@ -83,7 +109,11 @@ pub async fn req(
} }
} }
let mut partial: PartialUser = Default::default(); let mut partial: PartialUser = PartialUser {
badges: data.badges,
flags: data.flags,
..Default::default()
};
// 2. Apply new avatar // 2. Apply new avatar
if let Some(avatar) = data.avatar { if let Some(avatar) = data.avatar {