QtPass 1.4.0
Multi-platform GUI for pass, the standard unix password manager.
Loading...
Searching...
No Matches
usersdialog.cpp
Go to the documentation of this file.
1#include "usersdialog.h"
2#include "qtpasssettings.h"
3#include "ui_usersdialog.h"
4#include <QCloseEvent>
5#include <QKeyEvent>
6#include <QMessageBox>
7#include <QRegularExpression>
8#include <QWidget>
9#include <utility>
10
11#ifdef QT_DEBUG
12#include "debughelper.h"
13#endif
18UsersDialog::UsersDialog(QString dir, QWidget *parent)
19 : QDialog(parent), ui(new Ui::UsersDialog), m_dir(std::move(dir)) {
20
21 ui->setupUi(this);
22
23 QList<UserInfo> users = QtPassSettings::getPass()->listKeys();
24 if (users.isEmpty()) {
25 QMessageBox::critical(parent, tr("Keylist missing"),
26 tr("Could not fetch list of available GPG keys"));
27 return;
28 }
29
30 QList<UserInfo> secret_keys = QtPassSettings::getPass()->listKeys("", true);
31 foreach (const UserInfo &sec, secret_keys) {
32 for (auto &user : users)
33 if (sec.key_id == user.key_id)
34 user.have_secret = true;
35 }
36
37 QList<UserInfo> selected_users;
38 int count = 0;
39
40 QStringList recipients = QtPassSettings::getPass()->getRecipientString(
41 m_dir.isEmpty() ? "" : m_dir, " ", &count);
42 if (!recipients.isEmpty())
43 selected_users = QtPassSettings::getPass()->listKeys(recipients);
44 foreach (const UserInfo &sel, selected_users) {
45 for (auto &user : users)
46 if (sel.key_id == user.key_id)
47 user.enabled = true;
48 }
49
50 if (count > selected_users.size()) {
51 // Some keys seem missing from keyring, add them separately
52 QStringList recipients = QtPassSettings::getPass()->getRecipientList(
53 m_dir.isEmpty() ? "" : m_dir);
54 foreach (const QString recipient, recipients) {
55 if (QtPassSettings::getPass()->listKeys(recipient).empty()) {
56 UserInfo i;
57 i.enabled = true;
58 i.key_id = recipient;
59 i.name = " ?? " + tr("Key not found in keyring");
60 users.append(i);
61 }
62 }
63 }
64
65 m_userList = users;
66 populateList();
67
68 connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
70 connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
71 connect(ui->listWidget, &QListWidget::itemChanged, this,
72 &UsersDialog::itemChange);
73
74 ui->lineEdit->setClearButtonEnabled(true);
75}
76
81
82Q_DECLARE_METATYPE(UserInfo *)
83
84
87void UsersDialog::accept() {
88 QtPassSettings::getPass()->Init(m_dir, m_userList);
89
90 QDialog::accept();
91}
92
98void UsersDialog::closeEvent(QCloseEvent *event) {
99 // TODO(annejan) save window size or something
100 event->accept();
101}
102
108void UsersDialog::keyPressEvent(QKeyEvent *event) {
109 switch (event->key()) {
110 case Qt::Key_Escape:
111 ui->lineEdit->clear();
112 break;
113 default:
114 break;
115 }
116}
117
122void UsersDialog::itemChange(QListWidgetItem *item) {
123 if (!item)
124 return;
125 auto *info = item->data(Qt::UserRole).value<UserInfo *>();
126 if (!info)
127 return;
128 info->enabled = item->checkState() == Qt::Checked;
129}
130
136void UsersDialog::populateList(const QString &filter) {
137 QRegularExpression nameFilter(
138 QRegularExpression::wildcardToRegularExpression("*" + filter + "*"),
139 QRegularExpression::CaseInsensitiveOption);
140 ui->listWidget->clear();
141 if (!m_userList.isEmpty()) {
142 for (auto &user : m_userList) {
143 if (filter.isEmpty() || nameFilter.match(user.name).hasMatch()) {
144 if (!user.isValid() && !ui->checkBox->isChecked())
145 continue;
146 if (user.expiry.toSecsSinceEpoch() > 0 &&
147 user.expiry.daysTo(QDateTime::currentDateTime()) > 0 &&
148 !ui->checkBox->isChecked())
149 continue;
150 QString userText = user.name + "\n" + user.key_id;
151 if (user.created.toSecsSinceEpoch() > 0) {
152 userText +=
153 " " + tr("created") + " " +
154 QLocale::system().toString(user.created, QLocale::ShortFormat);
155 }
156 if (user.expiry.toSecsSinceEpoch() > 0)
157 userText +=
158 " " + tr("expires") + " " +
159 QLocale::system().toString(user.expiry, QLocale::ShortFormat);
160 auto *item = new QListWidgetItem(userText, ui->listWidget);
161 item->setCheckState(user.enabled ? Qt::Checked : Qt::Unchecked);
162 item->setData(Qt::UserRole, QVariant::fromValue(&user));
163 if (user.have_secret) {
164 // item->setForeground(QColor(32, 74, 135));
165 item->setForeground(Qt::blue);
166 QFont font;
167 font.setFamily(font.defaultFamily());
168 font.setBold(true);
169 item->setFont(font);
170 } else if (!user.isValid()) {
171 item->setBackground(QColor(164, 0, 0));
172 item->setForeground(Qt::white);
173 } else if (user.expiry.toSecsSinceEpoch() > 0 &&
174 user.expiry.daysTo(QDateTime::currentDateTime()) > 0) {
175 item->setForeground(QColor(164, 0, 0));
176 } else if (!user.fullyValid()) {
177 item->setBackground(QColor(164, 80, 0));
178 item->setForeground(Qt::white);
179 }
180
181 ui->listWidget->addItem(item);
182 }
183 }
184 }
185}
186
191void UsersDialog::on_lineEdit_textChanged(const QString &filter) {
192 populateList(filter);
193}
194
198void UsersDialog::on_checkBox_clicked() { populateList(ui->lineEdit->text()); }
static QStringList getRecipientString(QString for_file, QString separator=" ", int *count=NULL)
Pass::getRecipientString formated string for use with GPG.
Definition: pass.cpp:339
static QStringList getRecipientList(QString for_file)
Pass::getRecipientList return list of gpg-id's to encrypt for.
Definition: pass.cpp:318
QList< UserInfo > listKeys(QStringList keystrings, bool secret=false)
Pass::listKeys list users.
Definition: pass.cpp:130
virtual void Init(QString path, const QList< UserInfo > &users)=0
static Pass * getPass()
Handles listing and editing of GPG users.
Definition: usersdialog.h:23
~UsersDialog()
UsersDialog::~UsersDialog basic destructor.
Definition: usersdialog.cpp:80
void accept()
UsersDialog::accept.
Definition: usersdialog.cpp:87
UsersDialog(QString dir, QWidget *parent=nullptr)
UsersDialog::UsersDialog basic constructor.
Definition: usersdialog.cpp:18
void closeEvent(QCloseEvent *event)
UsersDialog::closeEvent might have to store size and location if that is wanted.
Definition: usersdialog.cpp:98
void keyPressEvent(QKeyEvent *event)
UsersDialog::keyPressEvent clear the lineEdit when escape is pressed. No action for Enter currently.
Definition: configdialog.h:9
Stores key info lines including validity, creation date and more.
Definition: userinfo.h:11
bool enabled
UserInfo::enabled.
Definition: userinfo.h:50
QString key_id
UserInfo::key_id hexadecimal representation.
Definition: userinfo.h:36
QString name
UserInfo::name full name.
Definition: userinfo.h:32