use super::{AccessGrant, Deployment, Rights};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum QuotaSubject {
Workspace,
Owner,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum QuotaSubjectBasis {
WorkspaceCommercialEntitlement,
OwnerFallback,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct QuotaSubjectDecision {
pub subject: QuotaSubject,
pub grant: AccessGrant,
pub basis: QuotaSubjectBasis,
}
pub fn resolve_quota_subject(workspace_grant: &AccessGrant, owner_grant: &AccessGrant) -> QuotaSubjectDecision {
if workspace_grant.rights.commercial {
QuotaSubjectDecision {
subject: QuotaSubject::Workspace,
grant: workspace_grant.clone(),
basis: QuotaSubjectBasis::WorkspaceCommercialEntitlement,
}
} else {
QuotaSubjectDecision {
subject: QuotaSubject::Owner,
grant: owner_grant.clone(),
basis: QuotaSubjectBasis::OwnerFallback,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ByokExecution {
Server,
Local,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ByokAccessContext {
pub deployment: Deployment,
pub execution: ByokExecution,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ByokAccessBasis {
SelfHosted,
Workspace,
Owner,
Actor,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ByokAccessDecision {
pub allowed: bool,
pub basis: Option<ByokAccessBasis>,
}
pub fn evaluate_byok_access(
context: ByokAccessContext,
workspace_rights: Option<Rights>,
owner_rights: Option<Rights>,
actor_rights: Option<Rights>,
) -> ByokAccessDecision {
let basis = match context.deployment {
Deployment::SelfHosted => {
(workspace_rights.is_some() && owner_rights.is_some()).then_some(ByokAccessBasis::SelfHosted)
}
Deployment::Cloud => {
let candidates = match context.execution {
ByokExecution::Server => [
(workspace_rights, ByokAccessBasis::Workspace),
(owner_rights, ByokAccessBasis::Owner),
(None, ByokAccessBasis::Actor),
],
ByokExecution::Local => [
(workspace_rights, ByokAccessBasis::Workspace),
(actor_rights, ByokAccessBasis::Actor),
(owner_rights, ByokAccessBasis::Owner),
],
};
candidates
.into_iter()
.find_map(|(rights, basis)| rights.is_some_and(|rights| rights.copilot_byok).then_some(basis))
}
};
ByokAccessDecision {
allowed: basis.is_some(),
basis,
}
}
#[cfg(test)]
#[path = "../tests/access_control/workspace_access/tests.rs"]
mod tests;