Gestão de contas
Nesta parte, aprenderemos a gerenciar uma conta Jami. Isso significa como criar uma conta Jami, modificar as configurações básicas e excluir a conta. Esta parte NÃO explicará o significado de todas as configurações ou como podemos usar a conta para realizar qualquer ação, como adicionar um contato.
O que é uma conta
No Jami, uma conta é uma cadeia de certificados X509 que contém geralmente 3 certificados:
CA (auto-assinada se gerada localmente ou por uma empresa)
Conta (onde a impressão digital da chave pública é designada por “Jami ID”)
Dispositivo
Isto permite a uma empresa revogar uma conta, se necessário, e a uma conta revogar um dispositivo (se um for roubado, por exemplo).
Criar uma nova conta
Lado da demônio
API
Em 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>
Os detalhes podem ser recuperados a partir do método getAccountTemplate(type)
com type=JAMI
ou type=SIP
. Por exemplo, este é o seguinte código utilizado no 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();
}
Quando uma nova conta for adicionada, o sinal accountsChanged
será emitido. O cliente deve atualizar sua estrutura interna após esse sinal com outros métodos no ConfigurationManager.
Núcleo
A lógica principal para criar uma nova conta encontra-se em src/ringdht/ringaccount.cpp
, em RingAccount::createAccount
Como funciona, a partir do zero
Uma conta Jami é, na verdade, representada por alguns arquivos armazenados em um arquivo gzip. Se uma senha for fornecida durante a criação da conta, o arquivo será criptografado da seguinte forma: dht::crypto::aesEncrypt(archive, password)
(dht::crypto::aesEncrypt
é definido no OpenDHT e utiliza nettle/{aes,gcm}
). É com isso que o arquivo conterá um grande arquivo JSON:
A chave privada
ringAccountKey
e a cadeia de certificadosringAccountCert
(base64 codificada)Geração de chave CA (para certificados autônomos)
ringCAKey
Dispositivos revogados
ringAccountCRL
A chave privada do ethereum
ethKey
para o dispositivo. Ela só é usada quando você registra seu nome emns.jami.net
. Não é obrigatório.Os contatos
Configurações da conta
Então vamos gerá-lo!
PARA FAZER
Excluir a conta
A exclusão de uma conta Jami é muito simples. Como as chaves estão apenas no dispositivo, se as chaves forem excluídas… a conta será excluída! A única coisa fora do dispositivo é o nome de usuário, no servidor de nomes. Para remover essas informações, depende de como o servidor de nomes funciona. Por exemplo, isso não é possível com https://ns.jami.net
Lado da demônio
API
Em 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>
Quando a conta for excluída, o sinal accountsChanged
será emitido. O cliente deve atualizar sua estrutura interna após esse sinal com outros métodos no ConfigurationManager.
Núcleo
A lógica principal para criar uma nova conta está localizada em src/manager.cpp
, em Manager::removeAccount
. Ele remove os arquivos de contas e atualiza a configuração (dring.yml
).
Atualizar os detalhes de uma conta
API
Em 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>
O mapa pode conter uma atualização parcial e accountDetailsChanged
será emitido em caso de sucesso. getAccountDetails
Adicionar dispositivo
Existem duas possibilidades para adicionar um dispositivo.
Arquivo de cópia de segurança (depois importar da cópia de segurança)
API
Em 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>
Exportar em DHT
API
Em 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>
Em seguida, é emitida exportOnRingEnded
.
Revogar dispositivo
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>