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