Clean up extension confirmation prompts and make them consistent between Views and...
[chromium-blink-merge.git] / remoting / test / refresh_token_store.cc
blobce5a5b8c07e6c0efe8179fcdbd14c208d61a7df7
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.
5 #include "remoting/test/refresh_token_store.h"
7 #include "base/files/file_util.h"
8 #include "base/files/important_file_writer.h"
9 #include "base/json/json_reader.h"
10 #include "base/json/json_writer.h"
11 #include "base/logging.h"
12 #include "base/values.h"
14 namespace {
15 const base::FilePath::CharType kTokenFileName[] =
16 FILE_PATH_LITERAL("refresh_tokens.json");
17 const base::FilePath::CharType kRemotingFolder[] =
18 FILE_PATH_LITERAL("remoting");
19 const base::FilePath::CharType kRefreshTokenStoreFolder[] =
20 FILE_PATH_LITERAL("token_store");
21 } // namespace
23 namespace remoting {
24 namespace test {
26 // Provides functionality to write a refresh token to a local folder on disk and
27 // read it back during subsequent tool runs.
28 class RefreshTokenStoreOnDisk : public RefreshTokenStore {
29 public:
30 RefreshTokenStoreOnDisk(const std::string& user_name,
31 const base::FilePath& refresh_token_file_path);
32 ~RefreshTokenStoreOnDisk() override;
34 // RefreshTokenStore interface.
35 std::string FetchRefreshToken() override;
36 bool StoreRefreshToken(const std::string& refresh_token) override;
38 private:
39 // Returns the path for the file used to read from or store a refresh token
40 // for the user.
41 base::FilePath GetPathForRefreshTokenFile();
43 // Used to access the user specific token file.
44 std::string user_name_;
46 // Path used to retrieve the refresh token file.
47 base::FilePath refresh_token_file_path_;
49 DISALLOW_COPY_AND_ASSIGN(RefreshTokenStoreOnDisk);
52 RefreshTokenStoreOnDisk::RefreshTokenStoreOnDisk(
53 const std::string& user_name,
54 const base::FilePath& refresh_token_file_path)
55 : user_name_(user_name), refresh_token_file_path_(refresh_token_file_path) {
58 RefreshTokenStoreOnDisk::~RefreshTokenStoreOnDisk() {
61 std::string RefreshTokenStoreOnDisk::FetchRefreshToken() {
62 base::FilePath refresh_token_file_path(GetPathForRefreshTokenFile());
63 DCHECK(!refresh_token_file_path.empty());
64 DVLOG(2) << "Reading token from: " << refresh_token_file_path.value();
66 std::string file_contents;
67 if (!base::ReadFileToString(refresh_token_file_path, &file_contents)) {
68 DVLOG(1) << "Couldn't read token file: " << refresh_token_file_path.value();
69 return std::string();
72 scoped_ptr<base::Value> token_data(base::JSONReader::Read(file_contents));
73 base::DictionaryValue* tokens = nullptr;
74 if (!token_data || !token_data->GetAsDictionary(&tokens)) {
75 LOG(ERROR) << "Refresh token file contents were not valid JSON, "
76 << "could not retrieve token.";
77 return std::string();
80 std::string refresh_token;
81 if (!tokens->GetStringWithoutPathExpansion(user_name_, &refresh_token)) {
82 // This may not be an error as the file could exist but contain refresh
83 // tokens for other users.
84 DVLOG(1) << "Could not find token for: " << user_name_;
85 return std::string();
88 return refresh_token;
91 bool RefreshTokenStoreOnDisk::StoreRefreshToken(
92 const std::string& refresh_token) {
93 DCHECK(!refresh_token.empty());
95 base::FilePath file_path(GetPathForRefreshTokenFile());
96 DCHECK(!file_path.empty());
97 DVLOG(2) << "Storing token to: " << file_path.value();
99 base::FilePath refresh_token_file_dir(file_path.DirName());
100 if (!base::DirectoryExists(refresh_token_file_dir) &&
101 !base::CreateDirectory(refresh_token_file_dir)) {
102 LOG(ERROR) << "Failed to create directory, refresh token not stored.";
103 return false;
106 std::string file_contents("{}");
107 if (base::PathExists(file_path)) {
108 if (!base::ReadFileToString(file_path, &file_contents)) {
109 LOG(ERROR) << "Invalid token file: " << file_path.value();
110 return false;
114 scoped_ptr<base::Value> token_data(base::JSONReader::Read(file_contents));
115 base::DictionaryValue* tokens = nullptr;
116 if (!token_data || !token_data->GetAsDictionary(&tokens)) {
117 LOG(ERROR) << "Invalid refresh token file format, could not store token.";
118 return false;
121 std::string json_string;
122 tokens->SetStringWithoutPathExpansion(user_name_, refresh_token);
123 if (!base::JSONWriter::Write(*token_data, &json_string)) {
124 LOG(ERROR) << "Couldn't convert JSON data to string";
125 return false;
128 if (!base::ImportantFileWriter::WriteFileAtomically(file_path, json_string)) {
129 LOG(ERROR) << "Failed to save refresh token to the file on disk.";
130 return false;
133 return true;
136 base::FilePath RefreshTokenStoreOnDisk::GetPathForRefreshTokenFile() {
137 base::FilePath refresh_token_file_path(refresh_token_file_path_);
139 // If we weren't given a specific file path, then use the default path.
140 if (refresh_token_file_path.empty()) {
141 if (!GetTempDir(&refresh_token_file_path)) {
142 LOG(WARNING) << "Failed to retrieve temporary directory path.";
143 return base::FilePath();
146 refresh_token_file_path = refresh_token_file_path.Append(kRemotingFolder);
147 refresh_token_file_path =
148 refresh_token_file_path.Append(kRefreshTokenStoreFolder);
151 // If no file has been specified, then we will use a default file name.
152 if (refresh_token_file_path.Extension().empty()) {
153 refresh_token_file_path = refresh_token_file_path.Append(kTokenFileName);
156 return refresh_token_file_path;
159 scoped_ptr<RefreshTokenStore> RefreshTokenStore::OnDisk(
160 const std::string& user_name,
161 const base::FilePath& refresh_token_file_path) {
162 return make_scoped_ptr<RefreshTokenStore>(
163 new RefreshTokenStoreOnDisk(user_name, refresh_token_file_path));
166 } // namespace test
167 } // namespace remoting