Changeset 27925


Ignore:
Timestamp:
Mar 24, 2014, 9:19:22 PM (6 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.