Remove enterprise leftovers from community
CI / Rust Checks (push) Failing after 2m6s
CI / UI Checks (push) Has been skipped
CI / Frontend E2E (push) Has been skipped
CI / Deployment Manifests (push) Has been skipped
Deploy / deploy (push) Successful in 2m26s

This commit is contained in:
github-ops
2026-06-20 12:04:46 +00:00
parent 5f8c208409
commit 0af60b1693
46 changed files with 46 additions and 7096 deletions
+2 -229
View File
@@ -1,13 +1,9 @@
use std::sync::Arc;
use async_trait::async_trait;
use time::OffsetDateTime;
use crate::{
IssueAgentTokenRequest, IssueOneTimeAgentTokenRequest, IssuedAgentTokenResponse,
MachineAccessMode, Membership, MembershipRole, OperationSecurityLevel, PlatformApiKeyScope,
User, UserId, WorkspaceId,
MachineAccessMode, Membership, OperationSecurityLevel, PlatformApiKeyScope, User, WorkspaceId,
};
use async_trait::async_trait;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct VerifiedMachineCredential {
@@ -32,70 +28,6 @@ pub trait MachineCredentialVerifier: Send + Sync {
pub type SharedMachineCredentialVerifier = Arc<dyn MachineCredentialVerifier>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TokenIssuerActor {
pub user_id: UserId,
pub workspace_id: WorkspaceId,
pub role: MembershipRole,
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum TokenIssuerError {
#[error("machine tokens are not available in this edition")]
NotSupportedInEdition,
#[error("invalid grant: {0}")]
InvalidGrant(String),
#[error("agent key is unknown")]
AgentKeyUnknown,
#[error("operation is not strict")]
OperationNotStrict,
#[error("operation is not published for agent")]
OperationNotPublishedForAgent,
#[error("registry failure: {0}")]
RegistryFailure(String),
#[error("replay guard failure: {0}")]
ReplayGuardFailure(String),
}
#[async_trait]
pub trait MachineTokenIssuer: Send + Sync {
async fn issue_short_lived(
&self,
request: IssueAgentTokenRequest,
actor: &TokenIssuerActor,
) -> Result<IssuedAgentTokenResponse, TokenIssuerError>;
async fn issue_one_time(
&self,
request: IssueOneTimeAgentTokenRequest,
actor: &TokenIssuerActor,
) -> Result<IssuedAgentTokenResponse, TokenIssuerError>;
}
pub type SharedMachineTokenIssuer = Arc<dyn MachineTokenIssuer>;
#[derive(Clone, Copy, Debug, Default)]
pub struct NoMachineTokenIssuer;
#[async_trait]
impl MachineTokenIssuer for NoMachineTokenIssuer {
async fn issue_short_lived(
&self,
_request: IssueAgentTokenRequest,
_actor: &TokenIssuerActor,
) -> Result<IssuedAgentTokenResponse, TokenIssuerError> {
Err(TokenIssuerError::NotSupportedInEdition)
}
async fn issue_one_time(
&self,
_request: IssueOneTimeAgentTokenRequest,
_actor: &TokenIssuerActor,
) -> Result<IssuedAgentTokenResponse, TokenIssuerError> {
Err(TokenIssuerError::NotSupportedInEdition)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum IdentityProviderKind {
Password,
@@ -126,64 +58,8 @@ pub struct LoginPayload {
pub password: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SsoAuthorizeRequest {
pub workspace_id: WorkspaceId,
pub provider_id: String,
pub base_origin: String,
pub return_to: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SsoAuthorizeRedirect {
pub authorization_url: String,
pub state: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SsoCallbackRequest {
pub workspace_id: WorkspaceId,
pub provider_id: String,
pub code: String,
pub base_origin: String,
pub return_to: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TwoFactorPendingIdentity {
pub user_id: UserId,
pub workspace_id: Option<WorkspaceId>,
pub return_to: Option<String>,
pub expires_at: OffsetDateTime,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TwoFactorStatus {
pub enabled: bool,
pub pending_setup: bool,
pub recovery_codes_remaining: usize,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TwoFactorSetup {
pub secret: String,
pub otpauth_url: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TwoFactorActivation {
pub recovery_codes: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Default)]
pub struct TwoFactorChallenge {
pub code: Option<String>,
pub recovery_code: Option<String>,
}
pub enum LoginOutcome {
Authenticated(AuthenticatedIdentity),
TwoFactorRequired(TwoFactorPendingIdentity),
}
#[async_trait]
@@ -193,109 +69,6 @@ pub trait IdentityProvider: Send + Sync {
fn kind(&self) -> IdentityProviderKind;
async fn login_password(&self, payload: LoginPayload) -> Result<LoginOutcome, IdentityError>;
async fn begin_sso(
&self,
_request: SsoAuthorizeRequest,
) -> Result<SsoAuthorizeRedirect, IdentityError> {
Err(IdentityError::NotSupportedForProvider)
}
async fn complete_sso(
&self,
_request: SsoCallbackRequest,
) -> Result<LoginOutcome, IdentityError> {
Err(IdentityError::NotSupportedForProvider)
}
async fn get_two_factor_status(
&self,
_user_id: &UserId,
) -> Result<TwoFactorStatus, IdentityError> {
Err(IdentityError::NotSupportedForProvider)
}
async fn begin_two_factor_setup(
&self,
_user_id: &UserId,
_email: &str,
) -> Result<TwoFactorSetup, IdentityError> {
Err(IdentityError::NotSupportedForProvider)
}
async fn activate_two_factor(
&self,
_user_id: &UserId,
_code: &str,
) -> Result<TwoFactorActivation, IdentityError> {
Err(IdentityError::NotSupportedForProvider)
}
async fn disable_two_factor(
&self,
_user_id: &UserId,
_challenge: TwoFactorChallenge,
) -> Result<(), IdentityError> {
Err(IdentityError::NotSupportedForProvider)
}
async fn verify_two_factor_login(
&self,
_pending: &TwoFactorPendingIdentity,
_challenge: TwoFactorChallenge,
) -> Result<AuthenticatedIdentity, IdentityError> {
Err(IdentityError::NotSupportedForProvider)
}
}
pub type SharedIdentityProvider = Arc<dyn IdentityProvider>;
#[cfg(test)]
mod tests {
use super::{MachineTokenIssuer, NoMachineTokenIssuer, TokenIssuerActor, TokenIssuerError};
use crate::{
AgentTokenGrantType, IssueAgentTokenRequest, IssueOneTimeAgentTokenRequest, MembershipRole,
UserId, WorkspaceId,
};
fn actor() -> TokenIssuerActor {
TokenIssuerActor {
user_id: UserId::new("user_01"),
workspace_id: WorkspaceId::new("ws_01"),
role: MembershipRole::Owner,
}
}
#[tokio::test]
async fn no_machine_token_issuer_rejects_short_lived_issue() {
let result = NoMachineTokenIssuer
.issue_short_lived(
IssueAgentTokenRequest {
grant_type: AgentTokenGrantType::AgentKey,
agent_key: Some("crk_agent_secret".to_owned()),
refresh_token: None,
scope: vec![],
},
&actor(),
)
.await;
assert_eq!(result, Err(TokenIssuerError::NotSupportedInEdition));
}
#[tokio::test]
async fn no_machine_token_issuer_rejects_one_time_issue() {
let result = NoMachineTokenIssuer
.issue_one_time(
IssueOneTimeAgentTokenRequest {
agent_key: "crk_agent_secret".to_owned(),
operation_id: "op_01".into(),
scope: vec![],
},
&actor(),
)
.await;
assert_eq!(result, Err(TokenIssuerError::NotSupportedInEdition));
}
}
-75
View File
@@ -1,75 +0,0 @@
use std::sync::Arc;
use async_trait::async_trait;
use crate::{TenantId, UsageRollup};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum BillingGate {
Allow,
Deny { reason: String },
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum BillingError {
#[error("billing integration is not available in this edition")]
NotSupportedInEdition,
#[error("billing provider failure: {0}")]
Provider(String),
}
#[async_trait]
pub trait BillingHook: Send + Sync {
async fn on_rollup(&self, rollup: UsageRollup) -> Result<(), BillingError>;
async fn check_billing_gate(&self, tenant: &TenantId) -> Result<BillingGate, BillingError>;
}
pub type SharedBillingHook = Arc<dyn BillingHook>;
#[derive(Clone, Copy, Debug, Default)]
pub struct NoopBillingHook;
#[async_trait]
impl BillingHook for NoopBillingHook {
async fn on_rollup(&self, _rollup: UsageRollup) -> Result<(), BillingError> {
Ok(())
}
async fn check_billing_gate(&self, _tenant: &TenantId) -> Result<BillingGate, BillingError> {
Ok(BillingGate::Allow)
}
}
#[cfg(test)]
mod tests {
use super::{BillingGate, BillingHook, NoopBillingHook};
use crate::{TenantId, UsagePeriod, UsageRollup, WorkspaceId};
#[tokio::test]
async fn noop_billing_hook_allows_default_gate_and_rollups() {
let hook = NoopBillingHook;
hook.on_rollup(UsageRollup {
workspace_id: WorkspaceId::new("ws_01"),
agent_id: None,
operation_id: None,
period: UsagePeriod::Last24Hours,
calls_total: 10,
calls_ok: 9,
calls_error: 1,
p50_ms: 12,
p95_ms: 42,
p99_ms: 77,
})
.await
.unwrap();
let gate = hook
.check_billing_gate(&TenantId::new("tenant_01"))
.await
.unwrap();
assert_eq!(gate, BillingGate::Allow);
}
}
-2
View File
@@ -1,8 +1,6 @@
pub mod access;
pub mod audit;
pub mod auth;
pub mod billing;
pub mod capability;
pub mod metering;
pub mod protocol;
pub mod tenancy;
-81
View File
@@ -1,81 +0,0 @@
use std::sync::Arc;
use async_trait::async_trait;
use crate::{TenantId, WorkspaceId};
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct TenantResolutionContext {
pub workspace_id: Option<WorkspaceId>,
pub workspace_slug: Option<String>,
pub host: Option<String>,
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum TenancyError {
#[error("tenant lookup is not supported in this edition")]
UnsupportedLookup,
#[error("internal tenancy failure: {0}")]
Internal(String),
}
#[async_trait]
pub trait TenantController: Send + Sync {
fn resolve_tenant(&self, request: &TenantResolutionContext) -> Result<TenantId, TenancyError>;
async fn list_workspaces_for_tenant(
&self,
tenant: &TenantId,
) -> Result<Vec<WorkspaceId>, TenancyError>;
}
pub type SharedTenantController = Arc<dyn TenantController>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SingleTenantController {
tenant_id: TenantId,
}
impl Default for SingleTenantController {
fn default() -> Self {
Self {
tenant_id: TenantId::new("default"),
}
}
}
#[async_trait]
impl TenantController for SingleTenantController {
fn resolve_tenant(&self, _request: &TenantResolutionContext) -> Result<TenantId, TenancyError> {
Ok(self.tenant_id.clone())
}
async fn list_workspaces_for_tenant(
&self,
_tenant: &TenantId,
) -> Result<Vec<WorkspaceId>, TenancyError> {
Ok(Vec::new())
}
}
#[cfg(test)]
mod tests {
use super::{SingleTenantController, TenantController, TenantResolutionContext};
use crate::TenantId;
#[tokio::test]
async fn single_tenant_controller_returns_default_tenant() {
let controller = SingleTenantController::default();
let tenant = controller
.resolve_tenant(&TenantResolutionContext::default())
.unwrap();
let workspaces = controller
.list_workspaces_for_tenant(&tenant)
.await
.unwrap();
assert_eq!(tenant, TenantId::new("default"));
assert!(workspaces.is_empty());
}
}