Ignore:
Timestamp:
07/08/12 17:02:01 (8 years ago)
Author:
icy
Message:

Version 2.0.0, advance ACL . Code copied from git/master.

I could not use merging with git svn . Stupidly copy-&-paste ;)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • extensions/Icy_Picture_Modify/include/functions_icy_picture_modify.inc.php

    r11637 r16495  
    2929 * 
    3030*/ 
    31 function icy_check_image_owner($image_id, $user_id = 0) 
     31function icy_check_image_owner($image_id) 
    3232{ 
    33   if (!preg_match(PATTERN_ID, $image_id)) 
    34   { 
    35     bad_request('invalid picture identifier'); 
    36   } 
    37   if (!preg_match(PATTERN_ID, $user_id)) 
    38   { 
    39     bad_request('invalid category identifier'); 
    40   } 
    41  
    42   $query = ' 
    43 SELECT COUNT(id) 
    44   FROM '.IMAGES_TABLE.' 
    45   WHERE id = '.$image_id.' 
    46   AND added_by = '.$user_id.' 
    47 ;'; 
    48  
    49   list($count) = pwg_db_fetch_row(pwg_query($query)); 
    50  
    51   return ($count > 0 ? true: false); 
     33  global $user; 
     34  return $user['id'] == icy_get_user_owner_of_image($image_id); 
    5235} 
    5336 
     
    5841 * 
    5942*/ 
    60 function icy_does_image_exist($image_id) 
     43function icy_image_exists($image_id) 
    6144{ 
    6245  if (!preg_match(PATTERN_ID, $image_id)) 
     
    7255  return ($count > 0 ? true: false); 
    7356} 
     57 
     58/* 
     59 * Check if an image is editable by current user 
     60 * @icy_acl   access rules (provided by icy module) 
     61 * @image_id  identity of the image 
     62 * @return    boolean value 
     63 * @author    icy 
     64 */ 
     65function icy_image_editable($image_id) { 
     66  return icy_acl("edit_image_of", $image_id, icy_get_user_owner_of_image($image_id)); 
     67} 
     68 
     69function icy_image_deletable($image_id) { 
     70  return icy_acl("delete_image_of", $image_id, icy_get_user_owner_of_image($image_id)); 
     71} 
     72 
     73 
     74/* 
     75 * Return list of visible/uploadable categories 
     76 * @author  icy 
     77 */ 
     78function icy_acl_get_data($symbol) { 
     79  global $user, $ICY_ACL; 
     80 
     81  // Load ACL setting for this user 
     82  $this_user = $user['username']; 
     83  $my_acl = $ICY_ACL['default']; 
     84  if (array_key_exists($this_user, $ICY_ACL)) { 
     85    $my_acl = array_replace($my_acl, $ICY_ACL[$this_user]); 
     86  } 
     87 
     88  // Load ACL setting for the symbol 
     89  if (!array_key_exists($symbol, $my_acl)) { 
     90    return NULL; 
     91  } 
     92 
     93  return $my_acl[$symbol]; 
     94} 
     95 
     96/* 
     97 * 
     98 * visible: upload, assosiate,... 
     99 * @symbol    must be ended by "_to" or "_from" 
     100 */ 
     101function icy_acl_get_categories($symbol) { 
     102  global $user, $conf; 
     103 
     104  $all_categories = array(); 
     105  $symbol_categories = array(); 
     106  $symbol_settings = NULL; 
     107 
     108  // It's always EMPTY array for any kind of guests 
     109  if ($user['id'] == $conf['guest_id']) { 
     110    return $symbol_categories; 
     111  } 
     112 
     113  // check if $symbol is valid 
     114  if (!preg_match("/_(to|from)$/", $symbol)) { 
     115    return $symbol_categories; 
     116  } 
     117 
     118  $symbol_settings = icy_acl_get_data($symbol); 
     119  if (!$symbol_settings) { 
     120    return $symbol_categories; 
     121  } 
     122 
     123  // all known categories in the system 
     124  $query = 'SELECT id FROM '.CATEGORIES_TABLE.';'; 
     125  $all_categories = array_unique(array_from_query($query, 'id')); 
     126  $forbidden_categories = explode(',',calculate_permissions($user['id'], $user['status'])); 
     127 
     128  // ICY_ACL allows user to access all categories. In this case, 
     129  // the plugin 'community' plays an empty role (we just supress it) 
     130  if (icy_acl_symbol_data_wide_open($symbol_settings)) { 
     131    $symbol_categories = $all_categories; 
     132  } 
     133  elseif (is_array($symbol_settings)) { 
     134    $symbol_categories = array_values(array_intersect($symbol_settings, $all_categories)); 
     135  } 
     136  else { 
     137    // not wide-open, not an-array. So waht!? 
     138    $symbol_settings = array(); 
     139  } 
     140 
     141  // Make sure categories are in our sytem 
     142  // remove all forbidden categories from the list 
     143  if (in_array('sub', icy_acl_get_data($symbol))) { 
     144    // FIXME: (get_subcat_ids) requires a 0-based array 
     145    // FIXME: + array(0) is really a trick :) In Piwigo 2.4, (get_subcat_ids) 
     146    // FIXME: will generate NOTICE (SQL syntax error) if $symbol_categories is empty. 
     147    $symbol_categories = array_merge($symbol_categories, get_subcat_ids($symbol_categories + array(0))); 
     148  } 
     149  $symbol_categories = array_diff($symbol_categories, $forbidden_categories); 
     150  return array_values($symbol_categories); 
     151} 
     152/* 
     153 * FIXME: Test if current user is logged in 
     154 * FIXME: $guestowner must be provided explicitly 
     155 * 
     156 * Check if the current user has permission to do something 
     157 * @symbol     Action to be checked 
     158 * @guestdata  Object of the action 
     159 * @guestowner Owner of @guestdata 
     160 * 
     161 * There are two cases of @symbol: 
     162 * - _from/_to: action on an category 
     163 * - _of      : action on the author 
     164 * - others   : boolean flag 
     165 * 
     166 * There are three cases of symbol data 
     167 * - Array of categories (' identities)    [_from/_to] 
     168 *    $guestowner is simply ignored 
     169 * - Array of usernames (list of authors)  [_of] 
     170 *    $guestowner must be specified 
     171 * - Others: {"any", "owner", TRUE, FALSE} [others] 
     172 */ 
     173 function icy_acl($symbol, $guestdata = NULL, $guestowner = NULL) { 
     174  global $user, $ICY_ACL, $conf; 
     175 
     176  // Load ACL setting for this user 
     177  $this_user = $user['id']; 
     178 
     179  if ($user['id'] == $conf['guest_id']) { 
     180    return FALSE; 
     181  } 
     182  elseif (is_admin()) { 
     183    return TRUE; 
     184  } 
     185 
     186  $symbol_settings = icy_acl_get_data($symbol); 
     187 
     188 
     189  if (! preg_match("/_(to|from|of)$/", $symbol)) { 
     190    return is_bool($symbol_settings) ? $symbol_settings: FALSE; 
     191  } 
     192 
     193  if (! is_array($symbol_settings) ) { 
     194    return FALSE; 
     195  } elseif (icy_acl_symbol_data_wide_open($symbol_settings)) { 
     196    return TRUE; 
     197  } 
     198 
     199  if (preg_match("/_(to|from)$/", $symbol)) { 
     200    return in_array($guestdata, $symbol_settings); 
     201  } 
     202  elseif (preg_match("/_of$/", $symbol)) { 
     203    $guestowner = icy_get_username_of($guestowner); 
     204    // Replace 'owner' by the $guestowner. For example 
     205    //  array('owner','ruby', 12) => array($guestowner, 'ruby', 12) 
     206    array_walk($symbol_settings, 
     207     create_function('&$val, $key', 
     208       'if ($val == "owner") {$val = "'.$user['username'].'";}')); 
     209    return in_array($guestowner, $symbol_settings); 
     210  } 
     211} 
     212 
     213function icy_acl_symbol_data_wide_open($symbol_data) { 
     214  return (is_array($symbol_data) and in_array("any", $symbol_data)); 
     215} 
     216 
     217/* 
     218 * Write some logs for debugging 
     219 * @notes     Data will be written to STDERRR (default) 
     220 *            or to file `<ROOT>/_data/icy.log` 
     221 * @author    icy 
     222 */ 
     223function icy_log($st, $stderr = FALSE) { 
     224  if ($stderr === TRUE) { 
     225    $_f_log = "php://stderr"; 
     226  } 
     227  else { 
     228    $_f_log = PHPWG_ROOT_PATH.'_data/icy.log'; 
     229  } 
     230 
     231  $_f_handle = fopen($_f_log, 'a'); 
     232  if ($_f_handle) { 
     233    $new_line = "\n"; 
     234    fwrite($_f_handle, "piwigo/icy_picture_modify: $st". $new_line ); 
     235    if ($stderr !== TRUE) { 
     236      fclose($_f_handle); 
     237    } 
     238  } 
     239} 
     240 
     241/* 
     242 * Get UserId from their UserName 
     243 * @user_name   username as string 
     244 * @author      icy 
     245 */ 
     246function icy_get_user_id_from_name($user_name) { 
     247  $user_name = pwg_db_real_escape_string($user_name); 
     248 
     249  $query = ' 
     250SELECT id 
     251  FROM '.USERS_TABLE.' 
     252  WHERE username = "'.$user_name.'" 
     253  LIMIT 1 
     254;'; 
     255 
     256  list($user_id) = pwg_db_fetch_row(pwg_query($query)); 
     257 
     258  // FIXME: Is this the best way? 
     259  if ($user_id == NULL) $user_id = 0; 
     260 
     261  #! icy_log("icy_get_user_id_from_name: map userid <= username: $user_name <= $user_id"); 
     262  return $user_id; 
     263} 
     264 
     265/* 
     266 * Rerturn the owner id of an image 
     267 * @author    icy 
     268 * @image_id  identity of the image 
     269 */ 
     270function icy_get_user_owner_of_image($image_id) { 
     271  // FIXME: Clean this up!!! 
     272  if (!preg_match(PATTERN_ID, $image_id)) 
     273    bad_request('invalid picture identifier'); 
     274 
     275  $query = ' 
     276SELECT added_by 
     277  FROM '.IMAGES_TABLE.' 
     278  WHERE id = '.$image_id.' 
     279  LIMIT 1 
     280;'; 
     281 
     282  list($owner) = pwg_db_fetch_row(pwg_query($query)); 
     283  #! icy_log("icy_get_user_owner_of_image: image_id, added_by = $image_id, $owner"); 
     284  return $owner ? $owner : 0; 
     285} 
     286 
     287/* 
     288 * Return the username from user_id 
     289 */ 
     290function icy_get_username_of($user_id) { 
     291  if (!preg_match(PATTERN_ID, $user_id)) 
     292    bad_request('invalid user identifier'); 
     293 
     294  $query = ' 
     295SELECT username 
     296  FROM '.USERS_TABLE.' 
     297  WHERE id = '.$user_id.' 
     298  LIMIT 1 
     299;'; 
     300 
     301  list($username) = pwg_db_fetch_row(pwg_query($query)); 
     302  #! icy_log("icy_get_username_of: user_id, user_name = $user_id, $username"); 
     303  return $username; 
     304} 
     305 
     306/* 
     307 * Check if a plugin is enabled 
     308 * @plugin_name   name of the plugin 
     309 * @author        icy 
     310 */ 
     311function icy_plugin_enabled($plugin_name) { 
     312  $return = false; 
     313 
     314  $query = ' 
     315SELECT count(id) 
     316  FROM '.PLUGINS_TABLE.' 
     317  WHERE id = "'.pwg_db_real_escape_string($plugin_name).'" 
     318  AND state="active" 
     319  LIMIT 1 
     320;'; 
     321 
     322  list($count) = pwg_db_fetch_row(pwg_query($query)); 
     323  $return = ($count == 1 ? true : false); 
     324 
     325  // we need the file ^^ 
     326  if ($plugin_name == "community") 
     327    $return = $return 
     328                and is_file(PHPWG_PLUGINS_PATH 
     329                  .'community/include/functions_community.inc.php'); 
     330 
     331  return $return; 
     332} 
     333 
     334/* 
     335 * Load ICY_ACL configuration from files 
     336 * @author   icy 
     337 */ 
     338function icy_acl_load_configuration($force = FALSE) { 
     339  global $ICY_ACL; 
     340  $conf_path = PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'config/icy_acl.zml'; 
     341 
     342  if (($force == FALSE) 
     343      and isset($ICY_ACL['default']) 
     344      and isset($_SESSION['icy_picture_modify_acl_mtime']) 
     345      and ($_SESSION['icy_picture_modify_acl_mtime'] == filemtime($conf_path))) { 
     346    #! icy_log("icy_acl_load_configuration: configuration is up-to-date"); 
     347    return FALSE; 
     348  } 
     349 
     350  $ICY_ACL = icy_zml_parser(<<<EOF 
     351default: 
     352  edit_image_of: owner 
     353  delete_image_of: 
     354  upload_image_to: sub 
     355  moderate_image: no 
     356  create_gallery_to: sub 
     357  associate_image_to: 
     358  present_image_to: sub 
     359EOF 
     360); 
     361 
     362  if (file_exists($conf_path)) { 
     363    #! icy_log("icy_acl_load_configuration: now loading ACL from $conf_path"); 
     364    $ICY_ACL = array_replace($ICY_ACL, icy_zml_parser(file($conf_path))); 
     365    $_SESSION['icy_picture_modify_acl_mtime'] = filemtime($conf_path); 
     366  } 
     367 
     368  return TRUE; 
     369} 
     370 
     371/* 
     372 * Return array of variable from a `.zml` array  / string 
     373 * Syntax of the `.zml` file can be found in `doc/zaml.md` 
     374 * @author icy 
     375 */ 
     376function icy_zml_parser($data) { 
     377  $acl = array(); 
     378  $author = 'default'; 
     379  $acl[$author] = array(); 
     380 
     381  if (is_string($data)) { 
     382    $data = preg_split("/[\r\n]/", $data); 
     383  } 
     384 
     385  foreach($data as $line) { 
     386    # AUTHOR: 
     387    if (preg_match('/^([^[:space:]:]+):$/', $line, $gs)) { 
     388      $author = trim($gs[1]); 
     389      if (! array_key_exists($author, $acl)) { 
     390        $acl[$author] = array(); 
     391      } 
     392      continue; 
     393    } 
     394 
     395    # AUTHOR: @REFERENCE 
     396    if (preg_match('/^([^[:space:]:]+):[[:space:]]+@([^[:space:]:]+)$/', $line, $gs)) { 
     397      $ref_author = trim($gs[2]); 
     398      if (!array_key_exists($ref_author, $acl)) { 
     399        continue; 
     400      } 
     401      $author = trim($gs[1]); 
     402      if (! array_key_exists($author, $acl)) { 
     403        $acl[$author] = array(); 
     404      } 
     405      $acl[$author] = array_replace($acl[$ref_author], $acl[$author]); 
     406    } 
     407 
     408    # <two spaces> KEY: [VALUE] 
     409    if (preg_match('/  ([^:]+):(.*)$/', $line, $gs)) { 
     410      $key = $gs[1]; 
     411      $val = trim($gs[2]); 
     412      if (in_array($val, array("","false","no"))) { 
     413        $val = FALSE; 
     414      } 
     415      elseif (in_array($val, array("yes", "true"))) { 
     416        $val = TRUE; 
     417      } 
     418      else { 
     419        $val = array_unique(preg_split("/[[:space:],:;]+/", $val)); 
     420      } 
     421      $acl[$author][$key] = $val; 
     422    } 
     423 
     424    # Other line is ignored :) 
     425  } 
     426  return $acl; 
     427} 
     428 
     429/* 
     430 * Overwrite the ACl setings from community plugin 
     431 * @author: icy 
     432 */ 
     433function icy_acl_fix_community($force = FALSE) { 
     434  global $user, $_SESSION; 
     435 
     436  if (!icy_plugin_enabled("community")) { 
     437    return TRUE; 
     438  } 
     439 
     440  require_once(PHPWG_PLUGINS_PATH.'community/include/functions_community.inc.php'); 
     441 
     442  # <community_support> 
     443  $cache_key = community_get_cache_key(); 
     444  if (!isset($cache_key))  { 
     445    $cache_key = community_update_cache_key(); 
     446  } 
     447 
     448  if (($force == FALSE) 
     449      and isset($_SESSION['community_user_permissions']) 
     450      and isset($_SESSION['community_user_permissions']['icy_acl_fixed'])) { 
     451    #! icy_log("icy_fix_community_acl: the fix is up-to-date " . print_r($_SESSION['community_user_permissions'], true)); 
     452    return TRUE; 
     453  } 
     454 
     455  # icy_log("WARNING: icy_fix_community_acl: the fix is out-of-date. will fix it again"); 
     456  # </community_support> 
     457 
     458  $return = array( 
     459    'create_categories' => array(), 
     460    'upload_categories' => array(), 
     461    'permission_ids' => array(), 
     462    ); 
     463 
     464  $return['upload_whole_gallery'] = icy_acl_symbol_data_wide_open(icy_acl_get_data("upload_image_to")); 
     465  $return['create_whole_gallery'] = icy_acl_symbol_data_wide_open(icy_acl_get_data("create_gallery_to")); 
     466  $return['upload_categories'] = icy_acl_get_categories("upload_image_to"); 
     467  $return['create_categories'] = icy_acl_get_categories("create_gallery_to"); 
     468  $return['permission_ids'] = array(); 
     469  $return['icy_acl_fixed'] = 1; 
     470 
     471  $_SESSION['community_user_permissions'] = $return; 
     472  $_SESSION['community_cache_key'] = $cache_key; 
     473  $_SESSION['community_user_id'] = $user['id']; 
     474} 
     475 
     476 
     477if (!function_exists('array_replace')) { 
     478  function array_replace() { 
     479    $array=array(); 
     480    $n=func_num_args(); 
     481    while ($n-- >0) $array+=func_get_arg($n); 
     482    return $array; 
     483  } 
     484} 
    74485?> 
Note: See TracChangeset for help on using the changeset viewer.