[Acho que a causa raiz desse problema é que eu não entendo permissões e privilégios...]
Então, para montar o cenário, a configuração que tenho é um DB, chame de MyDb .
Eu tenho dois usuários, spu1 e u1 , spu1 é um superusuário e u1 um usuário 'regular'. O proprietário do MyDb é spu1 . Acho que também devo dizer que o u1 criou bancos de dados e criou privilégios de função herdados de uma função de grupo.
Eu tenho um esquema sch1 , que é um esquema definido pelo usuário.
Dentro desse esquema eu tenho uma tabela, chamo tbl1 , e uma visão materializada, chamo mvw1 .
O dono do tbl1 é o spu1 , o dono do mvw1 é u1 .
O problema:
Na configuração atual, conforme descrito acima, não consigo atualizar mvw1 como u1 ou spu1 . Eu simplesmente recebo o erro divertido abaixo (que pesquisei extensivamente, mas não encontrei nada que resolva bastante minha configuração ..).
ERROR: permission denied for relation tbl1
********** Error **********
ERROR: permission denied for relation tbl1
SQL state: 42501
eu descobri que
- Alterar o proprietário de mvw1 para spu1 , me permite atualizar como spu1 .
- Executar o abaixo me permite atualizar mvw1 como u1 .
Estou tentando descobrir quais são as permissões ausentes (idealmente o mínimo necessário) que preciso conceder ao usuário regular, u1 , para que eu possa atualizar essa visualização quando estiver conectado como eles.
A primeira opção, embora seja bom saber, não resolve o meu problema. A segunda opção parece que estou de fato concedendo permissões de superusuário a um não superusuário, ou melhor, concedendo privilégios maiores do que preciso.
Se alguém puder me explicar o que exatamente está acontecendo aqui (ou apontar quais informações eu perdi na descrição do meu problema necessário para resolvê-lo), e deixe-me saber se minha segunda opção é de fato o caminho a seguir ou de uma alternativa melhor?
Muito obrigado!
Você pode fazer isso com uma função que é executada no contexto de segurança de seu proprietário.
Função que atualiza a view (crie-a com o usuário que possui a MV/tabela):
Conceda execute na função para qualquer usuário que você deseja que possa atualizar a visualização:
Para atualizar:
Dos documentos do Postgres :
Versão que suporta um parâmetro:
... mas não tenho certeza se o SQL dinâmico ainda será executado como definidor.
A segunda tentativa de função de @Philᵀᴹ é vulnerável à injeção de SQL usando:
where
example_mview_name
eexample_table_name
referem-se a qualquer uma de suas visualizações e tabelas materializadas, respectivamente.O que é perigoso de várias maneiras.
Eu sugeriria usar apenas sua primeira tentativa ou da seguinte maneira:
format()
com especificador de formato%I
Outra opção é criar uma função de grupo (não superusuário) à qual spu1 e u1 pertencem/herdarem (por exemplo, "refreshers") e atribuir essa função de grupo como o proprietário da visão materializada.