feat(dovecot): historical-account andriy.oblivantsev@wheregroup.com for wheregroup incubator (#252) #6
@@ -20,12 +20,21 @@ mailboxes:
|
||||
- `ano@produktor.io`
|
||||
- `postmaster@produktor.io`
|
||||
- `postman@produktor.io`
|
||||
- `wheregroup@produktor.io` — incubator mailbox (issue #251): nobody logs in;
|
||||
legacy `.eml` corpus is imported via `doveadm import` by the ETL connector.
|
||||
- `andriy.oblivantsev@wheregroup.com` — incubator mailbox of the гдеgroup
|
||||
period (issue #252): the owner's **historical address**, not an abstract
|
||||
source box. Nobody logs in; legacy `.eml` corpus is imported via doveadm by
|
||||
the ETL connector (`bin/mail/incubator.go`, 2dph), routed to
|
||||
`Sent`/`INBOX`/`INBOX/Unmatched` by the recipient headers.
|
||||
- `wheregroup@produktor.io` — superseded A1 pilot box (abstract "source"
|
||||
model, issue #251): its 1000 imported messages are migrated to
|
||||
`andriy.oblivantsev@wheregroup.com` and the account is then deleted (issue
|
||||
#252). Listed until deletion; `user-patches.sh` skips owners that are no
|
||||
longer in `postfix-accounts.cf`.
|
||||
|
||||
Passwords live in `.env` (`INFO_PASSWORD`, `ANDRIY_PASSWORD`; `ano@` uses
|
||||
`GATOR_MAIL_PASS` in the gator repo `.env`; `wheregroup@` uses
|
||||
`WHEGROUP_PASSWORD`, random — no interactive login). Do not commit `.env`.
|
||||
`GATOR_MAIL_PASS` in the gator repo `.env`; `andriy.oblivantsev@wheregroup.com`
|
||||
uses `ANDRIY_WG_PASSWORD`, random — no interactive login; `wheregroup@` uses
|
||||
`WHEGROUP_PASSWORD`). Do not commit `.env`.
|
||||
|
||||
## Web UI (Roundcube)
|
||||
|
||||
@@ -75,21 +84,24 @@ changedetector (`check-for-changes.sh`, polls every 2 s) picks up the edited
|
||||
Dovecot. No mail is lost, no container recreation.
|
||||
|
||||
```bash
|
||||
# 1. random password for the new source mailbox (stored in .env only)
|
||||
# 1. random password for the new historical-address mailbox (stored in .env only)
|
||||
PW=$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 32)
|
||||
printf 'WHEGROUP_PASSWORD=%s\n' "$PW" >> .env # never commit .env
|
||||
printf 'ANDRIY_WG_PASSWORD=%s\n' "$PW" >> .env # never commit .env
|
||||
|
||||
# 2. add the account — password is read from stdin, never from argv/ps
|
||||
# 2. add the account — password is read from stdin, never from argv/ps.
|
||||
# DMS accepts any virtual user: the domain need not be serviced by
|
||||
# mail.produktor.io (verified live with wheregroup.com, issue #252) — the
|
||||
# account only serves IMAP/doveadm, no inbound delivery.
|
||||
printf '%s\n%s\n' "$PW" "$PW" |
|
||||
docker exec -i mailserver setup email add wheregroup@produktor.io
|
||||
docker exec -i mailserver setup email add andriy.oblivantsev@wheregroup.com
|
||||
|
||||
# 3. changedetector applies within ~5 s; verify
|
||||
docker exec mailserver doveadm user wheregroup@produktor.io
|
||||
docker exec mailserver doveadm user andriy.oblivantsev@wheregroup.com
|
||||
|
||||
# 4. give the fresh mailbox an INBOX (a brand-new owner has none — without it
|
||||
# `doveadm mailbox list -u <owner>` is empty and user-patches.sh cannot
|
||||
# record any share), then apply the shared/ACL policy
|
||||
docker exec mailserver doveadm mailbox create -u wheregroup@produktor.io INBOX
|
||||
docker exec mailserver doveadm mailbox create -u andriy.oblivantsev@wheregroup.com INBOX
|
||||
docker exec mailserver /bin/bash /tmp/docker-mailserver/user-patches.sh
|
||||
```
|
||||
|
||||
@@ -107,11 +119,13 @@ right sets for `info@`:
|
||||
|
||||
- **production owners** (`ano@`, `andriy.oblivantsev@`, `postmaster@`):
|
||||
read-only — `lookup read` (issue #79);
|
||||
- **incubator owners** (`wheregroup@produktor.io`, later `gmail_lenovo@`,
|
||||
`tb-*`/`pst-*`): read **and delete** — `lookup read delete expunge
|
||||
write-deleted` (issue #251). The owner never logs in; mail arrives via
|
||||
`doveadm import`. Deleting a message in Roundcube = filter/exclusion from
|
||||
the corpus (auto-sync, epic B), so the delete button must work in `Shared/`.
|
||||
- **incubator owners** (one account per historical address of the owner:
|
||||
`andriy.oblivantsev@wheregroup.com` for the гдеgroup period; later
|
||||
`eslider@gmail.com`, `...@viscreation.de`, ...): read **and delete** —
|
||||
`lookup read delete expunge write-deleted` (issue #251). The owner never
|
||||
logs in; mail arrives via `doveadm import`. Deleting a message in
|
||||
Roundcube = filter/exclusion from the corpus (auto-sync, epic B), so the
|
||||
delete button must work in `Shared/`.
|
||||
Verified on live: `write-deleted` is sufficient for the `\Deleted` flag
|
||||
Roundcube sets (no extra `write` right needed), `expunge` is also what
|
||||
Dovecot MOVE needs on the source side when Roundcube moves a deleted message
|
||||
|
||||
+10
-3
@@ -3,11 +3,18 @@
|
||||
# two owner classes (issue #79, issue #251 / epic #250):
|
||||
# - production owners (ano@, andriy.oblivantsev@, postmaster@): read-only
|
||||
# (`lookup read`) — one login in Roundcube covers the whole account list;
|
||||
# - incubator owners (wheregroup@produktor.io; future sources like
|
||||
# gmail_lenovo@, tb-*/pst-*): read + delete (`lookup read delete expunge
|
||||
# - incubator owners: read + delete (`lookup read delete expunge
|
||||
# write-deleted`) — the mailbox owner never logs in, mail is imported via
|
||||
# doveadm; deleting a message in Roundcube = filter/exclusion from the
|
||||
# corpus (autosync, epic B).
|
||||
# Incubator model (corrected 2026-09-02, issue #252): the incubator mailbox IS
|
||||
# the owner's HISTORICAL ADDRESS per period, not an abstract "source" mailbox.
|
||||
# The wheregroup period = andriy.oblivantsev@wheregroup.com; later periods get
|
||||
# their own account (eslider@gmail.com, ...@viscreation.de, ...).
|
||||
# wheregroup@produktor.io stays listed as the superseded A1 pilot box until
|
||||
# its 1000 messages are migrated and the account is deleted — grant_share
|
||||
# skips owners that are not (yet) in postfix-accounts.cf, so a deleted account
|
||||
# is a silent no-op.
|
||||
# DMS runs this only on the FIRST start of each container instance (plain
|
||||
# `docker compose restart` skips the setup step by design — /CONTAINER_START
|
||||
# marker), so it must stay idempotent. ACLs, the shared dict and subscriptions
|
||||
@@ -31,7 +38,7 @@ chmod 0770 "${SHARED_DB_DIR}"
|
||||
# when Roundcube moves a deleted message to Trash.
|
||||
READER='info@produktor.io'
|
||||
PRODUCTION_OWNERS='ano@produktor.io andriy.oblivantsev@produktor.io postmaster@produktor.io'
|
||||
INCUBATOR_OWNERS='wheregroup@produktor.io'
|
||||
INCUBATOR_OWNERS='andriy.oblivantsev@wheregroup.com wheregroup@produktor.io'
|
||||
|
||||
grant_share() { # $1=owner, remaining=right names
|
||||
local owner=$1
|
||||
|
||||
Reference in New Issue
Block a user