diff options
Diffstat (limited to 'src/authorization/gitlab_entities.rs')
| -rw-r--r-- | src/authorization/gitlab_entities.rs | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/authorization/gitlab_entities.rs b/src/authorization/gitlab_entities.rs new file mode 100644 index 00000000..643f90e8 --- /dev/null +++ b/src/authorization/gitlab_entities.rs @@ -0,0 +1,208 @@ +use serde::Serialize; +use std::collections::HashMap; + +// Cedar entity structures optimized for GitLab authorization +#[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, +} + +// GitLab-specific entity builders +pub struct GitLabEntityBuilder; + +impl GitLabEntityBuilder { + // Build User entity with GitLab-specific attributes + pub fn build_user(user: &crate::gitlab::User) -> CedarEntity { + CedarEntity { + uid: CedarUid { + entity_type: "User".to_string(), + id: user.id.to_string(), + }, + attrs: serde_json::json!({ + "username": user.username, + "name": user.name, + "admin": user.admin.unwrap_or(false), + "blocked": user.state == "blocked", + "bot": user.bot.unwrap_or(false), + "external": user.external.unwrap_or(false), + "created_at": user.created_at + }), + parents: vec![], + } + } + + // Build Project entity - simplified without feature checks + pub fn build_project(project: &crate::gitlab::Project) -> CedarEntity { + 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": project.path_with_namespace, + "visibility": project.visibility, + "archived": project.archived.unwrap_or(false), + "members": [] // Will be populated separately + }), + parents: vec![CedarParent { + parent_type: "Namespace".to_string(), + id: project.namespace.id.to_string(), + }], + } + } + + // Build Group/Namespace entity + pub fn build_namespace(namespace: &crate::gitlab::Namespace) -> CedarEntity { + let mut parents = vec![]; + if let Some(parent_id) = namespace.parent_id { + parents.push(CedarParent { + parent_type: "Namespace".to_string(), + id: parent_id.to_string(), + }); + } + + CedarEntity { + uid: CedarUid { + entity_type: "Namespace".to_string(), + id: namespace.id.to_string(), + }, + attrs: serde_json::json!({ + "name": namespace.name, + "path": namespace.path, + "full_path": namespace.full_path, + "kind": namespace.kind, + "visibility_level": namespace.visibility_level + }), + parents, + } + } + + // Build Membership entity - represents user access to projects/groups + pub fn build_project_membership( + user_id: u64, + project_id: u64, + member: &crate::gitlab::Member, + ) -> CedarEntity { + CedarEntity { + uid: CedarUid { + entity_type: "ProjectMembership".to_string(), + id: format!("{}:{}", user_id, project_id), + }, + attrs: serde_json::json!({ + "user_id": user_id, + "project_id": project_id, + "access_level": member.access_level, + "expires_at": member.expires_at + }), + parents: vec![ + CedarParent { + parent_type: "User".to_string(), + id: user_id.to_string(), + }, + CedarParent { + parent_type: "Project".to_string(), + id: project_id.to_string(), + }, + ], + } + } + + // Build Group Membership entity + pub fn build_group_membership( + user_id: u64, + group_id: u64, + member: &crate::gitlab::Member, + ) -> CedarEntity { + CedarEntity { + uid: CedarUid { + entity_type: "GroupMembership".to_string(), + id: format!("{}:{}", user_id, group_id), + }, + attrs: serde_json::json!({ + "user_id": user_id, + "group_id": group_id, + "access_level": member.access_level, + "expires_at": member.expires_at + }), + parents: vec![ + CedarParent { + parent_type: "User".to_string(), + id: user_id.to_string(), + }, + CedarParent { + parent_type: "Namespace".to_string(), + id: group_id.to_string(), + }, + ], + } + } + + // Build Issue entity + pub fn build_issue(issue: &crate::gitlab::Issue, project_id: u64) -> CedarEntity { + CedarEntity { + uid: CedarUid { + entity_type: "Issue".to_string(), + id: issue.id.to_string(), + }, + attrs: serde_json::json!({ + "iid": issue.iid, + "title": issue.title, + "state": issue.state, + "confidential": issue.confidential, + "author_id": issue.author.id, + "assignee_ids": issue.assignees.iter().map(|a| a.id).collect::<Vec<_>>(), + "created_at": issue.created_at, + "updated_at": issue.updated_at + }), + parents: vec![CedarParent { + parent_type: "Project".to_string(), + id: project_id.to_string(), + }], + } + } + + // Build MergeRequest entity + pub fn build_merge_request(mr: &crate::gitlab::MergeRequest, project_id: u64) -> CedarEntity { + CedarEntity { + uid: CedarUid { + entity_type: "MergeRequest".to_string(), + id: mr.id.to_string(), + }, + attrs: serde_json::json!({ + "iid": mr.iid, + "title": mr.title, + "state": mr.state, + "merge_status": mr.merge_status, + "author_id": mr.author.id, + "assignee_id": mr.assignee.as_ref().map(|a| a.id), + "target_branch": mr.target_branch, + "source_branch": mr.source_branch, + "work_in_progress": mr.work_in_progress, + "created_at": mr.created_at, + "updated_at": mr.updated_at + }), + parents: vec![CedarParent { + parent_type: "Project".to_string(), + id: project_id.to_string(), + }], + } + } +}
\ No newline at end of file |
