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
=
28 refresh_token_dir_path
.Append(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 explicit 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
) {
65 RefreshTokenStoreOnDisk::~RefreshTokenStoreOnDisk() {
68 std::string
RefreshTokenStoreOnDisk::FetchRefreshToken() {
69 base::FilePath
token_dir_path(GetRefreshTokenDirPath(user_name_
));
70 DCHECK(!token_dir_path
.empty());
72 DVLOG(2) << "Reading token from path: " << token_dir_path
.value();
73 base::FilePath
token_file_path(token_dir_path
.Append(kTokenFileName
));
75 std::string refresh_token
;
76 if (!base::ReadFileToString(token_file_path
, &refresh_token
)) {
77 DVLOG(1) << "Failed to read token file from: " << token_dir_path
.value();
84 bool RefreshTokenStoreOnDisk::StoreRefreshToken(
85 const std::string
& refresh_token
) {
86 DCHECK(!refresh_token
.empty());
88 base::FilePath
token_dir_path(GetRefreshTokenDirPath(user_name_
));
89 if (token_dir_path
.empty()) {
93 base::FilePath
token_file_path(token_dir_path
.Append(kTokenFileName
));
94 if (!base::DirectoryExists(token_dir_path
) &&
95 !base::CreateDirectory(token_dir_path
)) {
96 LOG(ERROR
) << "Failed to create directory, refresh token not stored.";
100 #if defined(OS_POSIX)
101 // For POSIX we can set permissions on the token file so we do so here.
102 // The test code should not run on other platforms since the code to safely
103 // store the token has not been implemented yet.
105 // Create an empty stub file if one does not exist.
106 if (!base::PathExists(token_file_path
) &&
107 base::WriteFile(token_file_path
, "", 0) < 0) {
108 LOG(ERROR
) << "Failed to create stub file, refresh token not stored.";
112 // Set permissions on the stub file.
114 base::FILE_PERMISSION_READ_BY_USER
| base::FILE_PERMISSION_WRITE_BY_USER
;
115 if (!SetPosixFilePermissions(token_file_path
, mode
)) {
116 LOG(ERROR
) << "Failed to set file permissions, refresh token not stored.";
120 // Write the refresh token to our newly created file.
121 if (base::WriteFile(token_file_path
, refresh_token
.c_str(),
122 refresh_token
.size()) < 0) {
123 LOG(ERROR
) << "Failed to save refresh token to the file on disk.";
134 scoped_ptr
<RefreshTokenStore
> RefreshTokenStore::OnDisk(
135 const std::string
& user_name
) {
136 return make_scoped_ptr
<RefreshTokenStore
>(
137 new RefreshTokenStoreOnDisk(user_name
));
141 } // namespace remoting