| // 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 "peridot/lib/firebase_auth/testing/credentials.h" |
| |
| #include <rapidjson/document.h> |
| #include <rapidjson/schema.h> |
| |
| #include "peridot/lib/firebase_auth/testing/json_schema.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 = |
| json_schema::InitSchema(kServiceAccountConfigurationSchema); |
| |
| FXL_DCHECK(json.IsObject()); |
| if (!json_schema::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 |