How to enable users only to view certain rows in a table - mysql

I currently have two tables. One is accounts and one is tbl_units_info. My boss wants me to make it so that accounts are restricted from reading certain rows in a table. Frankly, I think my boss has no idea what he is talking about, but I'm hoping someone here can prove me wrong.
For example, accountname krikara can only view the entries of the tbl_units_info table where the TBID column is 0909.
Is this even possible? To make krikara only able to view the rows in that table where column TBID = 0909?

It can not be implemented plainly on DBMS level since SELECT privilege has table level. You can not restrict rows reading. And this is good, I think - because data could be changed, so in general there is no solid condition for rows restriction (and, therefore, there could not be valid implementation for that on DBMS level).
You can, however, use VIEW - but it is a middlepoint, not common solution (I still not think it will help with tracking rows changes, but may be I'm wrong due to your application logic)
You can try to implement it in your application, but it still has problem I've described above: in table, data is changing. You'll probably have troubles with tracking all changes. I think you can separate your rows on two (several) tables and then build your permissions model. But - if some basically similar entities must have different permissions - probably you should reconsider application security model?

You could solve it by giving accounts just the reading rights to a view instead of the whole table.
CREATE VIEW `tbl_units_info_krikara` AS
SELECT * FROM `tbl_units_ino` WHERE `TBID`='0909';
And then assign the respective rights to your user.
MySQL CREATE VIEW documentation

Related

What is MySQL View for?

MySQL Documentation explains how to create a view. However it doesn't explain why should I make a MySQL View in the first place.
Thus, my question is, what is MySQL View? What is it for? At what circumstances should I make or not make one?
Quoting the documentation
The view definition is “frozen” at creation time and is not affected by subsequent changes to the definitions of the underlying tables.
I don't see how creating a view would be beneficial, so please, enlighten me.
View the data without storing the data into the object.
Restrict the view of a table i.e. can hide some of columns in the tables.
Join two or more tables and show it as one object to user.
Restrict the access of a table so that nobody can insert the rows into the table.
Where I work, we use the views as big painful querys that we need many times, we decided to create views for them instead of doing a manual query and when we need to access the information
SELECT * FROM view WHERE (anything)

SQL Database architecture with multiple end Users

I am making a web application where users get and manage data from multiple tables as well as create other users to access said data. currently I have it set up for one group of users.
My question is would it be better to have multiple databases in which each database has its own user which is stored in a master table("I don't like the sound of this one") or have a column in each table defining the user group that has access to it? Are either of these a good idea or is something else more appropriate?
You should have a column in each table. In my opinion, its the correct thing to do, and also you have only one database to do mantainance.
Just imagine the time it would take to add a column to a table in the future, and you should do it in multiple databases.

How can I allow users sql access to a table limited to certain rows?

I'm building an stock exchange simulation game. I have a table called 'Market_data' and in the game players simulate being in particular dates and are allowed to use SQL queries to retrieve the historical data and plan their course of action. My difficulty is that I need to limit the rows they can access based on the current date they are playing on so they cant see rows with a date greater than the current date.
Eg: An user is running the game and is currently in the year 2010, if he does a simple select like "SELECT * FROM market_data" I don't want him to see rows with Date > 'x-x-2010'
The only soution that I know of is to parse the user's SQL and add WHERE clauses to remove newer dates but it seems time consuming and prone to errors and I wasn't sure whether there were better alternatives. Any ideas on how to do this right will be thanked.
Solution is SQL Views, Views are used for several different reasons:
*1.*To hide data complexity. Instead of forcing your users to learn the T-SQL JOIN syntax you might wish to provide a view that runs a commonly requested SQL statement.
*2.*To protect the data. If you have a table containing sensitive data in certain columns, you might wish to hide those columns from certain groups of users. For instance, customer names, addresses and their social security numbers might all be stored in the same table; however, for lower level employees like shipping clerks, you can create a view that only displays customer name and address. You can grant permissions to a view without allowing users to query the underlying tables. There are a couple of ways you might want to secure your data:
a.Create a view to allow reading of only certain columns from a table. A common example of this would be the salary column in the employee table. You might not want all personnel to be able to read manager's or each other's salary. This is referred to as partitioning a table vertically and is accomplished by specifying only the appropriate columns in the CREATE VIEW statement.
b.Create a view to allow reading only certain rows from a table. For instance, you might have a view for department managers. This way, each manager can provide raises only to the employees of his or her department. This is referred to as horizontal partitioning and is accomplished by providing a WHERE clause in the SELECT statement that creates a view.
*3.*Enforcing some simple business rules. For example, if you wish to generate a list of customers that need to receive the fall catalog, you can create a view of customers that have previously bought your shirts during the fall.
*4.*Data exports with BCP. If you are using BCP to export your SQL Server data into text files, you can format the data through views since BCP's formatting ability is quite limited.
*5.*Customizing data. If you wish to display some computed values or column names formatted differently than the base table columns, you can do so by creating views.
reference taken from http://sqlserverpedia.com.
1)You can use mysql proxy http://dev.mysql.com/downloads/mysql-proxy/ with custom rules restricting access.
2)You can use stored procedures/functions
3)You can use views
The basic way would be :
-> Prevent that user (or group) from accessing the base table.
-> Define a view on top of that table that shows only the rows these users are supposed to see.
-> Give those users SELECT permission on the view.
-> And you can also use SQL Encryption,Decryption and Hashing concept.
Encryption & Decryption examples can be found here:
http://msdn.microsoft.com/en-us/library/ms179331.aspx
Hashing example can be found here:
http://msdn.microsoft.com/en-us/library/ms174415.aspx

Regex for SQL string to allow SELECT queries on variable named tables only?

The table names are variable, but what is certain is that SELECT only is allowed and certain tables are excluded (ie Users, Log). I'm making a reporting form where a user can just enter sql queries to make template reports.
SELECT 'field1' As 'foo', 'field2' as 'bar'.. 'fieldn'
FROM 'table1',..'tablen'
JOIN ... ON ...
WHERE CONDITION
Although I'm thinking I can have the table names in a html select list of existing tables.
Also make a user reporter_appname#localhost with SELECT access only to all tables except Users and Log? In that case I won't need to bother with a regex check of the query?
(This would be in PHP)
(Ideally I just wanted a single textarea where the admin can just type their query, my report function would then take the output and present it nicely etc.)
I suggest you re-think your design.
Identifying valid select statements (and excluding all other statements) is basically impossible without completely parsing SQL. A regex is not going to be up to the task.
Even if you allow only select statements, users could perform denial-of-service attacks on your database. It is very easy to create select statements that run forever (we've all done it). A malicious user could crash your site in a hurry. And even well-intentioned users might do this by accident.
It would be much better to give the users more limited options for creating reports. Let them select certain tables and columns from a list, and create the appropriate query for them.
There is probably free MySQL reporting software out there that could serve as a good starting point, though I don't have any experience with this myself.
I think that you should rethink the design of your application.
The Users and Log tables should be on one database and the tables with the data for the reports should be on another database.
If you have them all in one database already just create another database, link them and then create synonyms from one database to another only for the tables that the user can access via his queries.
The user will run his queries on the database you have just created and he will be limited to those tables that have synonyms on it.
I do not know if this would be the best option because your description of the case is relatively vague but based on the information I have this could be a solution.

mysql query all sub-accounts and their sub-accounts and so on

I have one table like this
account_id (INT)
inviter_id (INT)
Now, logged in user with account id 5 wants to see the logs that related to all of his invitees, directly and indirectly, as this table may represent nested hierarchy of unlimited depth.
How would I do that with MySQL?
I accept a solution in PHP/C/C++/C# (:
Actually I've looked for it here and at google and couldn't find anything for that particular case, as everyone try to have nested menus at their website and ask about it.
I've been thinking about simply querying for all accounts in the database (there are about a few hundreds) and from there simply build a tree, or something, but then again I have to stay synced with the database.
So to stay synced with the database I've thought about querying the COUNT() of the accounts in the table, but, what if I need to change an inviter'd (maybe deleting one)?
Anyway, I could appply the rule of "not changing inviter" - if I'd do that, then COUNT() would work I think - is there any better approach to that kind of issue?
you can take a look at my answer(s) here if you like:
Print hierachical data in a parent child form unordered list php?
or here:
Mysql Recursive Stored Procedure...Limit 0 reached...can't change the max_sp_recursion_depth variable
or here:
Multi-tiered Comment Replies: Display and Storage
or here:
MySQL Hierarchical Structure Data Extraction
hope it helps
Check this out, this might give you some ideas: http://www.ideashower.com/our_solutions/create-a-parent-child-array-structure-in-one-pass/