Dada uma função de banco de dados, user1
, uma função something()
definida como um procedimento armazenado e uma exibição criada como:
CREATE VIEW view1 AS select * from something()
E, dadas essas permissões:
REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1
Quando executo SELECT * FROM view1
, recebo um erro permission denied for function something()
.
Minha pergunta é, se eu revogar as permissões de seleção na exibição, por que a função é chamada? Esperava receber algo como:
permission denied for relation view1
Obrigada!
O problema nesse caso não é exatamente a ordem de permissão, mas a ordem de execução.
Em resumo, para PostgreSQL:
1- Views que estão acessando tabelas irão sobrescrever a permissão de tabelas
2- Views acessando funções, será necessário avaliar todas as funções, antes de serem verificadas - então as funções devem ser executadas antes de acessar a view, mesmo que a view não possua permissões select...
Como podemos provar isso?
No postgresql, as views são capazes de lhe dar permissões para fazer um select em uma tabela, mesmo que o usuário não tenha essas permissões.
Por exemplo:
Faça login como usuário 1:
No caso, o usuário poderá selecionar view2 mesmo não tendo permissão para selecionar a tabela.
Mas e se fizermos a mesma coisa com uma função ? O comportamento NÃO é o mesmo. Vamos criar uma função que espere 5 segundos antes de retornar 1 (para que possamos depurar se o postgresql estiver executando a função toda vez que chamamos a view)
Faça login como usuário 1:
A permissão para fazer select na view não substitui a permissão da função, e pior ainda se revogarmos as permissões da view1, a mensagem ainda mostra que o postgresql parou nossa consulta por causa da função, não importa qual seja a permissão da view.. (isso é exatamente o que está acontecendo na pergunta)
Mas a função está realmente sendo verificada primeiro? Se dermos as permissões 'all' para a função, mas revogarmos a permissão de visualização...
Como você vê, postgresql ESPERA 5 SEGUNDOS antes de dizer que não temos permissão para exibir a exibição , mostrando que a função "something()" é executada. Portanto, o retorno de dados da função deve existir antes da verificação da visualização.
Então agora com esses testes, agora sabemos que o PostgreSQL precisava primeiro avaliar todas as funções antes de continuar nossa consulta, é como se a consulta ainda não existisse até que todas as funções envolvidas fossem totalmente concluídas, então a visão não pode ser resolvida para o postgresql saber se temos ou não permissão para selecioná-lo.
Acho que isso responde sua pergunta nos termos de "ordem de permissão", mas por que o postgresql precisa avaliar todas as funções antes de continuar, isso é outra pergunta ...