mirror of
https://github.com/lldap/lldap.git
synced 2026-07-25 17:58:44 +00:00
server: Prevent regular users from modifying non-editable attributes
This commit is contained in:
committed by
nitnelave
parent
a6481dde56
commit
829c3f2bb1
@@ -160,10 +160,12 @@ pub struct AttributeList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AttributeList {
|
impl AttributeList {
|
||||||
|
pub fn get_attribute_schema(&self, name: &str) -> Option<&AttributeSchema> {
|
||||||
|
self.attributes.iter().find(|a| a.name == name)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_attribute_type(&self, name: &str) -> Option<(AttributeType, bool)> {
|
pub fn get_attribute_type(&self, name: &str) -> Option<(AttributeType, bool)> {
|
||||||
self.attributes
|
self.get_attribute_schema(name)
|
||||||
.iter()
|
|
||||||
.find(|a| a.name == name)
|
|
||||||
.map(|a| (a.attribute_type, a.is_list))
|
.map(|a| (a.attribute_type, a.is_list))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ impl<Handler: BackendHandler> Mutation<Handler> {
|
|||||||
.attributes
|
.attributes
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|attr| deserialize_attribute(&schema.get_schema().user_attributes, attr))
|
.map(|attr| deserialize_attribute(&schema.get_schema().user_attributes, attr, true))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
handler
|
handler
|
||||||
.create_user(CreateUserRequest {
|
.create_user(CreateUserRequest {
|
||||||
@@ -206,6 +206,7 @@ impl<Handler: BackendHandler> Mutation<Handler> {
|
|||||||
let handler = context
|
let handler = context
|
||||||
.get_writeable_handler(&user_id)
|
.get_writeable_handler(&user_id)
|
||||||
.ok_or_else(field_error_callback(&span, "Unauthorized user update"))?;
|
.ok_or_else(field_error_callback(&span, "Unauthorized user update"))?;
|
||||||
|
let is_admin = context.validation_result.is_admin();
|
||||||
let avatar = user
|
let avatar = user
|
||||||
.avatar
|
.avatar
|
||||||
.map(|bytes| base64::engine::general_purpose::STANDARD.decode(bytes))
|
.map(|bytes| base64::engine::general_purpose::STANDARD.decode(bytes))
|
||||||
@@ -219,7 +220,7 @@ impl<Handler: BackendHandler> Mutation<Handler> {
|
|||||||
.insert_attributes
|
.insert_attributes
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|attr| deserialize_attribute(&schema.get_schema().user_attributes, attr))
|
.map(|attr| deserialize_attribute(&schema.get_schema().user_attributes, attr, is_admin))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
handler
|
handler
|
||||||
.update_user(UpdateUserRequest {
|
.update_user(UpdateUserRequest {
|
||||||
@@ -257,7 +258,7 @@ impl<Handler: BackendHandler> Mutation<Handler> {
|
|||||||
.insert_attributes
|
.insert_attributes
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|attr| deserialize_attribute(&schema.get_schema().group_attributes, attr))
|
.map(|attr| deserialize_attribute(&schema.get_schema().group_attributes, attr, true))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
handler
|
handler
|
||||||
.update_group(UpdateGroupRequest {
|
.update_group(UpdateGroupRequest {
|
||||||
@@ -474,7 +475,7 @@ async fn create_group_with_details<Handler: BackendHandler>(
|
|||||||
.attributes
|
.attributes
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|attr| deserialize_attribute(&schema.get_schema().group_attributes, attr))
|
.map(|attr| deserialize_attribute(&schema.get_schema().group_attributes, attr, true))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let request = CreateGroupRequest {
|
let request = CreateGroupRequest {
|
||||||
display_name: request.display_name,
|
display_name: request.display_name,
|
||||||
@@ -491,11 +492,19 @@ async fn create_group_with_details<Handler: BackendHandler>(
|
|||||||
fn deserialize_attribute(
|
fn deserialize_attribute(
|
||||||
attribute_schema: &AttributeList,
|
attribute_schema: &AttributeList,
|
||||||
attribute: AttributeValue,
|
attribute: AttributeValue,
|
||||||
|
is_admin: bool,
|
||||||
) -> FieldResult<DomainAttributeValue> {
|
) -> FieldResult<DomainAttributeValue> {
|
||||||
let attribute_type = attribute_schema
|
let attribute_schema = attribute_schema
|
||||||
.get_attribute_type(&attribute.name)
|
.get_attribute_schema(&attribute.name)
|
||||||
.ok_or_else(|| anyhow!("Attribute {} is not defined in the schema", attribute.name))?;
|
.ok_or_else(|| anyhow!("Attribute {} is not defined in the schema", attribute.name))?;
|
||||||
if !attribute_type.1 && attribute.value.len() != 1 {
|
if !is_admin && !attribute_schema.is_editable {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"Permission denied: Attribute {} is not editable by regular users",
|
||||||
|
attribute.name
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
if !attribute_schema.is_list && attribute.value.len() != 1 {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Attribute {} is not a list, but multiple values were provided",
|
"Attribute {} is not a list, but multiple values were provided",
|
||||||
attribute.name
|
attribute.name
|
||||||
@@ -515,7 +524,7 @@ fn deserialize_attribute(
|
|||||||
let parse_photo = |value: &String| -> FieldResult<JpegPhoto> {
|
let parse_photo = |value: &String| -> FieldResult<JpegPhoto> {
|
||||||
Ok(JpegPhoto::try_from(value.as_str()).context("Provided image is not a valid JPEG")?)
|
Ok(JpegPhoto::try_from(value.as_str()).context("Provided image is not a valid JPEG")?)
|
||||||
};
|
};
|
||||||
let deserialized_values = match attribute_type {
|
let deserialized_values = match (attribute_schema.attribute_type, attribute_schema.is_list) {
|
||||||
(AttributeType::String, false) => Serialized::from(&attribute.value[0]),
|
(AttributeType::String, false) => Serialized::from(&attribute.value[0]),
|
||||||
(AttributeType::String, true) => Serialized::from(&attribute.value),
|
(AttributeType::String, true) => Serialized::from(&attribute.value),
|
||||||
(AttributeType::Integer, false) => Serialized::from(&parse_int(&attribute.value[0])?),
|
(AttributeType::Integer, false) => Serialized::from(&parse_int(&attribute.value[0])?),
|
||||||
|
|||||||
Reference in New Issue
Block a user