User Tools

Site Tools


new_permission_model

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
new_permission_model [2007/02/13 21:08] – one more to-do item. pizzanew_permission_model [2007/04/26 19:45] (current) – rewrote the last part. pizza
Line 8: Line 8:
   * Allow individual "clients" access to different sets of photos   * Allow individual "clients" access to different sets of photos
   * Allow finer-grained control over original images   * Allow finer-grained control over original images
-  * ... 
  
-This permission model will be group-based; individual users will have a personal "group", but can exist in any number of groups.  "Guests" will have the special group 0, and permissions can be assigned to them like any other group. +This permission model will be group-based; individual users will have a personal "group", but can exist in any number of groups.  "Guests" will have their own special group, and permissions can be assigned to them like any other group. 
  
-By default, no groups will have permission to do anything, other than the administrator, who has full access to everything.  Permissions are explicitly granted on an image-by-image basis, but if no specific permission is set on the image, the folder/album's default permissions are used instead.+By default, no groups will have permission to do anything, other than the administrator, who has full access to everything.  Permissions are explicitly granted on an image-by-image basis, so if no specific permission is set on the image for a particular groupaccess will be denied.
  
 This allows "group ownership" of images, folders, etc, and allows for individual user control while allowing them to share a common set of images.   This allows "group ownership" of images, folders, etc, and allows for individual user control while allowing them to share a common set of images.  
Line 18: Line 17:
 ==== Schema ==== ==== Schema ====
  
-  create sequence groups_sequence start 0; +<code> 
-   +-- as of 4/26/2007 @12:15pm
-  create table groups ( +
-        identifier integer not null primary key, +
-        owner_id references users(identifier), -- who owns this group? +
-        description text +
-        password text                          -- group password, if any. +
-  ); +
-   +
-  create table group_memberships ( +
-        group_id integer not null references groups(identifier), +
-        user integer not null references users(identifier) +
-  ); +
-   +
-  create table photo_permissions ( +
-        photo integer not null references photo(identifier), +
-        group_id integer not null references groups(identifier), +
-        -- basic permissions per-image +
-        view boolean not null, -- aka thumbnail/preview & basic info +
-        details boolean not null, -- view all detailed info on image +
-        original boolean not null, -- access original +
-        edit boolean not null, -- modify  +
-        remove boolean nut null -- remove +
-  ); +
-   +
-  create table folder_permissions ( +
-        folder integer not null references folder(identifier), +
-        group_id integer not null references groups(identifier), +
-        -- default image permissions for this folder +
-        view boolean not null, -- aka thumbnail/preview & basic info +
-        details boolean not null, -- view all detailed info on image +
-        original boolean not null, -- access original +
-        edit boolean not null, -- modify  +
-        delete boolean nut null -- remove +
-        -- folder permissions +
-        list boolean not null, -- display folder & view photo list +
-        modify boolean not null -- add/remove entries, (photos and/or subfolders) +
-  ); +
-   +
-  create table album_permissions ( +
-        album integer not null references album(identifier), +
-        group_id integer not null references groups(identifier), +
-        -- default image permissions for this folder +
-        view boolean not null, -- aka thumbnail/preview & basic info +
-        details boolean not null, -- view all detailed info on image +
-        original boolean not null, -- access original +
-        edit boolean not null, -- modify  +
-        delete boolean nut null -- remove +
-        -- album permissions +
-        list boolean not null, -- display album & view photo list +
-        modify boolean not null -- add/remove entries, (photos and/or subalbums) +
-  ); +
-   +
-  alter table photo add owner integer references groups(identifier); +
-  alter table folder add owner integer references groups(identifier); +
-  alter table album add owner integer references groups(identifier); +
-   +
-  -- post-migration we need to: +
-  alter table photo drop users; +
-  alter table folder drop users; +
-  alter table album drop users; +
-  alter table photo alter column owner set not null; +
-  alter table folder alter column owner set not null; +
-  alter table album alter column owner set not null; +
-  alter table photo drop hide_original; +
-  alter table photo drop access_rights; +
-  alter table folder drop access_rights; +
-  alter table album drop access_rights; +
-  alter table users drop type; +
-  drop table user_type; +
-  drop sequence user_type_sequence; +
-   +
-  -- Don't forget about camera/film/filter/flash/support/scanner/location/clients +
-  -- as they also have user/owners.. +
-  -- We also need Indices!+
  
-==== Migration ====+create sequence groups_sequence start 0;
  
-The goal of this migration is to transform all existing permissions to the new model.+-- 'date_added' is set via trigger.
  
-== Set things up ==+create table groups ( 
 +      identifier integer not null primary key, 
 +      description text, 
 +      password text,                         -- group password, if any... 
 +      date_added timestamp without time zone 
 +);
  
-  * Create new tables. (see above)+create table group_memberships ( 
 +      group_id integer not null references groups(identifier), 
 +      user integer not null references users(identifier), 
 +      owner boolean not null default 'f', -- aka can change permissions 
 +      date_added timestamp without time zone 
 +);
  
-  * Create group 0, "Admin Users", and populate it with all admin users.+-- setting 'owner' to 't' implicitly sets 'view' to 't' (via trigger) 
 +-- setting 'edit' to 't' implicitly sets 'caption' to 't' (via trigger)
  
-  INSERT INTO groups(identifier, owner_iddescription)   +create table photo_permissions ( 
-       VALUES (0'Administrators');+      photo integer not null references photo(identifier), 
 +      group_id integer not null references groups(identifier), 
 +      -- basic permissions per-image 
 +      owner boolean not null-- aka can change permissions 
 +      view boolean not null-- aka thumbnail/preview & basic info 
 +      details boolean not null-- view all detailed info on image 
 +      original boolean not null, -- access original 
 +      edit boolean not null, -- modify  
 +      caption boolean not null, -- modify keywords/captions/etc 
 +      delete boolean not null -- remove 
 +);
  
-  INSERT INTO group_memberships(group_id, user+create table folder_permissions ( 
-       SELECT $_admin_grp_id as group_id, u.identifier +      folder integer not null references folder(identifier), 
-         FROM users uuser_type t +      group_id integer not null references groups(identifier), 
-        WHERE u.type = t.identifier +      -- default image permissions for this folder 
-          AND t.value = 'Administrator';+      owner boolean not null-- aka can change permissions 
 +      edit boolean not null, -- modify  
 +      delete boolean nut null, -- remove 
 +      list boolean not null, -- display folder & view photo list 
 +      modify boolean not null -- add/remove entries, (photos and/or subfolders) 
 +);
  
-  * Create group 1"Guest"+create table album_permissions ( 
 +      album integer not null references album(identifier), 
 +      group_id integer not null references groups(identifier), 
 +      -- default image permissions for this album 
 +      owner boolean not null, -- aka can change permissions 
 +      edit boolean not null, -- modify  
 +      delete boolean nut null, -- remove 
 +      list boolean not null, -- display album & view photo list 
 +      modify boolean not null -- add/remove entries, (photos and/or subalbums) 
 +);
  
-  INSERT INTO groups(identifier, owner_id, description)   +-- Lookup functions go here!
-       VALUES (1, 0, 'Guests');+
  
-  * Create group 2, "Registered Users". 
  
-  INSERT INTO groups(identifier, owner_id, description)   +-- post-migration we need to:
-       VALUES (2, 2, 'Registered Users');+
  
-== The following list needs to be repeated for each user ==+drop table client; 
 +drop table client_status;
  
-  * Create a new group of the same name, make only that user a member.+alter table photo drop users; 
 +alter table folder drop users; 
 +alter table album drop users;
  
-  $_grp_id = SELECT nextval(groups_sequence)+alter table photo drop hide_original
-   +alter table photo drop access_rights; 
-  INSERT INTO groups(identifier, owner_id, description)   +alter table folder drop access_rights
-       VALUES ($grp_id, $grp_id ,'$_userid's group')+alter table album drop access_rights;
-  INSERT INTO group_memberships(group, user)  +
-       VALUES ($_new_grpid, $_userid);+
  
-  * Update ownerships to point to the new group:+------- not sure about these:
  
-  UPDATE folder f  +-- alter table users drop type;  
-     SET f.owner = (SELECT g.group_id  +-- drop table user_type
-                      FROM group_memberships g  +-- drop sequence user_type_sequence;
-                     WHERE g.user = f.users) , +
-   WHERE f.users = $_userid+
-         +
-    UPDATE album a +
-     SET a.owner = (SELECT g.group_id  +
-                      FROM group_memberships g  +
-                     WHERE g.user = a.users) , +
-   WHERE a.users = $_userid+
-   +
-    UPDATE photo p +
-     SET p.owner = (SELECT g.group_id  +
-                      FROM group_memberships g  +
-                     WHERE g.user = p.users) , +
-   WHERE p.users = $_userid +
  
-  * Add user into the "Registered Users" group.+-- Don't forget about camera/film/filter/flash/support/scanner/location/clients 
 +-- as they also have user/owners.
 +-- We also need Indices! 
 +</code> 
 +==== Psuedocode ====
  
-  INSERT INTO group_memberships(group_id, user)  +This code is roughly what we need to do to see if an image/folder/album has the appropriate permissions.  Before it goes into production it'll need to be implemented on the database using pl/pgsql.
-       VALUES ($_reg_users_grpid, $_userid);+
  
-  * Create a new group called "$_userid's clients"make all of their clients members +<code> 
 +// type == photo, group, album 
 +// identifier == photo#, group#, album# 
 +// user == userid 
 +// permission == view/original/edit/caption/delete/details list/modify 
 +// returns true if allowed, or false if no match found or denied. 
 +function detail_permission(user, type, identifier, permission) { 
 +      "SELECT g.group_id, p.$permission 
 +        FROM $type_permissions p, 
 +       WHERE p.$type = $identifier 
 +         AND p.group_id in (SELECT 1 UNION SELECT g.group_id from group_memberships g 
 +                            WHERE g.user = $user);"
  
-  INSERT INTO groups(identifier, description  +      foreach ($results as $result{ 
-       VALUES (SELECT nextval(groups_sequence),'$_userid's clients'); +              if ($result == true
-  INSERT INTO group_memberships(group_id, user)   +                      return true
-       SELECT $_userid_clients_grpid as group_id, c.client +              } 
-         FROM clients c +      } 
-        WHERE c.users = $_userid;+      return false; 
 +}
  
-== For each folder =+function user_in_admin_grp($user) { 
 +    $res "SELECT userid from group_memberships where user $user and group_id 0";
  
-  * Add row granting owner all rights, including defaults:+    return (num_rows($res) > 0)); 
 +}
  
-  INSERT INTO folder_permissions (folder, group_idviewdetailsoriginaleditdeletelist, modify+// view == "folder""album""photo""search"etc... 
-       VALUES ($_folderid, $_usergrp, 't', 't', 't', 't', 't', 't', 't');+function permission(userphotopermissionview{ 
 +      if ($user == NULL) user = "null"; 
 +      // members of admin group get all permissions implicitly. 
 +      if (user_in_admin_grp($user)return TRUE;
  
-  * if access_rights is private, stop here.+      // explicit permission on the photo trumps everything else. 
 +      $stored = detail_permission($user, 'photo', 
 +                                  $photo, $permission); 
 +      return $stored; 
 +
 +</code>
  
-  * if access_rights is protected (ie clients-only)+A few comments:
  
-  INSERT INTO folder_permissions (foldergroup_id, view, details, original, edit, delete, list, modify) +  * Admin group id is 0.  Guest group id is 1.  These are fixed. 
-       VALUES ($_folderid, $_user_client_grp, 't', 't', 'f', 'f', 'f', 't', 'f'); +  * Guest users have a NULL useridwhich has to be handled cleanly. 
 +  * All users (and guests) are implicitly members of the 'guestsgroup.
  
-  * if access_rights is public (ie everyone)+==== Migration ====
  
-  INSERT INTO folder_permissions (folder, group_id, view, details, original, edit, delete, list, modify) +The goal of this migration is to transform all existing permissions to the new model.
-       VALUES ($_folderid, $_guest_grp, 't', 'f', 'f', 'f', 'f', 't', 'f'); +
  
-== For each album: ==+=== Set things up ===
  
-  * Add row granting owner all rightsincluding defaults:+  - Create new tables. (see above) 
 +  - Create group 0, "Admin Users", and populate it with all admin users. 
 +  - Create group 1, "Guests" 
 +  - Create group 2"Registered Users"
 +   
 +=== The following list needs to be repeated for each user ===
  
-  INSERT INTO album_permissions (albumgroup_id, view, details, original, edit, delete, list, modify) +  - If user is adminadd user to "Admin Users" group as an owner. 
-       VALUES ($_albumid, $_usergrp, 't', 't''t', 't', 't', 't', 't');+  - Add user to "Registered Users" group. 
 +  - Create a new "$user's private" groupadd user to it as the owner. 
 +  - Create a new "$user's clients" groupadd user to it as the owner.  Then add all of user's clients to it. 
 +  - Create a group for each individual client and add user to it as the ownerthen add the client to it.
  
-  * if access_rights is private, stop here.+== For each folder == 
  
-  if access_rights is protected (ie clients-only)+  - Add row granting owner all rights to the folder. 
 +  - if access_rights is private, stop here. 
 +  - if access_rights is protected (ie clients-only) add a row granting read access to the client group. 
 +  - if access_rights is public (ie everyone) add a row granting read access to guest group.
  
-  INSERT INTO album_permissions (album, group_id, view, details, original, edit, delete, list, modify) +== For each album: ==
-       VALUES ($_albumid, $_user_client_grp, 't', 't', 'f', 'f', 'f', 't', 'f'); +
  
-  if access_rights is public (ie everyone) +  - Add row granting owner all rights to the folder. 
- +  - if access_rights is private or album_type is 'client', stop here. 
-  INSERT INTO album_permissions (album, group_id, view, details, original, edit, delete, list, modify) +  - if access_rights is protected (ie clients-onlyadd a row granting read access to the client group. 
-       VALUES ($_albumid, $_guest_grp, 't', 'f', 'f', 'f', 'f', 't', 'f')+  - if access_rights is public (ie everyoneadd a row granting read access to guest group.
  
 == For each photo: == == For each photo: ==
  
-  Add row granting owner all rights.+  Add row granting owner all rights
 +  - if access_rights is protected (ie clients-only) add a row granting read access to the client group. 
 +  - if access_rights is public (ie everyone) add a row granting read access to guest group. 
 +  - If access_rights is private, stop here.
  
-  INSERT INTO photo_permissions (photo, group_id, view, details, original, edit, delete) +//Note -- the 'hide_originalsetting will be respected for these entries//
-       VALUES ($_photoid, $_usergrp, 't', 't', 't', 't', 't');+
  
-  * If access_rights is private, stop here.+=== Finally ===
  
-  * If access_rights is protected (ie clients only): +  - Drop all obseleted columns and tables from the database (see above) 
- + 
-  INSERT INTO photo_permissions (photo, group_id, view, details, original, edit, delete) +
-       VALUES ($_photoid, $_user_client_grp, 't', 't', !$_hide_original, 'f', 'f'); +
- +
-//Note; we may want to forego this step if the photo implicitly has identical permissions as we're granting// +
- +
-  * If access_rights is public (ie guest access): +
- +
-  INSERT INTO photo_permissions (photo, group_id, view, details, original, edit, delete) +
-       VALUES ($_photoid, $_guest_grp, 't', 'f', !$_hide_original, 'f', 'f'); +
- +
-//Note; we may want to forego this step if the photo implicitly has identical permissions as we're granting.// +
- +
-//Note2:  The //hide_original// problem [[pobug>8]] [[pobug>79]] makes this part difficult; existing behaivor says that "if hide_original is false, everyone who can view the preview can download the original." but the help text says "allow for authorized users" but there's no mechanism for saying who those users are.// +
- +
-== Finally == +
- +
-  - Drop all necessary columns from the database (see above) +
-  - ??? +
-  - Profit +
- +
-==== Psuedocode ==== +
- +
-This code is roughly what we need to do to see if an image has the appropriate permissions.  Before it goes into production it'll need to be implemented on the database using pl/pgsql, but the initial pass can be written in PHP. +
- +
-  // type == photo, group, album +
-  // identifier == photo#, group#, album# +
-  // user == userid +
-  // permission == view/original/edit/delete details/list/modify +
-  // returns true if match found, false if denied, null if no match found. +
-   +
-  function detail_permission(user, type, identifier, permission) { +
-        "SELECT p.$permission +
-          FROM $type_permissions p, +
-         WHERE p.$type = $identifier +
-           AND p.group_id in (SELECT g.group_id from group_memberships g +
-                              WHERE g.user = $user);" +
-   +
-  // If we have no hits, we must defer to parent permission and return NULL. +
-  // if we get any "TRUE"s, we return TRUE.  Otherwise we return FALSE. +
- +
-        $best = null; +
-        foreach ($results as $result) { +
-                if ($result == true) { +
-                        return $result; +
-                } else { +
-                        $best = false; +
-                } +
-        } +
-        return null; +
-  } +
-   +
-  // view == "folder", "album", "photo", "search", etc... +
-   +
-  function permission(user, photo, permission, view) { +
-        // explicit permission on the photo trumps everything else. +
-        $stored = detail_permission($user, 'photo', +
-                                    $photo, $permission); +
-        if ($stored != null) +
-                return $stored; +
-   +
-        if ($view != 'album') { +
-                $folder = folder_for_photo($identifier); +
-                // make the lookup deal with parents too. +
-                while($folder != null) { +
-                   $stored = detail_permission($user, 'folder', +
-                                               $folder, $permission); +
-                   if ($view == 'folder' && $stored != null) { +
-                           return $stored; +
-                   } +
-                   if ($stored == true) return true; +
-   +
-                   $folder = parent_for_folder($folder); +
-                } +
-        } +
-   +
-        if (view != 'folder') { +
-                foreach (albums_for_photo($photo) as $album) { +
-                        while ($album != null) { +
-                           $auth = detail_permission($user, 'album', +
-                                                     $album, $permission); +
-                           if ($auth != null) { +
-                                   if ($auth == true) return true; +
-                                   $stored = $auth; +
-                           } +
-                           $album = parent_for_album($album); +
-                        } +
-                } +
-        } +
-   +
-        return false;  // no "allowed" permission found, we have to deny it. +
-  }+
  
-==== Source Hax0r ====+==== Roadmap ====
  
-  * Account creation needs to create appropriate user+client groups + permissions. +  - Schema finalization 
-  * Folder/Album creation needs to create appropriate permissions+  - Migration code for installer 
-  * Folder/Album edit needs to be able to edit permissions. +  - Write PL/pgsql permission lookup code and any necessary triggers
-  * Client addition/removal needs to twiddle appropriate groups. +  - Define default permission sets for new users and new folders/albums/photos.  //In other words, each new photo etc gets permissions G1->X, G2->Y, G3->Z)// 
-  * Photo downloaddisplay code needs to grok new permission model. +  - Port account creation/registration (auto-create necessary groups, etc) 
-  * Folder/Album/Search listing code needs to be aware of permissions too. +  - Port admin pages (account statusetc) 
-  * Need to create UI for group creation/deletion/modification. +  - Port photo & version import pages 
-  * Bulk update sets/clears permissions too? +  - Port photo view/description/edit pages  
-  * equipment pages need to be updated for groups too.. +  - Port folder/album/search/print/export/spool/etc (ie photo listing) pages 
-  * Admin tests need to check user's presence in admin group, not user_type. +  - Port folder/album add/edit/delete pages (don't forget password-protection!) 
-  * all calls fetching the usertype for each session need to be updated.  This means pretty much every file... +  - Port bulk update 
-  * Add "default" permissions to global prefs, and allow each user to tweak their default permission set for new folders/albums/photos.+  - Create Group management UI elements 
 +  - Create Permission management UI elements (for photo add and bulk update too!) 
 +  - Port over equipment/profile pages (yuck)
new_permission_model.1171400912.txt.gz · Last modified: 2007/02/13 21:08 by pizza