isb_server/auth/http/config.rs
1//! What the identity endpoints are built with ([`super::AuthApi::new`]).
2
3use std::path::PathBuf;
4use std::sync::Arc;
5
6use super::super::oauth::ProviderConfig;
7use super::super::{Principal, ops};
8use crate::server::http::Request;
9
10/// Something worth telling a user out of band.
11#[derive(Debug, Clone)]
12pub enum Notice {
13 PasswordReset {
14 email: String,
15 token: String,
16 /// The reset page, when the public URL is known.
17 link: Option<String>,
18 },
19}
20
21/// Delivers a [`Notice`] (email, chat). `Err` is logged, never shown to the
22/// requester, who gets the same answer either way.
23pub type Notifier = Arc<dyn Fn(&Notice) -> Result<(), String> + Send + Sync>;
24
25/// The superadmin behind a request, if any: a superadmin token, or a
26/// listed tailnet or Access identity (the daemon's gate).
27pub type SuperadminFn =
28 Arc<dyn Fn(&Request) -> Option<Arc<super::super::Superadmin>> + Send + Sync>;
29
30/// The tailnet or Access agent identity behind a request, if an org maps
31/// it (the daemon's gate).
32pub type AgentFn = Arc<dyn Fn(&Request) -> Option<Principal> + Send + Sync>;
33
34#[derive(Clone, Default)]
35pub struct ApiConfig {
36 /// Who is an org's tailnet or Access agent. Asked last, and only for a
37 /// request with no bearer token and no session cookie.
38 pub agent: Option<AgentFn>,
39 /// Which front doors this server has, for `agent_identity_list`.
40 pub agent_ways: super::super::agent_identities::AgentWays,
41 /// Where users reach isb (`https://isb.example.com`), for the links in
42 /// invitations and resets. Without it the token alone is returned.
43 pub public_url: Option<String>,
44 /// Delivers password resets. Without one, the reset token is written to
45 /// stderr (the daemon's journal) with a note saying so.
46 pub notifier: Option<Notifier>,
47 /// Where the first-run setup token is written while setup is needed.
48 pub setup_token_file: Option<PathBuf>,
49 /// The person the front door verified, if any: who may claim setup
50 /// without the token, and sign in with no password.
51 pub edge: Option<super::super::edge::EdgeFn>,
52 /// External sign-in providers (they need `public_url` for their
53 /// callback URL).
54 pub providers: Vec<ProviderConfig>,
55 /// Let anyone with a verified email from a provider make an account.
56 /// Off: after the first admin, accounts come by invitation.
57 pub open_signup: bool,
58 /// Where sign-ins, token, invitation, member and user changes are
59 /// recorded.
60 pub audit: Option<Arc<crate::audit::AuditLog>>,
61 /// Who is a superadmin. A superadmin is signed in as its principal
62 /// (ahead of any session cookie) and is a platform admin here.
63 pub superadmin: Option<SuperadminFn>,
64 /// The orgs that exist, for `me`: without it the store's org rows
65 /// stand in (see [`ops::me`]).
66 pub orgs: Option<ops::OrgsFn>,
67}
68
69impl std::fmt::Debug for ApiConfig {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 f.debug_struct("ApiConfig")
72 .field("public_url", &self.public_url)
73 .field("notifier", &self.notifier.is_some())
74 .field("setup_token_file", &self.setup_token_file)
75 .field("providers", &self.providers)
76 .field("open_signup", &self.open_signup)
77 .field("audit", &self.audit.is_some())
78 .field("superadmin", &self.superadmin.is_some())
79 .field("agent", &self.agent.is_some())
80 .field("edge", &self.edge.is_some())
81 .field("orgs", &self.orgs.is_some())
82 .finish()
83 }
84}