Thread: Different views with same name for different users

Different views with same name for different users

From
"Harald Massa"
Date:
Hello,

i've got a table of around 10.000 records.

Users A, B, C are allowed to see all the records

user D only some
user E only some others

To take logic away from the application to the database,
I would like to have a view as

for user D:
CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria for viewable
user D)

for user E:
CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria for viewable
user E)

for users A, B, C
CREATE VIEW PERS as SELECT * FROM TOTALDATABASE

so in my application I can do alll the SELECTS on PERS ... which looks
different for every user.

Which is the most elegant way to do this?
(is there any way at all????)

Tnx

Harald




Re: Different views with same name for different users

From
Holger Krug
Date:
On Wed, Jan 16, 2002 at 02:21:39PM +0100, Harald Massa wrote:
> i've got a table of around 10.000 records.
>
> Users A, B, C are allowed to see all the records
>
> user D only some
> user E only some others
>
> Which is the most elegant way to do this?
> (is there any way at all????)

You cannot create different views with the same name in one PostgreSQL
database.  Hence the first answer is: there is no way.

Nevertheless that's not the right answer. You can create only one view:

   CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria)

Within criteria you can check the user (`current_user') and return
`true' or `false' depending on the record at hand and the current
user.

--
Holger Krug
hkrug@rationalizer.com

Re: Different views with same name for different users

From
Darren Ferguson
Date:
Correct me if i am wrong which is normally the case :-))

But you could create the views as you have said then grant user access
permissions on them. I.e. get the priveldged user to create all the views
and then use the GRANT command to allow users to access them. I.e.

GRANT ALL ON PERS TO user D;

Hope this helps

Darren

Darren Ferguson

On Wed, 16 Jan 2002, Harald Massa wrote:

> Hello,
>
> i've got a table of around 10.000 records.
>
> Users A, B, C are allowed to see all the records
>
> user D only some
> user E only some others
>
> To take logic away from the application to the database,
> I would like to have a view as
>
> for user D:
> CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria for viewable
> user D)
>
> for user E:
> CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria for viewable
> user E)
>
> for users A, B, C
> CREATE VIEW PERS as SELECT * FROM TOTALDATABASE
>
> so in my application I can do alll the SELECTS on PERS ... which looks
> different for every user.
>
> Which is the most elegant way to do this?
> (is there any way at all????)
>
> Tnx
>
> Harald
>
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
>


Re: Different views with same name for different users

From
Holger Krug
Date:
On Wed, Jan 16, 2002 at 09:59:42AM -0500, Darren Ferguson wrote:
> But you could create the views as you have said then grant user access
> permissions on them. I.e. get the priveldged user to create all the views
> and then use the GRANT command to allow users to access them. I.e.

You forgot: He aimed to create all the different views with one and
the same name. This is impossible in PostgreSQL.

--
Holger Krug
hkrug@rationalizer.com

Re: Different views with same name for different users

From
"Steve Boyle \(Roselink\)"
Date:
Harald,

Possible method to implement security that I think matches your requirements
follows, please feel free to comment:-

(
Notes:
 ------
    I have only implemented the 'select' view the model could be easily
expanded to cope with different             security permissions.
    I have added the notion of user groups for convenience.
    You could probably do something similar hooking into the pg_tables,
there are would be pros and             cons if you did that.
    You would probably want to modify the keys / foreign keys before using
the model (i.e. I've set them         all as varchar(50).
)

hih

steve boyle

-- create tables
create table users (
    user_id varchar(50),
    primary key (user_id)
);

create table items (
    item_id varchar(50),
    primary key (item_id)
);

create table groups (
    group_id    varchar(50),
    primary key (group_id)
);

create table user_groups (
    fk_user_id  varchar(50),
    fk_group_id varchar(50),
    primary key (fk_user_id,fk_group_id)
);

create table item_group_permissions (
    fk_group_id varchar(50),
    fk_item_id  varchar(50),
    canselect   bool default true,
    canupdate   bool default false,
    candelete   bool default false,
    primary key (fk_group_id,fk_item_id)
);

-- add foreign key constraints
alter table user_groups add constraint fk_groups_user_groups_group_id
foreign key (fk_group_id)
    references groups(group_id)
    on update cascade
    not deferrable
    initially immediate;

alter table user_groups add constraint fk_users_user_groups_user_id
foreign key (fk_user_id)
    references users(user_id)
    on update cascade
    not deferrable
    initially immediate;

alter table item_group_permissions add constraint
fk_groups_item_group_permissions_group_id
foreign key (fk_group_id)
    references groups(group_id)
    on update cascade
    not deferrable
    initially immediate;

alter table item_group_permissions add constraint
fk_items_item_group_permissions_item_id
foreign key (fk_item_id)
    references items(item_id)
    on update cascade
    not deferrable
    initially immediate;

-- insert demo data

insert into items (item_id) values ('item 1');
insert into items (item_id) values ('item 2');
insert into items (item_id) values ('item 3');

insert into users (user_id) values ('user 1');
insert into users (user_id) values ('user 2');
insert into users (user_id) values ('user 3');
insert into users (user_id) values ('user 4');

insert into groups (group_id) values ('group 1');
insert into groups (group_id) values ('group 2');
insert into groups (group_id) values ('group 3');

insert into user_groups(fk_user_id, fk_group_id) values ('user 1', 'group
1');
insert into user_groups(fk_user_id, fk_group_id) values ('user 2', 'group
2');
insert into user_groups(fk_user_id, fk_group_id) values ('user 3', 'group
3');
insert into user_groups(fk_user_id, fk_group_id) values ('user 4', 'group
1');
insert into user_groups(fk_user_id, fk_group_id) values ('user 4', 'group
2');

insert into item_group_permissions
    (fk_group_id, fk_item_id, canselect, canupdate, candelete) values
    ('group 1', 'item 1', 'T', 'T', 'T');
insert into item_group_permissions
    (fk_group_id, fk_item_id, canselect, canupdate, candelete) values
    ('group 2', 'item 2', 'T', 'T', 'T');
insert into item_group_permissions
    (fk_group_id, fk_item_id, canselect, canupdate, candelete) values
    ('group 3', 'item 3', 'T', 'T', 'T');
insert into item_group_permissions
    (fk_group_id, fk_item_id, canselect, canupdate, candelete) values
    ('group 2', 'item 1', 'T', 'F', 'F');
insert into item_group_permissions
    (fk_group_id, fk_item_id, canselect, canupdate, candelete) values
    ('group 3', 'item 1', 'T', 'F', 'F');
insert into item_group_permissions
    (fk_group_id, fk_item_id, canselect, canupdate, candelete) values
    ('group 2', 'item 3', 'T', 'F', 'F');
insert into item_group_permissions
    (fk_group_id, fk_item_id, canselect, canupdate, candelete) values
    ('group 3', 'item 2', 'T', 'F', 'F');

-- create permission api views

create view usr_select_items as
select distinct items.item_id, item_group_permissions.canselect,
users.user_id
from users inner join
    items
    inner join
        groups
            inner join item_group_permissions on
                groups.group_id = item_group_permissions.fk_group_id
            inner join user_groups
                on groups.group_id = user_groups.fk_group_id
        on items.item_id = item_group_permissions.fk_item_id
    on users.user_id = user_groups.fk_user_id
where
    item_group_permissions.canselect='T' and
users.user_id::text=getpgusername()::text
order by items.item_id;

-- Other api permission views could follow

----- Original Message -----
From: "Harald Massa" <HaraldMassa@ghum.de>
To: <pgsql-general@postgresql.org>
Sent: Wednesday, January 16, 2002 1:21 PM
Subject: [GENERAL] Different views with same name for different users


> Hello,
>
> i've got a table of around 10.000 records.
>
> Users A, B, C are allowed to see all the records
>
> user D only some
> user E only some others
>
> To take logic away from the application to the database,
> I would like to have a view as
>
> for user D:
> CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria for
viewable
> user D)
>
> for user E:
> CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria for
viewable
> user E)
>
> for users A, B, C
> CREATE VIEW PERS as SELECT * FROM TOTALDATABASE
>
> so in my application I can do alll the SELECTS on PERS ... which looks
> different for every user.
>
> Which is the most elegant way to do this?
> (is there any way at all????)
>
> Tnx
>
> Harald
>
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
>


Re: Different views with same name for different users

From
Elein
Date:
Holger Krug wrote:

> On Wed, Jan 16, 2002 at 02:21:39PM +0100, Harald Massa wrote:
>
>>i've got a table of around 10.000 records.
>>
>>Users A, B, C are allowed to see all the records
>>
>>user D only some
>>user E only some others
>>
>>Which is the most elegant way to do this?
>>(is there any way at all????)
>>
>
> You cannot create different views with the same name in one PostgreSQL
> database.  Hence the first answer is: there is no way.
>
> Nevertheless that's not the right answer. You can create only one view:
>
>    CREATE VIEW PERS as SELECT * FROM TOTALDATABASE where (criteria)
>
> Within criteria you can check the user (`current_user') and return
> `true' or `false' depending on the record at hand and the current
> user.
>
>

how about

create view pers as
select ... from totaldb where userid='D' and (d criteria)
union
select ... from totaldb where userid in 'A, B, C' and (abc criteria)
union
select ... from totaldb where userid = 'E' and (e criteria);

You would have to match the columns, perhaps put "not available" where
appropriate.  Of course there are spiffier ways to group permissions
instead of hardcoding ids.

elein

--
--------------------------------------------------------
elein@nextbus.com
(510)420-3120
www.nextbus.com
    spinning to infinity, hallelujah
--------------------------------------------------------


Re: Different views with same name for different users

From
"Harald Massa"
Date:
I found (thank you, Holger Krug) a way to do the access-problem


create view pers as select * from totaldatabase
where case currentuser="userA" then beraterid in (1256,2523,2521,623,124)
else beraterid in (9123, 12312,12313) end

(or more case statements.)

But NOW there are 2 drawbacks

1.) INSERT and UPDATE became MUCH MORE complicated. I have defined rules (do
instead insert ....), but now partial inserts (only SOME columns of the
orignal table) do not work.

2.) there is some bad performance penality. If I do a
explain select * from totaldatabase
where case currentuser="userA" then beraterid in (1256,2523,2521,623,124)
else beraterid in (9123, 12312,12313) end
allways the sequential scan is used - also that only 2% of the rows are
visible. The Planner seems not to realise, that currentuser="userA" DOES NOT
change with each row.

I think I'll ask my question in another way again..

Thank you all,

HArald