use gunnar_proto::{DirectoryUser, Principal, ScimToken, SsoProvider};
use crate::seam::ControlResult;
#[derive(Clone, PartialEq, Eq)]
pub enum SecretChange {
Keep,
Clear,
Set(String),
}
impl std::fmt::Debug for SecretChange {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
SecretChange::Keep => "Keep",
SecretChange::Clear => "Clear",
SecretChange::Set(_) => "Set(<redacted>)",
})
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Room {
pub room_bytes: u64,
pub cap: Option<u64>,
pub stored: u64,
}
#[derive(Clone)]
pub struct SsoLoginAsk {
pub account: String,
pub issuer: String,
pub subject: String,
pub user_name: String,
pub display_name: String,
pub email: String,
pub email_verified: bool,
pub idp_ids: Vec<String>,
pub room: Room,
pub session: Option<(String, i64)>,
pub now_unix_ms: i64,
}
impl std::fmt::Debug for SsoLoginAsk {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SsoLoginAsk")
.field("account", &self.account)
.field("user_name", &self.user_name)
.finish_non_exhaustive()
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct DirUser {
pub user: DirectoryUser,
pub deleted: bool,
}
#[derive(Debug, Clone)]
pub struct SsoLoginOutcome {
pub principal: Principal,
pub user: DirUser,
pub created: bool,
pub claimed: bool,
pub claimed_by: String,
pub fingerprint: Option<String>,
}
#[derive(Debug, Clone)]
pub struct ProvisionAsk {
pub account: String,
pub user_name: String,
pub display_name: String,
pub email: String,
pub external_id: String,
pub active: bool,
pub source: &'static str,
pub room: Room,
pub actor: String,
pub now_unix_ms: i64,
}
#[derive(Debug, Clone, Default)]
pub struct UserPatch {
pub user_name: Option<String>,
pub display_name: Option<String>,
pub email: Option<String>,
pub external_id: Option<String>,
pub active: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GroupRow {
pub id: String,
pub account: String,
pub display_name: String,
pub external_id: String,
pub members: Vec<String>,
pub created_at_unix_ms: i64,
}
pub trait SsoPlane: Send + Sync {
fn provider(&self, account: &str) -> ControlResult<Option<SsoProvider>>;
fn set_provider(
&self,
provider: SsoProvider,
secret: SecretChange,
actor: &str,
) -> ControlResult<SsoProvider>;
fn remove_provider(&self, account: &str) -> ControlResult<bool>;
fn any_provider(&self) -> ControlResult<bool>;
fn account_for_domain(&self, domain: &str) -> ControlResult<Option<String>>;
fn client_secret(&self, account: &str) -> ControlResult<Option<String>>;
fn login(&self, ask: SsoLoginAsk) -> ControlResult<SsoLoginOutcome>;
fn directory(&self, account: &str) -> ControlResult<Vec<DirUser>>;
fn provision(&self, ask: ProvisionAsk) -> ControlResult<DirUser>;
fn update_user(
&self,
account: &str,
principal_id: &str,
patch: UserPatch,
actor: &str,
) -> ControlResult<(DirUser, bool)>;
fn delete_user(&self, account: &str, principal_id: &str, actor: &str)
-> ControlResult<DirUser>;
fn create_scim_token(
&self,
account: &str,
id: &str,
label: &str,
secret_hash: &str,
created_by: &str,
) -> ControlResult<ScimToken>;
fn scim_tokens(&self, account: &str) -> ControlResult<Vec<ScimToken>>;
fn revoke_scim_token(&self, account: &str, id: &str) -> ControlResult<bool>;
fn scim_account(&self, secret_hash: &str) -> ControlResult<Option<String>>;
fn groups(&self, account: &str) -> ControlResult<Vec<GroupRow>>;
fn put_group(&self, group: GroupRow) -> ControlResult<GroupRow>;
fn remove_group(&self, account: &str, id: &str) -> ControlResult<bool>;
fn passkey_login_refused(&self, principal_id: &str) -> ControlResult<Option<String>>;
fn passkeys_of(&self, principal_id: &str) -> ControlResult<Vec<Vec<u8>>>;
}