summaryrefslogtreecommitdiff
path: root/src/authorization/gitlab_entities.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/authorization/gitlab_entities.rs')
-rw-r--r--src/authorization/gitlab_entities.rs208
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