1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/values.h"
10 #include "chrome/common/extensions/api/permissions.h"
11 #include "extensions/common/error_utils.h"
12 #include "extensions/common/extension.h"
13 #include "extensions/common/permissions/permission_set.h"
14 #include "extensions/common/permissions/permissions_info.h"
15 #include "extensions/common/permissions/usb_device_permission.h"
16 #include "extensions/common/url_pattern_set.h"
18 using extensions::APIPermission
;
19 using extensions::PermissionSet
;
20 using extensions::PermissionsInfo
;
22 namespace extensions
{
24 using api::permissions::Permissions
;
26 namespace permissions_api_helpers
{
30 const char kDelimiter
[] = "|";
31 const char kInvalidParameter
[] =
32 "Invalid argument for permission '*'.";
33 const char kInvalidOrigin
[] =
34 "Invalid value for origin pattern *: *";
35 const char kUnknownPermissionError
[] =
36 "'*' is not a recognized permission.";
37 const char kUnsupportedPermissionId
[] =
38 "Only the usbDevices permission supports arguments.";
42 scoped_ptr
<Permissions
> PackPermissionSet(const PermissionSet
* set
) {
43 Permissions
* permissions(new Permissions());
45 permissions
->permissions
.reset(new std::vector
<std::string
>());
46 for (APIPermissionSet::const_iterator i
= set
->apis().begin();
47 i
!= set
->apis().end(); ++i
) {
48 scoped_ptr
<base::Value
> value(i
->ToValue());
50 permissions
->permissions
->push_back(i
->name());
52 std::string
name(i
->name());
54 base::JSONWriter::Write(value
.get(), &json
);
55 permissions
->permissions
->push_back(name
+ kDelimiter
+ json
);
59 // TODO(rpaquay): We currently don't expose manifest permissions
60 // to apps/extensions via the permissions API.
62 permissions
->origins
.reset(new std::vector
<std::string
>());
63 URLPatternSet hosts
= set
->explicit_hosts();
64 for (URLPatternSet::const_iterator i
= hosts
.begin(); i
!= hosts
.end(); ++i
)
65 permissions
->origins
->push_back(i
->GetAsString());
67 return scoped_ptr
<Permissions
>(permissions
);
70 scoped_refptr
<PermissionSet
> UnpackPermissionSet(
71 const Permissions
& permissions
,
72 bool allow_file_access
,
75 APIPermissionSet apis
;
76 std::vector
<std::string
>* permissions_list
= permissions
.permissions
.get();
77 if (permissions_list
) {
78 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
79 for (std::vector
<std::string
>::iterator it
= permissions_list
->begin();
80 it
!= permissions_list
->end(); ++it
) {
81 // This is a compromise: we currently can't switch to a blend of
82 // objects/strings all the way through the API. Until then, put this
84 // http://code.google.com/p/chromium/issues/detail?id=162042
85 if (it
->find(kDelimiter
) != std::string::npos
) {
86 size_t delimiter
= it
->find(kDelimiter
);
87 std::string permission_name
= it
->substr(0, delimiter
);
88 std::string permission_arg
= it
->substr(delimiter
+ 1);
90 scoped_ptr
<base::Value
> permission_json(
91 base::JSONReader::Read(permission_arg
));
92 if (!permission_json
.get()) {
93 *error
= ErrorUtils::FormatErrorMessage(kInvalidParameter
, *it
);
97 APIPermission
* permission
= NULL
;
99 // Explicitly check the permissions that accept arguments until the bug
100 // referenced above is fixed.
101 const APIPermissionInfo
* usb_device_permission_info
=
102 info
->GetByID(APIPermission::kUsbDevice
);
103 if (permission_name
== usb_device_permission_info
->name()) {
104 permission
= new UsbDevicePermission(usb_device_permission_info
);
106 *error
= kUnsupportedPermissionId
;
111 if (!permission
->FromValue(permission_json
.get(), NULL
, NULL
)) {
112 *error
= ErrorUtils::FormatErrorMessage(kInvalidParameter
, *it
);
115 apis
.insert(permission
);
117 const APIPermissionInfo
* permission_info
= info
->GetByName(*it
);
118 if (!permission_info
) {
119 *error
= ErrorUtils::FormatErrorMessage(
120 kUnknownPermissionError
, *it
);
123 apis
.insert(permission_info
->id());
128 // TODO(rpaquay): We currently don't expose manifest permissions
129 // to apps/extensions via the permissions API.
130 ManifestPermissionSet manifest_permissions
;
132 URLPatternSet origins
;
133 if (permissions
.origins
.get()) {
134 for (std::vector
<std::string
>::iterator it
= permissions
.origins
->begin();
135 it
!= permissions
.origins
->end(); ++it
) {
136 int allowed_schemes
= Extension::kValidHostPermissionSchemes
;
137 if (!allow_file_access
)
138 allowed_schemes
&= ~URLPattern::SCHEME_FILE
;
139 URLPattern
origin(allowed_schemes
);
140 URLPattern::ParseResult parse_result
= origin
.Parse(*it
);
141 if (URLPattern::PARSE_SUCCESS
!= parse_result
) {
142 *error
= ErrorUtils::FormatErrorMessage(
145 URLPattern::GetParseResultString(parse_result
));
148 origins
.AddPattern(origin
);
152 return scoped_refptr
<PermissionSet
>(
153 new PermissionSet(apis
, manifest_permissions
, origins
, URLPatternSet()));
156 } // namespace permissions_api_helpers
157 } // namespace extensions