diff options
author | danno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-29 09:20:03 +0000 |
---|---|---|
committer | danno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-29 09:20:03 +0000 |
commit | 2a87dce080ab4f09a180e9e6881a85ac9e8aedde (patch) | |
tree | c1d960efade31be45b7b7ba30532af14279d4bda /chrome/browser/policy | |
parent | dc7bec0219a6d54cadf530786907bc72c6b31268 (diff) | |
download | chromium_src-2a87dce080ab4f09a180e9e6881a85ac9e8aedde.zip chromium_src-2a87dce080ab4f09a180e9e6881a85ac9e8aedde.tar.gz chromium_src-2a87dce080ab4f09a180e9e6881a85ac9e8aedde.tar.bz2 |
Implement device token fetcher
First step in mechanism for fetching cloud-based policy for CrOS.
BUG=none
TEST=DeviceTokenFetcher*
Review URL: http://codereview.chromium.org/4121003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64388 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/policy')
-rw-r--r-- | chrome/browser/policy/device_management_backend.h | 114 | ||||
-rw-r--r-- | chrome/browser/policy/device_token_fetcher.cc | 165 | ||||
-rw-r--r-- | chrome/browser/policy/device_token_fetcher.h | 134 | ||||
-rw-r--r-- | chrome/browser/policy/device_token_fetcher_unittest.cc | 178 | ||||
-rw-r--r-- | chrome/browser/policy/mock_device_management_backend.cc | 61 | ||||
-rw-r--r-- | chrome/browser/policy/mock_device_management_backend.h | 52 | ||||
-rw-r--r-- | chrome/browser/policy/proto/device_management_backend.proto | 165 |
7 files changed, 869 insertions, 0 deletions
diff --git a/chrome/browser/policy/device_management_backend.h b/chrome/browser/policy/device_management_backend.h new file mode 100644 index 0000000..25c7b1b --- /dev/null +++ b/chrome/browser/policy/device_management_backend.h @@ -0,0 +1,114 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_BACKEND_H_ +#define CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_BACKEND_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "base/non_thread_safe.h" +#include "chrome/browser/policy/proto/device_management_backend.pb.h" + +namespace policy { + +namespace em = enterprise_management; + +// Interface for clients that need to converse with the device management +// server, which provides services to register Chrome installations and CrOS +// devices for the purpose of fetching centrally-administered policy from the +// cloud. +class DeviceManagementBackend : NonThreadSafe { + public: + enum ErrorCode { + // Request payload invalid. + kErrorRequestInvalid, + // The HTTP request failed. + kErrorRequestFailed, + // The HTTP request returned a non-success code. + kErrorHttpStatus, + // Response could not be decoded. + kErrorResponseDecoding, + // Service error: Management not supported. + kErrorServiceManagementNotSupported, + // Service error: Device not found. + kErrorServiceDeviceNotFound, + // Service error: Device token invalid. + kErrorServiceManagementTokenInvalid, + // Service error: Activation pending. + kErrorServiceActivationPending, + }; + + class DeviceRegisterResponseDelegate { + public: + virtual ~DeviceRegisterResponseDelegate() {} + virtual void HandleRegisterResponse( + const em::DeviceRegisterResponse& response) = 0; + virtual void OnError(ErrorCode code) = 0; + + protected: + DeviceRegisterResponseDelegate() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceRegisterResponseDelegate); + }; + + class DeviceUnregisterResponseDelegate { + public: + virtual ~DeviceUnregisterResponseDelegate() {} + virtual void HandleUnregisterResponse( + const em::DeviceUnregisterResponse& response) = 0; + virtual void OnError(ErrorCode code) = 0; + + protected: + DeviceUnregisterResponseDelegate() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceUnregisterResponseDelegate); + }; + + class DevicePolicyResponseDelegate { + public: + virtual ~DevicePolicyResponseDelegate() {} + + virtual void HandlePolicyResponse( + const em::DevicePolicyResponse& response) = 0; + virtual void OnError(ErrorCode code) = 0; + + protected: + DevicePolicyResponseDelegate() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DevicePolicyResponseDelegate); + }; + + virtual ~DeviceManagementBackend() {} + + virtual void ProcessRegisterRequest( + const std::string& auth_token, + const std::string& device_id, + const em::DeviceRegisterRequest& request, + DeviceRegisterResponseDelegate* delegate) = 0; + + virtual void ProcessUnregisterRequest( + const std::string& device_management_token, + const em::DeviceUnregisterRequest& request, + DeviceUnregisterResponseDelegate* delegate) = 0; + + virtual void ProcessPolicyRequest( + const std::string& device_management_token, + const em::DevicePolicyRequest& request, + DevicePolicyResponseDelegate* delegate) = 0; + + protected: + DeviceManagementBackend() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceManagementBackend); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_BACKEND_H_ diff --git a/chrome/browser/policy/device_token_fetcher.cc b/chrome/browser/policy/device_token_fetcher.cc new file mode 100644 index 0000000..9362747 --- /dev/null +++ b/chrome/browser/policy/device_token_fetcher.cc @@ -0,0 +1,165 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/policy/device_token_fetcher.h" + +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/singleton.h" +#include "chrome/browser/net/gaia/token_service.h" +#include "chrome/browser/policy/mock_device_management_backend.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/net/gaia/gaia_constants.h" +#include "chrome/common/notification_details.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" +#include "chrome/common/notification_type.h" + +namespace { + +static const char kPlaceholderDeviceID[] = "placeholder_device_id"; + +} // namespace + +namespace policy { + +bool UserDirDeviceTokenPathProvider::GetPath(FilePath* path) const { + FilePath dir_path; + if ( PathService::Get(chrome::DIR_USER_DATA, &dir_path)) + return false; + *path = dir_path.Append(FILE_PATH_LITERAL("DeviceManagementToken")); + return true; +} + +DeviceTokenFetcher::DeviceTokenFetcher( + DeviceManagementBackend* backend, + StoredDeviceTokenPathProvider* path_provider) + : backend_(backend), + path_provider_(path_provider), + state_(kStateLoadDeviceTokenFromDisk), + device_token_load_complete_event_(true, false) { +} + +void DeviceTokenFetcher::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(CalledOnValidThread()); + if (type == NotificationType::TOKEN_AVAILABLE) { + const Source<TokenService> token_service(source); + const TokenService::TokenAvailableDetails* token_details = + Details<const TokenService::TokenAvailableDetails>(details).ptr(); + if (token_details->service() == GaiaConstants::kDeviceManagementService && + state_ < kStateHasAuthToken) { + DCHECK_EQ(kStateFetchingAuthToken, state_); + SetState(kStateHasAuthToken); + em::DeviceRegisterRequest register_request; + backend_->ProcessRegisterRequest(token_details->token(), + GetDeviceID(), + register_request, + this); + } + } else { + NOTREACHED(); + } +} + +void DeviceTokenFetcher::HandleRegisterResponse( + const em::DeviceRegisterResponse& response) { + DCHECK(CalledOnValidThread()); + DCHECK_EQ(kStateHasAuthToken, state_); + if (response.has_device_management_token()) { + device_token_ = response.device_management_token(); + FilePath device_token_path; + if (path_provider_->GetPath(&device_token_path)) { + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + NewRunnableFunction(&WriteDeviceTokenToDisk, + device_token_path, + device_token_)); + } + SetState(kStateHasDeviceToken); + } else { + NOTREACHED(); + SetState(kStateFailure); + } +} + +void DeviceTokenFetcher::OnError(DeviceManagementBackend::ErrorCode code) { + DCHECK(CalledOnValidThread()); + SetState(kStateFailure); +} + +void DeviceTokenFetcher::StartFetching() { + DCHECK(CalledOnValidThread()); + if (state_ < kStateHasDeviceToken) { + FilePath device_token_path; + FetcherState new_state = kStateFailure; + if (path_provider_->GetPath(&device_token_path)) { + if (file_util::PathExists(device_token_path)) { + std::string device_token; + if (file_util::ReadFileToString(device_token_path, &device_token_)) { + new_state = kStateHasDeviceToken; + } + } + if (new_state != kStateHasDeviceToken) { + new_state = kStateFetchingAuthToken; + // The policy provider gets initialized with the PrefService and Profile + // before ServiceTokens are available. Install a notification observer + // to ensure that the device management token gets fetched after the + // AuthTokens are available if it's needed. + registrar_.Add(this, + NotificationType::TOKEN_AVAILABLE, + NotificationService::AllSources()); + } + } + SetState(new_state); + } +} + +bool DeviceTokenFetcher::IsTokenPending() { + DCHECK(CalledOnValidThread()); + return !device_token_load_complete_event_.IsSignaled(); +} + +std::string DeviceTokenFetcher::GetDeviceToken() { + DCHECK(CalledOnValidThread()); + device_token_load_complete_event_.Wait(); + return device_token_; +} + +void DeviceTokenFetcher::SetState(FetcherState state) { + DCHECK(CalledOnValidThread()); + state_ = state; + if (state == kStateFailure) { + device_token_load_complete_event_.Signal(); + } else if (state == kStateHasDeviceToken) { + device_token_load_complete_event_.Signal(); + NotificationService::current()->Notify( + NotificationType::DEVICE_TOKEN_AVAILABLE, + Source<DeviceTokenFetcher>(this), + NotificationService::NoDetails()); + } +} + +bool DeviceTokenFetcher::IsTokenValid() const { + return state_ == kStateHasDeviceToken; +} + +// static +void DeviceTokenFetcher::WriteDeviceTokenToDisk( + const FilePath& path, + const std::string& device_token) { + file_util::WriteFile(path, + device_token.c_str(), + device_token.length()); +} + +// static +std::string DeviceTokenFetcher::GetDeviceID() { + // TODO(danno): fetch a real device_id + return kPlaceholderDeviceID; +} + +} diff --git a/chrome/browser/policy/device_token_fetcher.h b/chrome/browser/policy/device_token_fetcher.h new file mode 100644 index 0000000..f5a0770 --- /dev/null +++ b/chrome/browser/policy/device_token_fetcher.h @@ -0,0 +1,134 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_ +#define CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_ +#pragma once + +#include <string> + +#include "base/file_path.h" +#include "base/non_thread_safe.h" +#include "base/waitable_event.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/browser/policy/device_management_backend.h" + +namespace policy { + +namespace em = enterprise_management; + +// Abstracts how the path is determined where the DeviceTokenFetcher stores the +// device token once it has been returned from the server. Tests provide a mock +// implementation to the DeviceTokenFetcher that doesn't write to DIR_USER_DATA. +class StoredDeviceTokenPathProvider { + public: + virtual ~StoredDeviceTokenPathProvider() {} + + // Sets |path| to contain the path at which to use to store the device + // management token file. Returns true if successful, otherwise false. + virtual bool GetPath(FilePath* path) const = 0; + protected: + StoredDeviceTokenPathProvider() {} + private: + DISALLOW_COPY_AND_ASSIGN(StoredDeviceTokenPathProvider); +}; + +// Provides a path to the device token that's inside DIR_USER_DATA. +class UserDirDeviceTokenPathProvider : public StoredDeviceTokenPathProvider { + public: + UserDirDeviceTokenPathProvider() {} + virtual ~UserDirDeviceTokenPathProvider() {} + virtual bool GetPath(FilePath* path) const; + private: + DISALLOW_COPY_AND_ASSIGN(UserDirDeviceTokenPathProvider); +}; + +// Fetches the device token that can be used for policy requests with the device +// management server, either from disk if it already has been successfully +// requested, otherwise from the device management server. An instance of the +// fetcher is shared as a singleton by all users of the device management token +// to ensure they all get the same token. +class DeviceTokenFetcher + : public NonThreadSafe, + public NotificationObserver, + public DeviceManagementBackend::DeviceRegisterResponseDelegate { + public: + // Requests to the device management server are sent through |backend|. The + // DeviceTokenFetcher assumes ownership of |backend|, which is passed in + // explicitly to simplify mocking of the backend for unit testing. The + // fetcher uses |path_provider| to determine the directory in which the device + // token is stored once it's retrieved from the server. The fetcher assumes + // ownership of |path_provider|. + DeviceTokenFetcher(DeviceManagementBackend* backend, + StoredDeviceTokenPathProvider* path_provider); + virtual ~DeviceTokenFetcher() {} + + // NotificationObserver method overrides: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // DeviceManagementBackend::DeviceRegisterResponseDelegate method overrides: + virtual void HandleRegisterResponse( + const em::DeviceRegisterResponse& response); + virtual void OnError(DeviceManagementBackend::ErrorCode code); + + // Called by subscribers of the device management token to indicate that they + // will need the token in the future. + void StartFetching(); + + // Returns true if there is a pending token request to the device management + // server. + bool IsTokenPending(); + + // Returns the device management token for this device, blocking until + // outstanding requests to the device management server are satisfied. In the + // case that the token could not be fetched, an empty string is returned. + std::string GetDeviceToken(); + + // True if the device token has been fetched and is valid. + bool IsTokenValid() const; + + private: + // The different states that the fetcher can be in during the process of + // getting the device token. + enum FetcherState { + kStateLoadDeviceTokenFromDisk, + kStateFetchingAuthToken, + kStateHasAuthToken, + kStateHasDeviceToken, + kStateFailure + }; + + // Moves the fetcher into a new state. If the fetcher has the device token + // or is moving into the failure state, callers waiting on WaitForToken + // are unblocked. + void SetState(FetcherState state); + + // Saves the device management token to disk once it has been retrieved from + // the server. Must be called on the FILE thread. + static void WriteDeviceTokenToDisk(const FilePath& path, + const std::string& token); + + // Returns the device ID used to register the device with the device + // management server and generate the device token. + static std::string GetDeviceID(); + + scoped_ptr<DeviceManagementBackend> backend_; + scoped_ptr<StoredDeviceTokenPathProvider> path_provider_; + FetcherState state_; + std::string device_token_; + + // An event that is signaled only once the device token has been fetched + // or it has been determined that there was an error during fetching. + base::WaitableEvent device_token_load_complete_event_; + + // Registers the fetcher for notification of successful Gaia logins. + NotificationRegistrar registrar_; +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_ diff --git a/chrome/browser/policy/device_token_fetcher_unittest.cc b/chrome/browser/policy/device_token_fetcher_unittest.cc new file mode 100644 index 0000000..3d15d1b6 --- /dev/null +++ b/chrome/browser/policy/device_token_fetcher_unittest.cc @@ -0,0 +1,178 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/file_util.h" +#include "base/message_loop.h" +#include "base/scoped_temp_dir.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/net/gaia/token_service.h" +#include "chrome/browser/policy/device_token_fetcher.h" +#include "chrome/browser/policy/mock_device_management_backend.h" +#include "chrome/common/net/gaia/gaia_constants.h" +#include "chrome/common/notification_details.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" +#include "chrome/common/notification_type.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace policy { + +using testing::_; +using testing::Mock; + +class MockDeviceTokenPathProvider + : public StoredDeviceTokenPathProvider { + public: + MockDeviceTokenPathProvider() { + EXPECT_TRUE(temp_user_data_dir_.CreateUniqueTempDir()); + } + + virtual ~MockDeviceTokenPathProvider() {} + + virtual bool GetPath(FilePath* path) const { + if (!file_util::PathExists(temp_user_data_dir_.path())) + return false; + *path = temp_user_data_dir_.path().Append( + FILE_PATH_LITERAL("temp_token_file")); + return true; + } + + private: + ScopedTempDir temp_user_data_dir_; + + DISALLOW_COPY_AND_ASSIGN(MockDeviceTokenPathProvider); +}; + +class MockTokenAvailableObserver : public NotificationObserver { + public: + MockTokenAvailableObserver() {} + virtual ~MockTokenAvailableObserver() {} + + MOCK_METHOD3(Observe, void( + NotificationType type, + const NotificationSource& source, + const NotificationDetails& details)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockTokenAvailableObserver); +}; + +class DeviceTokenFetcherTest : public testing::Test { + protected: + DeviceTokenFetcherTest() { + backend_ = new MockDeviceManagementBackend(); + path_provider_ = new MockDeviceTokenPathProvider(); + fetcher_.reset(new DeviceTokenFetcher(backend_, path_provider_)); + fetcher_->StartFetching(); + } + + virtual void SetUp() { + ui_thread_.reset(new BrowserThread(BrowserThread::UI, &loop_)); + file_thread_.reset(new BrowserThread(BrowserThread::FILE, &loop_)); + } + + virtual void TearDown() { + loop_.RunAllPending(); + } + + void SimulateSuccessfulLogin() { + const std::string service(GaiaConstants::kDeviceManagementService); + const std::string auth_token(kFakeGaiaAuthToken); + const Source<TokenService> source(NULL); + TokenService::TokenAvailableDetails details(service, auth_token); + NotificationService::current()->Notify( + NotificationType::TOKEN_AVAILABLE, + source, + Details<const TokenService::TokenAvailableDetails>(&details)); + loop_.RunAllPending(); + } + + MockDeviceManagementBackend* backend_; // weak + MockDeviceTokenPathProvider* path_provider_; // weak + scoped_ptr<DeviceTokenFetcher> fetcher_; + + private: + MessageLoop loop_; + scoped_ptr<BrowserThread> ui_thread_; + scoped_ptr<BrowserThread> file_thread_; + + static const char kFakeGaiaAuthToken[]; +}; + +const char DeviceTokenFetcherTest::kFakeGaiaAuthToken[] = "0123456789abcdef"; + +TEST_F(DeviceTokenFetcherTest, IsPending) { + ASSERT_TRUE(fetcher_->IsTokenPending()); + SimulateSuccessfulLogin(); + ASSERT_FALSE(fetcher_->IsTokenPending()); +} + +TEST_F(DeviceTokenFetcherTest, SimpleFetchSingleLogin) { + SimulateSuccessfulLogin(); + ASSERT_FALSE(fetcher_->IsTokenPending()); + ASSERT_TRUE(fetcher_->IsTokenValid()); + const std::string token(fetcher_->GetDeviceToken()); + EXPECT_NE("", token); +} + +TEST_F(DeviceTokenFetcherTest, SimpleFetchDoubleLogin) { + SimulateSuccessfulLogin(); + ASSERT_FALSE(fetcher_->IsTokenPending()); + const std::string token(fetcher_->GetDeviceToken()); + EXPECT_NE("", token); + + SimulateSuccessfulLogin(); + ASSERT_FALSE(fetcher_->IsTokenPending()); + const std::string token2(fetcher_->GetDeviceToken()); + EXPECT_NE("", token2); + EXPECT_EQ(token, token2); +} + +TEST_F(DeviceTokenFetcherTest, FetchBetweenBrowserLaunchAndNotify) { + NotificationRegistrar registrar; + MockTokenAvailableObserver observer; + registrar.Add(&observer, + NotificationType::DEVICE_TOKEN_AVAILABLE, + NotificationService::AllSources()); + EXPECT_CALL(observer, Observe(_, _, _)).Times(1); + + SimulateSuccessfulLogin(); + ASSERT_FALSE(fetcher_->IsTokenPending()); + const std::string token(fetcher_->GetDeviceToken()); + EXPECT_NE("", token); + + Mock::VerifyAndClearExpectations(&observer); + EXPECT_CALL(observer, Observe(_, _, _)).Times(1); + + // Swap out the fetchers, including copying the device management token on + // disk to where the new fetcher expects it. + backend_ = new MockDeviceManagementBackend(); + FilePath old_path; + ASSERT_TRUE(path_provider_->GetPath(&old_path)); + MockDeviceTokenPathProvider* new_provider = + new MockDeviceTokenPathProvider(); + FilePath new_path; + ASSERT_TRUE(new_provider->GetPath(&new_path)); + ASSERT_TRUE(file_util::Move(old_path, new_path)); + path_provider_ = new_provider; + fetcher_.reset(new DeviceTokenFetcher(backend_, path_provider_)); + + fetcher_->StartFetching(); + ASSERT_FALSE(fetcher_->IsTokenPending()); + const std::string token2(fetcher_->GetDeviceToken()); + EXPECT_NE("", token2); + EXPECT_EQ(token, token2); +} + +TEST_F(DeviceTokenFetcherTest, FailedServerRequest) { + backend_->SetFailure(true); + SimulateSuccessfulLogin(); + ASSERT_FALSE(fetcher_->IsTokenPending()); + const std::string token(fetcher_->GetDeviceToken()); + EXPECT_EQ("", token); +} + +} // namespace policy diff --git a/chrome/browser/policy/mock_device_management_backend.cc b/chrome/browser/policy/mock_device_management_backend.cc new file mode 100644 index 0000000..61a20e9c --- /dev/null +++ b/chrome/browser/policy/mock_device_management_backend.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/logging.h" +#include "chrome/browser/policy/mock_device_management_backend.h" + +namespace { + +static const char kFakeDeviceManagementToken[] = "FAKE_DEVICE_TOKEN_"; +static char next_token_suffix_ = '0'; + +} // namespace + +namespace policy { + +using enterprise_management::DeviceRegisterRequest; +using enterprise_management::DeviceUnregisterRequest; +using enterprise_management::DevicePolicyRequest; +using enterprise_management::DeviceRegisterResponse; +using enterprise_management::DeviceUnregisterResponse; +using enterprise_management::DevicePolicyResponse; + +MockDeviceManagementBackend::MockDeviceManagementBackend() + : DeviceManagementBackend(), + failure_(false) { +} + +void MockDeviceManagementBackend::ProcessRegisterRequest( + const std::string& auth_token, + const std::string& device_id, + const DeviceRegisterRequest& request, + DeviceRegisterResponseDelegate* delegate) { + if (failure_) { + delegate->OnError(kErrorRequestInvalid); + } else { + DeviceRegisterResponse response; + std::string token(kFakeDeviceManagementToken); + token += next_token_suffix_++; + response.set_device_management_token(token); + delegate->HandleRegisterResponse(response); + } +} + +void MockDeviceManagementBackend::ProcessUnregisterRequest( + const std::string& device_management_token, + const DeviceUnregisterRequest& request, + DeviceUnregisterResponseDelegate* delegate) { + // TODO(danno): need a mock implementation for the backend here. + NOTREACHED(); +} + +void MockDeviceManagementBackend::ProcessPolicyRequest( + const std::string& device_management_token, + const DevicePolicyRequest& request, + DevicePolicyResponseDelegate* delegate) { + // TODO(danno): need a mock implementation for the backend here. + NOTREACHED(); +} + +} // namespace diff --git a/chrome/browser/policy/mock_device_management_backend.h b/chrome/browser/policy/mock_device_management_backend.h new file mode 100644 index 0000000..290e615 --- /dev/null +++ b/chrome/browser/policy/mock_device_management_backend.h @@ -0,0 +1,52 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_POLICY_MOCK_DEVICE_MANAGEMENT_BACKEND_H_ +#define CHROME_BROWSER_POLICY_MOCK_DEVICE_MANAGEMENT_BACKEND_H_ +#pragma once + +#include <string> + +#include "chrome/browser/policy/device_management_backend.h" + +namespace policy { + +namespace em = enterprise_management; + +// Useful for unit testing when a server-based backend isn't +// available. Simulates both successful and failed requests to the device +// management server. +class MockDeviceManagementBackend + : public DeviceManagementBackend { + public: + MockDeviceManagementBackend(); + virtual ~MockDeviceManagementBackend() {} + + void SetFailure(bool failure) { failure_ = failure; } + + // DeviceManagementBackend method overrides: + virtual void ProcessRegisterRequest( + const std::string& auth_token, + const std::string& device_id, + const em::DeviceRegisterRequest& request, + DeviceRegisterResponseDelegate* delegate); + + virtual void ProcessUnregisterRequest( + const std::string& device_management_token, + const em::DeviceUnregisterRequest& request, + DeviceUnregisterResponseDelegate* delegate); + + virtual void ProcessPolicyRequest( + const std::string& device_management_token, + const em::DevicePolicyRequest& request, + DevicePolicyResponseDelegate* delegate); + + private: + bool failure_; + DISALLOW_COPY_AND_ASSIGN(MockDeviceManagementBackend); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_MOCK_DEVICE_MANAGEMENT_BACKEND_H_ diff --git a/chrome/browser/policy/proto/device_management_backend.proto b/chrome/browser/policy/proto/device_management_backend.proto new file mode 100644 index 0000000..6b0cc8d --- /dev/null +++ b/chrome/browser/policy/proto/device_management_backend.proto @@ -0,0 +1,165 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package enterprise_management; + +// Generic value container. +message GenericValue { + enum ValueType { + VALUE_TYPE_BOOL = 1; + VALUE_TYPE_INT64 = 2; + VALUE_TYPE_STRING = 3; + VALUE_TYPE_DOUBLE = 4; + VALUE_TYPE_BYTES = 5; + VALUE_TYPE_BOOL_ARRAY = 6; + VALUE_TYPE_INT64_ARRAY_ = 7; + VALUE_TYPE_STRING_ARRAY = 8; + VALUE_TYPE_DOUBLE_ARRAY = 9; + } + + optional ValueType value_type = 1 [default = VALUE_TYPE_STRING]; + + // basic value types + optional bool bool_value = 2; + optional int64 int64_value = 3; + optional string string_value = 4; + optional double double_value = 5; + optional bytes bytes_value = 6; + repeated bool bool_array = 7; + repeated int64 int64_array = 8; + repeated string string_array = 9; + repeated double double_array = 10; +} + +// Generic name value pair container. +message GenericNamedValue { + required string name = 1; + optional GenericValue value = 2; +} + +// A setting is a set of generic name value pairs. +message GenericSetting { + repeated GenericNamedValue named_value = 1; +} + +// Identify a single device policy setting key/value pair. +message DevicePolicySetting { + // key of the policy setting + required string policy_key = 1; + // value of the setting + optional GenericSetting policy_value = 2; + // watermark for setting value. + optional string watermark = 3; +} + +// Request from device to server to register device. +message DeviceRegisterRequest { + // reregister device without erasing server state. + // it can be used to refresh dmtoken etc. + optional bool reregister = 1; +} + +// Response from server to device register request. +message DeviceRegisterResponse { + // device mangement toke for this registration. + required string device_management_token = 1; +} + +// Request from device to server to unregister device. +message DeviceUnregisterRequest { +} + +// Response from server to device unregister request. +message DeviceUnregisterResponse { +} + +// Request for a setting or with optional watermark on client side. +message DevicePolicySettingRequest { + // setting key + required string key = 1; + // watermark last read from server if available. + optional string watermark = 2; +} + +// Request from device to server to read device policies. +message DevicePolicyRequest { + // identify request scope: CrOS settings or other type of settings. + optional string policy_scope = 1; + // identify key to the settings: proxy etc. + repeated DevicePolicySettingRequest setting_request = 2; +} + +// Response from server to agent for reading policies. +message DevicePolicyResponse { + // the result of the settings. + repeated DevicePolicySetting setting = 1; +} + +// Request from the DMAgent on the device to the DMServer. +// This is container for all requests from client. +// +// Authorization: +// 1. If request is register_request, client must pass in GoogleLogin auth +// cookie in Authorization header: +// Authorization: GoogleLogin auth=<auth cookie> +// The response will contain an unique DMToken for future requests. +// Depending on domain policy, the request may need admin approval before +// DMToken is issued. +// 2. For other requests, client must pass in DMToken in Authorization header: +// Authorization: GoogleDMToken token=<google dm token> +// +// Http Query parameters: +// Query parameters contain the following information in each request: +// request: register/unregister/policy etc. +// devicetype: CrOS/Android/Iphone etc. +// apptype: CrOS/AndroidDM etc. +// deviceid: unique id that identify the device. +// agent: identify agent on device. +message DeviceManagementRequest { + // Register request. + optional DeviceRegisterRequest register_request = 1; + + // Unregister request. + optional DeviceUnregisterRequest unregister_request = 2; + + // Data request. + optional DevicePolicyRequest policy_request = 3; +} + +// Response from server to device. +message DeviceManagementResponse { + // Error code to client. + enum ErrorCode { + SUCCESS = 0; + // Returned for register request when device management is not supported + // for the domain. + DEVICE_MANAGEMENT_NOT_SUPPORTED = 1; + // Returned when the device is not found. + DEVICE_NOT_FOUND = 2; + // Returned when passed in device management token doesn't match the token + // on server side. + DEVICE_MANAGEMENT_TOKEN_INVALID = 3; + // Returned when device registration is pending approval (if required). + ACTIVATION_PENDING = 4; + } + + // Error code for this request. + required ErrorCode error = 1; + + // Error message. + optional string error_message = 2; + + // Register response + optional DeviceRegisterResponse register_response = 3; + + // Unregister response + optional DeviceUnregisterResponse unregister_response = 4; + + // Policy response. + optional DevicePolicyResponse policy_response = 5; +} |