Skip to content

Commit ccb5ee1

Browse files
cynthiajianga-maurice
authored andcommitted
[Auth] Persistence with secure interface
+ Remove early access flag + save/load with secure interface + add encode/decode to raw flatbuffer data + add fake internal impl PiperOrigin-RevId: 245321552
1 parent cae247c commit ccb5ee1

File tree

11 files changed

+437
-126
lines changed

11 files changed

+437
-126
lines changed

app/src/util_desktop.cc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2016 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "app/src/util_desktop.h"
18+
19+
#include "app/src/log.h"
20+
#include "openssl/base64.h"
21+
22+
namespace firebase {
23+
24+
bool Base64Encode(const std::string& input, std::string* output) {
25+
size_t base64_length = 0;
26+
if ((EVP_EncodedLength(&base64_length, input.size()) == 0) ||
27+
(base64_length == 0)) {
28+
LogError("Failed base64 EVP_EncodedLength(%s)", input.c_str());
29+
return false;
30+
}
31+
output->resize(base64_length);
32+
if (EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&(*output)[0]),
33+
reinterpret_cast<const uint8_t*>(&input[0]),
34+
input.size()) == 0u) {
35+
LogError("Failed base64 EVP_EncodeBlock()");
36+
return false;
37+
}
38+
// Trim the terminating null character.
39+
output->resize(base64_length - 1);
40+
return true;
41+
}
42+
43+
bool Base64Decode(const std::string& input, std::string* output) {
44+
size_t decoded_length = 0;
45+
if ((EVP_DecodedLength(&decoded_length, input.size()) == 0) ||
46+
(decoded_length == 0)) {
47+
LogError("Failed to get decoded length for input(%s)", input.c_str());
48+
return false;
49+
}
50+
std::string buffer;
51+
buffer.resize(decoded_length);
52+
if (EVP_DecodeBase64(reinterpret_cast<uint8_t*>(&(buffer)[0]),
53+
&decoded_length, decoded_length,
54+
reinterpret_cast<const uint8_t*>(&(input)[0]),
55+
input.size()) == 0) {
56+
LogError("Failed to decode input");
57+
return false;
58+
}
59+
// Decoded length includes null termination, remove.
60+
buffer.resize(buffer.size() - 1);
61+
output->assign(buffer);
62+
return true;
63+
}
64+
65+
} // namespace firebase

app/src/util_desktop.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2016 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef FIREBASE_APP_CLIENT_CPP_SRC_UTIL_DESKTOP_H_
18+
#define FIREBASE_APP_CLIENT_CPP_SRC_UTIL_DESKTOP_H_
19+
20+
#include <string>
21+
22+
namespace firebase {
23+
24+
// Encoding the input string with base64, and set to output.
25+
bool Base64Encode(const std::string& input, std::string* output);
26+
27+
// Decoding the input string with base64, and set to output.
28+
bool Base64Decode(const std::string& input, std::string* output);
29+
30+
} // namespace firebase
31+
32+
#endif // FIREBASE_APP_CLIENT_CPP_SRC_UTIL_DESKTOP_H_

auth/src/desktop/auth_desktop.cc

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,8 @@ void Auth::InitPlatformAuth(AuthData* const auth_data) {
205205
internal::FnAuthStopTokenListener,
206206
Auth::StopTokenRefreshThreadForRegistry);
207207

208-
#ifdef FIREBASE_EARLY_ACCESS_PREVIEW
209208
// Load existing UserData
210209
InitializeUserDataPersist(auth_data);
211-
#endif // FIREBASE_EARLY_ACCESS_PREVIEW
212-
213210
InitializeTokenRefresher(auth_data);
214211
}
215212

@@ -233,9 +230,7 @@ void Auth::DestroyPlatformAuth(AuthData* const auth_data) {
233230
auth_data->id_token_listeners.clear();
234231
}
235232

236-
#ifdef FIREBASE_EARLY_ACCESS_PREVIEW
237233
DestroyUserDataPersist(auth_data);
238-
#endif // FIREBASE_EARLY_ACCESS_PREVIEW
239234

240235
UserView::ClearUser(auth_data);
241236

@@ -424,19 +419,16 @@ void ResetTokenRefreshCounter(AuthData* auth_data) {
424419
auth_impl->token_refresh_thread.WakeThread();
425420
}
426421

427-
#ifdef FIREBASE_EARLY_ACCESS_PREVIEW
428422
void InitializeUserDataPersist(AuthData* auth_data) {
429423
auto auth_impl = static_cast<AuthImpl*>(auth_data->auth_impl);
430-
auth_data->auth->AddAuthStateListener(&(auth_impl->user_data_persist));
431-
auth_impl->user_data_persist.LoadUserData(auth_data);
424+
auth_data->auth->AddAuthStateListener(auth_impl->user_data_persist.get());
425+
auth_impl->user_data_persist->LoadUserData(auth_data);
432426
}
433427

434428
void DestroyUserDataPersist(AuthData* auth_data) {
435429
auto auth_impl = static_cast<AuthImpl*>(auth_data->auth_impl);
436-
auth_impl->user_data_persist.Destroy();
437-
auth_data->auth->RemoveAuthStateListener(&(auth_impl->user_data_persist));
430+
auth_data->auth->RemoveAuthStateListener(auth_impl->user_data_persist.get());
438431
}
439-
#endif // FIREBASE_EARLY_ACCESS_PREVIEW
440432

441433
void IdTokenRefreshThread::WakeThread() { wakeup_sem_.Post(); }
442434

auth/src/desktop/auth_desktop.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ class IdTokenRefreshThread {
102102

103103
// The desktop-specific Auth implementation.
104104
struct AuthImpl {
105-
AuthImpl() : async_sem(0), active_async_calls(0) {}
105+
AuthImpl() : async_sem(0), active_async_calls(0) {
106+
user_data_persist = MakeUnique<UserDataPersist>();
107+
}
106108

107109
// The application's API key.
108110
std::string api_key;
@@ -113,9 +115,8 @@ struct AuthImpl {
113115

114116
// Thread responsible for refreshing the auth token periodically.
115117
IdTokenRefreshThread token_refresh_thread;
116-
#ifdef FIREBASE_EARLY_ACCESS_PREVIEW
117-
UserDataPersist user_data_persist;
118-
#endif // FIREBASE_EARLY_ACCESS_PREVIEW
118+
// Instance responsible for user data persistence.
119+
UniquePtr<UserDataPersist> user_data_persist;
119120
// Synchronization primitives used for managing threads spawned by CallAsync.
120121
Semaphore async_sem;
121122
Mutex async_mutex;
@@ -128,10 +129,8 @@ const int kMinutesPerTokenRefresh = 58;
128129
const int kMsPerTokenRefresh =
129130
kMinutesPerTokenRefresh * internal::kMillisecondsPerMinute;
130131

131-
#ifdef FIREBASE_EARLY_ACCESS_PREVIEW
132132
void InitializeUserDataPersist(AuthData* auth_data);
133133
void DestroyUserDataPersist(AuthData* auth_data);
134-
#endif // FIREBASE_EARLY_ACCESS_PREVIEW
135134

136135
} // namespace auth
137136
} // namespace firebase
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "auth/src/desktop/secure/user_secure_fake_internal.h"
16+
17+
#include <dirent.h>
18+
19+
#include <cstdio>
20+
#include <fstream>
21+
22+
namespace firebase {
23+
namespace auth {
24+
namespace secure {
25+
26+
UserSecureFakeInternal::UserSecureFakeInternal(const char* secure_path)
27+
: secure_path_(secure_path) {}
28+
29+
UserSecureFakeInternal::~UserSecureFakeInternal() {}
30+
31+
std::string UserSecureFakeInternal::LoadUserData(const std::string& app_name) {
32+
std::string output;
33+
std::string filename = GetFilePath(app_name);
34+
35+
std::ifstream infile;
36+
infile.open(filename, std::ios::binary);
37+
if (infile.fail()) {
38+
return "";
39+
}
40+
41+
infile.seekg(0, std::ios::end);
42+
int64_t length = infile.tellg();
43+
infile.seekg(0, std::ios::beg);
44+
output.resize(length);
45+
infile.read(&*output.begin(), length);
46+
if (infile.fail()) {
47+
return "";
48+
}
49+
infile.close();
50+
return output;
51+
}
52+
53+
void UserSecureFakeInternal::SaveUserData(const std::string& app_name,
54+
const std::string& user_data) {
55+
std::string filename = GetFilePath(app_name);
56+
57+
std::ofstream ofile(filename, std::ios::binary);
58+
ofile.write(user_data.c_str(), user_data.length());
59+
ofile.close();
60+
}
61+
62+
void UserSecureFakeInternal::DeleteUserData(const std::string& app_name) {
63+
std::string filename = GetFilePath(app_name);
64+
std::ifstream infile;
65+
infile.open(filename, std::ios::binary);
66+
if (infile.fail()) {
67+
return;
68+
}
69+
infile.close();
70+
std::remove(filename.c_str());
71+
}
72+
73+
void UserSecureFakeInternal::DeleteAllData() {
74+
// These are data types defined in the "dirent" header
75+
DIR* theFolder = opendir(secure_path_.c_str());
76+
struct dirent* next_file;
77+
78+
while ((next_file = readdir(theFolder)) != nullptr) {
79+
// build the path for each file in the folder
80+
std::string filepath = secure_path_ + "/";
81+
filepath.append(next_file->d_name);
82+
remove(filepath.c_str());
83+
}
84+
closedir(theFolder);
85+
}
86+
87+
std::string UserSecureFakeInternal::GetFilePath(const std::string& app_name) {
88+
std::string filepath = secure_path_ + "/" + app_name + "_bin";
89+
return filepath;
90+
}
91+
92+
} // namespace secure
93+
} // namespace auth
94+
} // namespace firebase
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef FIREBASE_AUTH_CLIENT_CPP_SRC_DESKTOP_SECURE_USER_SECURE_FAKE_INTERNAL_H_
16+
#define FIREBASE_AUTH_CLIENT_CPP_SRC_DESKTOP_SECURE_USER_SECURE_FAKE_INTERNAL_H_
17+
18+
#include <string>
19+
20+
#include "auth/src/desktop/secure/user_secure_internal.h"
21+
22+
namespace firebase {
23+
namespace auth {
24+
namespace secure {
25+
26+
// Fake implementation for the secure manager of user data.
27+
class UserSecureFakeInternal : public UserSecureInternal {
28+
public:
29+
explicit UserSecureFakeInternal(const char* secure_path);
30+
~UserSecureFakeInternal() override;
31+
32+
std::string LoadUserData(const std::string& app_name) override;
33+
34+
void SaveUserData(const std::string& app_name,
35+
const std::string& user_data) override;
36+
37+
void DeleteUserData(const std::string& app_name) override;
38+
39+
void DeleteAllData() override;
40+
41+
private:
42+
std::string GetFilePath(const std::string& app_name);
43+
44+
const std::string secure_path_;
45+
};
46+
47+
} // namespace secure
48+
} // namespace auth
49+
} // namespace firebase
50+
51+
#endif // FIREBASE_AUTH_CLIENT_CPP_SRC_DESKTOP_SECURE_USER_SECURE_FAKE_INTERNAL_H_

0 commit comments

Comments
 (0)