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 1608 : CallServicesManager& getCallServicesManager() { return callsm_; }
201 :
202 2062 : 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
|