QtPass Developer documentation
QtPass test coverage
Current view: top level - src/profileinit.h Coverage Total Hit
Test: QtPass Lines: 100.0 % 1 1
Test Date: 2026-11-14 13:19:18 Functions: - 0 0

            Line data    Source code
       1              : // SPDX-FileCopyrightText: 2026 Anne Jan Brouwer
       2              : // SPDX-License-Identifier: GPL-3.0-or-later
       3              : /**
       4              :  * @file
       5              :  * @brief Initialising a new profile's store (.gpg-id, signature, Git) with
       6              :  * blocking processes, apart from the active store's backend.
       7              :  */
       8              : #ifndef SRC_PROFILEINIT_H_
       9              : #define SRC_PROFILEINIT_H_
      10              : 
      11              : #include <QCoreApplication>
      12              : #include <QList>
      13              : #include <QProcessEnvironment>
      14              : #include <QString>
      15              : 
      16              : struct AppSettings;
      17              : struct UserInfo;
      18              : 
      19              : /**
      20              :  * @class ProfileInit
      21              :  * @ingroup settings
      22              :  * @brief Turn a directory into a password store without going through the
      23              :  *        Pass backend of the currently active store.
      24              :  *
      25              :  * The backend is a shared singleton bound to the active store (settings
      26              :  * snapshot, PASSWORD_STORE_DIR, one FIFO of asynchronous processes), so a
      27              :  * new profile cannot be initialised through it without racing the active
      28              :  * store (#1774). Everything here is synchronous and touches only @p dir.
      29              :  */
      30              : class ProfileInit {
      31           21 :   Q_DECLARE_TR_FUNCTIONS(ProfileInit)
      32              : 
      33              : public:
      34              :   /**
      35              :    * @brief The environment QtPass runs gpg in outside the active store's
      36              :    * backend: the system's, with GNUPGHOME set to the configured GPG home
      37              :    * when there is one, so lookups and signatures use the keyring that signs.
      38              :    * @param s The settings naming the GPG home.
      39              :    * @return The environment for a gpg process.
      40              :    */
      41              :   static auto gpgEnvironment(const AppSettings &s) -> QProcessEnvironment;
      42              :   /**
      43              :    * @brief Check if a profile path needs initialization.
      44              :    * @param path The profile path to check.
      45              :    * @return true if the path exists but has no .gpg-id file.
      46              :    */
      47              :   static auto needsInit(const QString &path) -> bool;
      48              : 
      49              :   /**
      50              :    * @brief Write the recipients and, if wanted, put the folder under git.
      51              :    *
      52              :    * Writes `<dir>/.gpg-id` with the enabled key ids, signs it when
      53              :    * @p s.passSigningKey is set, and when @p useGit runs `git init`,
      54              :    * `git add` and `git commit` inside @p dir with blocking processes.
      55              :    * Existing `*.gpg` files are left alone: re-encrypting them needs the
      56              :    * backend, i.e. the profile has to be the active store; @p note says so.
      57              :    * @param dir Directory to initialise; created if missing.
      58              :    * @param users Key list; only entries with enabled == true are written.
      59              :    * @param s Settings for the gpg/git executables and the signing key.
      60              :    * @param useGit Whether to create a repository and commit the file.
      61              :    * @param note Receives a translated message for the user (empty on a quiet
      62              :    *             success): the error, or the warning about existing entries.
      63              :    * @return true when the .gpg-id (and signature/commit if requested) is in
      64              :    *         place.
      65              :    */
      66              :   static auto initialise(const QString &dir, const QList<UserInfo> &users,
      67              :                          const AppSettings &s, bool useGit, QString *note)
      68              :       -> bool;
      69              : 
      70              :   /**
      71              :    * @brief Put an existing store under Git: `git init`, stage the `.gpg`
      72              :    * entries and the `.gpg-id` files (nothing else that may lie around in the
      73              :    * folder) and make a first commit, with blocking processes of their own in
      74              :    * @p dir.
      75              :    * @param dir The store.
      76              :    * @param s Settings for the git executable.
      77              :    * @param note Receives a translated error on failure.
      78              :    * @return true when the repository exists and the commit is made.
      79              :    */
      80              :   static auto initGit(const QString &dir, const AppSettings &s, QString *note)
      81              :       -> bool;
      82              : 
      83              :   /**
      84              :    * @brief Whether git has a name and e-mail to commit with, i.e.
      85              :    * `user.name` and `user.email` resolve (globally or in @p dir).
      86              :    * @param dir Directory to ask in; a repository's own config counts.
      87              :    * @param s Settings for the git executable.
      88              :    * @return true when a commit would not fail for lack of an identity.
      89              :    */
      90              :   static auto gitIdentityConfigured(const QString &dir, const AppSettings &s)
      91              :       -> bool;
      92              : 
      93              : private:
      94              :   ProfileInit() = default;
      95              :   /**
      96              :    * @brief Write the enabled recipients to @p gpgIdFile, whole or not at
      97              :    * all; with @p signed_ the list carries the generation and folder header a
      98              :    * signed store's lists are checked against (GpgIdGeneration).
      99              :    * @param gpgIdFile The `.gpg-id` to write.
     100              :    * @param users The recipients; the enabled ones are written.
     101              :    * @param signed_ Whether the store gets a signing key, i.e. the header.
     102              :    * @param note Receives the reason on failure.
     103              :    * @param written Receives the exact bytes written, if not null.
     104              :    * @return Whether the file was written.
     105              :    */
     106              :   static auto writeGpgId(const QString &gpgIdFile, const QList<UserInfo> &users,
     107              :                          bool signed_, QString *note,
     108              :                          QByteArray *written = nullptr) -> bool;
     109              :   /**
     110              :    * @brief Sign the list just written as @p gpgIdFile, over the bytes
     111              :    * @p contents that were written.
     112              :    * @param gpgIdFile The `.gpg-id`; `<gpgIdFile>.sig` is written.
     113              :    * @param contents The bytes written as that file.
     114              :    * @param s The settings naming gpg and the signing key.
     115              :    * @param note Receives the reason on failure.
     116              :    * @return Whether the signature is in place.
     117              :    */
     118              :   static auto signGpgId(const QString &gpgIdFile, const QByteArray &contents,
     119              :                         const AppSettings &s, QString *note) -> bool;
     120              :   /**
     121              :    * @brief `git init` in @p dir, stage the `.gpg-id` and its signature, and
     122              :    * commit them (signed when `pass.signcommits` is set), with a QProcess of
     123              :    * its own in the store's Git environment.
     124              :    * @param dir The store, absolute.
     125              :    * @param gpgIdFile The `.gpg-id` just written.
     126              :    * @param sigFile Its `.sig`, or empty when the store is not signed.
     127              :    * @param s Settings for the git executable and the GPG home.
     128              :    * @param note Receives a translated error naming the failed git command.
     129              :    * @return Whether the commit was made.
     130              :    */
     131              :   static auto commitGpgId(const QString &dir, const QString &gpgIdFile,
     132              :                           const QString &sigFile, const AppSettings &s,
     133              :                           QString *note) -> bool;
     134              : };
     135              : 
     136              : #endif // SRC_PROFILEINIT_H_
        

Generated by: LCOV version 2.0-1