Skip to main content

ephemeris_forge_forgejo/plan/
access.rs

1use ephemeris_forge::{
2    AccessDecision, AccessOperation as Operation, CollaboratorDecision, Limitation,
3    PermissionScope, Report,
4};
5
6use crate::config::Access;
7use crate::{Live, Permission};
8
9pub(super) fn plan(
10    config: Option<&Access>,
11    live: &Live,
12    report: &mut Report,
13) -> Vec<Operation<Permission>> {
14    let Some(access) = config else {
15        return Vec::new();
16    };
17    let mut operations = Vec::new();
18    let grants = live.access.grants(PermissionScope::Organization);
19    for decision in access.plan(&grants) {
20        if let AccessDecision::PermissionMismatch {
21            team,
22            expected,
23            actual,
24        } = &decision
25        {
26            report
27                .limitations
28                .push(Limitation::TeamPermissionIsOrganizationWide {
29                    team: team.clone(),
30                    actual: actual.to_string(),
31                    expected: expected.to_string(),
32                    forge: "Forgejo",
33                });
34            continue;
35        }
36        decision.record(report, "Forgejo");
37        operations.extend(team_operation(decision));
38    }
39    for decision in
40        access.plan_collaborators(&live.access.collaborators, live.access.caller.as_ref())
41    {
42        decision.record(report);
43        operations.extend(collaborator_operation(decision));
44    }
45    operations
46}
47
48fn team_operation(decision: AccessDecision<Permission>) -> Option<Operation<Permission>> {
49    match decision {
50        AccessDecision::Add { team, permission } => Some(Operation::AddTeam { team, permission }),
51        AccessDecision::Remove { team } => Some(Operation::RemoveTeam { team }),
52        AccessDecision::PermissionMismatch {
53            team: _,
54            expected: _,
55            actual: _,
56        }
57        | AccessDecision::OrganizationPermission {
58            team: _,
59            expected: _,
60            actual: _,
61        }
62        | AccessDecision::NotInOrganization { team: _ }
63        | AccessDecision::Matches { team: _ }
64        | AccessDecision::SelfRemoval { team: _ }
65        | AccessDecision::Inherited { team: _ } => None,
66    }
67}
68
69fn collaborator_operation(
70    decision: CollaboratorDecision<Permission>,
71) -> Option<Operation<Permission>> {
72    match decision {
73        CollaboratorDecision::Add { user, permission }
74        | CollaboratorDecision::Change {
75            user,
76            permission,
77            actual: _,
78        } => Some(Operation::AddCollaborator { user, permission }),
79        CollaboratorDecision::Remove { user } => Some(Operation::RemoveCollaborator { user }),
80        CollaboratorDecision::Matches { user: _ }
81        | CollaboratorDecision::SelfRemoval { user: _ } => None,
82    }
83}