blob: dc3d1d2bdb8c3e07ccb321ae01972d5efccfef72 [file] [log] [blame]
// Copyright 2018 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 "src/ledger/lib/firebase_auth/testing/credentials.h"
#include <rapidjson/document.h>
#include <rapidjson/schema.h>
#include "garnet/public/lib/rapidjson_utils/rapidjson_validation.h"
namespace service_account {
namespace {
constexpr fxl::StringView kServiceAccountConfigurationSchema = R"({
"type": "object",
"additionalProperties": true,
"properties": {
"project_id": {
"type": "string"
},
"private_key": {
"type": "string"
},
"client_email": {
"type": "string"
},
"client_id": {
"type": "string"
}
},
"required": ["project_id", "private_key", "client_email", "client_id"]
})";
} // namespace
Credentials::Credentials(std::string project_id, std::string client_email,
std::string client_id,
bssl::UniquePtr<EVP_PKEY> private_key)
: project_id_(std::move(project_id)),
client_email_(std::move(client_email)),
client_id_(std::move(client_id)),
private_key_(std::move(private_key)) {}
std::unique_ptr<Credentials> Credentials::Parse(fxl::StringView json) {
rapidjson::Document document;
document.Parse(json.data(), json.size());
if (document.HasParseError() || !document.IsObject()) {
FXL_LOG(ERROR) << "Json file is incorrect: " << json;
return nullptr;
}
return Parse(document);
}
std::unique_ptr<Credentials> Credentials::Parse(const rapidjson::Value& json) {
static auto service_account_schema =
rapidjson_utils::InitSchema(kServiceAccountConfigurationSchema);
FXL_DCHECK(service_account_schema);
FXL_DCHECK(json.IsObject());
if (!rapidjson_utils::ValidateSchema(json, *service_account_schema)) {
return nullptr;
}
auto project_id = json["project_id"].GetString();
auto client_email = json["client_email"].GetString();
auto client_id = json["client_id"].GetString();
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(
json["private_key"].GetString(), json["private_key"].GetStringLength()));
bssl::UniquePtr<EVP_PKEY> private_key(
PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
if (EVP_PKEY_id(private_key.get()) != EVP_PKEY_RSA) {
FXL_LOG(ERROR) << "Provided key is not a RSA key.";
return nullptr;
}
return std::make_unique<Credentials>(
std::move(project_id), std::move(client_email), std::move(client_id),
std::move(private_key));
}
std::unique_ptr<Credentials> Credentials::Clone() {
if (!EVP_PKEY_up_ref(private_key_.get())) {
FXL_LOG(ERROR) << "Unable to increment the private key ref count.";
return nullptr;
}
bssl::UniquePtr<EVP_PKEY> private_key(private_key_.get());
return std::make_unique<Credentials>(project_id_, client_email_, client_id_,
std::move(private_key));
}
} // namespace service_account