blob: cf55dc74f4d84eba776347abb55606692f916b4b [file] [log] [blame]
[email protected]c333e792012-01-06 16:57:391// 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.
4
[email protected]57999812013-02-24 05:40:525#include "base/files/file_path.h"
[email protected]ffbec692012-02-26 20:26:426#include "base/json/json_file_value_serializer.h"
[email protected]c333e792012-01-06 16:57:397#include "base/memory/ref_counted.h"
8#include "base/path_service.h"
[email protected]78089f02012-07-19 06:11:289#include "base/run_loop.h"
[email protected]c333e792012-01-06 16:57:3910#include "base/values.h"
11#include "chrome/browser/extensions/extension_service.h"
12#include "chrome/browser/extensions/extension_service_unittest.h"
13#include "chrome/browser/extensions/permissions_updater.h"
14#include "chrome/common/chrome_notification_types.h"
15#include "chrome/common/chrome_paths.h"
16#include "chrome/common/extensions/extension.h"
[email protected]04e4bbe2013-04-27 07:44:2417#include "chrome/common/extensions/extension_test_util.h"
[email protected]c2e66e12012-06-27 06:27:0618#include "chrome/common/extensions/permissions/permission_set.h"
[email protected]c333e792012-01-06 16:57:3919#include "chrome/test/base/testing_profile.h"
[email protected]c333e792012-01-06 16:57:3920#include "content/public/browser/notification_observer.h"
21#include "content/public/browser/notification_registrar.h"
22#include "content/public/browser/notification_service.h"
23#include "testing/gtest/include/gtest/gtest.h"
24
[email protected]04e4bbe2013-04-27 07:44:2425using extension_test_util::LoadManifest;
26
[email protected]c333e792012-01-06 16:57:3927namespace extensions {
28
29namespace {
30
31// A helper class that listens for NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED.
32class PermissionsUpdaterListener : public content::NotificationObserver {
33 public:
34 PermissionsUpdaterListener()
35 : received_notification_(false), waiting_(false) {
36 registrar_.Add(this,
37 chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
38 content::NotificationService::AllSources());
39 }
40
41 void Reset() {
42 received_notification_ = false;
43 waiting_ = false;
44 extension_ = NULL;
45 permissions_ = NULL;
46 }
47
48 void Wait() {
49 if (received_notification_)
50 return;
51
52 waiting_ = true;
[email protected]78089f02012-07-19 06:11:2853 base::RunLoop run_loop;
54 run_loop.Run();
[email protected]c333e792012-01-06 16:57:3955 }
56
57 bool received_notification() const { return received_notification_; }
[email protected]dc24976f2013-06-02 21:15:0958 const Extension* extension() const { return extension_.get(); }
59 const PermissionSet* permissions() const { return permissions_.get(); }
60 UpdatedExtensionPermissionsInfo::Reason reason() const { return reason_; }
[email protected]c333e792012-01-06 16:57:3961
62 private:
63 virtual void Observe(int type,
64 const content::NotificationSource& source,
65 const content::NotificationDetails& details) OVERRIDE {
66 received_notification_ = true;
67 UpdatedExtensionPermissionsInfo* info =
68 content::Details<UpdatedExtensionPermissionsInfo>(details).ptr();
69
70 extension_ = info->extension;
71 permissions_ = info->permissions;
72 reason_ = info->reason;
73
74 if (waiting_) {
75 waiting_ = false;
[email protected]b3a25092013-05-28 22:08:1676 base::MessageLoopForUI::current()->Quit();
[email protected]c333e792012-01-06 16:57:3977 }
78 }
79
80 bool received_notification_;
81 bool waiting_;
82 content::NotificationRegistrar registrar_;
83 scoped_refptr<const Extension> extension_;
[email protected]c2e66e12012-06-27 06:27:0684 scoped_refptr<const PermissionSet> permissions_;
[email protected]c333e792012-01-06 16:57:3985 UpdatedExtensionPermissionsInfo::Reason reason_;
86};
87
88class PermissionsUpdaterTest : public ExtensionServiceTestBase {
89};
90
[email protected]04e4bbe2013-04-27 07:44:2491scoped_refptr<Extension> LoadOurManifest() {
[email protected]650b2d52013-02-10 03:41:4592 base::FilePath path;
[email protected]04e4bbe2013-04-27 07:44:2493 path = path.AppendASCII("api_test")
[email protected]c333e792012-01-06 16:57:3994 .AppendASCII("permissions")
[email protected]04e4bbe2013-04-27 07:44:2495 .AppendASCII("optional");
96 return LoadManifest(path.AsUTF8Unsafe(),
97 "manifest.json",
98 Manifest::INTERNAL,
99 Extension::NO_FLAGS);
[email protected]c333e792012-01-06 16:57:39100}
101
102void AddPattern(URLPatternSet* extent, const std::string& pattern) {
103 int schemes = URLPattern::SCHEME_ALL;
104 extent->AddPattern(URLPattern(schemes, pattern));
105}
106
107} // namespace
108
109// Test that the PermissionUpdater can correctly add and remove active
110// permissions. This tests all of PermissionsUpdater's public methods because
111// GrantActivePermissions and UpdateActivePermissions are used by
112// AddPermissions.
113TEST_F(PermissionsUpdaterTest, AddAndRemovePermissions) {
114 InitializeEmptyExtensionService();
115
116 // Load the test extension.
[email protected]04e4bbe2013-04-27 07:44:24117 scoped_refptr<Extension> extension = LoadOurManifest();
118 ASSERT_TRUE(extension.get());
[email protected]c333e792012-01-06 16:57:39119
[email protected]c2e66e12012-06-27 06:27:06120 APIPermissionSet default_apis;
121 default_apis.insert(APIPermission::kManagement);
[email protected]c333e792012-01-06 16:57:39122 URLPatternSet default_hosts;
123 AddPattern(&default_hosts, "http://a.com/*");
[email protected]c2e66e12012-06-27 06:27:06124 scoped_refptr<PermissionSet> default_permissions =
125 new PermissionSet(default_apis, default_hosts, URLPatternSet());
[email protected]c333e792012-01-06 16:57:39126
127 // Make sure it loaded properly.
[email protected]c2e66e12012-06-27 06:27:06128 scoped_refptr<const PermissionSet> permissions =
[email protected]c333e792012-01-06 16:57:39129 extension->GetActivePermissions();
[email protected]cadac622013-06-11 16:46:36130 ASSERT_EQ(*default_permissions.get(),
131 *extension->GetActivePermissions().get());
[email protected]c333e792012-01-06 16:57:39132
133 // Add a few permissions.
[email protected]c2e66e12012-06-27 06:27:06134 APIPermissionSet apis;
135 apis.insert(APIPermission::kTab);
136 apis.insert(APIPermission::kNotification);
[email protected]c333e792012-01-06 16:57:39137 URLPatternSet hosts;
138 AddPattern(&hosts, "http://*.c.com/*");
139
[email protected]c2e66e12012-06-27 06:27:06140 scoped_refptr<PermissionSet> delta =
141 new PermissionSet(apis, hosts, URLPatternSet());
[email protected]c333e792012-01-06 16:57:39142
143 PermissionsUpdaterListener listener;
144 PermissionsUpdater updater(profile_.get());
145 updater.AddPermissions(extension.get(), delta.get());
146
147 listener.Wait();
148
149 // Verify that the permission notification was sent correctly.
150 ASSERT_TRUE(listener.received_notification());
151 ASSERT_EQ(extension, listener.extension());
152 ASSERT_EQ(UpdatedExtensionPermissionsInfo::ADDED, listener.reason());
[email protected]dc24976f2013-06-02 21:15:09153 ASSERT_EQ(*delta.get(), *listener.permissions());
[email protected]c333e792012-01-06 16:57:39154
155 // Make sure the extension's active permissions reflect the change.
[email protected]c2e66e12012-06-27 06:27:06156 scoped_refptr<PermissionSet> active_permissions =
[email protected]dc24976f2013-06-02 21:15:09157 PermissionSet::CreateUnion(default_permissions.get(), delta.get());
[email protected]cadac622013-06-11 16:46:36158 ASSERT_EQ(*active_permissions.get(),
159 *extension->GetActivePermissions().get());
[email protected]c333e792012-01-06 16:57:39160
161 // Verify that the new granted and active permissions were also stored
162 // in the extension preferences. In this case, the granted permissions should
163 // be equal to the active permissions.
164 ExtensionPrefs* prefs = service_->extension_prefs();
[email protected]c2e66e12012-06-27 06:27:06165 scoped_refptr<PermissionSet> granted_permissions =
[email protected]c333e792012-01-06 16:57:39166 active_permissions;
167
[email protected]c2e66e12012-06-27 06:27:06168 scoped_refptr<PermissionSet> from_prefs =
[email protected]c333e792012-01-06 16:57:39169 prefs->GetActivePermissions(extension->id());
[email protected]dc24976f2013-06-02 21:15:09170 ASSERT_EQ(*active_permissions.get(), *from_prefs.get());
[email protected]c333e792012-01-06 16:57:39171
172 from_prefs = prefs->GetGrantedPermissions(extension->id());
[email protected]dc24976f2013-06-02 21:15:09173 ASSERT_EQ(*active_permissions.get(), *from_prefs.get());
[email protected]c333e792012-01-06 16:57:39174
175 // In the second part of the test, we'll remove the permissions that we
176 // just added except for 'notification'.
[email protected]c2e66e12012-06-27 06:27:06177 apis.erase(APIPermission::kNotification);
178 delta = new PermissionSet(apis, hosts, URLPatternSet());
[email protected]c333e792012-01-06 16:57:39179
180 listener.Reset();
[email protected]dc24976f2013-06-02 21:15:09181 updater.RemovePermissions(extension.get(), delta.get());
[email protected]c333e792012-01-06 16:57:39182 listener.Wait();
183
184 // Verify that the notification was correct.
185 ASSERT_TRUE(listener.received_notification());
186 ASSERT_EQ(extension, listener.extension());
187 ASSERT_EQ(UpdatedExtensionPermissionsInfo::REMOVED, listener.reason());
[email protected]dc24976f2013-06-02 21:15:09188 ASSERT_EQ(*delta.get(), *listener.permissions());
[email protected]c333e792012-01-06 16:57:39189
190 // Make sure the extension's active permissions reflect the change.
191 active_permissions =
[email protected]dc24976f2013-06-02 21:15:09192 PermissionSet::CreateDifference(active_permissions.get(), delta.get());
[email protected]cadac622013-06-11 16:46:36193 ASSERT_EQ(*active_permissions.get(),
194 *extension->GetActivePermissions().get());
[email protected]c333e792012-01-06 16:57:39195
196 // Verify that the extension prefs hold the new active permissions and the
197 // same granted permissions.
198 from_prefs = prefs->GetActivePermissions(extension->id());
[email protected]dc24976f2013-06-02 21:15:09199 ASSERT_EQ(*active_permissions.get(), *from_prefs.get());
[email protected]c333e792012-01-06 16:57:39200
201 from_prefs = prefs->GetGrantedPermissions(extension->id());
[email protected]dc24976f2013-06-02 21:15:09202 ASSERT_EQ(*granted_permissions.get(), *from_prefs.get());
[email protected]c333e792012-01-06 16:57:39203}
204
205} // namespace extensions