Home | History | Annotate | Download | only in permissions
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/common/extensions/permissions/media_galleries_permission.h"
      6 
      7 #include <set>
      8 #include <string>
      9 
     10 #include "base/logging.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "extensions/common/permissions/permissions_info.h"
     13 #include "grit/generated_resources.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 
     16 namespace {
     17 
     18 // copyTo permission requires delete permission as a prerequisite.
     19 // delete permission requires read permission as a prerequisite.
     20 bool IsValidPermissionSet(bool has_read, bool has_copy_to, bool has_delete) {
     21   if (has_copy_to)
     22     return has_read && has_delete;
     23   if (has_delete)
     24     return has_read;
     25   return true;
     26 }
     27 
     28 }  // namespace
     29 
     30 namespace extensions {
     31 
     32 const char MediaGalleriesPermission::kAllAutoDetectedPermission[] =
     33     "allAutoDetected";
     34 const char MediaGalleriesPermission::kReadPermission[] = "read";
     35 const char MediaGalleriesPermission::kCopyToPermission[] = "copyTo";
     36 const char MediaGalleriesPermission::kDeletePermission[] = "delete";
     37 
     38 MediaGalleriesPermission::MediaGalleriesPermission(
     39     const APIPermissionInfo* info)
     40   : SetDisjunctionPermission<MediaGalleriesPermissionData,
     41                              MediaGalleriesPermission>(info) {
     42 }
     43 
     44 MediaGalleriesPermission::~MediaGalleriesPermission() {
     45 }
     46 
     47 bool MediaGalleriesPermission::FromValue(const base::Value* value) {
     48   if (!SetDisjunctionPermission<MediaGalleriesPermissionData,
     49                                 MediaGalleriesPermission>::FromValue(value)) {
     50     return false;
     51   }
     52 
     53   bool has_read = false;
     54   bool has_copy_to = false;
     55   bool has_delete = false;
     56   for (std::set<MediaGalleriesPermissionData>::const_iterator it =
     57       data_set_.begin(); it != data_set_.end(); ++it) {
     58     if (it->permission() == kAllAutoDetectedPermission) {
     59       continue;
     60     }
     61     if (it->permission() == kReadPermission) {
     62       has_read = true;
     63       continue;
     64     }
     65     if (it->permission() == kCopyToPermission) {
     66       has_copy_to = true;
     67       continue;
     68     }
     69     if (it->permission() == kDeletePermission) {
     70       has_delete = true;
     71       continue;
     72     }
     73 
     74     // No other permissions, so reaching this means
     75     // MediaGalleriesPermissionData is probably out of sync in some way.
     76     // Fail so developers notice this.
     77     NOTREACHED();
     78     return false;
     79   }
     80 
     81   return IsValidPermissionSet(has_read, has_copy_to, has_delete);
     82 }
     83 
     84 PermissionMessages MediaGalleriesPermission::GetMessages() const {
     85   DCHECK(HasMessages());
     86   PermissionMessages result;
     87 
     88   bool has_all_auto_detected = false;
     89   bool has_read = false;
     90   bool has_copy_to = false;
     91   bool has_delete = false;
     92 
     93   for (std::set<MediaGalleriesPermissionData>::const_iterator it =
     94       data_set_.begin(); it != data_set_.end(); ++it) {
     95     if (it->permission() == kAllAutoDetectedPermission)
     96       has_all_auto_detected = true;
     97     else if (it->permission() == kReadPermission)
     98       has_read = true;
     99     else if (it->permission() == kCopyToPermission)
    100       has_copy_to = true;
    101     else if (it->permission() == kDeletePermission)
    102       has_delete = true;
    103   }
    104 
    105   if (!IsValidPermissionSet(has_read, has_copy_to, has_delete)) {
    106     NOTREACHED();
    107     return result;
    108   }
    109 
    110   // If |has_all_auto_detected| is false, then Chrome will prompt the user at
    111   // runtime when the extension call the getMediaGalleries API.
    112   if (!has_all_auto_detected)
    113     return result;
    114   // No access permission case.
    115   if (!has_read)
    116     return result;
    117 
    118   // Separate PermissionMessage IDs for read, copyTo, and delete. Otherwise an
    119   // extension can silently gain new access capabilities.
    120   result.push_back(PermissionMessage(
    121       PermissionMessage::kMediaGalleriesAllGalleriesRead,
    122       l10n_util::GetStringUTF16(
    123           IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ)));
    124 
    125   // For copyTo and delete, the proper combined permission message will be
    126   // derived in ChromePermissionMessageProvider::GetWarningMessages(), such
    127   // that the user get 1 entry for all media galleries access permissions,
    128   // rather than several separate entries.
    129   if (has_copy_to) {
    130     result.push_back(PermissionMessage(
    131         PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
    132         base::string16()));
    133   }
    134   if (has_delete) {
    135     result.push_back(PermissionMessage(
    136         PermissionMessage::kMediaGalleriesAllGalleriesDelete,
    137         base::string16()));
    138   }
    139   return result;
    140 }
    141 
    142 }  // namespace extensions
    143