Gestion du compte
Dans cette partie, nous allons apprendre à gérer un compte Jami. En d’autres termes, comment créer un compte Jami, modifier les paramètres de base et supprimer le compte. Cette partie n’expliquera PAS ce que signifient tous les paramètres ou comment utiliser le compte pour effectuer une action telle que l’ajout d’un contact.
What is an account
In Jami, an account is a X509 certificate chain generally containing 3 certificates:
CA (Self-Signed if locally generated or a company)
Account (Where the fingerprint of the public key is called the « Jami ID »)
Appareil
This allow a company to revoke an account if needed and an account to revoke a device (if one get stolen for example).
Création d’un nouveau compte
Le côté du Daemon
API
Dans cx.ring.Ring.ConfigurationManager:
<method name="addAccount" tp:name-for-bindings="addAccount">
<tp:docstring>
Add a new account. When created, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure.
<tp:rationale>If no details are specified, the default parameters are used.</tp:rationale>
<tp:rationale>The core tries to register the account as soon it is created.</tp:rationale>
</tp:docstring>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="MapStringString"/>
<arg type="a{ss}" name="details" direction="in" tp:type="String_String_Map">
<tp:docstring>
The new account settings
</tp:docstring>
</arg>
<arg type="s" name="createdAccountId" direction="out">
<tp:docstring>
A new account ID
</tp:docstring>
</arg>
</method>
The details can be retrieved from the method getAccountTemplate(type)
with type=JAMI
or type=SIP
. For example, this is the following code used in LRC.
std::string
NewAccountModel::createNewAccount(profile::Type type,
const std::string& displayName,
const std::string& archivePath,
const std::string& password,
const std::string& pin)
{
MapStringString details = type == profile::Type::SIP?
ConfigurationManager::instance().getAccountTemplate("SIP") :
ConfigurationManager::instance().getAccountTemplate("JAMI");
using namespace libjami::Account;
details[ConfProperties::TYPE] = type == profile::Type::SIP? "SIP" : "JAMI";
details[ConfProperties::DISPLAYNAME] = displayName.c_str();
details[ConfProperties::ALIAS] = displayName.c_str();
details[ConfProperties::UPNP_ENABLED] = "true";
details[ConfProperties::ARCHIVE_PASSWORD] = password.c_str();
details[ConfProperties::ARCHIVE_PIN] = pin.c_str();
details[ConfProperties::ARCHIVE_PATH] = archivePath.c_str();
QString accountId = ConfigurationManager::instance().addAccount(details);
return accountId.toStdString();
}
Lorsqu’un nouveau compte est ajouté, le signal accountsChanged
sera émis. Lors de la réception de ce signal, le client doit mettre à jour sa structure interne avec d’autres méthodes dans ConfigurationManager.
Noyau
La logique principale pour créer un nouveau compte se trouve dans src/ringdht/ringaccount.cpp
, dans RingAccount::createAccount
Comment cela fonctionne, depuis le début.
Un compte Jami est en fait représenté par des fichiers stockés dans une archive gzip. Si un mot de passe est fourni lors de la création du compte, l’archive sera cryptée comme suit : dht::crypto::aesEncrypt(archive, password)
(dht::crypto::aesEncrypt
est défini dans OpenDHT et utilise nettle/{aes,gcm}
). C’est ce que l’archive contiendra dans un gros fichier JSON :
La clé privée
ringAccountKey
et la chaîne de certificatsringAccountCert
(code de base 64)Clé CA générée (pour les certificats auto-signés)
ringCAKey
Appareils révoqués
ringAccountCRL
La clé privée ethereum
ethKey
pour l’appareil. Elle n’est utilisée que lorsque vous enregistrez votre nom surns.jami.net
. Ce n’est pas obligatoire.Les contacts
Les paramètres du compte
Alors générons-le !
A FAIRE
Supprimer le compte
La suppression d’un compte Jami est très simple. Comme les clés ne se trouvent que sur l’appareil, si les clés sont supprimées… le compte est supprimé ! La seule chose en dehors de l’appareil est le nom d’utilisateur, sur le serveur de noms. Pour supprimer cette information, cela dépend du fonctionnement du serveur de noms. Par exemple, ce n’est pas possible avec https://ns.jami.net
Le côté du Daemon
API
Dans cx.ring.Ring.ConfigurationManager:
<method name="removeAccount" tp:name-for-bindings="removeAccount">
<tp:docstring>
Remove an existing account. When removed, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure.
</tp:docstring>
<arg type="s" name="accoundID" direction="in">
<tp:docstring>
The account to remove, identified by its ID
</tp:docstring>
</arg>
</method>
Lorsque le compte est supprimé, le signal accountsChanged
sera émis. Lors de la réception du signal, le client doit mettre à jour sa structure interne avec d’autres méthodes dans ConfigurationManager.
Noyau
La logique principale pour créer un nouveau compte se trouve dans src/manager.cpp
, dans Manager::removeAccount
. Il supprime les fichiers des comptes et met à jour la configuration (dring.yml
).
Mettre à jour les détails d’un compte
API
Dans cx.ring.Ring.ConfigurationManager:
<method name="setAccountDetails" tp:name-for-bindings="setAccountDetails">
<tp:docstring>
Send new account parameters, or account parameters changes, to the core. The hash table is not required to be complete, only the updated parameters may be specified.
<tp:rationale>Account settings are written to the configuration file when the app properly quits.</tp:rationale>
<tp:rationale>After calling this method, the core will emit the signal <tp:member-ref>accountDetailsChanged</tp:member-ref> with the updated data. The client must subscribe to this signal and use it to update its internal data structure.</tp:rationale>
</tp:docstring>
<arg type="s" name="accountID" direction="in">
</arg>
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="MapStringString"/>
<arg type="a{ss}" name="details" direction="in" tp:type="String_String_Map">
</arg>
</method>
La carte peut contenir une mise à jour partielle et accountDetailsChanged
sera émis en cas de succès. getAccountDetails
Ajouter un appareil
Il y a deux possibilités pour ajouter un appareil.
Sauvegarde de l’archive (puis importation à partir de la sauvegarde)
API
Dans cx.ring.Ring.ConfigurationManager:
<method name="exportToFile" tp:name-for-bindings="exportToFile">
<tp:added version="5.1.0"/>
<tp:docstring>
Copy the account archive to the path provided in argument.
</tp:docstring>
<arg type="s" name="accountID" direction="in">
</arg>
<arg type="s" name="destinationPath" direction="in">
</arg>
<arg type="s" name="password" direction="in">
</arg>
<arg type="b" name="success" direction="out">
<tp:docstring>
True if the operation was initialized successfully.
</tp:docstring>
</arg>
</method>
Exportation sur la DHT
API
Dans cx.ring.Ring.ConfigurationManager:
<method name="exportOnRing" tp:name-for-bindings="exportOnRing">
<tp:docstring>
Export account on the DHT using the given password and generated PIN (returned through exportOnRingEnded signal).
</tp:docstring>
<arg type="s" name="accountID" direction="in">
</arg>
<arg type="s" name="password" direction="in">
</arg>
<arg type="b" name="success" direction="out">
<tp:docstring>
True if the operation was initialized successfully. exportOnRingEnded will be trigered on completion.
</tp:docstring>
</arg>
</method>
Ensuite, le message exportOnRingEnded
est émis.
Révoquer l’appareil
API
<method name="revokeDevice" tp:name-for-bindings="revokeDevice">
<tp:docstring>
Revoke device attached to the given Jami account, and publish the new revocation list.
</tp:docstring>
<arg type="s" name="accountID" direction="in">
</arg>
<arg type="s" name="password" direction="in">
</arg>
<arg type="s" name="deviceId" direction="in">
</arg>
<arg type="b" name="success" direction="out">
<tp:docstring>
True if the operation was performed successfully.
</tp:docstring>
</arg>
</method>
<signal name="deviceRevocationEnded" tp:name-for-bindings="deviceRevocationEnded">
<tp:docstring>
Notify clients when the revokeDevice operation ended.
</tp:docstring>
<arg type="s" name="accountID">
</arg>
<arg type="s" name="deviceId">
</arg>
<arg type="i" name="status">
<tp:docstring>
Status code: 0 for success
<ul>
<li>SUCCESS = 0 everything went fine. Device is now revoked.</li>
<li>WRONG_PASSWORD = 1 revocation failed: wrong password.</li>
<li>UNKNOWN_DEVICE = 2 revocation failed: unknown device.</li>
</ul>
</tp:docstring>
</arg>
</signal>