Add Tenants to Administration, and let an account be put in one
A tenant is a separate organisation on one server: its own people, domains and limits, and an administrator who manages only what is in it. It gets a section under Access, gated by sysTenantQuery and sysTenantGet, with a notice on a server that does not report Enterprise, where anyone inside a tenant is held to an ordinary user's permissions. The panel edits the tenant's name, logo, role and limits. The logo is an https address, drawn through the image proxy the strict image policy requires, or an image data URL. Limits change one quotas/<name> pointer each, so the four ihasmail does not offer keep their values, and an empty field is no limit. The role is the most anyone inside can be allowed. Stalwart keeps no list on a tenant -- each account, group, domain, list and role names its own -- so what a tenant holds is counted with memberTenantId queries and shown against its limits. Domains are added and taken out from the tenant's panel, one memberTenantId change each; only a domain in no tenant can be added, and its accounts stay where they are. Delete is offered once every count reads zero. A tenant does nothing until someone administers it, so the account panel gains a Tenant choice for an administrator who can read tenants: an Administrator inside a tenant administers that tenant. Nobody moves their own account. The mock has a tenant holding a domain and an administrator, a spare domain to assign, memberTenantId filters on every query, and Stalwart's rule that only an administrator outside every tenant may move things into one. A test of taking a domain back out found that the mock's pointer handling dropped a top-level null instead of storing it, so nothing had ever been cleared that way; it stores null now, as the server reads it back. Nothing about tenants has been written on a live server: production has none. KNOWN-ISSUES says what was read from source. Thirty-nine new strings and one plural, in all nine catalogues.
This commit is contained in:
@@ -86,6 +86,8 @@ works the same way — and dropped where 0.15 was the whole subject. Support for
|
||||
|
||||
**The picker is stricter than the server for a few permissions.** `GET /api/account` never lists some permissions an administrator holds — `sysLogCreate` among them, which was granted without complaint — so their *Allow* is locked for everyone. That errs towards refusing and can be revisited if it gets in anyone's way. Still from source only: that a denial anywhere in a role's tree wins (`permissions.rs` unions enabled and disabled across the tree, then subtracts). **`GET /api/schema` has not been fetched through ihasmail's server on production** — the route sends the session's Basic credential, which reaches every other endpoint, and the source serves the schema to any signed-in account; until it is seen working there the picker's fallback is a notice that the list could not be loaded.
|
||||
|
||||
- **Tenants were built from the 0.16.22 source, its schema and the mock; nothing about them has been written on a live server yet.** Production is Enterprise with no tenants. Read from source: `x:Tenant` is `name`, `logo`, `roles`, `permissions`, `quotas` (a map of `TenantStorageQuota` names) and computed `usedDiskQuota`; membership is `memberTenantId` on accounts, groups, domains, lists, roles and DKIM keys; only a caller outside every tenant may set it (`set.rs` passes `can_set_tenant` only when the token has no tenant, and anyone else gets "Cannot modify memberTenantId property"); a tenant administrator's queries are scoped to the tenant. Assumed, not confirmed: that a tenant still named by anything is refused as `objectIsLinked` — the panel offers the delete only once its counts are all zero, so this matters only if a count cannot be read.
|
||||
|
||||
- **The permission labels in eight languages are machine translations awaiting native review.** 661 labels and 59 headings per language, written against each catalogue's existing terms. The translators flagged the terms they were least sure of, which are the place to start: *principal* (JMAP/DAV), *throttles*, *listeners*, *lookups*, *milters*, *masked emails*, *samples* (spam training), *schedules* (MTA delivery), *email submission*, and the MTA stage settings. Several of Stalwart's own English labels are identical for different permissions (ARF, DMARC and TLS reports are all "Get reports"), and the translations inherit that; the heading above tells them apart.
|
||||
|
||||
- **A refused password shows the server's reason in English.** Every other refusal from the registry is said in the reader's language: each error type has its own message, and a value one of Stalwart's validators refused — a domain name, an address, an empty field — is recognised by the validator's wording and explained again rather than shown. A password policy is the exception, on purpose. Its rule is the server's to set, so there is nothing to translate it from in advance, and its reason follows a translated sentence rather than being dropped, which would leave "not accepted" with no way to find out why.
|
||||
|
||||
Reference in New Issue
Block a user