Tuesday, July 15, 2008

Controlling user access to data

A straight and simple question on Devshed prompted me to post this example about using updateable views to limit the ability of users to read and manipulate data both horizontally and vertically.
Before you ask, with "horizontally" I mean restricting access to a subset of rows in a table, with "vertically" I mean restricting access to a subset of columns in a table.
See this scenario, a table holding product data, named product_master and two users, one with full access and another one which we want to limit.
Specifically we want to allow this second user to see only products flagged as "enabled" (horizontal limitation, only a subset of rows) and, for those products, we want to be shure that he can only change (update) the product description.
How can we achieve this?
With a mix of grant management and updateable views, let's see this setup in action:
Structure for table product_master is:

  1. CREATE TABLE PRODUCT_MASTER(
  2. PRODUCT_CODE CHAR(5) NOT NULL,
  3. IS_ENABLED CHAR(1),
  4. PRODUCT_DESCR Varchar(50),
  5. CONSTRAINT PRODUCT_MASTER_PK PRIMARY KEY (PRODUCT_CODE)
  6. );
  7. GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE
  8. ON PRODUCT_MASTER TO SYSDBA WITH GRANT OPTION;

As you can see only sysdba has access to this table, nothing is granted to user pippo or public role.
We said that pippo should be able to update the product description, so I'll give him appropriate grants for this:

GRANT UPDATE ON PRODUCT_MASTER TO PIPPO; 

Ok, right now pippo can update the product table, then comes the hard part, allowing him to see and update only enabled products, those rows of the product master table that have the enabled field set to 'Y'.

This will be accomplished with an updateable view and proper grants, let's see it in action:

  1. CREATE VIEW ENABLED_PRODUCTS (PRODUCT_CODE, PRODUCT_DESCR)AS
  2. /* write select statement here */
  3. SELECT pm.PRODUCT_CODE, pm.PRODUCT_DESCR
  4. FROM product_master pm
  5. WHERE IS_ENABLED = 'Y'
  6. WITH CHECK OPTION;

The two important things here are the where condition in the select and the "with check option" clause.
The related grants to complete the magic are:

  1. GRANT SELECT, UPDATE ON ENABLED_PRODUCTS TO PIPPO;
  2. GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE
  3. ON ENABLED_PRODUCTS TO SYSDBA WITH GRANT OPTION;

Hope this helps

No comments: