| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "ios/chrome/browser/policy/browser_dm_token_storage_ios.h" |
| |
| #import <Foundation/Foundation.h> |
| |
| #import "base/apple/backup_util.h" |
| #import "base/apple/foundation_util.h" |
| #import "base/base64url.h" |
| #import "base/files/file_util.h" |
| #import "base/files/important_file_writer.h" |
| #import "base/hash/sha1.h" |
| #import "base/ios/device_util.h" |
| #import "base/path_service.h" |
| #import "base/strings/string_util.h" |
| #import "base/strings/sys_string_conversions.h" |
| #import "base/strings/utf_string_conversions.h" |
| #import "base/task/thread_pool.h" |
| #import "components/policy/core/common/policy_loader_ios_constants.h" |
| #import "components/policy/core/common/policy_logger.h" |
| #import "components/policy/policy_constants.h" |
| |
| namespace policy { |
| |
| namespace { |
| |
| const char kDmTokenBaseDir[] = |
| FILE_PATH_LITERAL("Google/Chrome Cloud Enrollment/"); |
| |
| bool GetDmTokenFilePath(base::FilePath* token_file_path, |
| const std::string& client_id, |
| bool create_dir) { |
| if (!base::PathService::Get(base::DIR_APP_DATA, token_file_path)) |
| return false; |
| |
| *token_file_path = token_file_path->Append(kDmTokenBaseDir); |
| |
| if (create_dir && !base::CreateDirectory(*token_file_path)) |
| return false; |
| |
| std::string filename; |
| base::Base64UrlEncode(base::SHA1HashString(client_id), |
| base::Base64UrlEncodePolicy::OMIT_PADDING, &filename); |
| *token_file_path = token_file_path->Append(filename.c_str()); |
| |
| return true; |
| } |
| |
| bool StoreDMTokenInDirAppDataDir(const std::string& token, |
| const std::string& client_id) { |
| base::FilePath token_file_path; |
| if (!GetDmTokenFilePath(&token_file_path, client_id, /*create_dir=*/true)) { |
| NOTREACHED(); |
| return false; |
| } |
| |
| if (!base::ImportantFileWriter::WriteFileAtomically(token_file_path, token)) { |
| LOG_POLICY(ERROR, CBCM_ENROLLMENT) << "Failed to save DMToken to file"; |
| return false; |
| } |
| |
| base::apple::SetBackupExclusion(token_file_path); |
| return true; |
| } |
| |
| bool DeleteDMTokenFromAppDataDir(const std::string& client_id) { |
| base::FilePath token_file_path; |
| if (!GetDmTokenFilePath(&token_file_path, client_id, /*create_dir=*/false)) { |
| NOTREACHED(); |
| return false; |
| } |
| |
| return base::DeleteFile(token_file_path); |
| } |
| |
| } // namespace |
| |
| BrowserDMTokenStorageIOS::BrowserDMTokenStorageIOS() |
| : task_runner_(base::ThreadPool::CreateTaskRunner({base::MayBlock()})) {} |
| |
| BrowserDMTokenStorageIOS::~BrowserDMTokenStorageIOS() {} |
| |
| std::string BrowserDMTokenStorageIOS::InitClientId() { |
| return ios::device_util::GetVendorId(); |
| } |
| |
| std::string BrowserDMTokenStorageIOS::InitEnrollmentToken() { |
| NSDictionary* raw_policies = [[NSUserDefaults standardUserDefaults] |
| dictionaryForKey:kPolicyLoaderIOSConfigurationKey]; |
| NSString* token = |
| base::apple::ObjCCast<NSString>(raw_policies[base::SysUTF8ToNSString( |
| key::kCloudManagementEnrollmentToken)]); |
| |
| if (token) { |
| return std::string(base::TrimWhitespaceASCII(base::SysNSStringToUTF8(token), |
| base::TRIM_ALL)); |
| } |
| |
| return std::string(); |
| } |
| |
| std::string BrowserDMTokenStorageIOS::InitDMToken() { |
| base::FilePath token_file_path; |
| if (!GetDmTokenFilePath(&token_file_path, InitClientId(), |
| /*create_dir=*/false)) { |
| LOG_POLICY(WARNING, CBCM_ENROLLMENT) << "Failed to get DMToken file path"; |
| return std::string(); |
| } |
| |
| std::string token; |
| if (!base::ReadFileToString(token_file_path, &token)) { |
| LOG_POLICY(WARNING, CBCM_ENROLLMENT) << "Failed to read DMToken from file"; |
| return std::string(); |
| } |
| |
| return std::string(base::TrimWhitespaceASCII(token, base::TRIM_ALL)); |
| } |
| |
| bool BrowserDMTokenStorageIOS::InitEnrollmentErrorOption() { |
| // No error should be shown if enrollment fails on iOS. |
| LOG_POLICY(ERROR, CBCM_ENROLLMENT) << "Error initializing enrollment token"; |
| return false; |
| } |
| |
| bool BrowserDMTokenStorageIOS::CanInitEnrollmentToken() const { |
| return true; |
| } |
| |
| BrowserDMTokenStorage::StoreTask BrowserDMTokenStorageIOS::SaveDMTokenTask( |
| const std::string& token, |
| const std::string& client_id) { |
| return base::BindOnce(&StoreDMTokenInDirAppDataDir, token, client_id); |
| } |
| |
| BrowserDMTokenStorage::StoreTask BrowserDMTokenStorageIOS::DeleteDMTokenTask( |
| const std::string& client_id) { |
| return base::BindOnce(&DeleteDMTokenFromAppDataDir, client_id); |
| } |
| |
| scoped_refptr<base::TaskRunner> |
| BrowserDMTokenStorageIOS::SaveDMTokenTaskRunner() { |
| return task_runner_; |
| } |
| |
| } // namespace policy |