pub struct Orgs { /* private fields */ }Expand description
The organizations module (issue #652): organizations, memberships, roles
and email invitations. Compose it with Orgs::builder.
Implementations§
Source§impl Orgs
impl Orgs
Sourcepub fn new() -> Self
pub fn new() -> Self
The module with its defaults: the owner role alone, no manager roles,
no staff organization. The same as builder().build(), and what a
generated manifest mounts when it has nothing to configure.
Sourcepub fn builder() -> OrgsBuilder
pub fn builder() -> OrgsBuilder
A builder with the default role set: owner alone. Named builder
rather than new, like every other module in this workspace, because
it returns an OrgsBuilder rather than the module itself.
Trait Implementations§
Source§impl Module for Orgs
impl Module for Orgs
Source§fn requires(&self) -> &'static [Port]
fn requires(&self) -> &'static [Port]
Memberships are rows, so the module needs a database; every route but the admin listing acts for the account a credential proves, so it needs a verifier. A deployment without one refuses to boot rather than serving an organization’s roster to whoever asks.
Source§fn optional(&self) -> &'static [Port]
fn optional(&self) -> &'static [Port]
Clock decides “now” for expiry and single-use, IdGen mints ids and
the invitation token, and Mailer delivers the invitation. Each has a
working default or a documented absence, so none is required.
Source§fn personal_data(&self) -> &'static [PersonalDataSet]
fn personal_data(&self) -> &'static [PersonalDataSet]
Three tables, one declaration each — HarnessBuilder::build refuses a
table declared twice, so a column that names a second person cannot
get a declaration of its own and the choice has to be made once per
table:
org_membersis the member’s.Eraseis the only disposition that leaves no membership pointing at an account that no longer exists. Itsinvited_bynames whoever added them — a second person on the member’s row — so it is named inredacted: an export of the row shows the column and not the id. Nothing erases it, and the reason is in the declaration rather than left to be discovered: the framework blanks columns only on the rows a subject’s own value matches.orgsis retained: the row is not one person’s — deleting it would delete every other member’s organization — andcreated_byis kept as provenance. Erasure of the creator’s account does not remove the organization, which is whatRetainsays.org_invitationsis the inviter’s. The row is keyed byinvited_by, so erasing the inviter takes the invitations they sent; the invitee is held only as the SHA-256 of their address, which is not a value an erasure request can carry, so there is nothing to erase for them and nothing of theirs left to read.
Source§fn scheduled<'a>(
&'a self,
ctx: &'a ModuleContext,
cron: &'a str,
) -> BoxFuture<'a, Result<(), AnyError>>
fn scheduled<'a>( &'a self, ctx: &'a ModuleContext, cron: &'a str, ) -> BoxFuture<'a, Result<(), AnyError>>
The scheduled pass: delete invitations that have lapsed, so an organization is not left holding addresses it can no longer invite with. An accepted invitation is kept until it lapses — it is what the accept path reads back to tell who spent the token, and it holds only hashes.
Source§fn tables(&self) -> &'static [&'static str]
fn tables(&self) -> &'static [&'static str]
Source§fn migrations(&self) -> Migrations
fn migrations(&self) -> Migrations
Source§fn validate_config(&self, cfg: &dyn Config) -> Result<(), ConfigError>
fn validate_config(&self, cfg: &dyn Config) -> Result<(), ConfigError>
Source§fn self_check(&self) -> Vec<String>
fn self_check(&self) -> Vec<String>
Source§fn router(&self, ctx: ModuleContext) -> Router
fn router(&self, ctx: ModuleContext) -> Router
/v1/<name>.Source§fn surface(&self) -> Surface
fn surface(&self) -> Surface
Action::input::<Body>()), so the
declaration cannot drift from the route. Harness::build
validates it; GET /__surface serves the composition. Default:
nothing, and a module that declares nothing renders nothing.Source§fn harness_api(&self) -> u32
fn harness_api(&self) -> u32
Harness::build.Source§fn depends_on(&self) -> &'static [&'static str]
fn depends_on(&self) -> &'static [&'static str]
Source§fn actor_kinds(&self) -> &'static [&'static str]
fn actor_kinds(&self) -> &'static [&'static str]
[a-z0-9_-]; duplicates across
modules are a build error, and so is a kind with no handler registered
through
HarnessBuilder::actor. Read moreSource§fn emits(&self) -> &'static [&'static str]
fn emits(&self) -> &'static [&'static str]
"<module>.<event>"), listed by
/__health.Source§fn public_writes(&self) -> bool
fn public_writes(&self) -> bool
Source§fn public_write_policy(&self) -> RoutePolicy
fn public_write_policy(&self) -> RoutePolicy
RoutePolicy on
(issue #143). Read moreSource§fn signature_verification(&self) -> SignatureVerification
fn signature_verification(&self) -> SignatureVerification
RoutePolicy::Signature
deliveries (issue #533): how a webhook handler checks a machine
signature before acting. Read moreSource§fn max_body_bytes(&self, _cfg: &dyn Config) -> usize
fn max_body_bytes(&self, _cfg: &dyn Config) -> usize
Source§fn streaming_routes(&self) -> &'static [StreamRoute]
fn streaming_routes(&self) -> &'static [StreamRoute]
StreamRoute::max_bytes ceiling. Opt-in: the default
is empty, and every existing route keeps the buffered behaviour it
always had. Read moreSource§fn max_blob_object_bytes(&self) -> u64
fn max_blob_object_bytes(&self) -> u64
ScopedBlob the harness hands the module on
put_stream, upload_part and complete_multipart. Read moreSource§fn well_known(&self) -> Option<Router>
fn well_known(&self) -> Option<Router>
/.well-known, for
spec-mandated discovery documents (OIDC openid-configuration,
jwks.json) that must live outside /v1 (issue #46). Paths are
relative to the prefix: register /jwks.json, not
/.well-known/jwks.json. Read more