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:

  1. CA (auto-assinada se gerada localmente ou por uma empresa)

  2. Conta (onde a impressão digital da chave pública é designada por “Jami ID”)

  3. 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:

  1. A chave privada ringAccountKey e a cadeia de certificados ringAccountCert (base64 codificada)

  2. Geração de chave CA (para certificados autônomos) ringCAKey

  3. Dispositivos revogados ringAccountCRL

  4. A chave privada do ethereum ethKey para o dispositivo. Ela só é usada quando você registra seu nome em ns.jami.net. Não é obrigatório.

  5. Os contatos

  6. 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>