1 // Copyright 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/webview_handler.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_util.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "base/values.h" 12 #include "extensions/common/error_utils.h" 13 #include "extensions/common/manifest.h" 14 #include "extensions/common/manifest_constants.h" 15 16 namespace extensions { 17 18 namespace keys = extensions::manifest_keys; 19 namespace errors = extensions::manifest_errors; 20 21 namespace { 22 23 const WebviewInfo* GetResourcesInfo( 24 const Extension& extension) { 25 return static_cast<WebviewInfo*>( 26 extension.GetManifestData(keys::kWebviewAccessibleResources)); 27 } 28 29 } // namespace 30 31 WebviewInfo::WebviewInfo() { 32 } 33 34 WebviewInfo::~WebviewInfo() { 35 } 36 37 // static 38 bool WebviewInfo::IsResourceWebviewAccessible( 39 const Extension* extension, 40 const std::string& partition_id, 41 const std::string& relative_path) { 42 if (!extension) 43 return false; 44 45 const WebviewInfo* info = GetResourcesInfo(*extension); 46 if (!info) 47 return false; 48 49 bool partition_is_privileged = false; 50 for (size_t i = 0; 51 i < info->webview_privileged_partitions_.size(); 52 ++i) { 53 if (MatchPattern(partition_id, info->webview_privileged_partitions_[i])) { 54 partition_is_privileged = true; 55 break; 56 } 57 } 58 59 return partition_is_privileged && extension->ResourceMatches( 60 info->webview_accessible_resources_, relative_path); 61 } 62 63 WebviewHandler::WebviewHandler() { 64 } 65 66 WebviewHandler::~WebviewHandler() { 67 } 68 69 bool WebviewHandler::Parse(Extension* extension, base::string16* error) { 70 scoped_ptr<WebviewInfo> info(new WebviewInfo()); 71 72 const base::DictionaryValue* dict_value = NULL; 73 if (!extension->manifest()->GetDictionary(keys::kWebview, 74 &dict_value)) { 75 *error = ASCIIToUTF16(errors::kInvalidWebview); 76 return false; 77 } 78 79 const base::ListValue* url_list = NULL; 80 if (!dict_value->GetList(keys::kWebviewAccessibleResources, 81 &url_list)) { 82 *error = ASCIIToUTF16(errors::kInvalidWebviewAccessibleResourcesList); 83 return false; 84 } 85 86 for (size_t i = 0; i < url_list->GetSize(); ++i) { 87 std::string relative_path; 88 if (!url_list->GetString(i, &relative_path)) { 89 *error = ErrorUtils::FormatErrorMessageUTF16( 90 errors::kInvalidWebviewAccessibleResource, base::IntToString(i)); 91 return false; 92 } 93 URLPattern pattern(URLPattern::SCHEME_EXTENSION); 94 if (pattern.Parse(extension->url().spec()) != URLPattern::PARSE_SUCCESS) { 95 *error = ErrorUtils::FormatErrorMessageUTF16( 96 errors::kInvalidURLPatternError, extension->url().spec()); 97 return false; 98 } 99 while (relative_path[0] == '/') 100 relative_path = relative_path.substr(1, relative_path.length() - 1); 101 pattern.SetPath(pattern.path() + relative_path); 102 info->webview_accessible_resources_.AddPattern(pattern); 103 } 104 105 const base::ListValue* partition_list = NULL; 106 if (!dict_value->GetList(keys::kWebviewPrivilegedPartitions, 107 &partition_list)) { 108 *error = ASCIIToUTF16(errors::kInvalidWebviewPrivilegedPartitionList); 109 return false; 110 } 111 for (size_t i = 0; i < partition_list->GetSize(); ++i) { 112 std::string partition_wildcard; 113 if (!partition_list->GetString(i, &partition_wildcard)) { 114 *error = ErrorUtils::FormatErrorMessageUTF16( 115 errors::kInvalidWebviewPrivilegedPartition, base::IntToString(i)); 116 return false; 117 } 118 info->webview_privileged_partitions_.push_back(partition_wildcard); 119 } 120 extension->SetManifestData(keys::kWebviewAccessibleResources, info.release()); 121 return true; 122 } 123 124 const std::vector<std::string> WebviewHandler::Keys() const { 125 return SingleKey(keys::kWebview); 126 } 127 128 } // namespace extensions 129