Update column value modified from another user - sql

I have a column called Note, roleName and there are two roles, admin and engineer.
The engineer updates the notes and saves it , at the same time when admin logs in and modifies the same record (notes), he should be able to do it. How can I achieve this using case sql?

If two users update the same field in the same table, then the user which updates last, will win. If you are trying to do something like Google Docs, where many users can update the same data, that is going to be more than just a update to a table.

Related

Hasura SELECT permissions for table relationships

I'm building a forum. I have a really simple database setup:
Users: id, display_name, email, profile
Posts: id, title, content, user_id
The user_id is a foreign key to the Users table.
Permissions:
For inserting/updating, X-Hasura-User-Id must equal id and user_id for inserting into the Users and Posts table. (so they can only modify their own posts)
For selecting, I have it so a user can read any post, but they can only select the row of the User if id = X-Hasura-User-Id. This is so a User can only read their profile data.
However, for selecting, I obviously need the user to be able to access display_name of the user's table, to display the post's author.
Now I can obviously make it so for select, they only have access to this field, and everything works fine. I can return a GQL query that displays the posts and the author.
But doesn't this also mean that a user can just run a query to the Users table and get a list of all the display_names, essentially showing how many users I have?
Is there a way to set it up so that a user can only select their own info from the User's table, but like, if the query is 'coming from' the server, it can access the display_name? I know there are Admin roles etc but I don't think this applies here.
But doesn't this also mean that a user can just run a query to the Users table and get a list of all the display_names, essentially showing how many users I have?
Yes
Is there a way to set it up so that a user can only select their own info from the User's table, but like, if the query is 'coming from' the server, it can access the display_name?
No
It's a valid concern to worry about data leakage in terms of how many users you have. But in general I would not worry about it.
However, there are a few things you could do to prevent this problem.
What you can do is:
Limit the number of rows per request (https://hasura.io/docs/1.0/graphql/manual/deployment/production-checklist.html#limit-number-of-rows-returned)
Make sure users are not allowed to aggregation queries (https://hasura.io/docs/1.0/graphql/manual/queries/aggregation-queries.html#aggregate-fields)
Also what you can do is create a VIEW where the display_name is joined and added to the posts table.

Hide rows in a table from a user group

We have a table and multiple users access that table. However we would like to hide records in that table from a user group lets say GroupA. So that they don't see any records in their database except the ones that were created by them.
GroupA users should also have an option to add new records and edit their own record.
However, all other users (except groupA) should be able to see all records in the table.
We have SQL Server 2012.
Thanks.
You could create a view on the table for GroupA restricting records with appropriate criteria and grant SELECT to GroupA on view.
This is called row level security.
One common way is to allow access to the table only via a view.
(You can also write into a view).
The view must contain a WHERE statement which selects the rows the user is allowed to see.
BTW, be sure to use ORIGINAL_LOGIN when you reference to the current user.

3 Level authorization structure

I am working on banking application, I want to add a feature of maker,checker and authorize for every record in a table. I am explaining in below details
Suppose I have one table called invmast table. There are 3 users one is maker, 2nd one is checker and last one is authorize. So when maker user creates a transaction in database then this record is not live (means this record can not be available in invmast table). Once checker checked the record and authorizer authorized the record the record will go live ( means this record will insert in invmast table ). Same thing is applicable for update and delete also. So I want a table structure how to achieve this in real time. Please advice if any.
I am using vb.net and sql server 2008
Reads like a homework assignment.....
Lots of ways to solve this, here's a common design pattern:
Have an invmast_draft table that is identical to invmast but has an additional status column in the table. Apps need to be aware of this table, status column and what its values mean. In your case, it can have at least 3 values - draft, checked, authorized. Makers first create a transaction in this table. Once maker is done, the row is committed with the value "draft" in the status column. Checker then knows there's a new row to check and does his job. When done, row is updated with status set to checked. Authorizer does her thing. When authorizer updates the status as "authorized" you can then copy or move the row to the final invmast table rightaway. Alternatively, you can have a process that wakes up periodically to copy/move batches of rows. All depends on your business requirements. All kinds of optimizations can be performed here but you get the general idea.

Storing full name of database user

I have a QT application which uses database with several users (teachers in my case). I also have a table with teachers' names and information about them. Teacher logs in with his username and password at the beginning and then I need his full name somewhere in the program.
How should I retrieve it? Is there some way to store it in the table of db users? Or should I add column with username to my Teachers table? (It is my first application where I use databases so I'm sorry if this was asked before, I have no idea what I should google)
Database structure: https://yadi.sk/i/EmNwwsl7ia5JS
It's better to add two columns, for first name and last name, in the table where the username exists. So by using the username we can fetch the full name from the table.

use triggers to keep history of relational tables

say I have 6 tables.
Workstation
Workstation_CL
Location
Location_CL
Features
Features_CL
I am currently using triggers to do inserts into the "_CL" version of each table with an additional field that denotes whether the change was an "UPDATE", "INSERT" or "DELETE".
the workstation table keeps track of the "modified_by" user. if a user updates the location of a "Workstation" object, the "Location" table gets updated as well as the "Workstation" table. the only modification to the Workstation table is the "modified_by" field so that I will know who made the change.
The problem I am having is when I think about pulling an audit report. How will I link records in the "Location_CL" to the ones in the "Workstation_CL" both are populated by separate triggers.
somehow my question portion was erased. sorry about that.
Question: how can I pull some type of unique identifier to have in both the "Workstation_CL" and the "Location_CL" so that I can identify each revision? for instance, when I pull all records from the "Location_CL" and I see all location changes, pulling the username from the "Workstation_CL" that made the location change?
Give each revision a GUID generated by the trigger. Populate a field (RevisionId) in both tables with the value.
You need 2, maybe 3 columns on each audit table.
1) Timestamp, so you know when the changes were made.
2) User changed, so you can track who made the changes - I assume that Location can change independently of Workstation.
3) You might need an identifier for the transaction, too. I THINK you can get an id from the DB, though I'm not sure.
I don't think you can have an effective report without timestamps and users, though, and I don't think you just have the user on one table.
During the trigger event, I was able to exec the following:
SELECT #trans_id=transaction_id FROM sys.dm_tran_current_transaction
which gives me the transaction id for the current operation.
with that, I am able to insert it in to the corresponding _CL table and then perform selects that will match the auto-gen id's.