Changeset 27926


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

merge r27925 from branch 2.6 to trunk

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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin/include/functions.php

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

    r27369 r27926  
    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.