41 lines
1.2 KiB
Go
41 lines
1.2 KiB
Go
package store
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// bindMQScope checks the configured database owner and the immutable tenant
|
|
// mapping inside the caller's transaction, before committing any input ACK.
|
|
func bindMQScope(tx *sql.Tx, dispatcherID, tenantID, tenantKey string) error {
|
|
var owner string
|
|
if err := tx.QueryRow(`SELECT dispatcher_id FROM dispatcher_identity WHERE singleton=1`).Scan(&owner); err != nil {
|
|
return fmt.Errorf("read MQ owner: %w", err)
|
|
}
|
|
if owner != dispatcherID {
|
|
return ErrMessageScope
|
|
}
|
|
var conflicting int
|
|
if err := tx.QueryRow(`SELECT EXISTS(SELECT 1 FROM inbox WHERE (tenant_id=? AND tenant_key<>?) OR (tenant_key=? AND tenant_id<>?))`, tenantID, tenantKey, tenantKey, tenantID).Scan(&conflicting); err != nil {
|
|
return err
|
|
}
|
|
if conflicting != 0 {
|
|
return ErrMessageScope
|
|
}
|
|
if _, err := tx.Exec(`INSERT INTO tenant_bindings(tenant_id,tenant_key) VALUES(?,?) ON CONFLICT DO NOTHING`, tenantID, tenantKey); err != nil {
|
|
return err
|
|
}
|
|
var key string
|
|
if err := tx.QueryRow(`SELECT tenant_key FROM tenant_bindings WHERE tenant_id=?`, tenantID).Scan(&key); err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return ErrMessageScope
|
|
}
|
|
return err
|
|
}
|
|
if key != tenantKey {
|
|
return ErrMessageScope
|
|
}
|
|
return nil
|
|
}
|