mirror of
https://github.com/lldap/lldap.git
synced 2026-07-25 17:58:44 +00:00
server: add support for creating a group with attributes
This commit is contained in:
committed by
nitnelave
parent
2c398d0e8e
commit
2a5fd01439
@@ -120,10 +120,18 @@ pub struct UpdateUserRequest {
|
|||||||
pub insert_attributes: Vec<AttributeValue>,
|
pub insert_attributes: Vec<AttributeValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct CreateGroupRequest {
|
||||||
|
pub display_name: String,
|
||||||
|
pub attributes: Vec<AttributeValue>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
|
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct UpdateGroupRequest {
|
pub struct UpdateGroupRequest {
|
||||||
pub group_id: GroupId,
|
pub group_id: GroupId,
|
||||||
pub display_name: Option<String>,
|
pub display_name: Option<String>,
|
||||||
|
pub delete_attributes: Vec<String>,
|
||||||
|
pub insert_attributes: Vec<AttributeValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
|
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
|
||||||
@@ -180,7 +188,7 @@ pub trait GroupListerBackendHandler: ReadSchemaBackendHandler {
|
|||||||
pub trait GroupBackendHandler: ReadSchemaBackendHandler {
|
pub trait GroupBackendHandler: ReadSchemaBackendHandler {
|
||||||
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupDetails>;
|
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupDetails>;
|
||||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
||||||
async fn create_group(&self, group_name: &str) -> Result<GroupId>;
|
async fn create_group(&self, request: CreateGroupRequest) -> Result<GroupId>;
|
||||||
async fn delete_group(&self, group_id: GroupId) -> Result<()>;
|
async fn delete_group(&self, group_id: GroupId) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub mod tests {
|
|||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::{
|
||||||
handler::{
|
handler::{
|
||||||
CreateUserRequest, GroupBackendHandler, UserBackendHandler,
|
CreateGroupRequest, CreateUserRequest, GroupBackendHandler, UserBackendHandler,
|
||||||
UserListerBackendHandler, UserRequestFilter,
|
UserListerBackendHandler, UserRequestFilter,
|
||||||
},
|
},
|
||||||
sql_tables::init_table,
|
sql_tables::init_table,
|
||||||
@@ -98,7 +98,13 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insert_group(handler: &SqlBackendHandler, name: &str) -> GroupId {
|
pub async fn insert_group(handler: &SqlBackendHandler, name: &str) -> GroupId {
|
||||||
handler.create_group(name).await.unwrap()
|
handler
|
||||||
|
.create_group(CreateGroupRequest {
|
||||||
|
display_name: name.to_owned(),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insert_membership(handler: &SqlBackendHandler, group_id: GroupId, user_id: &str) {
|
pub async fn insert_membership(handler: &SqlBackendHandler, group_id: GroupId, user_id: &str) {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use crate::domain::{
|
use crate::domain::{
|
||||||
error::{DomainError, Result},
|
error::{DomainError, Result},
|
||||||
handler::{
|
handler::{
|
||||||
GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter, UpdateGroupRequest,
|
CreateGroupRequest, GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
|
||||||
|
UpdateGroupRequest,
|
||||||
},
|
},
|
||||||
model::{self, GroupColumn, MembershipColumn},
|
model::{self, GroupColumn, MembershipColumn},
|
||||||
sql_backend_handler::SqlBackendHandler,
|
sql_backend_handler::SqlBackendHandler,
|
||||||
@@ -9,9 +10,9 @@ use crate::domain::{
|
|||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use sea_orm::{
|
use sea_orm::{
|
||||||
sea_query::{Alias, Cond, Expr, Func, IntoCondition, SimpleExpr},
|
sea_query::{Alias, Cond, Expr, Func, IntoCondition, OnConflict, SimpleExpr},
|
||||||
ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect,
|
ActiveModelTrait, ColumnTrait, DatabaseTransaction, EntityTrait, QueryFilter, QueryOrder,
|
||||||
QueryTrait,
|
QuerySelect, QueryTrait, Set, TransactionTrait,
|
||||||
};
|
};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
@@ -139,29 +140,61 @@ impl GroupBackendHandler for SqlBackendHandler {
|
|||||||
|
|
||||||
#[instrument(skip(self), level = "debug", err, fields(group_id = ?request.group_id))]
|
#[instrument(skip(self), level = "debug", err, fields(group_id = ?request.group_id))]
|
||||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()> {
|
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()> {
|
||||||
let update_group = model::groups::ActiveModel {
|
Ok(self
|
||||||
group_id: ActiveValue::Set(request.group_id),
|
.sql_pool
|
||||||
display_name: request
|
.transaction::<_, (), DomainError>(|transaction| {
|
||||||
.display_name
|
Box::pin(
|
||||||
.map(ActiveValue::Set)
|
async move { Self::update_group_with_transaction(request, transaction).await },
|
||||||
.unwrap_or_default(),
|
)
|
||||||
..Default::default()
|
})
|
||||||
};
|
.await?)
|
||||||
update_group.update(&self.sql_pool).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug", ret, err)]
|
#[instrument(skip(self), level = "debug", ret, err)]
|
||||||
async fn create_group(&self, group_name: &str) -> Result<GroupId> {
|
async fn create_group(&self, request: CreateGroupRequest) -> Result<GroupId> {
|
||||||
let now = chrono::Utc::now().naive_utc();
|
let now = chrono::Utc::now().naive_utc();
|
||||||
let uuid = Uuid::from_name_and_date(group_name, &now);
|
let uuid = Uuid::from_name_and_date(&request.display_name, &now);
|
||||||
let new_group = model::groups::ActiveModel {
|
let new_group = model::groups::ActiveModel {
|
||||||
display_name: ActiveValue::Set(group_name.to_owned()),
|
display_name: Set(request.display_name),
|
||||||
creation_date: ActiveValue::Set(now),
|
creation_date: Set(now),
|
||||||
uuid: ActiveValue::Set(uuid),
|
uuid: Set(uuid),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
Ok(new_group.insert(&self.sql_pool).await?.group_id)
|
Ok(self
|
||||||
|
.sql_pool
|
||||||
|
.transaction::<_, GroupId, DomainError>(|transaction| {
|
||||||
|
Box::pin(async move {
|
||||||
|
let schema = Self::get_schema_with_transaction(transaction).await?;
|
||||||
|
let group_id = new_group.insert(transaction).await?.group_id;
|
||||||
|
let mut new_group_attributes = Vec::new();
|
||||||
|
for attribute in request.attributes {
|
||||||
|
if schema
|
||||||
|
.group_attributes
|
||||||
|
.get_attribute_type(&attribute.name)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
new_group_attributes.push(model::group_attributes::ActiveModel {
|
||||||
|
group_id: Set(group_id),
|
||||||
|
attribute_name: Set(attribute.name),
|
||||||
|
value: Set(attribute.value),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Err(DomainError::InternalError(format!(
|
||||||
|
"Attribute name {} doesn't exist in the group schema,
|
||||||
|
yet was attempted to be inserted in the database",
|
||||||
|
&attribute.name
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !new_group_attributes.is_empty() {
|
||||||
|
model::GroupAttributes::insert_many(new_group_attributes)
|
||||||
|
.exec(transaction)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
Ok(group_id)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug", err)]
|
#[instrument(skip(self), level = "debug", err)]
|
||||||
@@ -179,10 +212,84 @@ impl GroupBackendHandler for SqlBackendHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SqlBackendHandler {
|
||||||
|
async fn update_group_with_transaction(
|
||||||
|
request: UpdateGroupRequest,
|
||||||
|
transaction: &DatabaseTransaction,
|
||||||
|
) -> Result<()> {
|
||||||
|
let update_group = model::groups::ActiveModel {
|
||||||
|
group_id: Set(request.group_id),
|
||||||
|
display_name: request.display_name.map(Set).unwrap_or_default(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
update_group.update(transaction).await?;
|
||||||
|
let mut update_group_attributes = Vec::new();
|
||||||
|
let mut remove_group_attributes = Vec::new();
|
||||||
|
let schema = Self::get_schema_with_transaction(transaction).await?;
|
||||||
|
for attribute in request.insert_attributes {
|
||||||
|
if schema
|
||||||
|
.group_attributes
|
||||||
|
.get_attribute_type(&attribute.name)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
update_group_attributes.push(model::group_attributes::ActiveModel {
|
||||||
|
group_id: Set(request.group_id),
|
||||||
|
attribute_name: Set(attribute.name.to_owned()),
|
||||||
|
value: Set(attribute.value),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Err(DomainError::InternalError(format!(
|
||||||
|
"Group attribute name {} doesn't exist in the schema, yet was attempted to be inserted in the database",
|
||||||
|
&attribute.name
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for attribute in request.delete_attributes {
|
||||||
|
if schema
|
||||||
|
.group_attributes
|
||||||
|
.get_attribute_type(&attribute)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
remove_group_attributes.push(attribute);
|
||||||
|
} else {
|
||||||
|
return Err(DomainError::InternalError(format!(
|
||||||
|
"Group attribute name {} doesn't exist in the schema, yet was attempted to be removed from the database",
|
||||||
|
attribute
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !remove_group_attributes.is_empty() {
|
||||||
|
model::GroupAttributes::delete_many()
|
||||||
|
.filter(model::GroupAttributesColumn::GroupId.eq(request.group_id))
|
||||||
|
.filter(model::GroupAttributesColumn::AttributeName.is_in(remove_group_attributes))
|
||||||
|
.exec(transaction)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
if !update_group_attributes.is_empty() {
|
||||||
|
model::GroupAttributes::insert_many(update_group_attributes)
|
||||||
|
.on_conflict(
|
||||||
|
OnConflict::columns([
|
||||||
|
model::GroupAttributesColumn::GroupId,
|
||||||
|
model::GroupAttributesColumn::AttributeName,
|
||||||
|
])
|
||||||
|
.update_column(model::GroupAttributesColumn::Value)
|
||||||
|
.to_owned(),
|
||||||
|
)
|
||||||
|
.exec(transaction)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::domain::{handler::SubStringFilter, sql_backend_handler::tests::*, types::UserId};
|
use crate::domain::{
|
||||||
|
handler::{CreateAttributeRequest, SchemaBackendHandler, SubStringFilter},
|
||||||
|
sql_backend_handler::tests::*,
|
||||||
|
types::{AttributeType, Serialized, UserId},
|
||||||
|
};
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
async fn get_group_ids(
|
async fn get_group_ids(
|
||||||
@@ -304,6 +411,8 @@ mod tests {
|
|||||||
.update_group(UpdateGroupRequest {
|
.update_group(UpdateGroupRequest {
|
||||||
group_id: fixture.groups[0],
|
group_id: fixture.groups[0],
|
||||||
display_name: Some("Awesomest Group".to_owned()),
|
display_name: Some("Awesomest Group".to_owned()),
|
||||||
|
delete_attributes: Vec::new(),
|
||||||
|
insert_attributes: Vec::new(),
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -332,4 +441,93 @@ mod tests {
|
|||||||
vec![fixture.groups[2], fixture.groups[1]]
|
vec![fixture.groups[2], fixture.groups[1]]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_create_group() {
|
||||||
|
let fixture = TestFixture::new().await;
|
||||||
|
assert_eq!(
|
||||||
|
get_group_ids(&fixture.handler, None).await,
|
||||||
|
vec![fixture.groups[0], fixture.groups[2], fixture.groups[1]]
|
||||||
|
);
|
||||||
|
fixture
|
||||||
|
.handler
|
||||||
|
.add_group_attribute(CreateAttributeRequest {
|
||||||
|
name: "new_attribute".to_owned(),
|
||||||
|
attribute_type: AttributeType::String,
|
||||||
|
is_list: false,
|
||||||
|
is_visible: true,
|
||||||
|
is_editable: true,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let new_group_id = fixture
|
||||||
|
.handler
|
||||||
|
.create_group(CreateGroupRequest {
|
||||||
|
display_name: "New Group".to_owned(),
|
||||||
|
attributes: vec![AttributeValue {
|
||||||
|
name: "new_attribute".to_owned(),
|
||||||
|
value: Serialized::from("value"),
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let group_details = fixture
|
||||||
|
.handler
|
||||||
|
.get_group_details(new_group_id)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(&group_details.display_name, "New Group");
|
||||||
|
assert_eq!(
|
||||||
|
group_details.attributes,
|
||||||
|
vec![AttributeValue {
|
||||||
|
name: "new_attribute".to_owned(),
|
||||||
|
value: Serialized::from("value"),
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_set_group_attributes() {
|
||||||
|
let fixture = TestFixture::new().await;
|
||||||
|
fixture
|
||||||
|
.handler
|
||||||
|
.add_group_attribute(CreateAttributeRequest {
|
||||||
|
name: "new_attribute".to_owned(),
|
||||||
|
attribute_type: AttributeType::Integer,
|
||||||
|
is_list: false,
|
||||||
|
is_visible: true,
|
||||||
|
is_editable: true,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let group_id = fixture.groups[0];
|
||||||
|
let attributes = vec![AttributeValue {
|
||||||
|
name: "new_attribute".to_owned(),
|
||||||
|
value: Serialized::from(&42i64),
|
||||||
|
}];
|
||||||
|
fixture
|
||||||
|
.handler
|
||||||
|
.update_group(UpdateGroupRequest {
|
||||||
|
group_id,
|
||||||
|
display_name: None,
|
||||||
|
delete_attributes: Vec::new(),
|
||||||
|
insert_attributes: attributes.clone(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let details = fixture.handler.get_group_details(group_id).await.unwrap();
|
||||||
|
assert_eq!(details.attributes, attributes);
|
||||||
|
fixture
|
||||||
|
.handler
|
||||||
|
.update_group(UpdateGroupRequest {
|
||||||
|
group_id,
|
||||||
|
display_name: None,
|
||||||
|
delete_attributes: vec!["new_attribute".to_owned()],
|
||||||
|
insert_attributes: Vec::new(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let details = fixture.handler.get_group_details(group_id).await.unwrap();
|
||||||
|
assert_eq!(details.attributes, Vec::new());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ impl SqlBackendHandler {
|
|||||||
process_serialized(ActiveValue::Set(attribute.value), &attribute.name);
|
process_serialized(ActiveValue::Set(attribute.value), &attribute.name);
|
||||||
} else {
|
} else {
|
||||||
return Err(DomainError::InternalError(format!(
|
return Err(DomainError::InternalError(format!(
|
||||||
"Attribute name {} doesn't exist in the schema, yet was attempted to be inserted in the database",
|
"User attribute name {} doesn't exist in the schema, yet was attempted to be inserted in the database",
|
||||||
&attribute.name
|
&attribute.name
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ impl SqlBackendHandler {
|
|||||||
remove_user_attributes.push(attribute);
|
remove_user_attributes.push(attribute);
|
||||||
} else {
|
} else {
|
||||||
return Err(DomainError::InternalError(format!(
|
return Err(DomainError::InternalError(format!(
|
||||||
"Attribute name {} doesn't exist in the schema, yet was attempted to be removed from the database",
|
"User attribute name {} doesn't exist in the schema, yet was attempted to be removed from the database",
|
||||||
attribute
|
attribute
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@@ -334,7 +334,7 @@ impl UserBackendHandler for SqlBackendHandler {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Err(DomainError::InternalError(format!(
|
return Err(DomainError::InternalError(format!(
|
||||||
"Attribute name {} doesn't exist in the schema,
|
"Attribute name {} doesn't exist in the user schema,
|
||||||
yet was attempted to be inserted in the database",
|
yet was attempted to be inserted in the database",
|
||||||
&attribute.name
|
&attribute.name
|
||||||
)));
|
)));
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use tracing::info;
|
|||||||
use crate::domain::{
|
use crate::domain::{
|
||||||
error::Result,
|
error::Result,
|
||||||
handler::{
|
handler::{
|
||||||
AttributeSchema, BackendHandler, CreateUserRequest,
|
AttributeSchema, BackendHandler, CreateGroupRequest, CreateUserRequest,
|
||||||
GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
|
GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
|
||||||
ReadSchemaBackendHandler, Schema, UpdateGroupRequest, UpdateUserRequest,
|
ReadSchemaBackendHandler, Schema, UpdateGroupRequest, UpdateUserRequest,
|
||||||
UserBackendHandler, UserListerBackendHandler, UserRequestFilter,
|
UserBackendHandler, UserListerBackendHandler, UserRequestFilter,
|
||||||
@@ -101,7 +101,7 @@ pub trait AdminBackendHandler:
|
|||||||
async fn add_user_to_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()>;
|
async fn add_user_to_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()>;
|
||||||
async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()>;
|
async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()>;
|
||||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
||||||
async fn create_group(&self, group_name: &str) -> Result<GroupId>;
|
async fn create_group(&self, request: CreateGroupRequest) -> Result<GroupId>;
|
||||||
async fn delete_group(&self, group_id: GroupId) -> Result<()>;
|
async fn delete_group(&self, group_id: GroupId) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,8 +155,8 @@ impl<Handler: BackendHandler> AdminBackendHandler for Handler {
|
|||||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()> {
|
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()> {
|
||||||
<Handler as GroupBackendHandler>::update_group(self, request).await
|
<Handler as GroupBackendHandler>::update_group(self, request).await
|
||||||
}
|
}
|
||||||
async fn create_group(&self, group_name: &str) -> Result<GroupId> {
|
async fn create_group(&self, request: CreateGroupRequest) -> Result<GroupId> {
|
||||||
<Handler as GroupBackendHandler>::create_group(self, group_name).await
|
<Handler as GroupBackendHandler>::create_group(self, request).await
|
||||||
}
|
}
|
||||||
async fn delete_group(&self, group_id: GroupId) -> Result<()> {
|
async fn delete_group(&self, group_id: GroupId) -> Result<()> {
|
||||||
<Handler as GroupBackendHandler>::delete_group(self, group_id).await
|
<Handler as GroupBackendHandler>::delete_group(self, group_id).await
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::{
|
||||||
handler::{BackendHandler, CreateUserRequest, UpdateGroupRequest, UpdateUserRequest},
|
handler::{
|
||||||
|
BackendHandler, CreateGroupRequest, CreateUserRequest, UpdateGroupRequest,
|
||||||
|
UpdateUserRequest,
|
||||||
|
},
|
||||||
types::{GroupId, JpegPhoto, UserId},
|
types::{GroupId, JpegPhoto, UserId},
|
||||||
},
|
},
|
||||||
infra::{
|
infra::{
|
||||||
@@ -8,7 +11,7 @@ use crate::{
|
|||||||
AdminBackendHandler, ReadonlyBackendHandler, UserReadableBackendHandler,
|
AdminBackendHandler, ReadonlyBackendHandler, UserReadableBackendHandler,
|
||||||
UserWriteableBackendHandler,
|
UserWriteableBackendHandler,
|
||||||
},
|
},
|
||||||
graphql::api::field_error_callback,
|
graphql::api::{field_error_callback, Context},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use anyhow::Context as AnyhowContext;
|
use anyhow::Context as AnyhowContext;
|
||||||
@@ -16,8 +19,6 @@ use base64::Engine;
|
|||||||
use juniper::{graphql_object, FieldResult, GraphQLInputObject, GraphQLObject};
|
use juniper::{graphql_object, FieldResult, GraphQLInputObject, GraphQLObject};
|
||||||
use tracing::{debug, debug_span, Instrument};
|
use tracing::{debug, debug_span, Instrument};
|
||||||
|
|
||||||
use super::api::Context;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
/// The top-level GraphQL mutation type.
|
/// The top-level GraphQL mutation type.
|
||||||
pub struct Mutation<Handler: BackendHandler> {
|
pub struct Mutation<Handler: BackendHandler> {
|
||||||
@@ -126,7 +127,11 @@ impl<Handler: BackendHandler> Mutation<Handler> {
|
|||||||
let handler = context
|
let handler = context
|
||||||
.get_admin_handler()
|
.get_admin_handler()
|
||||||
.ok_or_else(field_error_callback(&span, "Unauthorized group creation"))?;
|
.ok_or_else(field_error_callback(&span, "Unauthorized group creation"))?;
|
||||||
let group_id = handler.create_group(&name).await?;
|
let request = CreateGroupRequest {
|
||||||
|
display_name: name,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let group_id = handler.create_group(request).await?;
|
||||||
Ok(handler
|
Ok(handler
|
||||||
.get_group_details(group_id)
|
.get_group_details(group_id)
|
||||||
.instrument(span)
|
.instrument(span)
|
||||||
@@ -188,6 +193,8 @@ impl<Handler: BackendHandler> Mutation<Handler> {
|
|||||||
.update_group(UpdateGroupRequest {
|
.update_group(UpdateGroupRequest {
|
||||||
group_id: GroupId(group.id),
|
group_id: GroupId(group.id),
|
||||||
display_name: group.display_name,
|
display_name: group.display_name,
|
||||||
|
delete_attributes: Vec::new(),
|
||||||
|
insert_attributes: Vec::new(),
|
||||||
})
|
})
|
||||||
.instrument(span)
|
.instrument(span)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ mockall::mock! {
|
|||||||
impl GroupBackendHandler for TestBackendHandler {
|
impl GroupBackendHandler for TestBackendHandler {
|
||||||
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupDetails>;
|
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupDetails>;
|
||||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
||||||
async fn create_group(&self, group_name: &str) -> Result<GroupId>;
|
async fn create_group(&self, request: CreateGroupRequest) -> Result<GroupId>;
|
||||||
async fn delete_group(&self, group_id: GroupId) -> Result<()>;
|
async fn delete_group(&self, group_id: GroupId) -> Result<()>;
|
||||||
}
|
}
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
+6
-3
@@ -8,8 +8,8 @@ use std::time::Duration;
|
|||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::{
|
||||||
handler::{
|
handler::{
|
||||||
CreateUserRequest, GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
|
CreateGroupRequest, CreateUserRequest, GroupBackendHandler, GroupListerBackendHandler,
|
||||||
UserBackendHandler, UserListerBackendHandler, UserRequestFilter,
|
GroupRequestFilter, UserBackendHandler, UserListerBackendHandler, UserRequestFilter,
|
||||||
},
|
},
|
||||||
sql_backend_handler::SqlBackendHandler,
|
sql_backend_handler::SqlBackendHandler,
|
||||||
sql_opaque_handler::register_password,
|
sql_opaque_handler::register_password,
|
||||||
@@ -63,7 +63,10 @@ async fn ensure_group_exists(handler: &SqlBackendHandler, group_name: &str) -> R
|
|||||||
{
|
{
|
||||||
warn!("Could not find {} group, trying to create it", group_name);
|
warn!("Could not find {} group, trying to create it", group_name);
|
||||||
handler
|
handler
|
||||||
.create_group(group_name)
|
.create_group(CreateGroupRequest {
|
||||||
|
display_name: group_name.to_owned(),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.context(format!("while creating {} group", group_name))?;
|
.context(format!("while creating {} group", group_name))?;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user