server: Add graphql support for creating/deleting attributes
This commit is contained in:
committed by
nitnelave
parent
2a5fd01439
commit
439fde434b
@@ -235,6 +235,7 @@ pub trait BackendHandler:
|
||||
+ UserListerBackendHandler
|
||||
+ GroupListerBackendHandler
|
||||
+ ReadSchemaBackendHandler
|
||||
+ SchemaBackendHandler
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -342,7 +342,17 @@ impl From<&GroupId> for Value {
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, EnumString, IntoStaticStr,
|
||||
Debug,
|
||||
Copy,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Hash,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
EnumString,
|
||||
IntoStaticStr,
|
||||
juniper::GraphQLEnum,
|
||||
)]
|
||||
pub enum AttributeType {
|
||||
String,
|
||||
|
||||
@@ -6,10 +6,10 @@ use tracing::info;
|
||||
use crate::domain::{
|
||||
error::Result,
|
||||
handler::{
|
||||
AttributeSchema, BackendHandler, CreateGroupRequest, CreateUserRequest,
|
||||
GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
|
||||
ReadSchemaBackendHandler, Schema, UpdateGroupRequest, UpdateUserRequest,
|
||||
UserBackendHandler, UserListerBackendHandler, UserRequestFilter,
|
||||
AttributeSchema, BackendHandler, CreateAttributeRequest, CreateGroupRequest,
|
||||
CreateUserRequest, GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
|
||||
ReadSchemaBackendHandler, Schema, SchemaBackendHandler, UpdateGroupRequest,
|
||||
UpdateUserRequest, UserBackendHandler, UserListerBackendHandler, UserRequestFilter,
|
||||
},
|
||||
types::{Group, GroupDetails, GroupId, User, UserAndGroups, UserId},
|
||||
};
|
||||
@@ -94,7 +94,10 @@ pub trait UserWriteableBackendHandler: UserReadableBackendHandler {
|
||||
|
||||
#[async_trait]
|
||||
pub trait AdminBackendHandler:
|
||||
UserWriteableBackendHandler + ReadonlyBackendHandler + UserWriteableBackendHandler
|
||||
UserWriteableBackendHandler
|
||||
+ ReadonlyBackendHandler
|
||||
+ UserWriteableBackendHandler
|
||||
+ SchemaBackendHandler
|
||||
{
|
||||
async fn create_user(&self, request: CreateUserRequest) -> Result<()>;
|
||||
async fn delete_user(&self, user_id: &UserId) -> Result<()>;
|
||||
@@ -103,6 +106,10 @@ pub trait AdminBackendHandler:
|
||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
||||
async fn create_group(&self, request: CreateGroupRequest) -> Result<GroupId>;
|
||||
async fn delete_group(&self, group_id: GroupId) -> Result<()>;
|
||||
async fn add_user_attribute(&self, request: CreateAttributeRequest) -> Result<()>;
|
||||
async fn add_group_attribute(&self, request: CreateAttributeRequest) -> Result<()>;
|
||||
async fn delete_user_attribute(&self, name: &str) -> Result<()>;
|
||||
async fn delete_group_attribute(&self, name: &str) -> Result<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -161,6 +168,18 @@ impl<Handler: BackendHandler> AdminBackendHandler for Handler {
|
||||
async fn delete_group(&self, group_id: GroupId) -> Result<()> {
|
||||
<Handler as GroupBackendHandler>::delete_group(self, group_id).await
|
||||
}
|
||||
async fn add_user_attribute(&self, request: CreateAttributeRequest) -> Result<()> {
|
||||
<Handler as SchemaBackendHandler>::add_user_attribute(self, request).await
|
||||
}
|
||||
async fn add_group_attribute(&self, request: CreateAttributeRequest) -> Result<()> {
|
||||
<Handler as SchemaBackendHandler>::add_group_attribute(self, request).await
|
||||
}
|
||||
async fn delete_user_attribute(&self, name: &str) -> Result<()> {
|
||||
<Handler as SchemaBackendHandler>::delete_user_attribute(self, name).await
|
||||
}
|
||||
async fn delete_group_attribute(&self, name: &str) -> Result<()> {
|
||||
<Handler as SchemaBackendHandler>::delete_group_attribute(self, name).await
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AccessControlledBackendHandler<Handler> {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::{
|
||||
domain::{
|
||||
handler::{
|
||||
BackendHandler, CreateGroupRequest, CreateUserRequest, UpdateGroupRequest,
|
||||
UpdateUserRequest,
|
||||
BackendHandler, CreateAttributeRequest, CreateGroupRequest, CreateUserRequest,
|
||||
UpdateGroupRequest, UpdateUserRequest,
|
||||
},
|
||||
types::{GroupId, JpegPhoto, UserId},
|
||||
types::{AttributeType, GroupId, JpegPhoto, UserId},
|
||||
},
|
||||
infra::{
|
||||
access_control::{
|
||||
@@ -285,4 +285,108 @@ impl<Handler: BackendHandler> Mutation<Handler> {
|
||||
.await?;
|
||||
Ok(Success::new())
|
||||
}
|
||||
|
||||
async fn add_user_attribute(
|
||||
context: &Context<Handler>,
|
||||
name: String,
|
||||
attribute_type: AttributeType,
|
||||
is_list: bool,
|
||||
is_visible: bool,
|
||||
is_editable: bool,
|
||||
) -> FieldResult<Success> {
|
||||
let span = debug_span!("[GraphQL mutation] add_user_attribute");
|
||||
span.in_scope(|| {
|
||||
debug!(?name, ?attribute_type, is_list, is_visible, is_editable);
|
||||
});
|
||||
let handler = context
|
||||
.get_admin_handler()
|
||||
.ok_or_else(field_error_callback(
|
||||
&span,
|
||||
"Unauthorized attribute creation",
|
||||
))?;
|
||||
handler
|
||||
.add_user_attribute(CreateAttributeRequest {
|
||||
name,
|
||||
attribute_type,
|
||||
is_list,
|
||||
is_visible,
|
||||
is_editable,
|
||||
})
|
||||
.instrument(span)
|
||||
.await?;
|
||||
Ok(Success::new())
|
||||
}
|
||||
|
||||
async fn add_group_attribute(
|
||||
context: &Context<Handler>,
|
||||
name: String,
|
||||
attribute_type: AttributeType,
|
||||
is_list: bool,
|
||||
is_visible: bool,
|
||||
is_editable: bool,
|
||||
) -> FieldResult<Success> {
|
||||
let span = debug_span!("[GraphQL mutation] add_group_attribute");
|
||||
span.in_scope(|| {
|
||||
debug!(?name, ?attribute_type, is_list, is_visible, is_editable);
|
||||
});
|
||||
let handler = context
|
||||
.get_admin_handler()
|
||||
.ok_or_else(field_error_callback(
|
||||
&span,
|
||||
"Unauthorized attribute creation",
|
||||
))?;
|
||||
handler
|
||||
.add_group_attribute(CreateAttributeRequest {
|
||||
name,
|
||||
attribute_type,
|
||||
is_list,
|
||||
is_visible,
|
||||
is_editable,
|
||||
})
|
||||
.instrument(span)
|
||||
.await?;
|
||||
Ok(Success::new())
|
||||
}
|
||||
|
||||
async fn delete_user_attribute(
|
||||
context: &Context<Handler>,
|
||||
name: String,
|
||||
) -> FieldResult<Success> {
|
||||
let span = debug_span!("[GraphQL mutation] delete_user_attribute");
|
||||
span.in_scope(|| {
|
||||
debug!(?name);
|
||||
});
|
||||
let handler = context
|
||||
.get_admin_handler()
|
||||
.ok_or_else(field_error_callback(
|
||||
&span,
|
||||
"Unauthorized attribute deletion",
|
||||
))?;
|
||||
handler
|
||||
.delete_user_attribute(&name)
|
||||
.instrument(span)
|
||||
.await?;
|
||||
Ok(Success::new())
|
||||
}
|
||||
|
||||
async fn delete_group_attribute(
|
||||
context: &Context<Handler>,
|
||||
name: String,
|
||||
) -> FieldResult<Success> {
|
||||
let span = debug_span!("[GraphQL mutation] delete_group_attribute");
|
||||
span.in_scope(|| {
|
||||
debug!(?name);
|
||||
});
|
||||
let handler = context
|
||||
.get_admin_handler()
|
||||
.ok_or_else(field_error_callback(
|
||||
&span,
|
||||
"Unauthorized attribute deletion",
|
||||
))?;
|
||||
handler
|
||||
.delete_group_attribute(&name)
|
||||
.instrument(span)
|
||||
.await?;
|
||||
Ok(Success::new())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,9 +438,8 @@ impl<Handler: BackendHandler> AttributeSchema<Handler> {
|
||||
fn name(&self) -> String {
|
||||
self.schema.name.clone()
|
||||
}
|
||||
fn attribute_type(&self) -> String {
|
||||
let name: &'static str = self.schema.attribute_type.into();
|
||||
name.to_owned()
|
||||
fn attribute_type(&self) -> AttributeType {
|
||||
self.schema.attribute_type
|
||||
}
|
||||
fn is_list(&self) -> bool {
|
||||
self.schema.is_list
|
||||
@@ -917,7 +916,7 @@ mod tests {
|
||||
"attributes": [
|
||||
{
|
||||
"name": "avatar",
|
||||
"attributeType": "JpegPhoto",
|
||||
"attributeType": "JPEG_PHOTO",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": true,
|
||||
@@ -925,7 +924,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "creation_date",
|
||||
"attributeType": "DateTime",
|
||||
"attributeType": "DATE_TIME",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": false,
|
||||
@@ -933,7 +932,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "display_name",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": true,
|
||||
@@ -941,7 +940,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "first_name",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": true,
|
||||
@@ -949,7 +948,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "last_name",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": true,
|
||||
@@ -957,7 +956,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "mail",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": true,
|
||||
@@ -965,7 +964,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "user_id",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": false,
|
||||
@@ -973,7 +972,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "uuid",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": false,
|
||||
@@ -985,7 +984,7 @@ mod tests {
|
||||
"attributes": [
|
||||
{
|
||||
"name": "creation_date",
|
||||
"attributeType": "DateTime",
|
||||
"attributeType": "DATE_TIME",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": false,
|
||||
@@ -993,7 +992,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "display_name",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": true,
|
||||
@@ -1001,7 +1000,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "group_id",
|
||||
"attributeType": "Integer",
|
||||
"attributeType": "INTEGER",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": false,
|
||||
@@ -1009,7 +1008,7 @@ mod tests {
|
||||
},
|
||||
{
|
||||
"name": "uuid",
|
||||
"attributeType": "String",
|
||||
"attributeType": "STRING",
|
||||
"isList": false,
|
||||
"isVisible": true,
|
||||
"isEditable": false,
|
||||
|
||||
@@ -42,6 +42,13 @@ mockall::mock! {
|
||||
async fn get_schema(&self) -> Result<Schema>;
|
||||
}
|
||||
#[async_trait]
|
||||
impl SchemaBackendHandler for TestBackendHandler {
|
||||
async fn add_user_attribute(&self, request: CreateAttributeRequest) -> Result<()>;
|
||||
async fn add_group_attribute(&self, request: CreateAttributeRequest) -> Result<()>;
|
||||
async fn delete_user_attribute(&self, name: &str) -> Result<()>;
|
||||
async fn delete_group_attribute(&self, name: &str) -> Result<()>;
|
||||
}
|
||||
#[async_trait]
|
||||
impl BackendHandler for TestBackendHandler {}
|
||||
#[async_trait]
|
||||
impl OpaqueHandler for TestBackendHandler {
|
||||
|
||||
Reference in New Issue
Block a user