blob: 37bf2ef1fd65578a0c35486fcdcf031b49247a55 [file] [log] [blame]
Robbie McElrath5e11b282018-06-29 19:28:551// Copyright 2018 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 "content/browser/network_service_client.h"
6
7#include "base/files/file.h"
8#include "base/files/file_path.h"
9#include "base/files/scoped_temp_dir.h"
10#include "base/test/scoped_task_environment.h"
11#include "content/browser/child_process_security_policy_impl.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace content {
15
16namespace {
17
18struct UploadResponse {
19 UploadResponse()
20 : callback(base::BindOnce(&UploadResponse::OnComplete,
21 base::Unretained(this))) {}
22
23 void OnComplete(int error_code, std::vector<base::File> opened_files) {
24 this->error_code = error_code;
25 this->opened_files = std::move(opened_files);
26 }
27
28 network::mojom::NetworkServiceClient::OnFileUploadRequestedCallback callback;
29 int error_code;
30 std::vector<base::File> opened_files;
31};
32
33void GrantAccess(const base::FilePath& file, int process_id) {
34 ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(process_id, file);
35}
36
37void CreateFile(const base::FilePath& path, const char* content) {
38 base::File file(path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
39 ASSERT_TRUE(file.IsValid());
40 int content_size = strlen(content);
41 int bytes_written = file.Write(0, content, content_size);
42 EXPECT_EQ(bytes_written, content_size);
43}
44
45void ValidateFileContents(base::File& file, const char* expected_content) {
46 int expected_length = strlen(expected_content);
47 ASSERT_EQ(file.GetLength(), expected_length);
48 char content[expected_length];
49 file.Read(0, content, expected_length);
50 EXPECT_EQ(0, strncmp(content, expected_content, expected_length));
51}
52
53const int kBrowserProcessId = 0;
54const int kRendererProcessId = 1;
55const char kFileContent1[] = "test file content one";
56const char kFileContent2[] = "test file content two";
57
58} // namespace
59
60class NetworkServiceClientTest : public testing::Test {
61 public:
62 NetworkServiceClientTest() : client_(mojo::MakeRequest(&client_ptr_)) {}
63
64 void SetUp() override {
65 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
66 ChildProcessSecurityPolicyImpl::GetInstance()->Add(kRendererProcessId);
67 }
68
69 void TearDown() override {
70 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(kRendererProcessId);
71 }
72
73 protected:
74 base::test::ScopedTaskEnvironment scoped_task_environment_;
75 network::mojom::NetworkServiceClientPtr client_ptr_;
76 NetworkServiceClient client_;
77 base::ScopedTempDir temp_dir_;
78};
79
80TEST_F(NetworkServiceClientTest, UploadNoFiles) {
81 UploadResponse response;
82 client_.OnFileUploadRequested(kRendererProcessId, true, {},
83 std::move(response.callback));
84 scoped_task_environment_.RunUntilIdle();
85 EXPECT_EQ(net::OK, response.error_code);
86 EXPECT_EQ(0U, response.opened_files.size());
87}
88
89TEST_F(NetworkServiceClientTest, UploadOneValidAsyncFile) {
90 base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
91 CreateFile(path, kFileContent1);
92 GrantAccess(path, kRendererProcessId);
93
94 UploadResponse response;
95 client_.OnFileUploadRequested(kRendererProcessId, true, {path},
96 std::move(response.callback));
97 scoped_task_environment_.RunUntilIdle();
98 EXPECT_EQ(net::OK, response.error_code);
99 ASSERT_EQ(1U, response.opened_files.size());
100 EXPECT_TRUE(response.opened_files[0].async());
101}
102
103TEST_F(NetworkServiceClientTest, UploadOneValidFile) {
104 base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
105 CreateFile(path, kFileContent1);
106 GrantAccess(path, kRendererProcessId);
107
108 UploadResponse response;
109 client_.OnFileUploadRequested(kRendererProcessId, false, {path},
110 std::move(response.callback));
111 scoped_task_environment_.RunUntilIdle();
112 EXPECT_EQ(net::OK, response.error_code);
113 ASSERT_EQ(1U, response.opened_files.size());
114 EXPECT_FALSE(response.opened_files[0].async());
115 ValidateFileContents(response.opened_files[0], kFileContent1);
116}
117
118TEST_F(NetworkServiceClientTest, UploadTwoValidFiles) {
119 base::FilePath path1 = temp_dir_.GetPath().AppendASCII("filename1");
120 base::FilePath path2 = temp_dir_.GetPath().AppendASCII("filename2");
121 CreateFile(path1, kFileContent1);
122 CreateFile(path2, kFileContent2);
123 GrantAccess(path1, kRendererProcessId);
124 GrantAccess(path2, kRendererProcessId);
125
126 UploadResponse response;
127 client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
128 std::move(response.callback));
129 scoped_task_environment_.RunUntilIdle();
130 EXPECT_EQ(net::OK, response.error_code);
131 ASSERT_EQ(2U, response.opened_files.size());
132 ValidateFileContents(response.opened_files[0], kFileContent1);
133 ValidateFileContents(response.opened_files[1], kFileContent2);
134}
135
136TEST_F(NetworkServiceClientTest, UploadOneUnauthorizedFile) {
137 base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
138 CreateFile(path, kFileContent1);
139
140 UploadResponse response;
141 client_.OnFileUploadRequested(kRendererProcessId, false, {path},
142 std::move(response.callback));
143 scoped_task_environment_.RunUntilIdle();
144 EXPECT_EQ(net::ERR_ACCESS_DENIED, response.error_code);
145 EXPECT_EQ(0U, response.opened_files.size());
146}
147
148TEST_F(NetworkServiceClientTest, UploadOneValidFileAndOneUnauthorized) {
149 base::FilePath path1 = temp_dir_.GetPath().AppendASCII("filename1");
150 base::FilePath path2 = temp_dir_.GetPath().AppendASCII("filename2");
151 CreateFile(path1, kFileContent1);
152 CreateFile(path2, kFileContent2);
153 GrantAccess(path1, kRendererProcessId);
154
155 UploadResponse response;
156 client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
157 std::move(response.callback));
158 scoped_task_environment_.RunUntilIdle();
159 EXPECT_EQ(net::ERR_ACCESS_DENIED, response.error_code);
160 EXPECT_EQ(0U, response.opened_files.size());
161}
162
163TEST_F(NetworkServiceClientTest, UploadOneValidFileAndOneNotFound) {
164 base::FilePath path1 = temp_dir_.GetPath().AppendASCII("filename1");
165 base::FilePath path2 = temp_dir_.GetPath().AppendASCII("filename2");
166 CreateFile(path1, kFileContent1);
167 GrantAccess(path1, kRendererProcessId);
168 GrantAccess(path2, kRendererProcessId);
169
170 UploadResponse response;
171 client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
172 std::move(response.callback));
173 scoped_task_environment_.RunUntilIdle();
174 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, response.error_code);
175 EXPECT_EQ(0U, response.opened_files.size());
176}
177
178TEST_F(NetworkServiceClientTest, UploadFromBrowserProcess) {
179 base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
180 CreateFile(path, kFileContent1);
181 // No grant necessary for browser process.
182
183 UploadResponse response;
184 client_.OnFileUploadRequested(kBrowserProcessId, false, {path},
185 std::move(response.callback));
186 scoped_task_environment_.RunUntilIdle();
187 EXPECT_EQ(net::OK, response.error_code);
188 ASSERT_EQ(1U, response.opened_files.size());
189 ValidateFileContents(response.opened_files[0], kFileContent1);
190}
191
192} // namespace content