supabase-operator/internal/db/roles_manager.go

70 lines
1.4 KiB
Go
Raw Permalink Normal View History

package db
import (
"context"
"errors"
"fmt"
"github.com/jackc/pgx/v5"
"sigs.k8s.io/controller-runtime/pkg/log"
"code.icb4dc0.de/prskr/supabase-operator/assets/migrations"
)
const (
alterUserPwd = `ALTER ROLE %s WITH PASSWORD '%s';`
checkUserExists = `SELECT 1 FROM pg_user WHERE usename = $1;`
)
func NewRolesManager(conn *pgx.Conn) RolesManager {
return RolesManager{
Conn: conn,
}
}
type RolesManager struct {
Conn *pgx.Conn
}
func (mgr RolesManager) UpdateRolePassword(ctx context.Context, roleName string, password []byte) error {
if err := mgr.ensureLoginRoleExists(ctx, roleName); err != nil {
return err
}
_, err := mgr.Conn.Exec(ctx, fmt.Sprintf(alterUserPwd, roleName, password))
return err
}
func (mgr RolesManager) ensureLoginRoleExists(ctx context.Context, roleName string) error {
logger := log.FromContext(ctx).WithValues("role_name", roleName)
rows, err := mgr.Conn.Query(ctx, checkUserExists, roleName)
if err != nil {
return err
}
defer rows.Close()
_, err = pgx.CollectExactlyOneRow(rows, func(row pgx.CollectableRow) (out int, err error) {
err = row.Scan(&out)
return
})
if err != nil {
if !errors.Is(err, pgx.ErrNoRows) {
return err
}
logger.Info("No rows, this means the role does not exists, creating it now")
} else {
return nil
}
script, err := migrations.RoleCreationScript(roleName)
if err != nil {
return err
}
_, err = mgr.Conn.Exec(ctx, script.Content)
return err
}