Skip to content
Snippets Groups Projects
Commit dcacf40e authored by Sébastien Blin's avatar Sébastien Blin
Browse files

swarm: add onConversationError()

This new API gives a feedback to clients to know when an error
occurs while interacting with conversations or retrieving new
messages. For now, it's more for debugging purpose, but can
be used for admins to know if somebody is trying to do bad commits

Change-Id: I1ec797a51bdc5880d0d116b53faf5c7e13af1e8b
GitLab: #373
parent 5b10c871
Branches
No related tags found
No related merge requests found
......@@ -1956,6 +1956,33 @@
</arg>
</signal>
<signal name="onConversationError" tp:name-for-bindings="onConversationError">
<tp:added version="10.0.0"/>
<tp:docstring>
Notify clients when an error occurs in a conversation
</tp:docstring>
<arg type="s" name="account_id">
<tp:docstring>
Account id related
</tp:docstring>
</arg>
<arg type="s" name="conversation_id">
<tp:docstring>
Conversation id
</tp:docstring>
</arg>
<arg type="u" name="code">
<tp:docstring>
TODO
</tp:docstring>
</arg>
<arg type="s" name="what">
<tp:docstring>
The error's description
</tp:docstring>
</arg>
</signal>
<signal name="debugMessageReceived" tp:name-for-bindings="debugMessageReceived">
<tp:added version="5.2.0"/>
<tp:docstring>
......
......@@ -305,6 +305,8 @@ DBusClient::initLibrary(int flags)
bind(&DBusConfigurationManager::conversationRemoved, confM, _1, _2)),
exportable_callback<ConversationSignal::ConversationMemberEvent>(
bind(&DBusConfigurationManager::conversationMemberEvent, confM, _1, _2, _3, _4)),
exportable_callback<ConversationSignal::OnConversationError>(
bind(&DBusConfigurationManager::onConversationError, confM, _1, _2, _3, _4)),
};
#ifdef ENABLE_VIDEO
......
......@@ -31,6 +31,7 @@ public:
virtual void conversationReady(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationRemoved(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationMemberEvent(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* memberUri */, int /* event */){}
virtual void onConversationError(const std::string& /*accountId*/, const std::string& /* conversationId */, uint32_t /* code */, const std::string& /* what */){}
};
%}
......@@ -66,4 +67,5 @@ public:
virtual void conversationReady(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationRemoved(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationMemberEvent(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* memberUri */, int /* event */){}
virtual void onConversationError(const std::string& /*accountId*/, const std::string& /* conversationId */, uint32_t /* code */, const std::string& /* what */){}
};
\ No newline at end of file
......@@ -320,7 +320,8 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM
exportable_callback<ConversationSignal::ConversationRequestReceived>(bind(&ConversationCallback::conversationRequestReceived, convM, _1, _2, _3)),
exportable_callback<ConversationSignal::ConversationReady>(bind(&ConversationCallback::conversationReady, convM, _1, _2)),
exportable_callback<ConversationSignal::ConversationRemoved>(bind(&ConversationCallback::conversationRemoved, convM, _1, _2)),
exportable_callback<ConversationSignal::ConversationMemberEvent>(bind(&ConversationCallback::conversationMemberEvent, convM, _1, _2, _3, _4))
exportable_callback<ConversationSignal::ConversationMemberEvent>(bind(&ConversationCallback::conversationMemberEvent, convM, _1, _2, _3, _4)),
exportable_callback<ConversationSignal::OnConversationError>(bind(&ConversationCallback::onConversationError, convM, _1, _2, _3, _4))
};
if (!DRing::init(static_cast<DRing::InitFlag>(DRing::DRING_FLAG_DEBUG)))
......
......@@ -31,6 +31,7 @@ public:
virtual void conversationReady(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationRemoved(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationMemberEvent(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* memberUri */, int /* event */){}
virtual void onConversationError(const std::string& /*accountId*/, const std::string& /* conversationId */, uint32_t /* code */, const std::string& /* what */){}
};
%}
......@@ -79,4 +80,5 @@ public:
virtual void conversationReady(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationRemoved(const std::string& /*accountId*/, const std::string& /* conversationId */){}
virtual void conversationMemberEvent(const std::string& /*accountId*/, const std::string& /* conversationId */, const std::string& /* memberUri */, int /* event */){}
virtual void onConversationError(const std::string& /*accountId*/, const std::string& /* conversationId */, uint32_t /* code */, const std::string& /* what */){}
};
\ No newline at end of file
......@@ -132,6 +132,7 @@ getSignalHandlers()
exported_callback<DRing::ConversationSignal::ConversationReady>(),
exported_callback<DRing::ConversationSignal::ConversationRemoved>(),
exported_callback<DRing::ConversationSignal::ConversationMemberEvent>(),
exported_callback<DRing::ConversationSignal::OnConversationError>(),
};
return handlers;
......
......@@ -107,6 +107,14 @@ struct DRING_PUBLIC ConversationSignal
const std::string& /* memberUri */,
int /* event 0 = add, 1 = joins, 2 = leave, 3 = banned */);
};
struct DRING_PUBLIC OnConversationError
{
constexpr static const char* name = "OnConversationError";
using cb_type = void(const std::string& /*accountId*/,
const std::string& /* conversationId */,
int code,
const std::string& what);
};
};
} // namespace DRing
......
......@@ -63,6 +63,10 @@ public:
remoteDevice,
conversationId);
if (!repository_) {
if (auto shared = account.lock()) {
emitSignal<DRing::ConversationSignal::OnConversationError>(
shared->getAccountID(), conversationId, EFETCH, "Couldn't clone repository");
}
throw std::logic_error("Couldn't clone repository");
}
}
......@@ -97,12 +101,7 @@ Conversation::Impl::isAdmin() const
auto adminsPath = repoPath() + DIR_SEPARATOR_STR + "admins";
auto cert = shared->identity().second;
auto parentCert = cert->issuer;
if (!parentCert) {
JAMI_ERR("Parent cert is null!");
return false;
}
auto uri = parentCert->getId().toString();
auto uri = cert->getIssuerUID();
return fileutils::isFile(fileutils::getFullPath(adminsPath, uri + ".crt"));
}
......@@ -123,10 +122,24 @@ Conversation::Impl::convCommitToMap(const std::vector<ConversationCommit>& commi
for (const auto& commit : commits) {
auto authorDevice = commit.author.email;
auto cert = tls::CertificateStore::instance().getCertificate(authorDevice);
if (!cert && cert->issuer) {
JAMI_WARN("No author found for commit %s", commit.id.c_str());
if (!cert) {
JAMI_WARN("No author found for commit %s, reload certificates", commit.id.c_str());
if (repository_)
repository_->pinCertificates();
// Get certificate from repo
try {
auto certPath = fileutils::getFullPath(repoPath(), std::string("devices") + DIR_SEPARATOR_STR + authorDevice + ".crt");
auto deviceCert = fileutils::loadTextFile(certPath);
cert = std::make_shared<crypto::Certificate>(deviceCert);
if (!cert) {
JAMI_ERR("No author found for commit %s", commit.id.c_str());
continue;
}
} catch (...) {
continue;
}
}
auto authorId = cert->issuer->getId().toString();
auto authorId = cert->getIssuerUID();
std::string parents;
auto parentsSize = commit.parents.size();
for (std::size_t i = 0; i < parentsSize; ++i) {
......@@ -522,15 +535,6 @@ Conversation::generateInvitation() const
std::map<std::string, std::string> invite;
Json::Value root;
root["conversationId"] = id();
// TODO remove, cause the peer cannot trust?
// Or add signatures?
for (const auto& member : getMembers()) {
Json::Value jsonMember;
for (const auto& [key, value] : member) {
jsonMember[key] = value;
}
root["members"].append(jsonMember);
}
// TODO metadatas
Json::StreamWriterBuilder wbuilder;
wbuilder["commentStyle"] = "None";
......
This diff is collapsed.
......@@ -45,6 +45,10 @@ using GitIndexConflictIterator
namespace jami {
constexpr auto EFETCH = 1;
constexpr auto EINVALIDMODE = 2;
constexpr auto EVALIDFETCH = 3;
class JamiAccount;
class ChannelSocket;
......@@ -255,6 +259,13 @@ public:
*/
void refreshMembers() const;
/**
* Because conversations can contains non contacts certificates, this methods
* loads certificates in conversations into the cert store
*/
void pinCertificates();
private:
ConversationRepository() = delete;
class Impl;
......
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment