/* * Copyright 2020 Toyota Connected North America * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include "g_hash_table.h" #include "logging.h" namespace secret { class Keyring { FHashTable m_attributes; std::string m_label; SecretSchema m_schema{}; public: explicit Keyring(const char* _label = "default") : m_label(_label) { m_schema = {m_label.c_str(), SECRET_SCHEMA_NONE, { {"account", SECRET_SCHEMA_ATTRIBUTE_STRING}, }}; } /** * @brief Add new a key and value to the keyring * @param[in] key A key to add * @param[in] value The value to associate with the key * @return bool * @retval true Normal end * @retval false Abnormal end * @relation * flutter */ bool addItem(const char* key, const char* value) { rapidjson::Document root = readFromKeyring(); if (root.IsObject() && root.HasMember(key) && root[key].IsString()) { root.RemoveMember(key); } rapidjson::Value k(key, root.GetAllocator()); rapidjson::Value v(value, root.GetAllocator()); root.AddMember(k, v, root.GetAllocator()); return this->storeToKeyring(root); } /** * @brief Get the string associate with a key from keyring * @param[in] key A key to get string * @return std::string * @retval The associated string, or "" if the key is not found * @relation * flutter */ std::string getItem(const char* key) { rapidjson::Document root = readFromKeyring(); if (root.IsObject() && root.HasMember(key) && root[key].IsString()) { return root[key].GetString(); } return ""; } /** * @brief Delete key and value from keyring * @param[in] key A key to delete * @return void * @relation * flutter */ void deleteItem(const char* key) { rapidjson::Document root = readFromKeyring(); if (root.HasMember(key)) { root.RemoveMember(key); } this->storeToKeyring(root); } /** * @brief Empty keyring * @return bool * @retval true Normal end * @retval false Abnormal end * @relation * flutter */ bool deleteKeyring() { rapidjson::Document d; d.SetObject(); return this->storeToKeyring(d); } /** * @brief Store a password in the secret service * @param[in] d A document for parsing JSON text as DOM * @return bool * @retval true Normal end * @retval false Abnormal end * @relation * flutter */ bool storeToKeyring(rapidjson::Document& d) { std::unique_ptr err = nullptr; GError* errPtr = err.get(); rapidjson::StringBuffer buffer; buffer.Clear(); rapidjson::Writer writer(buffer); d.Accept(writer); auto res = (bool)secret_password_storev_sync ( &m_schema, m_attributes.getGHashTable(), nullptr, m_label.c_str(), buffer.GetString(), nullptr, &errPtr); auto result = static_cast(res); if (err) { throw std::runtime_error(err->message); } return result; } /** * @brief Lookup a password in the secret service * @return rapidjson::Document * @retval A new password string * @relation * flutter */ rapidjson::Document readFromKeyring() { rapidjson::Document d; std::unique_ptr err = nullptr; GError* errPtr = err.get(); const gchar* result = secret_password_lookupv_sync( &m_schema, m_attributes.getGHashTable(), nullptr, &errPtr); if (err) { throw std::runtime_error(err->message); } if (result != nullptr && strcmp(result, "") != 0 && !d.Parse(result).HasParseError()) { if (strcmp(result, "null") == 0) { const char* json = "{}"; d.Parse(json); } return d; } this->storeToKeyring(d); return d; } }; } // namespace secret