PostgreSQL: permissão negada para relação

14

Estou um pouco confuso sobre a definição de permissões no PostgreSQL.

Eu tenho esses papéis:

                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 admin     | Superuser, Create role, Create DB, Replication | {}
 meltemi   | Create role, Create DB                         | {rails}
 rails     | Create DB, Cannot login                        | {}
 myapp     |                                                | {rails}

e bancos de dados:

                                    List of databases
        Name         | Owner  | Encoding |   Collate   |    Ctype    | Access privileges 
---------------------+--------+----------+-------------+-------------+-------------------
 myapp_production    | rails  | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 ...

O usuário myappnão tem nenhum problema ao consultar o myapp_productionbanco de dados, adicionando e excluindo registros. Eu gostaria de meltemipoder também consultar o mesmo banco de dados. Então, criei uma função railsque é proprietária do banco de dados e composta por ambos meltemie myappmembros rails. Mas ainda recebo permission denied for relationerros. Meltemipode visualizar o esquema, mas não pode consultar o banco de dados.

Acabei de notar (com \dtcomando) que myappé o proprietário das tabelas:

             List of relations
 Schema |       Name        | Type  | Owner 
--------+-------------------+-------+-------
 public | events            | table | myapp
 public | schema_migrations | table | myapp
 ...
 public | users             | table | myapp
 ...

As tabelas foram criadas por meio de um ORM (migrações do ActiveRecord do Rails).

Eu sei que a autorização é muito diferente no PostgreSQL (em oposição ao MySQL e outros que eu usei). Como devo configurar meu banco de dados para que diferentes usuários possam acessá-lo. Alguns devem ser capazes de CRUD, mas outros só podem ler, etc ...

Obrigado por qualquer ajuda. Desculpe, sei que esta é uma pergunta muito básica, mas não consegui encontrar a resposta.

Meltemi
fonte

Respostas:

4

Acabei de escrever sobre isso na minha resposta para Concedendo direitos no banco de dados postgresql a outro usuário no ServerFault.

Basicamente, a melhor solução quando você tem um único usuário e deseja conceder a outros usuários os mesmos direitos é transformar esse usuário em um grupo, criar um novo usuário com o mesmo nome que o original que é membro do grupo e conceda esse grupo a outros usuários também.

Portanto, no seu caso, railsé renomeado para dizer myapp_users, então você cria uma nova função de login (usuário) chamada railse GRANT myapp_users TO rails. Agora você é GRANT myapp_users TO meltemi. Agora, a nova railsconta e o meltemiusuário têm os direitos da railsconta antiga .

Para um controle mais refinado, geralmente aconselho que você evite dar aos usuários de login diários ou a seus grupos a propriedade das tabelas. Dê a eles acesso por meio de um NOINHERITgrupo ao qual devem explicitamente SET GROUPusar, ou melhor, usar um usuário completamente diferente para operações privilegiadas como DDL e GRANTs. Infelizmente, isso não funciona com o Rails, porque o Rails gosta de aplicar migrações sempre que lhe apetecer e o AFAIK não permite especificar um usuário diferente e mais privilegiado para executar as migrações.

Craig Ringer
fonte
OK, leia a postagem à qual você vinculou; muito útil! Agora, se estou entendendo bem as coisas, acho que você pode ter usado isso em myappvez de railsacima? Porque myapppossui as tabelas (nunca especifiquei isso, a migração deve ter). De qualquer forma, seria sorta faz sentido se eu renomeado myapppara myapp_groupe, em seguida, fez um novo usuário myappque o aplicativo trilhos usaria para se conectar ao DB. Make myappe existente meltemi, ambos membros da myapp_groupfunção. Mas o que acontece quando eu executo a próxima migração. não será possuído por myapprecriar o problema novamente?!?
Meltemi
1
Você deve entender que o PostgreSQL possui apenas roles(desde a versão 8.1). Os termos usere groupsão mantidos por razões históricas e compatibilidade. Basicamente, um "grupo" é uma função sem o privilégio de login. Você pode conceder myappa meltemimesmo se myappé apenas mais um "usuário". Comece lendo o manual aqui .
Erwin Brandstetter
Eu entendo o rolesvs groupsvs usersseparação no Postgres, pelo menos eu acho que sim. Desculpe por usar a terminologia errada (e confusa) acima. Mas ainda não entendo como configurar meu banco de dados, de modo que uma função sem login OWNS o banco de dados e duas funções de login myappe meltemiambas possam ter acesso total. Uma dessas funções myappestará executando migrações do Rails que, inevitavelmente?, Criarão novas tabelas que são mais uma vez pertencentes a myappum usuário de logon. Devo apenas fazer meltemium 'membro' myappe terminar com isso? Mas isso parece esquisito ... não ?!
Meltemi
1
@Meltemi: Se você quiser conceder todos os privilégios que myappdetém para meltemi, em seguida, que seria a coisa certa a fazer. Se você deseja meltemiobter apenas um subconjunto de privilégios, isso não aconteceria. Em seguida, crie uma função de grupo para manter o conjunto de privilégios e conceder isso a meltemi. Você provavelmente estará interessado nesta questão relacionada ao SO . Eu respondi explicandoDEFAULT PRIVILEGES
Erwin Brandstetter
@ Meltemi Sim, como de costume, as migrações do Rails complicam o cenário. O Rails realmente deve permitir que você especifique uma conta de usuário diferente para executar as migrações. Você pode adicionar um SET ROLEcomando ao início de suas migrações e um RESET ROLEao final, mas eu não confiaria que o Rails executasse tudo perfeitamente em ordem. Erwin está certo; nesse caso, a melhor solução alternativa será para GRANTos trilhos do usuário que pertencem ao outro usuário, usando o 1º usuário como um grupo para o segundo.
Craig Ringer