summaryrefslogtreecommitdiff
path: root/src/authorization/entities.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/authorization/entities.rs')
-rw-r--r--src/authorization/entities.rs145
1 files changed, 0 insertions, 145 deletions
diff --git a/src/authorization/entities.rs b/src/authorization/entities.rs
deleted file mode 100644
index 050f6f26..00000000
--- a/src/authorization/entities.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-use crate::gitlab::Api;
-use serde::Serialize;
-use std::collections::HashSet;
-use std::future::Future;
-use std::pin::Pin;
-
-type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
-
-// Cedar entity structures
-// Note: We define custom types instead of using cedar_policy::Entity directly because:
-// 1. Cedar's Entity type is for runtime use, not JSON serialization
-// 2. These types ensure our JSON output matches Cedar's expected format exactly
-// 3. The #[serde(rename)] attributes handle Cedar's specific field naming requirements
-#[derive(Debug, Serialize)]
-pub struct CedarEntity {
- pub uid: CedarUid,
- pub attrs: serde_json::Value,
- pub parents: Vec<CedarParent>,
-}
-
-#[derive(Debug, Serialize)]
-pub struct CedarUid {
- #[serde(rename = "type")]
- pub entity_type: String,
- pub id: String,
-}
-
-#[derive(Debug, Serialize)]
-pub struct CedarParent {
- #[serde(rename = "type")]
- pub parent_type: String,
- pub id: String,
-}
-
-pub struct EntitiesRepository {
- api: Api,
-}
-
-impl EntitiesRepository {
- pub fn new(api: Api) -> EntitiesRepository {
- EntitiesRepository { api }
- }
-
- pub async fn all(
- &self,
- project_path: String,
- ) -> Result<Vec<CedarEntity>, Box<dyn std::error::Error>> {
- let mut entities = Vec::new();
- let mut groups = HashSet::new();
-
- let project = self.api.get_project(&project_path).await?;
-
- entities.push(CedarEntity {
- uid: CedarUid {
- entity_type: "Project".to_string(),
- id: project.id.to_string(),
- },
- attrs: serde_json::json!({
- "name": project.name,
- "path": project.path,
- "full_path": format!("{}/{}", project.namespace.full_path, project.path),
- }),
- parents: if project.namespace.kind == "group" {
- vec![CedarParent {
- parent_type: "Group".to_string(),
- id: project.namespace.id.to_string(),
- }]
- } else {
- vec![]
- },
- });
-
- for member in self.api.get_project_members(project.id).await? {
- if member.state == "active" {
- entities.push(CedarEntity {
- uid: CedarUid {
- entity_type: "User".to_string(),
- id: member.id.to_string(),
- },
- attrs: serde_json::json!({
- "username": member.username,
- "access_level": member.access_level,
- }),
- parents: vec![],
- });
- }
- }
-
- if project.namespace.kind == "group" {
- self.fetch_hierarchy(project.namespace.id, &mut entities, &mut groups)
- .await?;
- }
-
- Ok(entities)
- }
-
- /// Validates that the entities can be parsed by Cedar
- pub fn is_valid(entities: &[CedarEntity]) -> Result<(), Box<dyn std::error::Error>> {
- let json = serde_json::to_string(entities)?;
- cedar_policy::Entities::from_json_str(&json, None)?;
- Ok(())
- }
-
- fn fetch_hierarchy<'a>(
- &'a self,
- group_id: u64,
- entities: &'a mut Vec<CedarEntity>,
- groups: &'a mut HashSet<u64>,
- ) -> BoxFuture<'a, Result<(), Box<dyn std::error::Error>>> {
- Box::pin(async move {
- if groups.contains(&group_id) {
- return Ok(());
- }
-
- groups.insert(group_id);
-
- let group = self.api.get_group(group_id).await?;
-
- let parents = if let Some(parent_id) = group.parent_id {
- self.fetch_hierarchy(parent_id, entities, groups).await?;
- vec![CedarParent {
- parent_type: "Group".to_string(),
- id: parent_id.to_string(),
- }]
- } else {
- vec![]
- };
-
- entities.push(CedarEntity {
- uid: CedarUid {
- entity_type: "Group".to_string(),
- id: group.id.to_string(),
- },
- attrs: serde_json::json!({
- "name": group.name,
- "path": group.path,
- "full_path": group.full_path,
- }),
- parents,
- });
-
- Ok(())
- })
- }
-}