Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions src/assignment/backend/sql/assignment/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ pub async fn list_for_multiple_actors_and_targets(
for target in params.targets.iter() {
cond = cond.add(
Condition::all()
.add(db_assignment::Column::TargetId.eq(&target.target_id))
.add(db_assignment::Column::TargetId.eq(&target.id))
.add_option(
target
.inherited
Expand Down Expand Up @@ -438,7 +438,8 @@ mod tests {
&RoleAssignmentListForMultipleActorTargetParameters {
actors: vec!["uid1".into(), "gid1".into(), "gid2".into()],
targets: vec![RoleAssignmentTarget {
target_id: "pid1".into(),
id: "pid1".into(),
r#type: RoleAssignmentTargetType::Project,
inherited: None
}],
role_id: Some("rid".into())
Expand Down Expand Up @@ -516,11 +517,13 @@ mod tests {
actors: vec!["uid1".into(), "gid1".into(), "gid2".into()],
targets: vec![
RoleAssignmentTarget {
target_id: "pid1".into(),
id: "pid1".into(),
r#type: RoleAssignmentTargetType::Project,
inherited: None
},
RoleAssignmentTarget {
target_id: "pid2".into(),
id: "pid2".into(),
r#type: RoleAssignmentTargetType::Project,
inherited: Some(true)
}
],
Expand Down Expand Up @@ -635,11 +638,13 @@ mod tests {
actors: vec![],
targets: vec![
RoleAssignmentTarget {
target_id: "pid1".into(),
id: "pid1".into(),
r#type: RoleAssignmentTargetType::Project,
inherited: None
},
RoleAssignmentTarget {
target_id: "pid2".into(),
id: "pid2".into(),
r#type: RoleAssignmentTargetType::Project,
inherited: Some(true)
}
],
Expand Down Expand Up @@ -692,11 +697,13 @@ mod tests {
actors: vec![],
targets: vec![
RoleAssignmentTarget {
target_id: "pid1".into(),
id: "pid1".into(),
r#type: RoleAssignmentTargetType::Project,
inherited: Some(false)
},
RoleAssignmentTarget {
target_id: "pid2".into(),
id: "pid2".into(),
r#type: RoleAssignmentTargetType::Project,
inherited: Some(true)
}
],
Expand Down
7 changes: 7 additions & 0 deletions src/assignment/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ pub enum AssignmentProviderError {
#[from]
source: RoleBuilderError,
},

#[error("request validation error: {}", source)]
Validation {
/// The source of the error.
#[from]
source: validator::ValidationErrors,
},
}

impl From<AssignmentDatabaseError> for AssignmentProviderError {
Expand Down
14 changes: 10 additions & 4 deletions src/assignment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// SPDX-License-Identifier: Apache-2.0

use async_trait::async_trait;
use validator::Validate;

pub mod backend;
pub mod error;
Expand All @@ -23,7 +24,8 @@ use crate::assignment::backend::{AssignmentBackend, SqlBackend};
use crate::assignment::error::AssignmentProviderError;
use crate::assignment::types::{
Assignment, Role, RoleAssignmentListForMultipleActorTargetParametersBuilder,
RoleAssignmentListParameters, RoleAssignmentTarget, RoleListParameters,
RoleAssignmentListParameters, RoleAssignmentTarget, RoleAssignmentTargetType,
RoleListParameters,
};
use crate::config::Config;
use crate::identity::IdentityApi;
Expand Down Expand Up @@ -93,6 +95,7 @@ impl AssignmentApi for AssignmentProvider {
state: &ServiceState,
params: &RoleAssignmentListParameters,
) -> Result<impl IntoIterator<Item = Assignment>, AssignmentProviderError> {
params.validate()?;
let mut request = RoleAssignmentListForMultipleActorTargetParametersBuilder::default();
let mut actors: Vec<String> = Vec::new();
let mut targets: Vec<RoleAssignmentTarget> = Vec::new();
Expand All @@ -114,7 +117,8 @@ impl AssignmentApi for AssignmentProvider {
};
if let Some(val) = &params.project_id {
targets.push(RoleAssignmentTarget {
target_id: val.clone(),
id: val.clone(),
r#type: RoleAssignmentTargetType::Project,
inherited: Some(false),
});
if let Some(parents) = state
Expand All @@ -125,14 +129,16 @@ impl AssignmentApi for AssignmentProvider {
{
parents.iter().for_each(|parent_project| {
targets.push(RoleAssignmentTarget {
target_id: parent_project.id.clone(),
id: parent_project.id.clone(),
r#type: RoleAssignmentTargetType::Project,
inherited: Some(true),
});
});
}
} else if let Some(val) = &params.domain_id {
targets.push(RoleAssignmentTarget {
target_id: val.clone(),
id: val.clone(),
r#type: RoleAssignmentTargetType::Domain,
inherited: Some(false),
});
}
Expand Down
8 changes: 1 addition & 7 deletions src/assignment/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,7 @@ use async_trait::async_trait;
use crate::assignment::AssignmentProviderError;
use crate::keystone::ServiceState;

pub use crate::assignment::types::assignment::{
Assignment, AssignmentBuilder, AssignmentBuilderError, AssignmentType,
RoleAssignmentListForMultipleActorTargetParameters,
RoleAssignmentListForMultipleActorTargetParametersBuilder, RoleAssignmentListParameters,
RoleAssignmentListParametersBuilder, RoleAssignmentListParametersBuilderError,
RoleAssignmentTarget,
};
pub use crate::assignment::types::assignment::*;
pub use crate::assignment::types::role::{Role, RoleBuilder, RoleBuilderError, RoleListParameters};

#[async_trait]
Expand Down
63 changes: 50 additions & 13 deletions src/assignment/types/assignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,45 @@
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use std::fmt;
use validator::Validate;

/// Role
#[derive(Builder, Clone, Debug, Deserialize, PartialEq, Serialize)]
/// The assignment object.
#[derive(Builder, Clone, Debug, Deserialize, PartialEq, Serialize, Validate)]
#[builder(setter(strip_option, into))]
pub struct Assignment {
/// The role ID.
#[validate(length(max = 64))]
pub role_id: String,
/// The role ID.
/// The role name.
#[builder(default)]
#[validate(length(max = 64))]
pub role_name: Option<String>,
/// The actor id.
#[validate(length(max = 64))]
pub actor_id: String,
/// The target id.
#[validate(length(max = 64))]
pub target_id: String,
/// The assignment type.
pub r#type: AssignmentType,
/// Inherited flag.
pub inherited: bool,
}

/// Role assignment type
/// Role assignment type.
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub enum AssignmentType {
/// Group to the domain.
GroupDomain,
/// Group to the project.
GroupProject,
/// User to the domain.
UserDomain,
/// User to the project.
UserProject,
/// User to the system.
UserSystem,
/// Group to the system.
GroupSystem,
}

Expand All @@ -60,28 +71,35 @@ impl fmt::Display for AssignmentType {
}

/// Parameters for listing role assignments for role/target/actor.
#[derive(Builder, Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
#[derive(Builder, Clone, Debug, Default, Deserialize, PartialEq, Serialize, Validate)]
#[builder(setter(strip_option, into))]
pub struct RoleAssignmentListParameters {
/// Query role assignments filtering results by the role
#[builder(default)]
#[validate(length(max = 64))]
pub role_id: Option<String>,

/// Get role assignments for the user
/// Get role assignments for the user.
#[builder(default)]
#[validate(length(max = 64))]
pub user_id: Option<String>,
/// Get role assignments for the group

/// Get role assignments for the group.
#[builder(default)]
#[validate(length(max = 64))]
pub group_id: Option<String>,

/// Query role assignments on the project
/// Query role assignments on the project.
#[builder(default)]
#[validate(length(max = 64))]
pub project_id: Option<String>,
/// Query role assignments on the domain
/// Query role assignments on the domain.
#[builder(default)]
#[validate(length(max = 64))]
pub domain_id: Option<String>,
/// Query role assignments on the system
/// Query role assignments on the system.
#[builder(default)]
#[validate(length(max = 64))]
pub system: Option<String>,

// #[builder(default)]
Expand All @@ -101,26 +119,45 @@ pub struct RoleAssignmentListParameters {
/// Querying effective role assignments for list of actors (typically user with
/// all groups user is member of) on list of targets (exactl project + inherited
/// from uppoer projects/domain).
#[derive(Builder, Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
#[derive(Builder, Clone, Debug, Default, Deserialize, PartialEq, Serialize, Validate)]
#[builder(setter(strip_option, into))]
pub struct RoleAssignmentListForMultipleActorTargetParameters {
/// List of actors for which assignments are looked up.
#[builder(default)]
#[validate(length(max = 64))]
pub actors: Vec<String>,

/// Optionally filter for the concrete role ID.
#[builder(default)]
#[validate(length(max = 64))]
pub role_id: Option<String>,

/// List of targets for which assignments are looked up.
#[builder(default)]
#[validate(nested)]
pub targets: Vec<RoleAssignmentTarget>,
}

/// Role assignment target which is either target_id or target_id with explicit
/// inherited parameter.
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Validate)]
pub struct RoleAssignmentTarget {
pub target_id: String,
/// The role assignment target ID.
#[validate(length(max = 64))]
pub id: String,
/// The role assignment target type.
pub r#type: RoleAssignmentTargetType,
/// Specifies whether the target is only considered for inherited assignments.
pub inherited: Option<bool>,
}

/// Role assignment target as Project(id), Domain(id) or System(id).
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum RoleAssignmentTargetType {
/// Project ID.
Project,
/// Domain ID.
Domain,
/// System ID.
System,
}
Loading