Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: mojo/shell/capability_filter_test.cc

Issue 1706833003: Move various Shell tests into a subdir. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@conn
Patch Set: . Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/shell/capability_filter_test.h ('k') | mojo/shell/capability_filter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "mojo/shell/capability_filter_test.h"
6
7 #include <utility>
8
9 #include "base/macros.h"
10 #include "base/stl_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "mojo/public/cpp/bindings/strong_binding.h"
13 #include "mojo/public/cpp/bindings/weak_binding_set.h"
14 #include "mojo/shell/application_loader.h"
15 #include "mojo/shell/public/cpp/connection.h"
16 #include "mojo/shell/public/cpp/interface_factory.h"
17 #include "mojo/shell/public/cpp/shell_connection.h"
18
19 namespace mojo {
20 namespace shell {
21 namespace test {
22
23 // Lives on the main thread of the test.
24 // Listens for interfaces exposed/blocked and for application connections being
25 // closed. Quits |loop| when all expectations are met.
26 class ConnectionValidator : public ApplicationLoader,
27 public ShellClient,
28 public InterfaceFactory<Validator>,
29 public Validator {
30 public:
31 ConnectionValidator(const std::set<std::string>& expectations,
32 base::MessageLoop* loop)
33 : app_(nullptr),
34 expectations_(expectations),
35 loop_(loop) {}
36 ~ConnectionValidator() override {}
37
38 bool expectations_met() {
39 return unexpected_.empty() && expectations_.empty();
40 }
41
42 void PrintUnmetExpectations() {
43 for (auto expectation : expectations_)
44 ADD_FAILURE() << "Unmet: " << expectation;
45 for (auto unexpected : unexpected_)
46 ADD_FAILURE() << "Unexpected: " << unexpected;
47 }
48
49 private:
50 // Overridden from ApplicationLoader:
51 void Load(const GURL& url,
52 InterfaceRequest<mojom::ShellClient> request) override {
53 app_.reset(new ShellConnection(this, std::move(request)));
54 }
55
56 // Overridden from ShellClient:
57 bool AcceptConnection(Connection* connection) override {
58 connection->AddInterface<Validator>(this);
59 return true;
60 }
61
62 // Overridden from InterfaceFactory<Validator>:
63 void Create(Connection* connection,
64 InterfaceRequest<Validator> request) override {
65 validator_bindings_.AddBinding(this, std::move(request));
66 }
67
68 // Overridden from Validator:
69 void AddInterfaceCalled(const String& app_url,
70 const String& service_url,
71 const String& name,
72 bool blocked) override {
73 Validate(base::StringPrintf("%s %s %s %s",
74 blocked ? "B" : "E", app_url.data(), service_url.data(), name.data()));
75 }
76 void ConnectionClosed(const String& app_url,
77 const String& service_url) override {
78 Validate(base::StringPrintf("C %s %s", app_url.data(), service_url.data()));
79 }
80
81 void Validate(const std::string& result) {
82 DVLOG(1) << "Validate: " << result;
83 auto i = expectations_.find(result);
84 if (i != expectations_.end()) {
85 expectations_.erase(i);
86 if (expectations_.empty())
87 loop_->QuitWhenIdle();
88 } else {
89 // This is a test failure, and will result in PrintUnexpectedExpecations()
90 // being called.
91 unexpected_.insert(result);
92 loop_->QuitWhenIdle();
93 }
94 }
95
96 scoped_ptr<ShellConnection> app_;
97 std::set<std::string> expectations_;
98 std::set<std::string> unexpected_;
99 base::MessageLoop* loop_;
100 WeakBindingSet<Validator> validator_bindings_;
101
102 DISALLOW_COPY_AND_ASSIGN(ConnectionValidator);
103 };
104
105 // This class models a system service that exposes two interfaces, Safe and
106 // Unsafe. The interface Unsafe is not to be exposed to untrusted applications.
107 class ServiceApplication : public ShellClient,
108 public InterfaceFactory<Safe>,
109 public InterfaceFactory<Unsafe>,
110 public Safe,
111 public Unsafe {
112 public:
113 ServiceApplication() : shell_(nullptr) {}
114 ~ServiceApplication() override {}
115
116 private:
117 // Overridden from ShellClient:
118 void Initialize(Shell* shell, const std::string& url, uint32_t id) override {
119 shell_ = shell;
120 // ServiceApplications have no capability filter and can thus connect
121 // directly to the validator application.
122 shell_->ConnectToInterface("test:validator", &validator_);
123 }
124 bool AcceptConnection(Connection* connection) override {
125 AddInterface<Safe>(connection);
126 AddInterface<Unsafe>(connection);
127 return true;
128 }
129
130 // Overridden from InterfaceFactory<Safe>:
131 void Create(Connection* connection,
132 InterfaceRequest<Safe> request) override {
133 safe_bindings_.AddBinding(this, std::move(request));
134 }
135
136 // Overridden from InterfaceFactory<Unsafe>:
137 void Create(Connection* connection,
138 InterfaceRequest<Unsafe> request) override {
139 unsafe_bindings_.AddBinding(this, std::move(request));
140 }
141
142 template <typename Interface>
143 void AddInterface(Connection* connection) {
144 validator_->AddInterfaceCalled(connection->GetRemoteApplicationURL(),
145 connection->GetConnectionURL(),
146 Interface::Name_,
147 !connection->AddInterface<Interface>(this));
148 }
149
150 Shell* shell_;
151 ValidatorPtr validator_;
152 WeakBindingSet<Safe> safe_bindings_;
153 WeakBindingSet<Unsafe> unsafe_bindings_;
154
155 DISALLOW_COPY_AND_ASSIGN(ServiceApplication);
156 };
157
158 ////////////////////////////////////////////////////////////////////////////////
159 // TestApplication:
160
161 TestApplication::TestApplication() : shell_(nullptr) {}
162 TestApplication::~TestApplication() {}
163
164 void TestApplication::Initialize(Shell* shell, const std::string& url,
165 uint32_t id) {
166 shell_ = shell;
167 url_ = url;
168 }
169 bool TestApplication::AcceptConnection(Connection* connection) {
170 // TestApplications receive their Validator via the inbound connection.
171 connection->GetInterface(&validator_);
172
173 connection1_ = shell_->Connect("test:service");
174 connection1_->SetRemoteInterfaceProviderConnectionErrorHandler(
175 base::Bind(&TestApplication::ConnectionClosed,
176 base::Unretained(this), "test:service"));
177
178 connection2_ = shell_->Connect("test:service2");
179 connection2_->SetRemoteInterfaceProviderConnectionErrorHandler(
180 base::Bind(&TestApplication::ConnectionClosed,
181 base::Unretained(this), "test:service2"));
182 return true;
183 }
184
185 void TestApplication::ConnectionClosed(const std::string& service_url) {
186 validator_->ConnectionClosed(url_, service_url);
187 }
188
189 ////////////////////////////////////////////////////////////////////////////////
190 // TestLoader:
191
192 TestLoader::TestLoader(ShellClient* delegate) : delegate_(delegate) {}
193 TestLoader::~TestLoader() {}
194
195 void TestLoader::Load(const GURL& url,
196 InterfaceRequest<mojom::ShellClient> request) {
197 app_.reset(new ShellConnection(delegate_.get(), std::move(request)));
198 }
199
200 ////////////////////////////////////////////////////////////////////////////////
201 // CapabilityFilterTest:
202
203 CapabilityFilterTest::CapabilityFilterTest() : validator_(nullptr) {}
204 CapabilityFilterTest::~CapabilityFilterTest() {}
205
206 void CapabilityFilterTest::RunBlockingTest() {
207 std::set<std::string> expectations;
208 expectations.insert("E test:trusted test:service mojo::shell::Safe");
209 expectations.insert("E test:trusted test:service mojo::shell::Unsafe");
210 expectations.insert("E test:trusted test:service2 mojo::shell::Safe");
211 expectations.insert("E test:trusted test:service2 mojo::shell::Unsafe");
212 expectations.insert("E test:untrusted test:service mojo::shell::Safe");
213 expectations.insert("B test:untrusted test:service mojo::shell::Unsafe");
214 expectations.insert("C test:untrusted test:service2");
215 InitValidator(expectations);
216
217 // This first application can only connect to test:service. Connections to
218 // test:service2 will be blocked. It also will only be able to see the
219 // "Safe" interface exposed by test:service. It will be blocked from seeing
220 // "Unsafe".
221 AllowedInterfaces interfaces;
222 interfaces.insert(Safe::Name_);
223 CapabilityFilter filter;
224 filter["test:service"] = interfaces;
225 RunApplication("test:untrusted", filter);
226
227 // This second application can connect to both test:service and
228 // test:service2. It can connect to both "Safe" and "Unsafe" interfaces.
229 RunApplication("test:trusted", GetPermissiveCapabilityFilter());
230
231 RunTest();
232 }
233
234 void CapabilityFilterTest::RunWildcardTest() {
235 std::set<std::string> expectations;
236 expectations.insert("E test:wildcard test:service mojo::shell::Safe");
237 expectations.insert("E test:wildcard test:service mojo::shell::Unsafe");
238 expectations.insert("E test:wildcard test:service2 mojo::shell::Safe");
239 expectations.insert("E test:wildcard test:service2 mojo::shell::Unsafe");
240 expectations.insert("C test:blocked test:service");
241 expectations.insert("C test:blocked test:service2");
242 expectations.insert("B test:wildcard2 test:service mojo::shell::Safe");
243 expectations.insert("B test:wildcard2 test:service mojo::shell::Unsafe");
244 expectations.insert("B test:wildcard2 test:service2 mojo::shell::Safe");
245 expectations.insert("B test:wildcard2 test:service2 mojo::shell::Unsafe");
246 expectations.insert("E test:wildcard3 test:service mojo::shell::Safe");
247 expectations.insert("E test:wildcard3 test:service mojo::shell::Unsafe");
248 expectations.insert("E test:wildcard3 test:service2 mojo::shell::Safe");
249 expectations.insert("B test:wildcard3 test:service2 mojo::shell::Unsafe");
250 InitValidator(expectations);
251
252 // This application is allowed to connect to any application because of a
253 // wildcard rule, and any interface exposed because of a wildcard rule in
254 // the interface array.
255 RunApplication("test:wildcard", GetPermissiveCapabilityFilter());
256
257 // This application is allowed to connect to no other applications because
258 // of an empty capability filter.
259 RunApplication("test:blocked", CapabilityFilter());
260
261 // This application is allowed to connect to any application because of a
262 // wildcard rule but may not connect to any interfaces because of an empty
263 // interface array.
264 CapabilityFilter filter1;
265 filter1["*"] = AllowedInterfaces();
266 RunApplication("test:wildcard2", filter1);
267
268 // This application is allowed to connect to both test:service and
269 // test:service2, and may see any interface exposed by test:service but only
270 // the Safe interface exposed by test:service2.
271 AllowedInterfaces interfaces2;
272 interfaces2.insert("*");
273 CapabilityFilter filter2;
274 filter2["test:service"] = interfaces2;
275 AllowedInterfaces interfaces3;
276 interfaces3.insert(Safe::Name_);
277 filter2["test:service2"] = interfaces3;
278 RunApplication("test:wildcard3", filter2);
279 }
280
281
282 void CapabilityFilterTest::SetUp() {
283 application_manager_.reset(new ApplicationManager(true));
284 CreateLoader<ServiceApplication>("test:service");
285 CreateLoader<ServiceApplication>("test:service2");
286 }
287
288 void CapabilityFilterTest::TearDown() {
289 application_manager_.reset();
290 }
291
292 class InterfaceProviderImpl : public shell::mojom::InterfaceProvider {
293 public:
294 explicit InterfaceProviderImpl(
295 shell::mojom::InterfaceProviderRequest interfaces,
296 InterfaceFactory<Validator>* factory)
297 : binding_(this, std::move(interfaces)),
298 factory_(factory) {}
299 ~InterfaceProviderImpl() override {}
300
301 private:
302 // shell::mojom::InterfaceProvider method.
303 void GetInterface(const mojo::String& interface_name,
304 ScopedMessagePipeHandle client_handle) override {
305 if (interface_name == Validator::Name_) {
306 factory_->Create(nullptr,
307 MakeRequest<Validator>(std::move(client_handle)));
308 }
309 }
310
311 Binding<InterfaceProvider> binding_;
312 InterfaceFactory<Validator>* factory_;
313
314 DISALLOW_COPY_AND_ASSIGN(InterfaceProviderImpl);
315 };
316
317 void CapabilityFilterTest::RunApplication(const std::string& url,
318 const CapabilityFilter& filter) {
319 shell::mojom::InterfaceProviderPtr remote_interfaces;
320
321 // We expose Validator to the test application via ConnectToApplication
322 // because we don't allow the test application to connect to test:validator.
323 // Adding it to the CapabilityFilter would interfere with the test.
324 shell::mojom::InterfaceProviderPtr local_interfaces;
325 new InterfaceProviderImpl(GetProxy(&local_interfaces), validator_);
326 scoped_ptr<ConnectToApplicationParams> params(
327 new ConnectToApplicationParams);
328 params->SetTarget(Identity(GURL(url), std::string(), filter));
329 params->set_remote_interfaces(GetProxy(&remote_interfaces));
330 params->set_local_interfaces(std::move(local_interfaces));
331 params->set_on_application_end(base::MessageLoop::QuitWhenIdleClosure());
332 application_manager_->ConnectToApplication(std::move(params));
333 }
334
335 void CapabilityFilterTest::InitValidator(
336 const std::set<std::string>& expectations) {
337 validator_ = new ConnectionValidator(expectations, &loop_);
338 application_manager()->SetLoaderForURL(make_scoped_ptr(validator_),
339 GURL("test:validator"));
340 }
341
342 void CapabilityFilterTest::RunTest() {
343 loop()->Run();
344 EXPECT_TRUE(validator_->expectations_met());
345 if (!validator_->expectations_met())
346 validator_->PrintUnmetExpectations();
347 }
348
349 } // namespace test
350 } // namespace shell
351 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/capability_filter_test.h ('k') | mojo/shell/capability_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698