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/logging.h"
11 const base::FilePath::CharType kTokenFileName
[] =
12 FILE_PATH_LITERAL("refresh_token.txt");
13 const base::FilePath::CharType kRemotingFolder
[] =
14 FILE_PATH_LITERAL("remoting");
15 const base::FilePath::CharType kRefreshTokenStoreFolder
[] =
16 FILE_PATH_LITERAL("refresh_token_store");
18 // Returns the FilePath of the token store file for |user_name|.
19 base::FilePath
GetRefreshTokenDirPath(const std::string
& user_name
) {
20 base::FilePath refresh_token_dir_path
;
21 if (!GetTempDir(&refresh_token_dir_path
)) {
22 LOG(WARNING
) << "Failed to retrieve temporary directory path.";
23 return base::FilePath();
26 refresh_token_dir_path
= refresh_token_dir_path
.Append(kRemotingFolder
);
27 refresh_token_dir_path
= refresh_token_dir_path
.Append(
28 kRefreshTokenStoreFolder
);
30 // We call AppendASCII here our user_name is a std::string but wide strings
31 // are used on WIN platforms. ApendASCII will convert our std::string into
32 // the correct type for windows platforms.
33 refresh_token_dir_path
= refresh_token_dir_path
.AppendASCII(user_name
);
35 return refresh_token_dir_path
;
43 // Provides functionality to write a refresh token to a local folder on disk and
44 // read it back during subsequent tool runs.
45 class RefreshTokenStoreOnDisk
: public RefreshTokenStore
{
47 RefreshTokenStoreOnDisk(const std::string user_name
);
48 ~RefreshTokenStoreOnDisk() override
;
50 // RefreshTokenStore interface.
51 std::string
FetchRefreshToken() override
;
52 bool StoreRefreshToken(const std::string
& refresh_token
) override
;
55 // Used to access the user specific token file.
56 std::string user_name_
;
58 DISALLOW_COPY_AND_ASSIGN(RefreshTokenStoreOnDisk
);
61 RefreshTokenStoreOnDisk::RefreshTokenStoreOnDisk(const std::string user_name
) :
62 user_name_(user_name
) {}
64 RefreshTokenStoreOnDisk::~RefreshTokenStoreOnDisk() {}
66 std::string
RefreshTokenStoreOnDisk::FetchRefreshToken() {
67 base::FilePath
token_dir_path(GetRefreshTokenDirPath(user_name_
));
68 DCHECK(!token_dir_path
.empty());
70 DVLOG(2) << "Reading token from path: " << token_dir_path
.value();
71 base::FilePath
token_file_path(token_dir_path
.Append(kTokenFileName
));
73 std::string refresh_token
;
74 if (!base::ReadFileToString(token_file_path
, &refresh_token
)) {
75 DVLOG(1) << "Failed to read token file from: " << token_dir_path
.value();
82 bool RefreshTokenStoreOnDisk::StoreRefreshToken(
83 const std::string
& refresh_token
) {
84 DCHECK(!refresh_token
.empty());
86 base::FilePath
token_dir_path(GetRefreshTokenDirPath(user_name_
));
87 if (token_dir_path
.empty()) {
91 base::FilePath
token_file_path(token_dir_path
.Append(kTokenFileName
));
92 if (!base::DirectoryExists(token_dir_path
) &&
93 !base::CreateDirectory(token_dir_path
)) {
94 LOG(ERROR
) << "Failed to create directory, refresh token not stored.";
99 // For POSIX we can set permissions on the token file so we do so here.
100 // The test code should not run on other platforms since the code to safely
101 // store the token has not been implemented yet.
103 // Create an empty stub file if one does not exist.
104 if (!base::PathExists(token_file_path
) &&
105 base::WriteFile(token_file_path
, "", 0) < 0) {
106 LOG(ERROR
) << "Failed to create stub file, refresh token not stored.";
110 // Set permissions on the stub file.
112 base::FILE_PERMISSION_READ_BY_USER
| base::FILE_PERMISSION_WRITE_BY_USER
;
113 if (!SetPosixFilePermissions(token_file_path
, mode
)) {
114 LOG(ERROR
) << "Failed to set file permissions, refresh token not stored.";
118 // Write the refresh token to our newly created file.
119 if (base::WriteFile(token_file_path
, refresh_token
.c_str(),
120 refresh_token
.size()) < 0) {
121 LOG(ERROR
) << "Failed to save refresh token to the file on disk.";
132 scoped_ptr
<RefreshTokenStore
> RefreshTokenStore::OnDisk(
133 const std::string
& user_name
) {
134 return make_scoped_ptr
<RefreshTokenStore
>(new RefreshTokenStoreOnDisk(
139 } // namespace remoting