More of a sanity check question.
I'm using a DB relation similar to this, which seems a popular pattern:
Such schema makes a registration and login process quite sophisticated. Say I want to register a user and give them a 'USER' role by default.
For registration:
Create a user and insert to the users table
Get the ID of the USER role from the roles table
Insert newly created user's ID and the fetched ID of the USER role to the users_roles table
For login (I want to fetch the user with their roles):
Authenticate user and get the user ID from users table
Get Role IDs for that user from the user_roles table (user may have more than one)
Get role names from the roles table
I'm guessing that you could probably do some clever JOINs and nested SELECTs to avoid multiple statements (I'm using an SDK though, with no raw SQL option - and that means three separate DB calls) but is there a better way to do this while preserving such DB design?
Related
When I create a USER with "CREATE USER user1 WITH PASSWORD 'aaaaaaaa'
It is also creating a ROLE in PG_ROLES table with role name as same as 'user1'
Is it a trigger peforrming the this? Or is it default behavior?
Assuming you are not running a very old (<8.1) version of Postgresql this is explained by the documentation for CREATE USER:
CREATE USER is now an alias for CREATE ROLE. The only difference is
that when the command is spelled CREATE USER, LOGIN is assumed by
default, whereas NOLOGIN is assumed when the command is spelled CREATE
ROLE.
Further details are available in the Database Roles section of the documentation:
The concept of roles subsumes the concepts of “users” and “groups”. In
PostgreSQL versions before 8.1, users and groups were distinct kinds
of entities, but now there are only roles. Any role can act as a user,
a group, or both.
The system catalogs docs explain that:
The view pg_roles provides access to information about database roles.
So based upon this it is to be expected that running CREATE USER will have an impact on pg_roles.
I have a group login which has the Server Role "dbcreator". Users of this login has been granted execute on "sp_delete_database_backuphistory" so that they can delete each others databases. The problem now is that it is possible for these users to delete databases created by other logins. Is there a solution for this? Can permission´s be set, so that these users ONLY can delete databases created with this login?
You can't do this directly, but you can wrap the system sp_delete_database_backuphistory into your own usp_delete_database_backuphistory
that can call sp_delete_database_backuphistory or return immediately depending on a result of the check you want to perform.
I cannot ask you in a comment what do you mean saying 'databases created by other users', first of all only login (not user) can create a database but this information (db creator) you cannot extract from any system metadata, all you can get is the current database owner and this can differ from database creator.
I mean, when you create a database you can explicitly assign other login to own the database, or you can do this later for certain purposes
I need to run queries as a "user" which is a record in a table, with permissions based on a record value of that user.
I have a database with a tUsers Table, such as:
ID Username Email Role
1 Pieman mail.com Admin
2 Cakedude mail.co.uk Receptionist
3 Muffin gh.com Other
I need to have it so only "users"/records with "Role" of "Admin" can view and edit the table, and "Receptionist" view it etc.
I know of and use GRANT for permissions, but don't know how to run a query as a user based on a table record and to have the permission only GRANTED if that users' role is "Admin"
So if I have:
USE DB1;
GRANT SELECT ON OBJECT::tUsers TO Admins;
GO
SELECT * FROM tUsers
How do I make that run as say tUser with ID 1, and the GRANT if the users' role = "Admin"
I'm sure I've seen this done before.
I'm fairly new and still learning the correct terminology, so if this is a duplicate question, or is essentially just describing an sql Function sorry.
I don't think you can grant or revoke permissions to users in your own user table. However you can of course restrict queries based on your own user table.
One solution is to do it in your application. Verifier permissions before you do anything for him/her.
Another solution is to use stored procedures which take user id as parameter and do the checking for you in a central place.
The third one is to user parameterized views where you filter out entries one user can't access.
There are other solutions but the basic idea is you need somehow check permissions instead asking dBm server to do it for you.
I have 2 tables, a Users table and a User_permissions table. A user can have many permissions and each permission can be assigned to many different users, although this relationship has not been configured into the database (not my decision!).
Let's say 2 new permissions are created - an admin permission and a superadmin permission. Furthermore, every user in the Users table need to be given this permission by inserting the username and permission name into the User_permissions table.
Obviously this could be done manually by INSERT INTO User_permissions VALUES (userA, admin) and so on but given that I have a list of over 1,000 users, is there an easier way of doing this? I was thinking of writing a quick script in Java, but is there an easier way using only SQL?
Use insert . . . select:
INSERT INTO User_permissions(user, permission)
SELECT user, 'admin'
FROM users u;
The goal is to allow all the "Teachers" that have access to the Faculty table to have Select permissions to only their own social security number and not everybody elses. Do any of you know how I can perform something like this? I do have all my users setup as Windows Users and I have a windows group called Teachers, if that helps.
Not possible using the standard permissions in SQL server (that I am aware of)
You will need to implement this kind of constraint in your code.
You could in theory pass in the SS# and query based on this and raise an error if they do not match.
Social security numbers shoud be encrypted so they can't see each others numbers if they call up the record. You can use a decryption proc to allow them to decrypt that checks the userid against the profile id and will only decrypt if they match.
Implementing Row-level Permissions
Row-level permissions are used for applications that store information in a single table. Each row has a column that defines a differentiating parameter, such as a user name, label or other identifier. You then create parameterized stored procedures, passing in the appropriate value. Users can see only rows that match the supplied value.
The following steps describe how to configure row-level permissions based on a user or login name.
Create the table, adding an additional column to store the name.
Create a view that has a WHERE clause based on the user name column. This will restrict the rows returned to those with the specified value. Use one of the built-in functions to specify a database user or login name. This eliminates the need to create different views for different users.
' Returns the login identification name of the user.
WHERE UserName = SUSER_SNAME()
' USER_NAME or CURRENT_USER Return the database user name.
WHERE UserName = CURRENT_USER()
Create stored procedures to select, insert, update, and delete data based on the view, not the base tables. The view provides a filter that restricts the rows returned or modified.
For stored procedures that insert data, capture the user name using the same function specified in the WHERE clause of the view and insert that value into the UserName column.
Deny all permissions on the tables and views to the public role. Users will not be able to inherit permissions from other database roles, because the WHERE clause is based on user or login names, not on roles.
Grant EXECUTE on the stored procedures to database roles. Users can only access data through the stored procedures provided.