Report as revoked only what the read-back shows gone, and take back what the reader passed on (review of hq issue 337)
A reader given a privilege WITH GRANT OPTION that passed it on made the plain revoke fail with dependent privileges exist; the pass still listed the table as revoked and logged it every minute. The pass now retries such a change with CASCADE, which reaches only grants that came from the reader, reads the grants back, reports as revoked only what is gone, and says what is still held and why when anything is.
This commit is contained in:
@@ -6,6 +6,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -354,3 +355,26 @@ func TestTheCataloguesReadableDeclarationsParse(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A change that fails reports nothing revoked, and says what is still held and why — every pass, not
|
||||
// "revoked" every pass.
|
||||
func TestAFailedChangeSaysWhatIsStillHeldAndRevokesNothing(t *testing.T) {
|
||||
conn := admin
|
||||
conn.ReaderPassword = "r"
|
||||
f, c := newFake(conn)
|
||||
f.answer(`^SELECT rolsuper`, []string{"a", "b", "c", "d", "e", "f", "g", "h", "i"},
|
||||
[]string{"f", "f", "f", "f", "f", "t", "t", "t", "default_transaction_read_only=on,statement_timeout=60s"})
|
||||
f.answer(`SELECT datname FROM pg_database WHERE datallowconn`, []string{"datname"}, []string{"app"})
|
||||
f.answer(`aclexplode\(c\.relacl\)`, []string{"nspname", "relname", "relkind", "privilege_type", "grantor"},
|
||||
[]string{"public", "vault", "r", "SELECT", "owner1"})
|
||||
f.answer(`aclexplode\(a\.attacl\)`, []string{"nspname", "relname", "attname", "privilege_type", "grantor"})
|
||||
f.fail(`^SET ROLE`, errors.New("server busy"))
|
||||
rep := c.ReconcileReader(ctx, Declarations{}, "")
|
||||
db := rep.Databases[0]
|
||||
if len(db.Revoked) != 0 {
|
||||
t.Fatalf("said revoked: %v", db.Revoked)
|
||||
}
|
||||
if !strings.Contains(db.Error, "STILL HELD") || !strings.Contains(db.Error, "public.vault") || !strings.Contains(db.Error, "server busy") {
|
||||
t.Fatal(db.Error)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user