Changeset 27925


Ignore:
Timestamp:
03/24/14 21:19:22 (5 years ago)
Author:
plg
Message:

bug 3057: avoid warnings and SQL crash when encountering inconsistent
permissions + rewrite permissions consistancy check when setting albums
to private status.

Location:
branches/2.6
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/2.6/admin/include/functions.php

    r26999 r27925  
    700700    pwg_query($query); 
    701701  } 
     702   
    702703  // make a category private => all its child categories become private 
    703704  if ($value == 'private') 
    704705  { 
    705706    $subcats = get_subcat_ids($categories); 
     707     
    706708    $query = ' 
    707709UPDATE '.CATEGORIES_TABLE.' 
     
    709711  WHERE id IN ('.implode(',', $subcats).')'; 
    710712    pwg_query($query); 
     713 
     714    // We have to keep permissions consistant: a sub-album can't be 
     715    // permitted to a user or group if its parent album is not permitted to 
     716    // the same user or group. Let's remove all permissions on sub-albums if 
     717    // it is not consistant. Let's take the following example: 
     718    // 
     719    // A1        permitted to U1,G1 
     720    // A1/A2     permitted to U1,U2,G1,G2 
     721    // A1/A2/A3  permitted to U3,G1 
     722    // A1/A2/A4  permitted to U2 
     723    // A1/A5     permitted to U4 
     724    // A6        permitted to U4 
     725    // A6/A7     permitted to G1 
     726    // 
     727    // (we consider that it can be possible to start with inconsistant 
     728    // permission, given that public albums can have hidden permissions, 
     729    // revealed once the album returns to private status) 
     730    // 
     731    // The admin selects A2,A3,A4,A5,A6,A7 to become private (all but A1, 
     732    // which is private, which can be true if we're moving A2 into A1). The 
     733    // result must be: 
     734    // 
     735    // A2 permission removed to U2,G2 
     736    // A3 permission removed to U3 
     737    // A4 permission removed to U2 
     738    // A5 permission removed to U2 
     739    // A6 permission removed to U4 
     740    // A7 no permission removed 
     741    //  
     742    // 1) we must extract "top albums": A2, A5 and A6 
     743    // 2) for each top album, decide which album is the reference for permissions 
     744    // 3) remove all inconsistant permissions from sub-albums of each top-album 
     745 
     746    // step 1, search top albums 
     747    $all_categories = array(); 
     748    $top_categories = array(); 
     749    $parent_ids = array(); 
     750     
     751    $query = ' 
     752SELECT 
     753    id, 
     754    name, 
     755    id_uppercat, 
     756    uppercats, 
     757    global_rank 
     758  FROM '.CATEGORIES_TABLE.' 
     759  WHERE id IN ('.implode(',', $categories).') 
     760;'; 
     761    $result = pwg_query($query); 
     762    while ($row = pwg_db_fetch_assoc($result)) 
     763    { 
     764      $all_categories[] = $row; 
     765    } 
     766     
     767    usort($all_categories, 'global_rank_compare'); 
     768 
     769    foreach ($all_categories as $cat) 
     770    { 
     771      $is_top = true; 
     772       
     773      if (!empty($cat['id_uppercat'])) 
     774      { 
     775        foreach (explode(',', $cat['uppercats']) as $id_uppercat) 
     776        { 
     777          if (isset($top_categories[$id_uppercat])) 
     778          { 
     779            $is_top = false; 
     780            break; 
     781          } 
     782        } 
     783      } 
     784 
     785      if ($is_top) 
     786      { 
     787        $top_categories[$cat['id']] = $cat; 
     788 
     789        if (!empty($cat['id_uppercat'])) 
     790        { 
     791          $parent_ids[] = $cat['id_uppercat']; 
     792        } 
     793      } 
     794    } 
     795 
     796    // step 2, search the reference album for permissions 
     797    //  
     798    // to find the reference of each top album, we will need the parent albums 
     799    $parent_cats = array(); 
     800 
     801    if (count($parent_ids) > 0) 
     802    { 
     803      $query = ' 
     804SELECT 
     805    id, 
     806    status 
     807  FROM '.CATEGORIES_TABLE.' 
     808  WHERE id IN ('.implode(',', $parent_ids).') 
     809;'; 
     810      $result = pwg_query($query); 
     811      while ($row = pwg_db_fetch_assoc($result)) 
     812      { 
     813        $parent_cats[$row['id']] = $row; 
     814      } 
     815    } 
     816 
     817    $tables = array( 
     818      USER_ACCESS_TABLE => 'user_id', 
     819      GROUP_ACCESS_TABLE => 'group_id' 
     820      ); 
     821 
     822    foreach ($top_categories as $top_category) 
     823    { 
     824      // what is the "reference" for list of permissions? The parent album 
     825      // if it is private, else the album itself 
     826      $ref_cat_id = $top_category['id']; 
     827 
     828      if (!empty($top_category['id_uppercat']) 
     829          and isset($parent_cats[ $top_category['id_uppercat'] ]) 
     830          and 'private' == $parent_cats[ $top_category['id_uppercat'] ]['status']) 
     831      { 
     832        $ref_cat_id = $top_category['id_uppercat']; 
     833      } 
     834 
     835      $subcats = get_subcat_ids(array($top_category['id'])); 
     836 
     837      foreach ($tables as $table => $field) 
     838      { 
     839        // what are the permissions user/group of the reference album 
     840        $query = ' 
     841SELECT '.$field.' 
     842  FROM '.$table.' 
     843  WHERE cat_id = '.$ref_cat_id.' 
     844;'; 
     845        $ref_access = array_from_query($query, $field); 
     846 
     847        if (count($ref_access) == 0) 
     848        { 
     849          $ref_access[] = -1; 
     850        } 
     851 
     852        // step 3, remove the inconsistant permissions from sub-albums 
     853        $query = ' 
     854DELETE 
     855  FROM '.$table.' 
     856  WHERE '.$field.' NOT IN ('.implode(',', $ref_access).') 
     857    AND cat_id IN ('.implode(',', $subcats).') 
     858;'; 
     859        pwg_query($query); 
     860      } 
     861    } 
    711862  } 
    712863} 
     
    11401291  if ('private' == $parent_status) 
    11411292  { 
    1142     foreach ($categories as $cat_id => $category) 
    1143     { 
    1144       if ('public' == $category['status']) 
    1145       { 
    1146         set_cat_status(array($cat_id), 'private'); 
    1147       } 
    1148        
    1149       $subcats = get_subcat_ids(array($cat_id)); 
    1150  
    1151       foreach ($tables as $table => $field) 
    1152       { 
    1153         $query = ' 
    1154 SELECT '.$field.' 
    1155   FROM '.$table.' 
    1156   WHERE cat_id = '.$cat_id.' 
    1157 ;'; 
    1158         $category_access = array_from_query($query, $field); 
    1159  
    1160         $query = ' 
    1161 SELECT '.$field.' 
    1162   FROM '.$table.' 
    1163   WHERE cat_id = '.$new_parent.' 
    1164 ;'; 
    1165         $parent_access = array_from_query($query, $field); 
    1166  
    1167         $to_delete = array_diff($category_access, $parent_access); 
    1168  
    1169         if (count($to_delete) > 0) 
    1170         { 
    1171           $query = ' 
    1172 DELETE FROM '.$table.' 
    1173   WHERE '.$field.' IN ('.implode(',', $to_delete).') 
    1174     AND cat_id IN ('.implode(',', $subcats).') 
    1175 ;'; 
    1176           pwg_query($query); 
    1177         } 
    1178       } 
    1179     } 
     1293    set_cat_status(array_keys($categories), 'private'); 
    11801294  } 
    11811295 
  • branches/2.6/include/functions_category.inc.php

    r26461 r27925  
    539539      continue; 
    540540 
     541    // Piwigo before 2.5.3 may have generated inconsistent permissions, ie 
     542    // private album A1/A2 permitted to user U1 but private album A1 not 
     543    // permitted to U1. 
     544    //  
     545    // TODO 2.7: add an upgrade script to repair permissions and remove this 
     546    // test 
     547    if ( !isset($cats[ $cat['id_uppercat'] ])) 
     548      continue; 
     549 
    541550    $parent = & $cats[ $cat['id_uppercat'] ]; 
    542551    $parent['nb_categories']++; 
Note: See TracChangeset for help on using the changeset viewer.