Ring Daemon 16.0.0
Loading...
Searching...
No Matches
contact_list.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 "jami_contact.h"
20
21#include <dhtnet/certstore.h>
22#include <opendht/infohash.h>
23#include <opendht/crypto.h>
24
25#include <map>
26#include <mutex>
27#include <chrono>
28
29namespace jami {
30
32{
33public:
34 using clock = std::chrono::system_clock;
35 using time_point = clock::time_point;
36 using VerifyResult = dht::crypto::TrustList::VerifyResult;
37
38 using OnContactAdded = std::function<void(const std::string&, bool)>;
39 using OnContactRemoved = std::function<void(const std::string&, bool)>;
40 using OnIncomingTrustRequest = std::function<
41 void(const std::string&, const std::string&, const std::vector<uint8_t>&, time_t)>;
42 using OnAcceptConversation = std::function<void(const std::string&, const std::string&)>;
43 using OnConfirmation = std::function<void(const std::string&, const std::string&)>;
44 using OnDevicesChanged = std::function<void(const std::map<dht::PkId, KnownDevice>&)>;
45
55
56 ContactList(const std::string& accountId,
57 const std::shared_ptr<crypto::Certificate>& cert,
58 const std::filesystem::path& path,
61
62 const std::string& accountId() const { return accountId_; }
63
64 void load();
65 void save();
66
67 /* Contacts */
68 std::map<std::string, std::string> getContactDetails(const dht::InfoHash&) const;
69 std::optional<Contact> getContactInfo(const dht::InfoHash&) const;
70
71 bool removeContact(const dht::InfoHash&, bool ban);
72 bool removeContactConversation(const dht::InfoHash&);
73 bool addContact(const dht::InfoHash&,
74 bool confirmed = false,
75 const std::string& conversationId = "");
76 void updateConversation(const dht::InfoHash& h, const std::string& conversationId);
77
78 bool setCertificateStatus(const std::string& cert_id,
79 const dhtnet::tls::TrustStore::PermissionStatus status);
80
81 bool setCertificateStatus(const std::shared_ptr<crypto::Certificate>& cert,
82 dhtnet::tls::TrustStore::PermissionStatus status,
83 bool local = true);
84
85 dhtnet::tls::TrustStore::PermissionStatus getCertificateStatus(const std::string& cert_id) const
86 {
87 return trust_->getCertificateStatus(cert_id);
88 }
89
90 std::vector<std::string> getCertificatesByStatus(dhtnet::tls::TrustStore::PermissionStatus status) const
91 {
92 return trust_->getCertificatesByStatus(status);
93 }
94
95 bool isAllowed(const crypto::Certificate& crt, bool allowPublic)
96 {
97 return trust_->isAllowed(crt, allowPublic);
98 }
99
100 VerifyResult isValidAccountDevice(const crypto::Certificate& crt) const
101 {
102 return accountTrust_.verify(crt);
103 }
104
105 const std::map<dht::InfoHash, Contact>& getContacts() const;
106 void setContacts(const std::map<dht::InfoHash, Contact>&);
107 void updateContact(const dht::InfoHash&, const Contact&, bool emit = true);
108
110 void saveContacts() const;
111
112 const std::filesystem::path& path() const { return path_; }
113
114 /* Contact requests */
115
118 bool onTrustRequest(const dht::InfoHash& peer_account,
119 const std::shared_ptr<dht::crypto::PublicKey>& peer_device,
120 time_t received,
121 bool confirm,
122 const std::string& conversationId,
123 std::vector<uint8_t>&& payload);
124 std::vector<std::map<std::string, std::string>> getTrustRequests() const;
125 std::map<std::string, std::string> getTrustRequest(const dht::InfoHash& from) const;
126 void acceptConversation(const std::string& convId, const std::string& deviceId = ""); // ToDO this is a bit dirty imho
127 bool acceptTrustRequest(const dht::InfoHash& from);
128 bool discardTrustRequest(const dht::InfoHash& from);
129
130 /* Devices */
131 const std::map<dht::PkId, KnownDevice>& getKnownDevices() const { return knownDevices_; }
132 void foundAccountDevice(const dht::PkId& device,
133 const std::string& name = {},
134 const time_point& last_sync = time_point::min());
135 bool foundAccountDevice(const std::shared_ptr<dht::crypto::Certificate>& crt,
136 const std::string& name = {},
137 const time_point& last_sync = time_point::min(),
138 bool notify = true);
139 bool removeAccountDevice(const dht::PkId& device);
140 void setAccountDeviceName(const dht::PkId& device, const std::string& name);
141 std::string getAccountDeviceName(const dht::PkId& device) const;
142
143 DeviceSync getSyncData() const;
144 bool syncDevice(const dht::PkId& device, const time_point& syncDate);
145
146private:
147 const std::string accountId_;
148 const std::filesystem::path path_;
149 mutable std::mutex mutex_;
150 std::map<dht::InfoHash, Contact> contacts_;
151 std::map<dht::InfoHash, TrustRequest> trustRequests_;
152 std::map<dht::InfoHash, KnownDevice> knownDevicesLegacy_;
153
154 std::map<dht::PkId, KnownDevice> knownDevices_;
155
156 // Trust store with account main certificate as the only CA
157 dht::crypto::TrustList accountTrust_;
158 // Trust store for to match peer certificates
159 std::unique_ptr<dhtnet::tls::TrustStore> trust_;
160 std::string accountUri_;
161
162 OnChangeCallback callbacks_;
163
164 void loadContacts();
165 void loadTrustRequests();
166
167 void loadKnownDevices();
168 void saveKnownDevices() const;
169
171 void saveTrustRequests() const;
172};
173
174} // namespace jami
const std::string & accountId() const
std::function< void(const std::string &, bool)> OnContactRemoved
bool removeAccountDevice(const dht::PkId &device)
std::function< void(const std::string &, const std::string &, const std::vector< uint8_t > &, time_t)> OnIncomingTrustRequest
std::vector< std::map< std::string, std::string > > getTrustRequests() const
void foundAccountDevice(const dht::PkId &device, const std::string &name={}, const time_point &last_sync=time_point::min())
bool removeContactConversation(const dht::InfoHash &)
bool addContact(const dht::InfoHash &, bool confirmed=false, const std::string &conversationId="")
std::function< void(const std::string &, bool)> OnContactAdded
clock::time_point time_point
void setContacts(const std::map< dht::InfoHash, Contact > &)
const std::filesystem::path & path() const
void saveContacts() const
Should be called only after updateContact.
bool onTrustRequest(const dht::InfoHash &peer_account, const std::shared_ptr< dht::crypto::PublicKey > &peer_device, time_t received, bool confirm, const std::string &conversationId, std::vector< uint8_t > &&payload)
Inform of a new contact request.
std::string getAccountDeviceName(const dht::PkId &device) const
VerifyResult isValidAccountDevice(const crypto::Certificate &crt) const
std::chrono::system_clock clock
DeviceSync getSyncData() const
void setAccountDeviceName(const dht::PkId &device, const std::string &name)
bool acceptTrustRequest(const dht::InfoHash &from)
bool discardTrustRequest(const dht::InfoHash &from)
std::map< std::string, std::string > getContactDetails(const dht::InfoHash &) const
void updateConversation(const dht::InfoHash &h, const std::string &conversationId)
void updateContact(const dht::InfoHash &, const Contact &, bool emit=true)
bool setCertificateStatus(const std::string &cert_id, const dhtnet::tls::TrustStore::PermissionStatus status)
dhtnet::tls::TrustStore::PermissionStatus getCertificateStatus(const std::string &cert_id) const
std::function< void(const std::map< dht::PkId, KnownDevice > &)> OnDevicesChanged
bool syncDevice(const dht::PkId &device, const time_point &syncDate)
const std::map< dht::PkId, KnownDevice > & getKnownDevices() const
std::optional< Contact > getContactInfo(const dht::InfoHash &) const
const std::map< dht::InfoHash, Contact > & getContacts() const
std::function< void(const std::string &, const std::string &)> OnAcceptConversation
void acceptConversation(const std::string &convId, const std::string &deviceId="")
std::map< std::string, std::string > getTrustRequest(const dht::InfoHash &from) const
dht::crypto::TrustList::VerifyResult VerifyResult
std::function< void(const std::string &, const std::string &)> OnConfirmation
std::vector< std::string > getCertificatesByStatus(dhtnet::tls::TrustStore::PermissionStatus status) const
bool isAllowed(const crypto::Certificate &crt, bool allowPublic)
bool removeContact(const dht::InfoHash &, bool ban)
void emitSignal(Args... args)
Definition ring_signal.h:64
OnIncomingTrustRequest trustRequest
OnAcceptConversation acceptConversation