blob: 939e185e55ab88478dcc0b92fd7b215a0dd9d125 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "peridot/lib/firebase_auth/firebase_auth_impl.h"
#include <utility>
#include "garnet/lib/callback/cancellable_helper.h"
#include "lib/fxl/functional/make_copyable.h"
namespace firebase_auth {
FirebaseAuthImpl::FirebaseAuthImpl(
async_t* async,
std::string api_key,
modular_auth::TokenProviderPtr token_provider,
std::unique_ptr<backoff::Backoff> backoff)
: api_key_(std::move(api_key)),
token_provider_(std::move(token_provider)),
backoff_(std::move(backoff)),
task_runner_(async) {}
void FirebaseAuthImpl::set_error_handler(fxl::Closure on_error) {
token_provider_.set_error_handler(std::move(on_error));
}
fxl::RefPtr<callback::Cancellable> FirebaseAuthImpl::GetFirebaseToken(
std::function<void(firebase_auth::AuthStatus, std::string)> callback) {
if (api_key_.empty()) {
FXL_LOG(WARNING) << "No Firebase API key provided. Connection to Firebase "
"may be unauthenticated.";
}
auto cancellable = callback::CancellableImpl::Create([] {});
GetToken([callback = cancellable->WrapCallback(callback)](
auto status, auto token) { callback(status, token->id_token); });
return cancellable;
}
fxl::RefPtr<callback::Cancellable> FirebaseAuthImpl::GetFirebaseUserId(
std::function<void(firebase_auth::AuthStatus, std::string)> callback) {
auto cancellable = callback::CancellableImpl::Create([] {});
GetToken([callback = cancellable->WrapCallback(callback)](
auto status, auto token) { callback(status, token->local_id); });
return cancellable;
}
void FirebaseAuthImpl::GetToken(
std::function<void(firebase_auth::AuthStatus,
modular_auth::FirebaseTokenPtr)> callback) {
token_provider_->GetFirebaseAuthToken(
api_key_, [this, callback = std::move(callback)](
modular_auth::FirebaseTokenPtr token,
modular_auth::AuthErr error) mutable {
if (!token || error.status != modular_auth::Status::OK) {
if (!token && error.status == modular_auth::Status::OK) {
FXL_LOG(ERROR)
<< "null Firebase token returned from token provider with no "
<< "error reported. This should never happen. Retrying.";
} else {
FXL_LOG(ERROR)
<< "Error retrieving the Firebase token from token provider: "
<< error.status << ", '" << error.message << "', retrying.";
}
task_runner_.PostDelayedTask(
[this, callback = std::move(callback)]() mutable {
GetToken(std::move(callback));
},
zx::duration(backoff_->GetNext().ToNanoseconds()));
return;
}
backoff_->Reset();
callback(firebase_auth::AuthStatus::OK, std::move(token));
});
}
} // namespace firebase_auth