Ring Daemon 16.0.0
Loading...
Searching...
No Matches
conversationrepository.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 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 <optional>
20#include <git2.h>
21#include <memory>
22#include <opendht/default_types.h>
23#include <string>
24#include <vector>
25
26#include "def.h"
27
28using GitPackBuilder = std::unique_ptr<git_packbuilder, decltype(&git_packbuilder_free)>;
29using GitRepository = std::unique_ptr<git_repository, decltype(&git_repository_free)>;
30using GitRevWalker = std::unique_ptr<git_revwalk, decltype(&git_revwalk_free)>;
31using GitCommit = std::unique_ptr<git_commit, decltype(&git_commit_free)>;
33 = std::unique_ptr<git_annotated_commit, decltype(&git_annotated_commit_free)>;
34using GitIndex = std::unique_ptr<git_index, decltype(&git_index_free)>;
35using GitTree = std::unique_ptr<git_tree, decltype(&git_tree_free)>;
36using GitRemote = std::unique_ptr<git_remote, decltype(&git_remote_free)>;
37using GitReference = std::unique_ptr<git_reference, decltype(&git_reference_free)>;
38using GitSignature = std::unique_ptr<git_signature, decltype(&git_signature_free)>;
39using GitObject = std::unique_ptr<git_object, decltype(&git_object_free)>;
40using GitDiff = std::unique_ptr<git_diff, decltype(&git_diff_free)>;
41using GitDiffStats = std::unique_ptr<git_diff_stats, decltype(&git_diff_stats_free)>;
43 = std::unique_ptr<git_index_conflict_iterator, decltype(&git_index_conflict_iterator_free)>;
44
45namespace jami {
46
47using DeviceId = dht::PkId;
48
49constexpr auto EFETCH = 1;
50constexpr auto EINVALIDMODE = 2;
51constexpr auto EVALIDFETCH = 3;
52constexpr auto EUNAUTHORIZED = 4;
53constexpr auto ECOMMIT = 5;
54
55class JamiAccount;
56
58{
59 std::string from {};
60 std::string to {};
61 uint64_t nbOfCommits {0}; // maximum number of commits wanted
62 bool skipMerge {false}; // Do not include merge commits in the log. Used by the module to get
63 // last interaction without potential merges
64 bool includeTo {false}; // If we want or not the "to" commit [from-to] or [from-to)
65 bool fastLog {false}; // Do not parse content, used mostly to count
66 bool logIfNotFound {true}; // Add a warning in the log if commit is not found
67
68 std::string authorUri {}; // filter commits from author
69};
70
71struct Filter
72{
73 std::string author;
74 std::string lastId;
75 std::string regexSearch;
76 std::string type;
80 bool caseSensitive {false};
81};
82
84{
85 std::string name {};
86 std::string email {};
87};
88
90
92{
93 std::string id {};
94 std::vector<std::string> parents {};
96 std::vector<uint8_t> signed_content {};
97 std::vector<uint8_t> signature {};
98 std::string commit_msg {};
99 std::string linearized_parent {};
101};
102
103enum class MemberRole { ADMIN = 0, MEMBER, INVITED, BANNED, LEFT };
104
106{
107 std::string uri;
109
110 std::map<std::string, std::string> map() const
111 {
112 std::string rolestr;
113 if (role == MemberRole::ADMIN) {
114 rolestr = "admin";
115 } else if (role == MemberRole::MEMBER) {
116 rolestr = "member";
117 } else if (role == MemberRole::INVITED) {
118 rolestr = "invited";
119 } else if (role == MemberRole::BANNED) {
120 rolestr = "banned";
121 } else if (role == MemberRole::LEFT) {
122 rolestr = "left"; // For one to one
123 }
124
125 return {{"uri", uri}, {"role", rolestr}};
126 }
128};
129
130enum class CallbackResult { Skip, Break, Ok };
131
133 = std::function<CallbackResult(const std::string&, const GitAuthor&, const GitCommit&)>;
135 = std::function<bool(const std::string&, const GitAuthor&, ConversationCommit&)>;
136using OnMembersChanged = std::function<void(const std::set<std::string>&)>;
137
142{
143public:
144 #ifdef LIBJAMI_TEST
145 static bool DISABLE_RESET; // Some tests inject bad files so resetHard() will break the test
146 #endif
154 static LIBJAMI_TEST_EXPORT std::unique_ptr<ConversationRepository> createConversation(
155 const std::shared_ptr<JamiAccount>& account,
156 ConversationMode mode = ConversationMode::INVITES_ONLY,
157 const std::string& otherMember = "");
158
167 static LIBJAMI_TEST_EXPORT std::unique_ptr<ConversationRepository> cloneConversation(
168 const std::shared_ptr<JamiAccount>& account,
169 const std::string& deviceId,
170 const std::string& conversationId,
171 std::function<void(std::vector<ConversationCommit>)>&& checkCommitCb = {});
172
178 ConversationRepository(const std::shared_ptr<JamiAccount>& account, const std::string& id);
180
186 std::string addMember(const std::string& uri);
187
195 bool fetch(const std::string& remoteDeviceId);
196
203 std::string remoteHead(const std::string& remoteDeviceId,
204 const std::string& branch = "main") const;
205
209 const std::string& id() const;
210
217 std::string commitMessage(const std::string& msg, bool verifyDevice = true);
218
219 std::vector<std::string> commitMessages(const std::vector<std::string>& msgs);
220
227 std::string amend(const std::string& id, const std::string& msg);
228
233 std::vector<ConversationCommit> log(const LogOptions& options = {}) const;
234 void log(PreConditionCb&& preCondition,
235 std::function<void(ConversationCommit&&)>&& emplaceCb,
236 PostConditionCb&& postCondition,
237 const std::string& from = "",
238 bool logIfNotFound = true) const;
239 std::optional<ConversationCommit> getCommit(const std::string& commitId,
240 bool logIfNotFound = true) const;
241
246 std::optional<std::string> linearizedParent(const std::string& commitId) const;
247
255 std::pair<bool, std::string> merge(const std::string& merge_id, bool force = false);
256
263 std::string mergeBase(const std::string& from, const std::string& to) const;
264
272 std::string diffStats(const std::string& newId, const std::string& oldId = "") const;
273
279 static std::vector<std::string> changedFiles(std::string_view diffStats);
280
285 std::string join();
286
291 std::string leave();
292
296 void erase();
297
302 ConversationMode mode() const;
303
316 std::string voteKick(const std::string& uri, const std::string& type);
323 std::string voteUnban(const std::string& uri, const std::string_view type);
331 std::string resolveVote(const std::string& uri,
332 const std::string_view type,
333 const std::string& voteType);
334
340 std::pair<std::vector<ConversationCommit>, bool> validFetch(
341 const std::string& remoteDevice) const;
342 bool validClone(std::function<void(std::vector<ConversationCommit>)>&& checkCommitCb) const;
343
348 void removeBranchWith(const std::string& remoteDevice);
349
354 std::vector<std::string> getInitialMembers() const;
355
360 std::vector<ConversationMember> members() const;
361
367 std::map<std::string, std::vector<DeviceId>> devices(bool ignoreExpired = true) const;
368
374 std::set<std::string> memberUris(std::string_view filter,
375 const std::set<MemberRole>& filteredRoles) const;
376
380 void refreshMembers() const;
381
382 void onMembersChanged(OnMembersChanged&& cb);
383
389 void pinCertificates(bool blocking = false);
396 std::string uriFromDevice(const std::string& deviceId) const;
397
403 std::string updateInfos(const std::map<std::string, std::string>& map);
404
409 std::map<std::string, std::string> infos() const;
410 static std::map<std::string, std::string> infosFromVCard(
411 std::map<std::string, std::string>&& details);
412
416 std::vector<std::map<std::string, std::string>> convCommitsToMap(
417 const std::vector<ConversationCommit>& commits) const;
418 std::optional<std::map<std::string, std::string>> convCommitToMap(
419 const ConversationCommit& commit) const;
420
424 std::string getHead() const;
425
426private:
427 ConversationRepository() = delete;
428 class Impl;
429 std::unique_ptr<Impl> pimpl_;
430};
431
432} // namespace jami
This class gives access to the git repository that represents the conversation.
std::optional< std::string > linearizedParent(const std::string &commitId) const
Get parent via topological + date sort in branch main of a commit.
Ring Account is build on top of SIPAccountBase and uses DHT to handle call connectivity.
Definition jamiaccount.h:96
std::unique_ptr< git_object, decltype(&git_object_free)> GitObject
std::unique_ptr< git_commit, decltype(&git_commit_free)> GitCommit
std::unique_ptr< git_index_conflict_iterator, decltype(&git_index_conflict_iterator_free)> GitIndexConflictIterator
std::unique_ptr< git_repository, decltype(&git_repository_free)> GitRepository
std::unique_ptr< git_index, decltype(&git_index_free)> GitIndex
std::unique_ptr< git_signature, decltype(&git_signature_free)> GitSignature
std::unique_ptr< git_diff_stats, decltype(&git_diff_stats_free)> GitDiffStats
std::unique_ptr< git_packbuilder, decltype(&git_packbuilder_free)> GitPackBuilder
std::unique_ptr< git_revwalk, decltype(&git_revwalk_free)> GitRevWalker
std::unique_ptr< git_remote, decltype(&git_remote_free)> GitRemote
std::unique_ptr< git_tree, decltype(&git_tree_free)> GitTree
std::unique_ptr< git_reference, decltype(&git_reference_free)> GitReference
std::unique_ptr< git_diff, decltype(&git_diff_free)> GitDiff
std::unique_ptr< git_annotated_commit, decltype(&git_annotated_commit_free)> GitAnnotatedCommit
MSGPACK_ADD_ENUM(jami::MemberRole)
#define LIBJAMI_TEST_EXPORT
Definition def.h:49
dht::PkId DeviceId
void emitSignal(Args... args)
Definition ring_signal.h:64
constexpr auto ECOMMIT
std::function< bool(const std::string &, const GitAuthor &, ConversationCommit &)> PostConditionCb
constexpr auto EINVALIDMODE
constexpr auto EVALIDFETCH
constexpr auto EUNAUTHORIZED
std::function< CallbackResult(const std::string &, const GitAuthor &, const GitCommit &)> PreConditionCb
constexpr auto EFETCH
std::function< void(const std::set< std::string > &)> OnMembersChanged
std::vector< uint8_t > signed_content
std::vector< std::string > parents
std::vector< uint8_t > signature
std::map< std::string, std::string > map() const