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

Side by Side Diff: chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc

Issue 12538009: Public Sessions: fetch device robot api token during enterprise enrollment. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: updated tests Created 7 years, 8 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" 5 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop.h"
10 #include "base/prefs/pref_registry_simple.h" 11 #include "base/prefs/pref_registry_simple.h"
11 #include "base/prefs/testing_pref_service.h" 12 #include "base/prefs/testing_pref_service.h"
12 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "chrome/browser/chromeos/cros/cros_library.h"
13 #include "chrome/browser/chromeos/cros/cryptohome_library.h" 15 #include "chrome/browser/chromeos/cros/cryptohome_library.h"
14 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" 16 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
15 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 17 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
16 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 18 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
19 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
20 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h "
17 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" 21 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
18 #include "chrome/browser/policy/cloud/cloud_policy_client.h" 22 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
19 #include "chrome/browser/policy/cloud/mock_device_management_service.h" 23 #include "chrome/browser/policy/cloud/mock_device_management_service.h"
20 #include "chrome/browser/policy/cloud/proto/device_management_backend.pb.h" 24 #include "chrome/browser/policy/cloud/proto/device_management_backend.pb.h"
21 #include "chrome/browser/prefs/browser_prefs.h" 25 #include "chrome/browser/prefs/browser_prefs.h"
26 #include "chrome/test/base/testing_browser_process.h"
22 #include "chromeos/dbus/cryptohome_client.h" 27 #include "chromeos/dbus/cryptohome_client.h"
23 #include "chromeos/dbus/dbus_client_implementation_type.h" 28 #include "chromeos/dbus/dbus_client_implementation_type.h"
29 #include "net/url_request/test_url_fetcher_factory.h"
30 #include "net/url_request/url_request_test_util.h"
24 #include "policy/policy_constants.h" 31 #include "policy/policy_constants.h"
25 #include "testing/gmock/include/gmock/gmock.h" 32 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h" 33 #include "testing/gtest/include/gtest/gtest.h"
27 34
28 using testing::AnyNumber; 35 using testing::AnyNumber;
29 using testing::AtMost; 36 using testing::AtMost;
30 using testing::DoAll; 37 using testing::DoAll;
31 using testing::Mock; 38 using testing::Mock;
32 using testing::SaveArg; 39 using testing::SaveArg;
33 using testing::_; 40 using testing::_;
34 41
35 namespace em = enterprise_management; 42 namespace em = enterprise_management;
36 43
37 namespace policy { 44 namespace policy {
38 namespace { 45 namespace test {
39 46
40 void CopyLockResult(base::RunLoop* loop, 47 void CopyLockResult(base::RunLoop* loop,
41 EnterpriseInstallAttributes::LockResult* out, 48 EnterpriseInstallAttributes::LockResult* out,
42 EnterpriseInstallAttributes::LockResult result) { 49 EnterpriseInstallAttributes::LockResult result) {
43 *out = result; 50 *out = result;
44 loop->Quit(); 51 loop->Quit();
45 } 52 }
46 53
47 class DeviceCloudPolicyManagerChromeOSTest 54 class DeviceCloudPolicyManagerChromeOSTest
48 : public chromeos::DeviceSettingsTestBase { 55 : public chromeos::DeviceSettingsTestBase {
49 protected: 56 protected:
50 DeviceCloudPolicyManagerChromeOSTest() 57 DeviceCloudPolicyManagerChromeOSTest()
51 : cryptohome_library_(chromeos::CryptohomeLibrary::GetImpl(true)), 58 : cryptohome_library_(chromeos::CryptohomeLibrary::GetImpl(true)),
52 stub_cryptohome_client_(chromeos::CryptohomeClient::Create( 59 stub_cryptohome_client_(chromeos::CryptohomeClient::Create(
53 chromeos::STUB_DBUS_CLIENT_IMPLEMENTATION, NULL)), 60 chromeos::STUB_DBUS_CLIENT_IMPLEMENTATION, NULL)),
54 install_attributes_(cryptohome_library_.get(), 61 install_attributes_(cryptohome_library_.get(),
55 stub_cryptohome_client_.get()), 62 stub_cryptohome_client_.get()),
56 store_(new DeviceCloudPolicyStoreChromeOS(&device_settings_service_, 63 store_(new DeviceCloudPolicyStoreChromeOS(&device_settings_service_,
57 &install_attributes_)), 64 &install_attributes_)),
58 manager_(make_scoped_ptr(store_), &install_attributes_) {} 65 manager_(make_scoped_ptr(store_), &install_attributes_) {}
59 66
60 virtual void SetUp() OVERRIDE { 67 virtual void SetUp() OVERRIDE {
61 DeviceSettingsTestBase::SetUp(); 68 DeviceSettingsTestBase::SetUp();
62 chrome::RegisterLocalState(local_state_.registry()); 69 chrome::RegisterLocalState(local_state_.registry());
63 manager_.Init(); 70 manager_.Init();
71
72 // DeviceOAuth2TokenService uses the system request context to fetch
73 // OAuth tokens, then writes the token to local state, encrypting it
74 // first with methods in CrosLibrary.
75 TestingBrowserProcess::GetGlobal()->SetSystemRequestContext(
76 new net::TestURLRequestContextGetter(loop_.message_loop_proxy()));
77 TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
78 chromeos::DeviceOAuth2TokenServiceFactory::Initialize();
79 chromeos::CrosLibrary::Initialize(true);
64 } 80 }
65 81
66 virtual void TearDown() OVERRIDE { 82 virtual void TearDown() OVERRIDE {
67 manager_.Shutdown(); 83 manager_.Shutdown();
68 DeviceSettingsTestBase::TearDown(); 84 DeviceSettingsTestBase::TearDown();
85
86 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown();
87 chromeos::CrosLibrary::Shutdown();
88 TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
69 } 89 }
70 90
71 scoped_ptr<chromeos::CryptohomeLibrary> cryptohome_library_; 91 scoped_ptr<chromeos::CryptohomeLibrary> cryptohome_library_;
72 scoped_ptr<chromeos::CryptohomeClient> stub_cryptohome_client_; 92 scoped_ptr<chromeos::CryptohomeClient> stub_cryptohome_client_;
73 EnterpriseInstallAttributes install_attributes_; 93 EnterpriseInstallAttributes install_attributes_;
74 94
95 net::TestURLFetcherFactory url_fetcher_factory_;
75 TestingPrefServiceSimple local_state_; 96 TestingPrefServiceSimple local_state_;
76 MockDeviceManagementService device_management_service_; 97 MockDeviceManagementService device_management_service_;
77 98
78 DeviceCloudPolicyStoreChromeOS* store_; 99 DeviceCloudPolicyStoreChromeOS* store_;
79 DeviceCloudPolicyManagerChromeOS manager_; 100 DeviceCloudPolicyManagerChromeOS manager_;
80 101
81 private: 102 private:
82 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSTest); 103 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSTest);
83 }; 104 };
84 105
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 public: 166 public:
146 void Done(EnrollmentStatus status) { 167 void Done(EnrollmentStatus status) {
147 status_ = status; 168 status_ = status;
148 done_ = true; 169 done_ = true;
149 } 170 }
150 171
151 protected: 172 protected:
152 DeviceCloudPolicyManagerChromeOSEnrollmentTest() 173 DeviceCloudPolicyManagerChromeOSEnrollmentTest()
153 : is_auto_enrollment_(false), 174 : is_auto_enrollment_(false),
154 register_status_(DM_STATUS_SUCCESS), 175 register_status_(DM_STATUS_SUCCESS),
155 fetch_status_(DM_STATUS_SUCCESS), 176 policy_fetch_status_(DM_STATUS_SUCCESS),
177 robot_auth_fetch_status_(DM_STATUS_SUCCESS),
156 store_result_(true), 178 store_result_(true),
157 status_(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS)), 179 status_(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS)),
158 done_(false) {} 180 done_(false) {}
159 181
160 virtual void SetUp() OVERRIDE { 182 virtual void SetUp() OVERRIDE {
161 DeviceCloudPolicyManagerChromeOSTest::SetUp(); 183 DeviceCloudPolicyManagerChromeOSTest::SetUp();
162 184
163 // Set up test data. 185 // Set up test data.
164 device_policy_.set_new_signing_key( 186 device_policy_.set_new_signing_key(
165 PolicyBuilder::CreateTestNewSigningKey()); 187 PolicyBuilder::CreateTestNewSigningKey());
166 device_policy_.policy_data().set_timestamp( 188 device_policy_.policy_data().set_timestamp(
167 (base::Time::NowFromSystemTime() - 189 (base::Time::NowFromSystemTime() -
168 base::Time::UnixEpoch()).InMilliseconds()); 190 base::Time::UnixEpoch()).InMilliseconds());
169 device_policy_.Build(); 191 device_policy_.Build();
170 192
171 register_response_.mutable_register_response()->set_device_management_token( 193 register_response_.mutable_register_response()->set_device_management_token(
172 PolicyBuilder::kFakeToken); 194 PolicyBuilder::kFakeToken);
173 fetch_response_.mutable_policy_response()->add_response()->CopyFrom( 195 policy_fetch_response_.mutable_policy_response()->add_response()->CopyFrom(
174 device_policy_.policy()); 196 device_policy_.policy());
197 robot_auth_fetch_response_.mutable_service_api_access_response()
198 ->set_auth_code("auth_code_for_test");
175 loaded_blob_ = device_policy_.GetBlob(); 199 loaded_blob_ = device_policy_.GetBlob();
176 200
177 // Initialize the manager. 201 // Initialize the manager.
178 FlushDeviceSettings(); 202 FlushDeviceSettings();
179 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE, store_->status()); 203 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE, store_->status());
180 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 204 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME));
181 205
182 PolicyBundle bundle; 206 PolicyBundle bundle;
183 EXPECT_TRUE(manager_.policies().Equals(bundle)); 207 EXPECT_TRUE(manager_.policies().Equals(bundle));
184 208
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 "auth token", is_auto_enrollment_, modes, 251 "auth token", is_auto_enrollment_, modes,
228 base::Bind(&DeviceCloudPolicyManagerChromeOSEnrollmentTest::Done, 252 base::Bind(&DeviceCloudPolicyManagerChromeOSEnrollmentTest::Done,
229 base::Unretained(this))); 253 base::Unretained(this)));
230 Mock::VerifyAndClearExpectations(&device_management_service_); 254 Mock::VerifyAndClearExpectations(&device_management_service_);
231 255
232 if (done_) 256 if (done_)
233 return; 257 return;
234 258
235 // Process registration. 259 // Process registration.
236 ASSERT_TRUE(register_job); 260 ASSERT_TRUE(register_job);
237 MockDeviceManagementJob* fetch_job = NULL; 261 MockDeviceManagementJob* policy_fetch_job = NULL;
238 EXPECT_CALL(device_management_service_, 262 EXPECT_CALL(device_management_service_,
239 CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH)) 263 CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH))
240 .Times(AtMost(1)) 264 .Times(AtMost(1))
241 .WillOnce(device_management_service_.CreateAsyncJob(&fetch_job)); 265 .WillOnce(device_management_service_.CreateAsyncJob(&policy_fetch_job));
242 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 266 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
243 .Times(AtMost(1)); 267 .Times(AtMost(1));
244 register_job->SendResponse(register_status_, register_response_); 268 register_job->SendResponse(register_status_, register_response_);
245 Mock::VerifyAndClearExpectations(&device_management_service_); 269 Mock::VerifyAndClearExpectations(&device_management_service_);
246 270
247 if (done_) 271 if (done_)
248 return; 272 return;
249 273
250 // Process policy fetch. 274 // Process policy fetch.
251 ASSERT_TRUE(fetch_job); 275 ASSERT_TRUE(policy_fetch_job);
252 fetch_job->SendResponse(fetch_status_, fetch_response_); 276 policy_fetch_job->SendResponse(policy_fetch_status_,
277 policy_fetch_response_);
253 278
254 if (done_) 279 if (done_)
255 return; 280 return;
256 281
257 // Process verification. 282 // Process verification.
283 MockDeviceManagementJob* robot_auth_fetch_job = NULL;
284 EXPECT_CALL(device_management_service_,
285 CreateJob(DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH))
286 .Times(AtMost(1))
287 .WillOnce(device_management_service_.CreateAsyncJob(
288 &robot_auth_fetch_job));
289 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
290 .Times(AtMost(1));
258 base::RunLoop().RunUntilIdle(); 291 base::RunLoop().RunUntilIdle();
292 Mock::VerifyAndClearExpectations(&device_management_service_);
259 293
260 if (done_) 294 if (done_)
261 return; 295 return;
262 296
297 // Process robot auth token fetch.
298 ASSERT_TRUE(robot_auth_fetch_job);
299 robot_auth_fetch_job->SendResponse(robot_auth_fetch_status_,
300 robot_auth_fetch_response_);
301 Mock::VerifyAndClearExpectations(&device_management_service_);
302
303 if (done_)
304 return;
305
306 // Process robot refresh token fetch.
307 // DeviceCloudPolicyManagerChromeOS holds an EnrollmentHandlerChromeOS which
308 // holds a GaiaOAuthClient that fetches the refresh token during enrollment.
309 // We return a successful OAuth response via a TestURLFetcher to trigger the
310 // happy path for these classes so that enrollment can continue.
311 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(0);
312 ASSERT_TRUE(url_fetcher);
313 url_fetcher->set_status(net::URLRequestStatus());
314 url_fetcher->set_response_code(200);
315 url_fetcher->SetResponseString("{\"access_token\":\"accessToken4Test\","
316 "\"expires_in\":1234,"
317 "\"refresh_token\":\"refreshToken4Test\"}");
318 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
319 base::RunLoop().RunUntilIdle();
320
263 // Process policy store. 321 // Process policy store.
264 device_settings_test_helper_.set_store_result(store_result_); 322 device_settings_test_helper_.set_store_result(store_result_);
265 device_settings_test_helper_.FlushStore(); 323 device_settings_test_helper_.FlushStore();
266 EXPECT_EQ(device_policy_.GetBlob(), 324 EXPECT_EQ(device_policy_.GetBlob(),
267 device_settings_test_helper_.policy_blob()); 325 device_settings_test_helper_.policy_blob());
268 326
269 if (done_) 327 if (done_)
270 return; 328 return;
271 329
272 // Key installation and policy load. 330 // Key installation and policy load.
273 device_settings_test_helper_.set_policy_blob(loaded_blob_); 331 device_settings_test_helper_.set_policy_blob(loaded_blob_);
274 owner_key_util_->SetPublicKeyFromPrivateKey( 332 owner_key_util_->SetPublicKeyFromPrivateKey(
275 device_policy_.new_signing_key()); 333 device_policy_.new_signing_key());
276 ReloadDeviceSettings(); 334 ReloadDeviceSettings();
335
336 if (done_)
337 return;
338
339 // Process robot refresh token store.
340 EXPECT_EQ(
341 "refreshToken4Test",
342 chromeos::DeviceOAuth2TokenServiceFactory::Get()->GetRefreshToken());
277 } 343 }
278 344
279 bool is_auto_enrollment_; 345 bool is_auto_enrollment_;
280 346
281 DeviceManagementStatus register_status_; 347 DeviceManagementStatus register_status_;
282 em::DeviceManagementResponse register_response_; 348 em::DeviceManagementResponse register_response_;
283 349
284 DeviceManagementStatus fetch_status_; 350 DeviceManagementStatus policy_fetch_status_;
285 em::DeviceManagementResponse fetch_response_; 351 em::DeviceManagementResponse policy_fetch_response_;
352
353 DeviceManagementStatus robot_auth_fetch_status_;
354 em::DeviceManagementResponse robot_auth_fetch_response_;
286 355
287 bool store_result_; 356 bool store_result_;
288 std::string loaded_blob_; 357 std::string loaded_blob_;
289 358
290 em::DeviceManagementRequest register_request_; 359 em::DeviceManagementRequest register_request_;
291 std::string client_id_; 360 std::string client_id_;
292 EnrollmentStatus status_; 361 EnrollmentStatus status_;
293 362
294 bool done_; 363 bool done_;
295 364
(...skipping 30 matching lines...) Expand all
326 } 395 }
327 396
328 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, RegistrationFailed) { 397 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, RegistrationFailed) {
329 register_status_ = DM_STATUS_REQUEST_FAILED; 398 register_status_ = DM_STATUS_REQUEST_FAILED;
330 RunTest(); 399 RunTest();
331 ExpectFailedEnrollment(EnrollmentStatus::STATUS_REGISTRATION_FAILED); 400 ExpectFailedEnrollment(EnrollmentStatus::STATUS_REGISTRATION_FAILED);
332 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status()); 401 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status());
333 } 402 }
334 403
335 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, PolicyFetchFailed) { 404 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, PolicyFetchFailed) {
336 fetch_status_ = DM_STATUS_REQUEST_FAILED; 405 policy_fetch_status_ = DM_STATUS_REQUEST_FAILED;
337 RunTest(); 406 RunTest();
338 ExpectFailedEnrollment(EnrollmentStatus::STATUS_POLICY_FETCH_FAILED); 407 ExpectFailedEnrollment(EnrollmentStatus::STATUS_POLICY_FETCH_FAILED);
339 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status()); 408 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status());
340 } 409 }
341 410
342 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, ValidationFailed) { 411 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, ValidationFailed) {
343 device_policy_.policy().set_policy_data_signature("bad"); 412 device_policy_.policy().set_policy_data_signature("bad");
344 fetch_response_.clear_policy_response(); 413 policy_fetch_response_.clear_policy_response();
345 fetch_response_.mutable_policy_response()->add_response()->CopyFrom( 414 policy_fetch_response_.mutable_policy_response()->add_response()->CopyFrom(
346 device_policy_.policy()); 415 device_policy_.policy());
347 RunTest(); 416 RunTest();
348 ExpectFailedEnrollment(EnrollmentStatus::STATUS_VALIDATION_FAILED); 417 ExpectFailedEnrollment(EnrollmentStatus::STATUS_VALIDATION_FAILED);
349 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE, 418 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE,
350 status_.validation_status()); 419 status_.validation_status());
351 } 420 }
352 421
353 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, StoreError) { 422 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, StoreError) {
354 store_result_ = false; 423 store_result_ = false;
355 RunTest(); 424 RunTest();
356 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR); 425 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR);
357 EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, 426 EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR,
358 status_.store_status()); 427 status_.store_status());
359 } 428 }
360 429
361 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, LoadError) { 430 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, LoadError) {
362 loaded_blob_.clear(); 431 loaded_blob_.clear();
363 RunTest(); 432 RunTest();
364 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR); 433 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR);
365 EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, 434 EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR,
366 status_.store_status()); 435 status_.store_status());
367 } 436 }
Mattias Nissler (ping if slow) 2013/04/22 10:59:00 We should probably have a couple test cases that c
368 437
369 } // namespace 438 } // namespace test
370 } // namespace policy 439 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698