Appearance
Lubb Office
Lubb Office is the operator console for the Kolab-backed business email and groupware service sold as "Business Email" (SOFT1-MAIL-20G) and hosted at office.lubb.co.za. It shows the mail domains and mailboxes exactly as they exist on the live Kolab server, lets staff provision, resize, suspend, resume and delete mailboxes from one screen, and keeps the billing side (Subscriptions) reconciled against what is actually running so nothing is served unbilled or billed unserved. It is an internal, services_admin-gated app — customers and resellers never see it; only staff on portal.lubb.co.za and tc use it.
What you can do
- Browse Mail Domains — every domain Kolab hosts mail for, read live on every page load, with its live mailbox count, its billed-subscription count, alias domains, and a Billed/Not billed status.
- Browse Mailboxes — every live mailbox across every hosted domain, read straight from the Kolab admin API (address, name, domain, quota, sign-in state, aliases), joined against the Subscriptions books to show Billed / Not billed / No customer and which customer and subscription status it maps to.
- Create a new mailbox — pick the domain, the address (before the
@), the person's first name and surname, a password and a quota, and it is provisioned on the mail server immediately. - Set a mailbox's quota (1, 2, 5, 10, 20, 50 GB, or Unlimited).
- Suspend / resume a mailbox — suspend locks the account out of IMAP, SMTP and webmail sign-in; incoming mail keeps arriving and is stored, so it is reversible and non-destructive.
- Delete a mailbox — permanently removes the Kolab account and its Cyrus-stored mail; irreversible. The underlying subscription is deliberately left untouched, since stopping billing is a separate commercial decision.
- Sync to subscriptions — upsert one Subscription per live mailbox on demand, so the books catch up with whatever changed on the mail server.
- Reconcile — a read-only comparison that reports mailboxes with no subscription (not billed), active subscriptions with no matching mailbox (orphaned), and subscriptions with no customer assigned (unassigned) — nothing is changed by running it.
- Manage Mailbox Subscriptions — the billing rows themselves (customer, product, status, start date), with the customer and status fields directly editable on the grid so a mailbox can be reassigned or its billing status corrected without hunting through the all-services grid.
- Suspend / Cancel / Reactivate a subscription, with suspend/cancel optionally carrying through to lock the mailbox itself (and reactivate to unlock it) — the mailbox-server change is best-effort and reported separately if the mail server is unreachable, so the books always update regardless.
Common tasks
Provision a mailbox for a customer On the Mailboxes grid, click "New mailbox" and fill in the domain, the address's local part, first name, surname, a password and (optionally) a quota. Saving creates the account on Kolab and immediately runs a sync so a subscription exists for it. If the domain has no existing customer on any of its mailboxes, the confirmation message flags it as unassigned — go to Mailbox Subscriptions and set the customer on that row.
Resize a mailbox On the Mailboxes grid, select a mailbox and use the row's "Set quota" action to pick a new size (or Unlimited). This updates Kolab directly and re-syncs the subscription's detail line so the new size shows up in billing too.
Suspend a mailbox for non-payment Either suspend from the Mailboxes grid directly (row action "Suspend"), or suspend the Mailbox Subscriptions row instead — the latter sets the subscription to
suspendedand also locks the mailbox out of sign-in in the same action. Suspending never stops inbound mail; it only blocks the user logging in.Reconcile billing against the mail server From the toolbar on any of the three grids, click "Reconcile". It reports mailboxes with no subscription, subscriptions whose mailbox no longer exists (only counted if the subscription is still active), and subscriptions with no customer — use it to spot drift before it costs money either direction. Nothing is changed automatically; use "Sync to subscriptions" or the Mailbox Subscriptions grid to fix what it reports.
Retire a mailbox Cancel its subscription first (Mailbox Subscriptions → "Cancel"), which stops billing and locks sign-in but leaves the mail intact. Only delete the mailbox itself (Mailboxes → "Delete mailbox") once it's confirmed the customer no longer needs the mail — deletion is permanent and removes the stored messages with it.
Fix an unassigned domain New mailboxes on a domain nobody has billed before come back from sync/reconcile as "no customer" rather than being guessed at. Open Mailbox Subscriptions, find the row(s) for that domain, and set the Customer column (an editable lookup) to the right account.
Data model
- Subscription (narrowed to
service_type == "mailbox") — the billing record for one mailbox:reference(the mailbox address, the join key back to Kolab),domain_name,customer_id,product/product_code(catalogue itemSOFT1-MAIL-20G, "Business Email"),status(active/suspended/cancelled),detail(name, alias count and quota as free text),started_at,qty. This is the only table Lubb Office owns locally. - ServiceProvider — used only as the grid framework's required
modelfor the two provider-backed grids (Mail Domains, Mailboxes); it isn't actually read or written for their rows, which come live from Kolab instead. - No mailbox or domain table exists locally by design: the Kolab LDAP directory is treated as the system of record, and with only a couple of domains and single-digit mailboxes, reading live on every load is cheap enough that a mirror table would just be a second place to be wrong.
Configuration & integrations
- Kolab Web Admin API —
https://office.lubb.co.za/admin/api/<service>.<method>, a JSON POST API. Credentials (url,api_key) resolve per-site from thelubbofficeRemote Connection viaerp_credentials. The API key must travel in the JSON body asapi_key; header auth (X-API-Key,Authorization: Bearer) is stripped by the Apache in front of the webadmin and silently fails. - Two API layers are used: stock Kolab methods (
domains.list,users.list,user.edit) for reads and for setting quota (the only placeuser.editis still needed, since the subscription-lifecycle service has no quota endpoint of its own); and a locally installedmailbox.*service (provision,status,cancel,resume,delete,alias_add,alias_remove) for everything else, which accepts a DN, nsuniqueid, primary address, alias or bare uid as the target. - office.lubb.co.za and mailsuite.telecloud.co.za are the same physical Kolab 16 host, serving Roundcube webmail at
/and the Kolab Web Admin at/admin. The separatemailsuite_serverRemote Connection is that box's SSH login (used elsewhere, for Branding → Propagate) and is not this integration. - One LDAP tree per hosted domain — a full catalogue requires
domains.listfollowed by oneusers.listper domain; a domain's otherassociateddomainvalues are alias names on the same tree, not separate domains. - "Cancel"/suspend on the mail server sets
nsaccountlock, which blocks LDAP bind and therefore sign-in, but this host's Postfix delivery rules don't key on that attribute — a suspended mailbox keeps accepting and storing inbound mail. - Registered on two sites:
portal_lubb(portal.lubb.co.za, which sharestc's database, so the app's home) andtcitself (where the customers and subscriptions actually live). Gated behind theservices_adminapp so it is staff-only.
API reference
Lubb Office has no dedicated REST routes of its own — all three screens are generic grids served by the shared grid engine under /grid/lubboffice-*, with the Kolab HTTP calls happening server-side inside each grid's data provider and row-button handlers.
| Grid slug | Screen | Notes |
|---|---|---|
lubboffice-domains | Mail Domains | Read-only (can_create/can_edit/can_delete all off); rows are fetched live from Kolab on every load, not stored |
lubboffice-mailboxes | Mailboxes | Read-only as a grid (no inline create/edit/delete row form); all changes go through the row/toolbar buttons below, which call the Kolab API directly |
lubboffice-subscriptions | Mailbox Subscriptions | Ordinary model-backed grid over Subscription, editable in place (customer, status), deletable |
Row and toolbar button actions (not separate routes — invoked through the grid's button/prompt mechanism):
| Grid | Action | Effect |
|---|---|---|
| Mailboxes | New mailbox | Provisions a Kolab account (mailbox.provision) then syncs subscriptions |
| Mailboxes | Set quota | Updates the mailbox's quota on Kolab (user.edit) and re-syncs |
| Mailboxes | Suspend / Resume | Locks/unlocks mail sign-in (mailbox.cancel / mailbox.resume) |
| Mailboxes | Delete mailbox | Permanently removes the account and mail (mailbox.delete) |
| Mailboxes, Mail Domains, Subscriptions | Sync to subscriptions | Upserts one Subscription per live mailbox |
| Mailboxes, Mail Domains, Subscriptions | Reconcile | Read-only report of unbilled / orphaned / unassigned rows |
| Mailbox Subscriptions | Suspend / Cancel / Reactivate | Updates the subscription's status, and best-effort locks/unlocks the mailbox to match |