PostgreSQL: drop user Or drop role? - postgresql

I created a read only user in PostgreSQL using the command line by:
CREATE USER xyz WITH ENCRYPTED PASSWORD 'xxx';
GRANT SELECT ON DATABASE mydb TO xyz;
In order to delete this user, what's the difference between
DROP USER xyz;
and
DROP ROLE xyz;

There is no difference. From the docs:
DROP USER is simply an alternate spelling of DROP ROLE.

Related

Permission denied for relation <table_name>

So I'm making this app and I'm using Postgres and I've already created a database, a user and a password and granted all privileges on the database to the user I've created.
The thing is, when I switch the database in psql using \c <database_name> I get in just fine and can use queries on it.
But when I run psql using postgres://user_name:password#localhost:5432/databasename on terminal and try to select * from the <table_name> it gives me this message
permission denied for relation <table_name>
Can you please tell me what to do, I've had this problem before and I had to create another database or change the user but I want a better solution please.
PS: I've tried to use this :
GRANT ALL PRIVILEGES ON TABLE <table_name> to <user_name>
This is how I created and accessed my database:
rawan95=# create database food ;
CREATE DATABASE
rawan95=# create user meal with password '123';
CREATE ROLE
rawan95=# grant all privileges on database food to meal;
GRANT
rawan95=# \c food
You are now connected to database "food" as user "rawan95".
After that, I've built it using
food=# \i src/database/db_build.sql
BEGIN
DROP TABLE
CREATE TABLE
INSERT 0 1
COMMIT
Then I selected data from the table just fine, but when I try to access it using this, I get an error: psql postgres://meal:123#localhost:5432/food
food=> select * from foods;
ERROR: permission denied for relation foods
You are granting the privileges before you create the tables.
As there are no tables at that moment nothing is granted. The tables you created are not owned by the user meal but the user rawan95 (which the \c command told you).
Plus: granting "all privileges" on a database, does not grant any select privilege. As documented in the manual "all privileges" are: CREATE, CONNECT, TEMPORARY, TEMP. The CREATE privilege would allow the user meal to create tables in that database.
If you want all those tables to be owned by the user meal you need to run your setup script after you connected as the user meal (the \c command did not change the current user)
If you do want rawan95 to be the owner of the tables, you need to either grant the select privilege after creating all tables:
grant select on all tables in schema public to meal;
Or, you can change the default privilege before creating the tables (before running db_build.sql), so that they are applied to all tables in the future:
alter default privileges in schema public
grant select on all tables to meal;
The alter default privileges only has an effect for tables that are created after that. So to fix your current setup, you need to first grant select on the existing tables, and the change the default privileges for all tables that are created in the future.
Have you granted usage on the schema? Without that the table permissions are useless.
GRANT USAGE ON SCHEMA schema_name TO username
EDIT: Based on comment thread below we have established.
The table is in public schema.
The table belongs to rawan95 but the schema does not (public schema belongs to root postgres user).
The OP is attempting to connect and access the table as user 'meal' they have granted table permissions using the rawan95 user but are unable to grant schema permissions.
From the above, the problem could still be that the user 'meal' does not have usage on the public schema. If you are on Linux the quickest way to sort this is to switch to the super user to make this change from terminal:
sudo -u postgres psql -c "GRANT USAGE ON SCHEMA public TO meal"
FURTHER EDIT - having read your new clarification this is not correct (or at least not useful). The issue is as pointed out by the other answerer that you didn't have a table at the time you did the grant.

How to grant user access to one table in a specific schema in Redshift

Logged in as the superuser, how can I grant user access to a specific table under a specific schema.
I tried this
GRANT SELECT on TABLE this_schema.my_table TO my_user
But when I login as my_user I can't select from the table. I don't want my_user to have access to any other tables in this_schema.
Is this possible?
Yes its possible.
You can use following command, to give select access of specific table to specific user.
GRANT SELECT on SCHEMA_NAME.TABLE_NAME TO USER_NAME;
NOTE: user still list and describe other tables in the given schema.
You need to grant usage on the schema as well
GRANT USAGE ON SCHEMA this_schema TO GROUP my_user;
Without creating user group, you can do:
GRANT SELECT ON TABLE my_table IN SCHEMA this_schema TO my_user;

Creating user with plain SQL

I would like to have user who can read and insert data to all tables within one schema. I've executed following SQl statements:
CREATE SCHEMA ABC;
CREATE USER MyUser with PASSWORD '12345678';
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA ABC TO MyUser;
When I try to login with this user I am getting exception: Role 'MyUser' does not exists.... What is not correct here?
How to Define Privileges Upon Role Creation
Now, we are ready to recreate the "demo_role" role with altered permissions. We can do this by specifying the permissions we want after the main create clause:
CREATE ROLE role_name WITH optional_permissions;
You can see a full list of the options by typing:
\h CREATE ROLE
We want to give this user the ability to log in, so we will type:
CREATE ROLE demo_role WITH LOGIN;
CREATE ROLE
If we want to get to this state without specifying the "login" attribute with every role creation, we can actually use the following command instead of the "CREATE ROLE" command:
CREATE USER role_name;
The only difference between the two commands is that "CREATE USER" automatically gives the role login privileges.
here or here about PostgreSQL User Administration.
Thanks
UPDATE
We want to give this user the ability to log in, so we will type:
CREATE ROLE demo_role WITH LOGIN;
CREATE ROLE
If we check the attributes \du
demo_role | | {}
my user name was case sensitive. using small letters solves problem.

Create trigger on create role

I have a PostgreSQL database. I create new READ-ONLY users as follows:
$ sudo -upostgres psql postgres
postgres=# CREATE ROLE readonly;
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
postgres=# BEGIN;
postgres=# CREATE ROLE "<PUT_READONLY_USERNAME_HERE>" WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE' IN ROLE readonly;
postgres=# COMMIT;
Also I have a table "is_admin" where I manually add new users (it happens really rarely). If it is read-only user users.is_admin = false and if it is user with all priveleges users.is_admin = true.
users.oid users.is_admin (bool)
1 true
2 false
3 false
... ...
Then in code I check if user is admin or not with this query:
SELECT users.is_admin
FROM users.users
JOIN pg_authid ON pg_authid.oid = users.oid::oid
WHERE rolname = "PUT_ROLNAME";
So, the main question is how to automatically add new users to "is_admin" table? I read that trigger or smth like that can help me (for example, trigger ON CREATE ROLE).
You can't create triggers on administrative change, like create role.
But I think you don't need is_admin column at all. You can simply use
select pg_has_role('username', 'rolename', 'MEMBER');
to determine if user has some role or not.

Postgres create database user with grant access to schema only

I have a database with a template_schema.I cloned this template schema and created a database user with password. I need to provide access to cloned schema only, for the created user.
SELECT clone_schema('my_template_schema','john_smith_gmail_com');
CREATE USER john_smith_gmail_com WITH PASSWORD 'mypassword';
Upto this Ok. Then I need to grant access to this user for this cloned schema(john_smith_gmail_com) only
Method :1
I tried to revoke all privileges on all tables of cloned schema(john_smith_gmail_com) for the user and grant select to the user. But my question is, can this user get SELECT access on other schema tables?
REVOKE ALL ON ALL TABLES IN SCHEMA john_smith_gmail_com FROM john_smith_gmail_com;
GRANT SELECT ON ALL TABLES IN SCHEMA john_smith_gmail_com TO john_smith_gmail_com;
Method :2
Create a role with only SELECT access and assign or grant this role to newly created user. If I do this, for which schema I grant access,because I clone schema dynamically?
Which method is best one?
From postgresql version 9.0 and forward, the best way is probably to use ALTER DEFAULT PRIVILEGES.
...the default privileges for any object type normally grant all grantable permissions to the object owner, and may grant some privileges to PUBLIC as well. However, this behavior can be changed by altering the global default privileges with ALTER DEFAULT PRIVILEGES.
So if all users like "john_smith_gmail_com" should only have SELECT access to tables in "their own" schema, after creating the schema and user, you can run:
ALTER DEFAULT PRIVILEGES IN SCHEMA john_smith_gmail_com GRANT SELECT ON TABLES TO john_smith_gmail_com;