Line data Source code
1 : /* 2 : * Copyright (C) 2004-2026 Savoir-faire Linux Inc. 3 : * 4 : * This program is free software: you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation, either version 3 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License 15 : * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 : */ 17 : #pragma once 18 : 19 : #include "noncopyable.h" 20 : #include "plugin/webviewservicesmanager.h" 21 : #include "pluginmanager.h" 22 : 23 : #include "callservicesmanager.h" 24 : #include "chatservicesmanager.h" 25 : #include "preferenceservicesmanager.h" 26 : #include <opendht/crypto.h> 27 : #include <vector> 28 : #include <map> 29 : 30 : namespace jami { 31 : 32 : using PreferencesMap = std::map<std::string, std::map<std::string, std::string>>; 33 : 34 : /** 35 : * @class JamiPluginManager 36 : * @brief This class provides an interface to functions exposed to the 37 : * Plugin System interface for lrc and clients. 38 : */ 39 : class JamiPluginManager 40 : { 41 : public: 42 : JamiPluginManager(); 43 : 44 : /** 45 : * @brief get the plugin's author 46 : * @param rootPath 47 : * @param pluginId 48 : * @return string 49 : */ 50 : std::string getPluginAuthor(const std::string& rootPath, const std::string& pluginId); 51 : 52 : /** 53 : * @brief Parses a manifest file and return its content 54 : * along with other internally added values. 55 : * @param rootPath installation path 56 : * @param reset If true, overrides previous details values 57 : * Reset is only used in the UT for now, but it can be useful 58 : * if we want to reset plugins language without restarting the application 59 : * @return Map where the keyset is {"id", "name", "description", "version", "iconPath", "backgroundPath","soPath"} 60 : */ 61 : std::map<std::string, std::string> getPluginDetails(const std::string& rootPath, bool reset = false); 62 : 63 : /** 64 : * @brief Returns a vector with installed plugins 65 : */ 66 : std::vector<std::string> getInstalledPlugins(); 67 : 68 : /** 69 : * @brief Check the validity of a plugin certificate 70 : * @param cert 71 : * @return true if valid 72 : */ 73 : bool checkPluginCertificateValidity(dht::crypto::Certificate* cert); 74 : 75 : /** 76 : * @brief check if the if the public key of the certificate is the same as the public key in the new plugin 77 : * @param oldJplPath, newJplPath 78 : * return true if valid 79 : */ 80 : bool checkPluginCertificatePublicKey(const std::string& oldJplPath, const std::string& newJplPath); 81 : 82 : /** 83 : * @brief check if all file are present in the signature file 84 : * @param jplPath 85 : * return true if valid 86 : */ 87 : bool checkPluginSignatureFile(const std::string& jplPath); 88 : 89 : /** 90 : * @brief Check the validity of a plugin signature 91 : * @param jplPath 92 : * @param cert 93 : * @return true if valid 94 : */ 95 : bool checkPluginSignatureValidity(const std::string& jplPath, dht::crypto::Certificate* cert); 96 : 97 : /** 98 : * @brief Checks if the plugin signature mechanism is valid by signature of files and each files is signed. 99 : * @param jplPath 100 : * @param 101 : * @return true if the plugin signature is valid 102 : * 103 : */ 104 : bool checkPluginSignature(const std::string& jplPath, dht::crypto::Certificate* cert); 105 : 106 : /** 107 : * @brief Checks if the certificate mechanism is valid by checking certificate of the plugin 108 : * @param jplPath 109 : * @param force 110 : * @return return certificate if valid 111 : */ 112 : std::unique_ptr<dht::crypto::Certificate> checkPluginCertificate(const std::string& jplPath, bool force); 113 : 114 : /** 115 : * @brief Checks if the plugin has a valid manifest, installs the plugin if not 116 : * previously installed or if installing a newer version of it. 117 : * @param jplPath 118 : * @param force If true, allows installing an older plugin version. 119 : * @return 0 if success 120 : * 100 if already installed with similar version 121 : * 200 if already installed with newer version 122 : * libarchive (mizip in apple platforms) error codes otherwise 123 : */ 124 : int installPlugin(const std::string& jplPath, bool force); 125 : 126 : /** 127 : * @brief Checks if the plugin has a valid manifest and if the plugin is loaded, 128 : * tries to unload it and then removes plugin folder. 129 : * @param rootPath 130 : * @return 0 if success 131 : */ 132 : int uninstallPlugin(const std::string& rootPath); 133 : 134 : /** 135 : * @brief Returns True if success 136 : * @param rootPath of the plugin folder 137 : */ 138 : bool loadPlugin(const std::string& rootPath); 139 : 140 : /** 141 : * @brief Returns True if success 142 : */ 143 : bool loadPlugins(); 144 : 145 : /** 146 : * @brief Returns True if success 147 : * @param rootPath of the plugin folder 148 : */ 149 : bool unloadPlugin(const std::string& rootPath); 150 : 151 : /** 152 : * @brief Returns vector with rootpaths of the loaded plugins 153 : */ 154 : std::vector<std::string> getLoadedPlugins() const; 155 : 156 : /** 157 : * @brief Returns contents of plugin's preferences.json file 158 : * @param rootPath 159 : * @param accountId 160 : */ 161 : std::vector<std::map<std::string, std::string>> getPluginPreferences(const std::string& rootPath, 162 : const std::string& accountId); 163 : 164 : /** 165 : * @brief Returns a Map with preferences keys and values. 166 : * @param rootPath 167 : * @param accountId 168 : */ 169 : std::map<std::string, std::string> getPluginPreferencesValuesMap(const std::string& rootPath, 170 : const std::string& accountId); 171 : 172 : /** 173 : * @brief Returns a Map of platform system. 174 : */ 175 : std::map<std::string, std::string> getPlatformInfo(); 176 : 177 : /** 178 : * @brief Modifies a preference value by saving it to a preferences.msgpack. 179 : * Plugin is reloaded only if the preference cannot take effect immediately. 180 : * In other words, if we have to reload plugin so that preference may take effect. 181 : * @param rootPath 182 : * @param accountId 183 : * @param key 184 : * @param value 185 : * @return True if success 186 : */ 187 : bool setPluginPreference(const std::filesystem::path& rootPath, 188 : const std::string& accountId, 189 : const std::string& key, 190 : const std::string& value); 191 : 192 : /** 193 : * @brief Reset plugin's preferences values to their defaultValues 194 : * @param rootPath 195 : * @param accountId 196 : * @return True if success. 197 : */ 198 : bool resetPluginPreferencesValuesMap(const std::string& rootPath, const std::string& accountId); 199 : 200 1604 : CallServicesManager& getCallServicesManager() { return callsm_; } 201 : 202 2082 : ChatServicesManager& getChatServicesManager() { return chatsm_; } 203 : 204 0 : WebViewServicesManager& getWebViewServicesManager() { return webviewsm_; } 205 : 206 : PreferenceServicesManager& getPreferenceServicesManager() { return preferencesm_; } 207 : 208 : #ifdef LIBJAMI_TEST 209 : void addPluginAuthority(const dht::crypto::Certificate& cert); 210 : #endif 211 : 212 : private: 213 : NON_COPYABLE(JamiPluginManager); 214 : 215 : /** 216 : * @brief Register services that can be called from plugin implementation side. 217 : */ 218 : void registerServices(); 219 : 220 : // PluginManager instance 221 : PluginManager pm_; 222 : dht::crypto::TrustList trust_; 223 : // Map between plugins installation path and manifest infos. 224 : std::map<std::string, std::map<std::string, std::string>> pluginDetailsMap_; 225 : 226 : // Services instances 227 : CallServicesManager callsm_; 228 : ChatServicesManager chatsm_; 229 : WebViewServicesManager webviewsm_; 230 : PreferenceServicesManager preferencesm_; 231 : }; 232 : } // namespace jami