Connect PPAPI IPC channels for non-SFI mode.
[chromium-blink-merge.git] / extensions / common / permissions / api_permission_set.cc
blobfbbfdc028dc47f6746f64e6004f6bc144209467b
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.
5 #include "extensions/common/permissions/api_permission_set.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/values.h"
11 #include "extensions/common/error_utils.h"
12 #include "extensions/common/manifest_constants.h"
13 #include "extensions/common/permissions/permissions_info.h"
15 namespace extensions {
17 namespace errors = manifest_errors;
19 namespace {
21 bool CreateAPIPermission(
22 const std::string& permission_str,
23 const base::Value* permission_value,
24 APIPermissionSet::ParseSource source,
25 APIPermissionSet* api_permissions,
26 base::string16* error,
27 std::vector<std::string>* unhandled_permissions) {
29 const APIPermissionInfo* permission_info =
30 PermissionsInfo::GetInstance()->GetByName(permission_str);
31 if (permission_info) {
32 scoped_ptr<APIPermission> permission(
33 permission_info->CreateAPIPermission());
34 if (source != APIPermissionSet::kAllowInternalPermissions &&
35 permission_info->is_internal()) {
36 // An internal permission specified in permissions list is an error.
37 if (error) {
38 *error = ErrorUtils::FormatErrorMessageUTF16(
39 errors::kPermissionNotAllowedInManifest, permission_str);
41 return false;
44 std::string error_details;
45 if (!permission->FromValue(permission_value, &error_details)) {
46 if (error) {
47 if (error_details.empty()) {
48 *error = ErrorUtils::FormatErrorMessageUTF16(
49 errors::kInvalidPermission,
50 permission_info->name());
51 } else {
52 *error = ErrorUtils::FormatErrorMessageUTF16(
53 errors::kInvalidPermissionWithDetail,
54 permission_info->name(),
55 error_details);
57 return false;
59 LOG(WARNING) << "Parse permission failed.";
60 } else {
61 api_permissions->insert(permission.release());
63 return true;
66 if (unhandled_permissions)
67 unhandled_permissions->push_back(permission_str);
68 else
69 LOG(WARNING) << "Unknown permission[" << permission_str << "].";
71 return true;
74 bool ParseChildPermissions(const std::string& base_name,
75 const base::Value* permission_value,
76 APIPermissionSet::ParseSource source,
77 APIPermissionSet* api_permissions,
78 base::string16* error,
79 std::vector<std::string>* unhandled_permissions) {
80 if (permission_value) {
81 const base::ListValue* permissions;
82 if (!permission_value->GetAsList(&permissions)) {
83 if (error) {
84 *error = ErrorUtils::FormatErrorMessageUTF16(
85 errors::kInvalidPermission, base_name);
86 return false;
88 LOG(WARNING) << "Permission value is not a list.";
89 // Failed to parse, but since error is NULL, failures are not fatal so
90 // return true here anyway.
91 return true;
94 for (size_t i = 0; i < permissions->GetSize(); ++i) {
95 std::string permission_str;
96 if (!permissions->GetString(i, &permission_str)) {
97 // permission should be a string
98 if (error) {
99 *error = ErrorUtils::FormatErrorMessageUTF16(
100 errors::kInvalidPermission,
101 base_name + '.' + base::IntToString(i));
102 return false;
104 LOG(WARNING) << "Permission is not a string.";
105 continue;
108 if (!CreateAPIPermission(
109 base_name + '.' + permission_str, NULL, source,
110 api_permissions, error, unhandled_permissions))
111 return false;
115 return CreateAPIPermission(base_name, NULL, source,
116 api_permissions, error, NULL);
119 } // namespace
121 void APIPermissionSet::insert(APIPermission::ID id) {
122 const APIPermissionInfo* permission_info =
123 PermissionsInfo::GetInstance()->GetByID(id);
124 DCHECK(permission_info);
125 insert(permission_info->CreateAPIPermission());
128 void APIPermissionSet::insert(APIPermission* permission) {
129 BaseSetOperators<APIPermissionSet>::insert(permission);
132 // static
133 bool APIPermissionSet::ParseFromJSON(
134 const base::ListValue* permissions,
135 APIPermissionSet::ParseSource source,
136 APIPermissionSet* api_permissions,
137 base::string16* error,
138 std::vector<std::string>* unhandled_permissions) {
139 for (size_t i = 0; i < permissions->GetSize(); ++i) {
140 std::string permission_str;
141 const base::Value* permission_value = NULL;
142 if (!permissions->GetString(i, &permission_str)) {
143 const base::DictionaryValue* dict = NULL;
144 // permission should be a string or a single key dict.
145 if (!permissions->GetDictionary(i, &dict) || dict->size() != 1) {
146 if (error) {
147 *error = ErrorUtils::FormatErrorMessageUTF16(
148 errors::kInvalidPermission, base::IntToString(i));
149 return false;
151 LOG(WARNING) << "Permission is not a string or single key dict.";
152 continue;
154 base::DictionaryValue::Iterator it(*dict);
155 permission_str = it.key();
156 permission_value = &it.value();
159 // Check if this permission is a special case where its value should
160 // be treated as a list of child permissions.
161 if (PermissionsInfo::GetInstance()->HasChildPermissions(permission_str)) {
162 if (!ParseChildPermissions(permission_str, permission_value, source,
163 api_permissions, error, unhandled_permissions))
164 return false;
165 continue;
168 if (!CreateAPIPermission(permission_str, permission_value, source,
169 api_permissions, error, unhandled_permissions))
170 return false;
172 return true;
175 void APIPermissionSet::AddImpliedPermissions() {
176 // The fileSystem.write and fileSystem.directory permissions imply
177 // fileSystem.writeDirectory.
178 // TODO(sammc): Remove this. See http://crbug.com/284849.
179 if (ContainsKey(map(), APIPermission::kFileSystemWrite) &&
180 ContainsKey(map(), APIPermission::kFileSystemDirectory)) {
181 insert(APIPermission::kFileSystemWriteDirectory);
185 } // namespace extensions