Final docs cleanup and check of the git repo. Looks good.
authorMarc Munro <marc@bloodnok.com>
Thu, 11 Aug 2011 23:25:39 +0000 (16:25 -0700)
committerMarc Munro <marc@bloodnok.com>
Thu, 11 Aug 2011 23:25:39 +0000 (16:25 -0700)
demo/veil_demo.sqs [new file with mode: 0644]
src/veil_mainpage.c

diff --git a/demo/veil_demo.sqs b/demo/veil_demo.sqs
new file mode 100644 (file)
index 0000000..553acc0
--- /dev/null
@@ -0,0 +1,1238 @@
+create table veil.veil_demo_init_fns() inherits (veil.veil_init_fns);
+
+insert into veil.veil_demo_init_fns values ('veil.veil_demo_init', 1);
+
+create schema hidden;
+revoke all on schema hidden from public;
+
+create table hidden.privileges (
+    privilege_id   integer not null,
+    privilege_name varchar(80) not null
+);
+alter table hidden.privileges add constraint privilege__pk
+    primary key(privilege_id);
+
+
+create table hidden.roles (
+    role_id    integer not null,
+    role_name  varchar(80) not null
+);
+alter table hidden.roles add constraint role__pk
+    primary key(role_id);
+
+
+create table hidden.role_privileges (
+    role_id        integer not null,
+    privilege_id   integer not null
+);
+
+alter table hidden.role_privileges add constraint role_privilege__pk
+    primary key(role_id, privilege_id);
+
+alter table hidden.role_privileges add constraint role_privilege__role_fk
+    foreign key(role_id)
+    references hidden.roles(role_id);
+
+alter table hidden.role_privileges add constraint role_privilege__priv_fk
+    foreign key(privilege_id)
+    references hidden.privileges(privilege_id);
+
+create table hidden.role_roles (
+    role_id        integer not null,
+    has_role_id        integer not null
+);
+
+alter table hidden.role_roles add constraint role_role__pk
+    primary key(role_id, has_role_id);
+
+alter table hidden.role_roles add constraint role_role__role_fk
+    foreign key(role_id)
+    references hidden.roles(role_id);
+
+alter table hidden.role_roles add constraint role_role__has_role_fk
+    foreign key(has_role_id)
+    references hidden.roles(role_id);
+
+
+create sequence person_id_seq;
+create table hidden.persons (
+    person_id      integer not null,
+    person_name        varchar(80) not null
+);
+alter table hidden.persons add constraint person__pk
+    primary key(person_id);
+
+
+create sequence project_id_seq;
+create table hidden.projects (
+    project_id     integer not null,
+    project_name   varchar(80) not null
+);
+alter table hidden.projects add constraint project__pk
+    primary key(project_id);
+
+
+create table hidden.detail_types (
+    detail_type_id   integer not null,
+    required_privilege_id integer not null,
+    detail_type_name     varchar(80) not null
+);
+alter table hidden.detail_types add constraint detail_type__pk
+    primary key(detail_type_id);
+
+alter table hidden.detail_types add constraint detail_type__priv_fk
+    foreign key(required_privilege_id)
+    references hidden.privileges(privilege_id);
+
+
+create table hidden.assignments (
+    project_id     integer not null,
+    person_id      integer not null,
+    role_id        integer not null
+);
+alter table hidden.assignments add constraint assignment__pk
+    primary key(project_id, person_id);
+
+alter table hidden.assignments add constraint assignment__project_fk
+    foreign key(project_id)
+    references hidden.projects(project_id);
+
+alter table hidden.assignments add constraint assignment__person_fk
+    foreign key(person_id)
+    references hidden.persons(person_id);
+
+alter table hidden.assignments add constraint assignment__role_fk
+    foreign key(role_id)
+    references hidden.roles(role_id);
+
+
+create table hidden.person_roles (
+    person_id      integer not null,
+    role_id        integer not null
+);
+alter table hidden.person_roles add constraint person_role__pk
+    primary key(person_id, role_id);
+
+alter table hidden.person_roles add constraint person_role__person_fk
+    foreign key(person_id)
+    references hidden.persons(person_id);
+
+alter table hidden.person_roles add constraint person_role__role_fk
+    foreign key(role_id)
+    references hidden.roles(role_id);
+
+
+create table hidden.project_details (
+    project_id     integer not null,
+    detail_type_id integer not null,
+    value      text not null
+);
+alter table hidden.project_details add constraint project_detail__pk
+    primary key(project_id, detail_type_id);
+
+alter table hidden.project_details add constraint project_detail__project_fk
+    foreign key(project_id)
+    references hidden.projects(project_id);
+
+alter table hidden.project_details add constraint project_detail__detail_fk
+    foreign key(detail_type_id)
+    references hidden.detail_types(detail_type_id);
+
+
+create table hidden.person_details (
+    person_id      integer not null,
+    detail_type_id integer not null,
+    value      text not null
+);
+alter table hidden.person_details add constraint person_detail__pk
+    primary key(person_id, detail_type_id);
+
+alter table hidden.person_details add constraint person_detail__person_fk
+    foreign key(person_id)
+    references hidden.persons(person_id);
+
+alter table hidden.person_details add constraint person_detail__detail_fk
+    foreign key(detail_type_id)
+    references hidden.detail_types(detail_type_id);
+
+
+insert into hidden.privileges (privilege_id, privilege_name) values
+(10001,    'select_privileges'),
+(10002,    'insert_privileges'),
+(10003,    'update_privileges'),
+(10004,    'delete_privileges'),
+(10005,    'select_roles'),
+(10006,    'insert_roles'),
+(10007,    'update_roles'),
+(10008,    'delete_roles'),
+(10009,    'select_role_privileges'),
+(10010,    'insert_role_privileges'),
+(10011,    'update_role_privileges'),
+(10012,    'delete_role_privileges'),
+(10013,    'select_persons'),
+(10014,    'insert_persons'),
+(10015,    'update_persons'),
+(10016,    'delete_persons'),
+(10017,    'select_projects'),
+(10018,    'insert_projects'),
+(10019,    'update_projects'),
+(10020,    'delete_projects'),
+(10021,    'select_detail_types'),
+(10022,    'insert_detail_types'),
+(10023,    'update_detail_types'),
+(10024,    'delete_detail_types'),
+(10025,    'select_assignments'),
+(10026,    'insert_assignments'),
+(10027,    'update_assignments'),
+(10028,    'delete_assignments'),
+(10029,    'select_person_roles'),
+(10030,    'insert_person_roles'),
+(10031,    'update_person_roles'),
+(10032,    'delete_person_roles'),
+(10033,    'select_project_details'),
+(10034,    'insert_project_details'),
+(10035,    'update_project_details'),
+(10036,    'delete_project_details'),
+(10037,    'select_person_details'),
+(10038,    'insert_person_details'),
+(10039,    'update_person_details'),
+(10040,    'delete_person_details'),
+(10041,    'select_role_roles'),
+(10042,    'insert_role_roles'),
+(10043,    'update_role_roles'),
+(10044,    'delete_role_roles'),
+(10100,    'can_connect'),
+(10150,    'view_basic'),
+(10151,    'view_personal'),
+(10152,    'view_personal_secure'),
+(10153,    'view_project_confidential');
+
+insert into hidden.roles (role_id, role_name) values
+(11001,    'DBA'),
+(11002,    'Personal Context'),
+(11003,    'Employee'),
+(11004,    'Worker'),
+(11005,    'Project Manager'),
+(11006,    'Director'),
+(11007,    'Manager');
+
+-- DBA can do anything (but is not automatically an employee)
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11001, privilege_id
+from   hidden.privileges
+where  privilege_id != 10100;
+
+-- Personal Context allows update of personal details
+insert into hidden.role_privileges (role_id, privilege_id) values
+(11002,    10013),
+(11002,    10015),
+(11002,    10025),
+(11002,    10029),
+(11002,    10037),
+(11002,    10038),
+(11002,    10039),
+(11002,    10040),
+(11002,    10150),
+(11002,    10151),
+(11002,    10152);
+
+-- Basic Access can see lookup data
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11003, privilege_id
+from   hidden.privileges
+where  privilege_name in ('select_privileges', 'select_roles',
+             'select_role_privileges', 'select_detail_types');
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11003, 10100;
+
+-- Workers can modify project info
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11004, privilege_id
+from   hidden.privileges
+where  privilege_name like '%project%'
+and    privilege_name not like 'delete%'
+and    privilege_name not like '%confidential';
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11004, 10025;
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11004, 10150;
+
+-- Project Manager can do anything to project info and can see personal info
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11005, privilege_id
+from   hidden.privileges
+where  privilege_name like '%project%'
+or     privilege_name like '%assignment%';
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11005, privilege_id
+from   hidden.privileges
+where  privilege_name like 'select_person%';
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11005, 10150;
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11005, 10151;
+
+-- Director can do anything except modify personal details
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11006, privilege_id
+from   hidden.privileges
+where  privilege_name not like '%person%';
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11006, privilege_id
+from   hidden.privileges
+where  privilege_name like 'select_person%';
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11006, 10014;
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11006, 10151;
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11006, 10152;
+
+-- Manager can see personal info
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11007, privilege_id
+from   hidden.privileges
+where  privilege_name like 'select_person%';
+
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11007, 10150;
+insert into hidden.role_privileges (role_id, privilege_id)
+select 11007, 10151;
+
+
+insert into hidden.persons (person_id, person_name) values
+(1, 'Deb (the DBA)'),
+(2, 'Pat (the PM)'),
+(3, 'Derick (the director)'),
+(4, 'Will (the worker)'),
+(5, 'Wilma (the worker)'),
+(6, 'Fred (the fired DBA)');
+
+insert into hidden.person_roles (person_id, role_id) values
+(1, 11001),
+(1, 11003),
+(2, 11003),
+(2, 11007),
+(3, 11003),
+(3, 11006),
+(4, 11003),
+(5, 11003),
+(6, 11001);
+
+insert into hidden.projects (project_id, project_name) values
+(101, 'Secret Project'),
+(102, 'Public project');
+
+insert into hidden.assignments (project_id, person_id, role_id) values
+(101, 3, 11005),
+(101, 5, 11004),
+(102, 2, 11005),
+(102, 4, 11004),
+(102, 5, 11004);
+
+insert into hidden.detail_types (detail_type_id, required_privilege_id, 
+                   detail_type_name) values
+(1001, 10150, 'start_date'),
+(1002, 10150, 'status'),
+(1003, 10150, 'join_date'),
+(1004, 10152, 'salary'),
+(1005, 10151, 'date of birth'),
+(1006, 10152, 'sin'),
+(1007, 10150, 'skills'),
+(1008, 10153, 'contract value');
+
+insert into hidden.person_details (person_id, detail_type_id, value) values
+(1, 1003, '20050102'),
+(2, 1003, '20050103'),
+(3, 1003, '20050104'),
+(4, 1003, '20050105'),
+(5, 1003, '20050106'),
+(6, 1003, '20050107'),
+(1, 1002, 'Employee'),
+(2, 1002, 'Employee'),
+(3, 1002, 'Employee'),
+(4, 1002, 'Employee'),
+(5, 1002, 'Employee'),
+(6, 1002, 'Terminated'),
+(1, 1004, '50,000'),
+(2, 1004, '50,000'),
+(3, 1004, '80,000'),
+(4, 1004, '30,000'),
+(5, 1004, '30,000'),
+(6, 1004, '40,000'),
+(1, 1005, '19610102'),
+(2, 1005, '19600102'),
+(3, 1005, '19650102'),
+(4, 1005, '19660102'),
+(5, 1005, '19670102'),
+(1, 1006, '123456789'),
+(2, 1006, '123456789'),
+(3, 1006, '123456789'),
+(4, 1006, '123456789'),
+(5, 1006, '123456789'),
+(1, 1007, 'Oracle, C, SQL'),
+(2, 1007, 'Soft peoply-stuff'),
+(3, 1007, 'None at all'),
+(4, 1007, 'Subservience'),
+(5, 1007, 'Subservience');
+
+
+insert into hidden.project_details (project_id, detail_type_id, value) values
+(101, 1001, '20050101'),
+(101, 1002, 'Secretly ongoing'),
+(101, 1008, '$800,000'),
+(102, 1001, '20050101'),
+(102, 1002, 'Ongoing'),
+(102, 1008, '$100,000');
+
+
+-- Veil Variables:
+--   Shared:
+--     privs_range Range The range of privilege_id in the privileges table
+--     roles_range Range The range of role_id in the roles table
+--     role_privs Bitmap Array Array of privilege bitmaps indexed by role_id
+--     det_types_range Range The range of detail_type_id in detail_types
+--     det_types_privs Int4Array Mapping of detail_type_id to the privilege
+--       required to access details of that type
+--     
+--   Session:
+--     person_id Int4 The id of the currently connected person
+--     global_context Bitmap The global privileges of the connected person
+--     project_context Bitmap Hash Hash of privilege bitmaps, indexed by
+--       project_id, giving the connected person's project privileges.
+--
+-- Security Contexts:
+--   Global
+--     Privileges are identified in variable global_context
+--   Personal
+--     Privileges are identified in role_privs[11002].
+--   Project
+--     A relational context.  Privileges are identified in
+--     project_context[project_id].
+
+-- Replacement for default version of veil_init.
+-- Initialise and load all shared variables.
+--
+create or replace
+function veil.veil_demo_init(doing_reset bool) returns bool as '
+declare
+    exists_privs_range bool;
+    exists_roles_range bool;
+    exists_role_privs  bool;
+    exists_det_types_range bool;
+    exists_det_types_privs bool;
+    init_reqd bool;
+    dummy     bool;
+    dummy2    bool;
+    dummyint  int4;
+    _count    int4;
+begin
+    -- Declare all shared variables.
+
+    select into exists_privs_range, exists_roles_range,
+       exists_role_privs, exists_det_types_range,
+       exists_det_types_privs
+           veil.share(''privs_range''), veil.share(''roles_range''),
+      veil.share(''role_privs''), veil.share(''det_types_range''),
+      veil.share(''det_types_privs'');
+
+    init_reqd = not (exists_privs_range and exists_role_privs and
+            exists_role_privs and exists_det_types_range and
+            exists_det_types_privs);
+
+    if init_reqd or doing_reset then
+       -- Load ranges for privs and roles.
+       select into dummyint
+              veil.init_range(''roles_range'', min(role_id), max(role_id))
+       from   hidden.roles;
+
+       select into dummyint
+              veil.init_range(''privs_range'', min(privilege_id), 
+                     max(privilege_id))
+       from   hidden.privileges;
+
+   -- Load range for detail_types
+       select into dummyint
+              veil.init_range(''det_types_range'', 
+                      min(detail_type_id), max(detail_type_id))
+       from   hidden.detail_types;
+
+   -- Initialise array of required privs for detail_types
+       select into dummy
+              veil.init_int4array(''det_types_privs'', ''det_types_range'');
+       select into _count
+              count(veil.int4array_set(''det_types_privs'', 
+                               detail_type_id, required_privilege_id))
+       from   hidden.detail_types;
+
+       -- Initialise role_privs bitmap_array
+       select into dummy
+              veil.init_bitmap_array(''role_privs'', ''roles_range'', 
+                        ''privs_range'');
+
+       -- Populate role_privs bitmap_array
+       select into _count
+              count(veil.bitmap_array_setbit(''role_privs'', 
+                            role_id, privilege_id))
+       from   hidden.role_privileges;
+
+    end if;
+
+    -- Declare important session variables, so that we do not 
+    -- get odd, undefined variable, error messages.
+    select into dummyint, dummy, dummy2
+      veil.int4_set(''person_id'',  null),
+      veil.init_bitmap(''global_context'', ''privs_range''),
+      veil.init_bitmap_hash(''project_context'', ''privs_range'');
+
+    return true;               
+end;
+' language plpgsql volatile security definer;
+
+revoke execute on function veil.veil_demo_init(bool) from public;
+
+
+create or replace
+function connect_person(_person_id int4) returns bool as '
+declare
+    dummy    int4;
+    _connect bool;
+    proj_roles record;
+    last_proj int4;
+    first_rec bool;
+begin
+    -- In reality this function would require some authentication token such 
+    -- as a password.  This is just a dumb demo version.
+
+    select into _connect disconnect_person();
+
+    -- Test whether provided person exists.  This is where we would, in a
+    -- real version, do proper authentication.
+    select into dummy 1
+    from   hidden.persons
+    where  person_id = _person_id;
+
+    if found then
+   -- The person exists and passes authentication
+
+   -- From the persons roles set the global_context bitmap.
+   select into dummy
+          count(veil.union_from_bitmap_array(''global_context'',
+                         ''role_privs'', role_id))
+   from   hidden.person_roles
+   where  person_id = _person_id;
+
+   -- Check that user has can_connect privilege
+   select into _connect
+       veil.bitmap_testbit(''global_context'', 10100);
+
+   if not _connect then
+       select into _connect disconnect_person();
+       return false;
+   end if;
+
+
+   -- From the persons assignments set the project_context bitmap hash.
+   select into dummy
+          count(veil.union_into_bitmap_hash(''project_context'',
+           project_id::text,
+           veil.bitmap_from_array(''scratch_bitmap'',
+                          ''role_privs'', role_id)))
+   from   hidden.assignments
+   where  person_id = _person_id;
+
+   -- Finally, record the person_id for the connection.
+   select into dummy veil.int4_set(''person_id'', _person_id);
+
+   return true;
+    else
+   return false;
+    end if;
+
+end;
+' language plpgsql volatile security definer;
+
+create or replace
+function disconnect_person() returns bool as '
+declare
+    dummy int4;
+    dummy2 bool;
+    dummy3 bool;
+begin
+    -- Clear session bitmaps, and reset the person_id
+    select into dummy, dummy2, dummy3
+      veil.int4_set(''person_id'', null),
+      veil.init_bitmap(''global_context'', ''privs_range''),
+      veil.init_bitmap_hash(''project_context'', ''privs_range'');
+    return false;
+end;
+' language plpgsql volatile security definer;
+
+
+create or replace
+function i_have_global_priv(priv_id int4) returns bool as '
+declare
+    connection_id int4;
+    result bool;
+begin
+    select into connection_id, result 
+           veil.int4_get(''person_id''), 
+           veil.bitmap_testbit(''global_context'', priv_id);
+    if connection_id is null then
+   return false;
+    else
+        return result;
+    end if;
+end;
+' language plpgsql volatile security definer;
+
+
+create or replace
+function i_have_personal_priv(priv_id int4, person_id int4) returns bool as '
+declare
+    connection_id int4;
+    result bool;
+begin
+    select into connection_id, result 
+           veil.int4_get(''person_id''), 
+           veil.bitmap_testbit(''global_context'', priv_id);
+    if connection_id is null then
+   -- No-one is connected
+   return false;
+    else
+   if result then
+       -- We have the required privilege in global context.  No need
+       -- to check any further
+       return true;
+   else
+       if person_id = connection_id then
+       -- We are connected as the owner of this record.  Check
+       -- whether we have the required privilege in personal 
+       -- context.
+       select into result
+                  veil.bitmap_array_testbit(''role_privs'', 
+                           11002, priv_id);
+       return result;
+       else
+       -- We have no personal context rights to this record
+       return false;
+       end if;
+   end if;
+    end if;
+end;
+' language plpgsql volatile security definer;
+
+
+create or replace
+function i_have_project_priv(priv_id int4, project_id int4) returns bool as '
+declare
+    connection_id int4;
+    result bool;
+begin
+    select into connection_id, result 
+           veil.int4_get(''person_id''), 
+           veil.bitmap_testbit(''global_context'', priv_id);
+    if connection_id is null then
+   -- No-one is connected
+   return false;
+    else
+   if result then
+       -- We have the required privilege in global context.  No need
+       -- to check any further
+       return true;
+   else
+       select into result
+           veil.bitmap_hash_testbit(''project_context'', 
+                        project_id::text, priv_id);
+       return result;
+   end if;
+    end if;
+end;
+' language plpgsql volatile security definer;
+
+
+create or replace
+function i_have_proj_or_pers_priv(
+    priv_id int4, project_id int4, person_id int4) returns bool as '
+declare
+    connection_id int4;
+    result bool;
+begin
+    select into connection_id, result 
+           veil.int4_get(''person_id''), 
+           veil.bitmap_testbit(''global_context'', priv_id);
+    if connection_id is null then
+   -- No-one is connected
+   return false;
+    else
+   if result then
+       -- We have the required privilege in global context.  No need
+       -- to check any further
+       return true;
+   else
+       if person_id = connection_id then
+       -- We are connected as the owner of this record.  Check
+       -- whether we have the required privilege in personal 
+       -- context.
+       select into result
+                  veil.bitmap_array_testbit(''role_privs'', 
+                           11002, priv_id);
+       return result;
+       end if;
+       select into result
+           veil.bitmap_hash_testbit(''project_context'', 
+                        project_id::text, priv_id);
+       return result;
+       -- We have no personal context rights to this record
+       -- so check project context
+       return false;
+   end if;
+    end if;
+end;
+' language plpgsql volatile security definer;
+
+create or replace
+function i_have_project_detail_priv(detail_id int4, proj_id int4) returns bool as '
+declare
+    result bool;
+begin
+    select into result 
+        i_have_project_priv(veil.int4array_get(''det_types_privs'', detail_id),
+               proj_id);
+    return result;
+end;
+' language plpgsql volatile security definer;
+
+create or replace
+function i_have_person_detail_priv(detail_id int4, person_id int4) returns bool as '
+declare
+    result bool;
+begin
+    select into result 
+       i_have_personal_priv(veil.int4array_get(''det_types_privs'', detail_id),
+               person_id);
+    return result;
+end;
+' language plpgsql volatile security definer;
+
+create view privileges(
+       privilege_id,
+       privilege_name) as
+select privilege_id,
+       privilege_name
+from   hidden.privileges
+where  i_have_global_priv(10001);
+
+create rule ii_privileges as
+on insert to privileges
+do instead 
+    insert into hidden.privileges
+      (privilege_id, privilege_name)
+    select new.privilege_id, new.privilege_name 
+    where  i_have_global_priv(10002);
+
+create rule iu_privileges as
+on update to privileges
+do instead
+    update hidden.privileges
+    set    privilege_name = new.privilege_name,
+      privilege_id = new.privilege_id
+    where  privilege_id = old.privilege_id
+    and    i_have_global_priv(10003);
+create rule id_privileges as
+on delete to privileges
+do instead
+    delete from hidden.privileges
+    where  privilege_id = old.privilege_id
+    and    i_have_global_priv(10004);
+
+grant select, insert, update, delete on privileges to public;    
+
+create view roles(
+       role_id,
+       role_name) as
+select role_id,
+       role_name
+from   hidden.roles
+where  i_have_global_priv(10005);
+
+create rule ii_roles as
+on insert to roles
+do instead 
+    insert into hidden.roles
+      (role_id, role_name)
+    select new.role_id, new.role_name
+    where  i_have_global_priv(10006);
+
+create rule iu_roles as
+on update to roles
+do instead
+    update hidden.roles
+    set    role_name = new.role_name,
+      role_id = new.role_id
+    where  role_id = old.role_id
+    and    i_have_global_priv(10007);
+create rule id_roles as
+on delete to roles
+do instead
+    delete from hidden.roles
+    where  role_id = old.role_id
+    and    i_have_global_priv(10008);
+
+grant select, insert, update, delete on roles to public;    
+
+create view role_privileges(
+       role_id,
+       privilege_id) as
+select role_id,
+       privilege_id
+from   hidden.role_privileges
+where  i_have_global_priv(10009);
+
+create rule ii_role_privileges as
+on insert to role_privileges
+do instead 
+    insert into hidden.role_privileges
+      (role_id, privilege_id)
+    select new.role_id, new.privilege_id
+    where  i_have_global_priv(10010);
+
+create rule iu_role_privileges as
+on update to role_privileges
+do instead
+    update hidden.role_privileges
+    set    role_id = new.role_id, 
+      privilege_id = new.privilege_id
+    where  role_id = old.role_id
+    and    privilege_id = old.privilege_id
+    and    i_have_global_priv(10011);
+create rule id_role_privileges as
+on delete to role_privileges
+do instead
+    delete from hidden.role_privileges
+    where  role_id = old.role_id
+    and    i_have_global_priv(10012);
+
+grant select, insert, update, delete on role_privileges to public;    
+
+
+create view role_roles(
+       role_id,
+       has_role_id) as
+select role_id,
+       has_role_id
+from   hidden.role_roles
+where  i_have_global_priv(10041);
+
+create rule ii_role_roles as
+on insert to role_roles
+do instead 
+    insert into hidden.role_roles
+      (role_id, has_role_id)
+    select new.role_id, new.has_role_id
+    where  i_have_global_priv(10042);
+
+create rule iu_role_roles as
+on update to role_roles
+do instead
+    update hidden.role_roles
+    set    role_id = new.role_id,
+      has_role_id = new.has_role_id
+    where  role_id = old.role_id
+    and    i_have_global_priv(10043);
+create rule id_role_roles as
+on delete to role_roles
+do instead
+    delete from hidden.role_roles
+    where  role_id = old.role_id
+    and    i_have_global_priv(10044);
+
+grant select, insert, update, delete on role_roles to public;    
+
+
+create view persons(
+       person_id,
+       person_name) as
+select person_id,
+       person_name
+from   hidden.persons
+where  i_have_personal_priv(10013, person_id);
+
+create rule ii_persons as
+on insert to persons
+do instead 
+    insert into hidden.persons
+      (person_id, person_name)
+    select new.person_id, new.person_name
+    where  i_have_personal_priv(10014, new.person_id);
+
+create rule iu_persons as
+on update to persons
+do instead
+    update hidden.persons
+    set    person_id = new.person_id,
+      person_name = new.person_name
+    where  person_id = old.person_id
+    and    i_have_personal_priv(10015, old.person_id);
+create rule id_persons as
+on delete to persons
+do instead
+    delete from hidden.persons
+    where  person_id = old.person_id
+    and    i_have_personal_priv(10016, old.person_id);
+
+grant select, insert, update, delete on persons to public;    
+
+
+create view projects(
+       project_id,
+       project_name) as
+select project_id,
+       project_name
+from   hidden.projects
+where  i_have_project_priv(10017, project_id);
+
+create rule ii_projects as
+on insert to projects
+do instead 
+    insert into hidden.projects
+      (project_id, project_name)
+    select new.project_id, new.project_name
+    where  i_have_project_priv(10018, new.project_id);
+
+create rule iu_projects as
+on update to projects
+do instead
+    update hidden.projects
+    set    project_id = new.project_id,
+      project_name = new.project_name
+    where  project_id = old.project_id
+    and    i_have_project_priv(10019, old.project_id);
+create rule id_projects as
+on delete to projects
+do instead
+    delete from hidden.projects
+    where  project_id = old.project_id
+    and    i_have_project_priv(10020, old.project_id);
+
+grant select, insert, update, delete on projects to public;    
+
+
+create view detail_types (
+       detail_type_id,
+       required_privilege_id,
+       detail_type_name) as 
+select detail_type_id,
+       required_privilege_id,
+       detail_type_name
+from   hidden.detail_types
+where  i_have_global_priv(10021);
+
+create rule ii_detail_types as
+on insert to detail_types
+do instead 
+    insert into hidden.detail_types
+      (detail_type_id, detail_type_name)
+    select new.detail_type_id, new.detail_type_name
+    where  i_have_global_priv(10022);
+
+create rule iu_detail_types as
+on update to detail_types
+do instead
+    update hidden.detail_types
+    set    detail_type_id = new.detail_type_id, 
+      detail_type_name = new.detail_type_name
+    where  detail_type_id = old.detail_type_id
+    and    i_have_global_priv(10023);
+create rule id_detail_types as
+on delete to detail_types
+do instead
+    delete from hidden.detail_types
+    where  detail_type_id = old.detail_type_id
+    and    i_have_global_priv(10024);
+
+grant select, insert, update, delete on detail_types to public;    
+
+
+create view assignments (
+       project_id,
+       person_id,
+       role_id) as
+select project_id,
+       person_id,
+       role_id
+from   hidden.assignments
+where  i_have_proj_or_pers_priv(10025, project_id, person_id);
+
+create rule ii_assignments as
+on insert to assignments
+do instead 
+    insert into hidden.assignments
+      (project_id, person_id, role_id)
+    select new.project_id, new.person_id, new.role_id
+    where  i_have_proj_or_pers_priv(10026, new.project_id, new.person_id);
+
+create rule iu_assignments as
+on update to assignments
+do instead
+    update hidden.assignments
+    set    project_id = new.project_id,
+      person_id = new.person_id, 
+      role_id = new.person_id
+    where  project_id = old.project_id
+    and    person_id = old.person_id
+    and    i_have_proj_or_pers_priv(10027, old.project_id, old.person_id);
+create rule id_assignments as
+on delete to assignments
+do instead
+    delete from hidden.assignments
+    where  project_id = old.project_id
+    and    person_id = old.person_id
+    and    i_have_proj_or_pers_priv(10028, old.project_id, old.person_id);
+
+grant select, insert, update, delete on assignments to public;    
+
+
+create view person_roles (
+       person_id,
+       role_id) as
+select person_id,
+       role_id
+from   hidden.person_roles
+where  i_have_personal_priv(10029, person_id);
+
+create rule ii_person_roles as
+on insert to person_roles
+do instead 
+    insert into hidden.person_roles
+      (person_id, role_id)
+    select new.person_id, new.role_id
+    where  i_have_personal_priv(10030, new.person_id);
+
+create rule iu_person_roles as
+on update to person_roles
+do instead
+    update hidden.person_roles
+    set    person_id = new.person_id,
+      role_id = new.role_id
+    where  person_id = old.person_id
+    and    role_id = old.role_id
+    and    i_have_personal_priv(10031, old.person_id);
+create rule id_person_roles as
+on delete to person_roles
+do instead
+    delete from hidden.person_roles
+    where  person_id = old.person_id
+    and    role_id = old.role_id
+    and    i_have_personal_priv(10032, old.person_id);
+
+grant select, insert, update, delete on person_roles to public;    
+
+
+create view project_details (
+       project_id,
+       detail_type_id,
+       value) as
+select project_id,
+       detail_type_id,
+       value
+from   hidden.project_details
+where  i_have_project_priv(10033, project_id)
+and    i_have_project_detail_priv(detail_type_id, project_id);
+
+create rule ii_project_details as
+on insert to project_details
+do instead 
+    insert into hidden.project_details
+      (project_id, detail_type_id, value)
+    select new.project_id, new.detail_type_id, new.value
+    where  i_have_project_priv(10034, new.project_id)
+    and    i_have_project_detail_priv(new.detail_type_id, new.project_id);
+
+create rule iu_project_details as
+on update to project_details
+do instead
+    update hidden.project_details
+    set    project_id = new.project_id, 
+      detail_type_id = new.detail_type_id, 
+      value = new.value
+    where  project_id = old.project_id
+    and    detail_type_id = old.detail_type_id
+    and    i_have_project_priv(10035, old.project_id)
+    and    i_have_project_detail_priv(old.detail_type_id, old.project_id);
+create rule id_project_details as
+on delete to project_details
+do instead
+    delete from hidden.project_details
+    where  project_id = old.project_id
+    and    detail_type_id = old.detail_type_id
+    and    i_have_project_priv(10036, old.project_id)
+    and    i_have_project_detail_priv(old.detail_type_id, old.project_id);
+
+grant select, insert, update, delete on project_details to public;    
+
+
+create view person_details (
+       person_id,
+       detail_type_id,
+       value) as
+select person_id,
+       detail_type_id,
+       value
+from   hidden.person_details
+where  i_have_personal_priv(10037, person_id)
+and    i_have_person_detail_priv(detail_type_id, person_id);
+
+create rule ii_person_details as
+on insert to person_details
+do instead 
+    insert into hidden.person_details
+      (person_id, detail_type_id, value)
+    select new.person_id, new.detail_type_id, new.value
+    where  i_have_personal_priv(10038, new.person_id)
+    and    i_have_person_detail_priv(new.detail_type_id, new.person_id);
+
+create rule iu_person_details as
+on update to person_details
+do instead
+    update hidden.person_details
+    set    person_id = new.person_id, 
+      detail_type_id = new.detail_type_id, 
+      value = new.value
+    where  person_id = old.person_id
+    and    detail_type_id = old.detail_type_id
+    and    i_have_personal_priv(10039, old.person_id)
+    and    i_have_person_detail_priv(old.detail_type_id, old.person_id);
+create rule id_person_details as
+on delete to person_details
+do instead
+    delete from hidden.person_details
+    where  person_id = old.person_id
+    and    detail_type_id = old.detail_type_id
+    and    i_have_personal_priv(10040, old.person_id)
+    and    i_have_person_detail_priv(old.detail_type_id, old.person_id);
+
+
+grant select, insert, update, delete on person_details to public;    
+
+
+create or replace
+function global_privs_qry() returns setof int4 as '
+select * from veil.bitmap_bits(''global_context'');
+' language sql
+stable security definer;
+
+create or replace view my_global_privs (
+       privilege_id) as
+select * from global_privs_qry();
+
+grant select on my_global_privs to public;    
+
+
+create or replace
+function personal_privs_qry() returns setof int4 as '
+select * from veil.bitmap_array_bits(''role_privs'', 11002);
+' language sql
+stable security definer;
+
+create or replace view my_personal_privs (
+       privilege_id) as
+select * from personal_privs_qry();
+
+grant select on my_personal_privs to public;    
+
+
+create or replace
+function projects_qry() returns setof varchar as '
+select * from veil.bitmap_hash_entries(''project_context'');
+' language sql
+stable security definer;
+
+create or replace view my_projects (
+       project_id) as
+select * from projects_qry();
+
+grant select on my_projects to public;    
+
+
+create type hidden.proj_privs as (
+    project_id  int4,
+    privilege_id int4
+);
+
+create or replace
+function project_privs() returns setof hidden.proj_privs as '
+declare
+    _project record;
+    _priv    record;
+    _result  hidden.proj_privs;
+begin
+    for _project in 
+        select * from veil.bitmap_hash_entries(''project_context'')
+    loop
+        _result.project_id = _project.veil_bitmap_hash_entries;
+        for _priv in
+            select * from veil.bitmap_hash_bits(''project_context'', 
+                                                _result.project_id)
+        loop
+            _result.privilege_id = _priv.veil_bitmap_hash_bits;
+            return next _result;
+        end loop;
+    end loop;
+    return;
+end;
+' language plpgsql
+stable security definer;
+
+grant execute on function project_privs() to public;
+
+create or replace view my_project_privs (
+       project_id,
+       privilege_id) as
+select * from project_privs();
+
+grant select on my_project_privs to public;    
+
+
+create or replace view my_privs (
+    context,
+    project,
+    privilege_id,
+    privilege_name)
+as 
+select a.context, a.project, a.id, p.privilege_name
+from   (
+        select 'Project' as context, project_id as project,
+               privilege_id as id, 3 as seq
+        from   my_project_privs
+        union all
+        select 'Global', null, privilege_id, 1
+        from   my_global_privs
+        union all
+        select 'Personal', null, privilege_id, 2
+        from   my_personal_privs
+       ) a,
+       privileges p
+where  p.privilege_id = a.id
+order by a.seq, a.context, a.project, a.id;
+
+grant select on my_privs to public;    
index 12d3018fa58db133db8229e5786bad3d66aeb8b2..f66781e654ddea842315525f9bb10028e7d82c94 100644 (file)
@@ -1887,15 +1887,19 @@ Next: \ref install
 Veil can be downloaded as a gzipped tarball from
 http://pgfoundry.org/projects/veil/
 
-The latest development version can also be retrieved from the cvs
-repository using the following commands.  When prompted for a password
-for anonymous, simply press the Enter key. 
+Since version 9.1, git is no longer available from cvs on pgfoundry.
+Development has switched to using git.  The primary git repository is 
+git://github.com/marcmunro/veil.git
+
+To checkout from git, create a suitable directory and do:
 
 \verbatim
-cvs -d :pserver:anonymous@cvs.pgfoundry.org:/cvsroot/veil login
-cvs -d :pserver:anonymous@cvs.pgfoundry.org:/cvsroot/veil checkout veil
+ git clone git://github.com/marcmunro/veil.git
 \endverbatim
 
+An alternative repository is also available here:
+git@bloodnok.com:veil.git
+
 \subsection Pre-requisites Pre-requisites
 You must have a copy of the Postgresql header files available in order
 to build Veil.  For this, you may need to install the postgres developer