Remove Option from ModelWithPermissions (#529)

<!-- Thank you for submitting this PR! :) -->

## Description

Much as per https://github.com/hasura/v3-engine/pull/524 for
`CommandWithPermission`, this removes the `Option` from
`ModelWithPermissions`. Again, select permissions are opt-in, so
`Some(HashMap::new())` is the same as `None`, so we can remove this
layer of indirection, which I believe was only there because we were
building up the `Model` type incrementally.

Functional no-op.

V3_GIT_ORIGIN_REV_ID: fcb6479f32b001380ae24db6439e96339a868692
This commit is contained in:
Daniel Harvey 2024-05-03 14:19:33 +01:00 committed by hasura-bot
parent 66990c0d91
commit aae750ae92
5 changed files with 87 additions and 117 deletions

View File

@ -84,14 +84,9 @@ pub fn build_model_argument_fields(
gql_schema::DeprecationStatus::NotDeprecated,
);
// if we have select_permissions, then work out which arguments to include in the schema
match &model.select_permissions {
// if no permissions apply, allow the argument through
None => Ok((field_name, builder.allow_all_namespaced(input_field, None))),
Some(permissions_by_namespace) => {
let mut namespaced_annotations = HashMap::new();
for (namespace, permission) in permissions_by_namespace {
for (namespace, permission) in &model.select_permissions {
// if there is a preset for this argument, remove it from the schema
// so the user cannot provide one
if permission.argument_presets.get(argument_name).is_none() {
@ -103,8 +98,6 @@ pub fn build_model_argument_fields(
field_name,
builder.conditional_namespaced(input_field, namespaced_annotations),
))
}
}
})
.collect()
}

View File

@ -20,9 +20,6 @@ pub(crate) fn get_select_permissions_namespace_annotations(
) -> Result<HashMap<Role, Option<types::NamespaceAnnotation>>, schema::Error> {
let mut permissions: HashMap<Role, Option<types::NamespaceAnnotation>> = model
.select_permissions
.as_ref()
.map(|permissions| {
permissions
.iter()
.map(|(role, select_permission)| {
(
@ -54,9 +51,7 @@ pub(crate) fn get_select_permissions_namespace_annotations(
}),
)
})
.collect()
})
.unwrap_or_default();
.collect();
// if any of model argument's input type has field presets defined, add
// them to model argument preset annotations as well. if there is no
@ -453,13 +448,7 @@ pub(crate) fn get_node_field_namespace_permissions(
) -> HashMap<Role, metadata_resolve::FilterPermission> {
let mut permissions = HashMap::new();
match &model.select_permissions {
// Model doesn't have any select permissions, so no `FilterPermission` can be obtained
None => {}
Some(select_permissions) => {
for (role, type_output_permission) in
&object_type_representation.type_output_permissions
{
for (role, type_output_permission) in &object_type_representation.type_output_permissions {
let is_global_id_field_accessible = object_type_representation
.object_type
.global_id_fields
@ -467,7 +456,7 @@ pub(crate) fn get_node_field_namespace_permissions(
.all(|field_name| type_output_permission.allowed_fields.contains(field_name));
if is_global_id_field_accessible {
let select_permission = select_permissions.get(role).map(|s| s.filter.clone());
let select_permission = model.select_permissions.get(role).map(|s| s.filter.clone());
match select_permission {
// Select permission doesn't exist for the role, so no `FilterPermission` can
@ -479,8 +468,6 @@ pub(crate) fn get_node_field_namespace_permissions(
}
};
}
}
}
permissions
}
@ -492,13 +479,7 @@ pub(crate) fn get_entities_field_namespace_permissions(
) -> HashMap<Role, metadata_resolve::FilterPermission> {
let mut permissions = HashMap::new();
match &model.select_permissions {
// Model doesn't have any select permissions, so no `FilterPermission` can be obtained
None => {}
Some(select_permissions) => {
for (role, type_output_permission) in
&object_type_representation.type_output_permissions
{
for (role, type_output_permission) in &object_type_representation.type_output_permissions {
if let Some(apollo_federation_config) = &object_type_representation
.object_type
.apollo_federation_config
@ -512,7 +493,7 @@ pub(crate) fn get_entities_field_namespace_permissions(
if is_all_keys_field_accessible {
let select_permission =
select_permissions.get(role).map(|s| s.filter.clone());
model.select_permissions.get(role).map(|s| s.filter.clone());
match select_permission {
// Select permission doesn't exist for the role, so no `FilterPermission` can
@ -525,8 +506,6 @@ pub(crate) fn get_entities_field_namespace_permissions(
};
}
}
}
}
permissions
}

View File

@ -46,7 +46,7 @@ pub fn resolve(
model_name.clone(),
ModelWithPermissions {
model: model.clone(),
select_permissions: None,
select_permissions: HashMap::new(),
},
)
})
@ -67,8 +67,8 @@ pub fn resolve(
model_name: model_name.clone(),
})?;
if model.select_permissions.is_none() {
let select_permissions = Some(resolve_model_select_permissions(
if model.select_permissions.is_empty() {
let select_permissions = resolve_model_select_permissions(
&model.model,
subgraph,
permissions,
@ -76,7 +76,7 @@ pub fn resolve(
object_types,
models, // This is required to get the model for the relationship target
boolean_expression_types,
)?);
)?;
model.select_permissions = select_permissions;
} else {

View File

@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ModelWithPermissions {
pub model: models::Model,
pub select_permissions: Option<HashMap<Role, SelectPermission>>,
pub select_permissions: HashMap<Role, SelectPermission>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]

View File

@ -25,12 +25,10 @@ pub fn resolve(
}
}
for model in models.values() {
if let Some(select_permissions) = &model.select_permissions {
for role in select_permissions.keys() {
for role in model.select_permissions.keys() {
roles.push(role.clone());
}
}
}
for command in commands.values() {
for role in command.permissions.keys() {
roles.push(role.clone());