Optimize certification trust level management.
A private key should be editable to Unknown or Ultimate levels only. A public key should be editable to all levels except Ultimate. Undefined level is excluded for both public and private keys. The public WTreeTableNode may list private keys if the user does not manage these private keys. Inform of this state in the tool tip. The certification trust level is excluded for any change.
This commit is contained in:
@@ -265,7 +265,7 @@ void K7Main::DisplayKeys(const vector<GpgME::Key>& kList, const WString& grpLabe
|
||||
* Here we allow the owner trust level of primary keys to be changed anytime.
|
||||
* Kleopatra doesn't do that for primary keys having ultimate trust level.
|
||||
*/
|
||||
lblOwnerTrust->doubleClicked().connect(std::bind(&KeyEdit::OnOwnerTrustDoubleClicked, m_keyEdit, keyNode));
|
||||
lblOwnerTrust->doubleClicked().connect(std::bind(&KeyEdit::OnOwnerTrustDoubleClicked, m_keyEdit, keyNode, k.hasSecret()));
|
||||
lblOwnerTrust->setToolTip(TR("TTTDoubleCLick"));
|
||||
}
|
||||
keyNode->setColumnWidget(2, unique_ptr<WText> (lblOwnerTrust));
|
||||
|
||||
63
KeyEdit.cpp
63
KeyEdit.cpp
@@ -12,6 +12,7 @@
|
||||
#include <Wt/WStandardItemModel.h>
|
||||
#include <Wt/WStandardItem.h>
|
||||
#include "GpgMEWorker.h"
|
||||
#include "Tools.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -28,29 +29,48 @@ KeyEdit::~KeyEdit()
|
||||
delete m_popupUid;
|
||||
}
|
||||
|
||||
void KeyEdit::OnOwnerTrustDoubleClicked(WTreeTableNode * keyNode)
|
||||
void KeyEdit::OnOwnerTrustDoubleClicked(WTreeTableNode * keyNode, bool keyHasSecret)
|
||||
{
|
||||
/*
|
||||
* TODO : decide if we should exclude any primary key with ultimate trust
|
||||
* level for any further change.
|
||||
* A private key that a user does not manage will have its public part
|
||||
* listed in the public WTreeTableNode. The certification trust level must
|
||||
* not be editable by anyone.
|
||||
*/
|
||||
WText * lblFpr = static_cast<WText*> (keyNode->columnWidget(3));
|
||||
if (!IsOurKey(lblFpr->text()) && Tools::KeyHasSecret(lblFpr->text())) {
|
||||
m_owner->m_tmwMessage->SetText(TR("OwnerTrustReadOnly"));
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* We leave a primary key with ultimate trust level for further change.
|
||||
* kleopatra does not do that.
|
||||
*/
|
||||
WComboBox * cmbOwnerTrust = new WComboBox();
|
||||
FillOwnerTrustCombo(cmbOwnerTrust);
|
||||
cmbOwnerTrust->blurred().connect(std::bind(&KeyEdit::OnOwnerTrustBlurred, this, keyNode));
|
||||
FillOwnerTrustCombo(cmbOwnerTrust, keyHasSecret);
|
||||
cmbOwnerTrust->blurred().connect(std::bind(&KeyEdit::OnOwnerTrustBlurred, this, keyNode, keyHasSecret));
|
||||
WText * lblOwnerTrust = static_cast<WText*> (keyNode->columnWidget(2));
|
||||
cmbOwnerTrust->setCurrentIndex(cmbOwnerTrust->findText(lblOwnerTrust->text()));
|
||||
// If nothing gets changed, don't go to engine.
|
||||
/*
|
||||
* Prepare to check for change in combobox item.
|
||||
* Change is detected by index, not value.
|
||||
*/
|
||||
cmbOwnerTrust->setAttributeValue("previousTrustLevel", std::to_string(cmbOwnerTrust->currentIndex()));
|
||||
keyNode->setColumnWidget(2, unique_ptr<WComboBox> (cmbOwnerTrust));
|
||||
// +++
|
||||
cmbOwnerTrust->setFocus();
|
||||
}
|
||||
|
||||
void KeyEdit::OnOwnerTrustBlurred(WTreeTableNode* keyNode)
|
||||
void KeyEdit::OnOwnerTrustBlurred(WTreeTableNode* keyNode, bool keyHasSecret)
|
||||
{
|
||||
// Get new level (not index)
|
||||
WComboBox * cmbOwnerTrust = static_cast<WComboBox*> (keyNode->columnWidget(2));
|
||||
shared_ptr<WAbstractItemModel> aiModel = cmbOwnerTrust->model();
|
||||
WStandardItemModel * iModel = static_cast<WStandardItemModel*> (aiModel.get());
|
||||
WStandardItem * item = iModel->item(cmbOwnerTrust->currentIndex(), 0);
|
||||
int newLevel = Tools::ToInt(item->text().toUTF8());
|
||||
|
||||
WText * lblOwnerTrust = new WText(cmbOwnerTrust->currentText());
|
||||
lblOwnerTrust->doubleClicked().connect(std::bind(&KeyEdit::OnOwnerTrustDoubleClicked, this, keyNode));
|
||||
lblOwnerTrust->doubleClicked().connect(std::bind(&KeyEdit::OnOwnerTrustDoubleClicked, this, keyNode, keyHasSecret));
|
||||
const WText * lblFpr = static_cast<WText*> (keyNode->columnWidget(3));
|
||||
const uint newTrustLevel = cmbOwnerTrust->currentIndex();
|
||||
const WString previousTrustLevel = cmbOwnerTrust->attributeValue("previousTrustLevel");
|
||||
@@ -58,9 +78,9 @@ void KeyEdit::OnOwnerTrustBlurred(WTreeTableNode* keyNode)
|
||||
// If nothing was changed, don't go to engine.
|
||||
if (WString(std::to_string(newTrustLevel)) == previousTrustLevel)
|
||||
return;
|
||||
|
||||
|
||||
GpgMEWorker gpgWorker;
|
||||
GpgME::Error e = gpgWorker.EditOwnerTrust(lblFpr->text().toUTF8().c_str(), (GpgME::Key::OwnerTrust) newTrustLevel);
|
||||
GpgME::Error e = gpgWorker.EditOwnerTrust(lblFpr->text().toUTF8().c_str(), (GpgME::Key::OwnerTrust) newLevel);
|
||||
if (e.code() != 0)
|
||||
{
|
||||
lblOwnerTrust->setText(previousTrustLevel);
|
||||
@@ -70,21 +90,24 @@ void KeyEdit::OnOwnerTrustBlurred(WTreeTableNode* keyNode)
|
||||
m_owner->m_tmwMessage->SetText(TR("OwnerTrustSuccess"));
|
||||
}
|
||||
|
||||
void KeyEdit::FillOwnerTrustCombo(WComboBox * cmb)
|
||||
void KeyEdit::FillOwnerTrustCombo(WComboBox * cmb, bool keyHasSecret)
|
||||
{
|
||||
/*
|
||||
* We should perhaps exclude OwnerTrust::Ultimate.
|
||||
* kleopatra doesn't do that.
|
||||
*/
|
||||
shared_ptr<WStandardItemModel> siModel = make_shared<WStandardItemModel> ();
|
||||
OwnerTrustMap OwnerTrustLevel = m_owner->OwnerTrustLevel;
|
||||
vector<unique_ptr < WStandardItem>> colIndex;
|
||||
vector<unique_ptr < WStandardItem>> colText;
|
||||
OwnerTrustMap::iterator it;
|
||||
for (it = OwnerTrustLevel.begin(); it != OwnerTrustLevel.end(); it++)
|
||||
{
|
||||
colIndex.push_back(cpp14::make_unique<WStandardItem> (std::to_string((*it).first)));
|
||||
colText.push_back(cpp14::make_unique<WStandardItem> ((*it).second));
|
||||
colIndex.push_back(cpp14::make_unique<WStandardItem> (std::to_string(UserID::Validity::Unknown)));
|
||||
colText.push_back(cpp14::make_unique<WStandardItem> (TR("UidUnknown")));
|
||||
if (keyHasSecret) {
|
||||
colIndex.push_back(cpp14::make_unique<WStandardItem> (std::to_string(UserID::Validity::Ultimate)));
|
||||
colText.push_back(cpp14::make_unique<WStandardItem> (TR("UidUltimate")));
|
||||
} else {
|
||||
colIndex.push_back(cpp14::make_unique<WStandardItem> (std::to_string(UserID::Validity::Never)));
|
||||
colText.push_back(cpp14::make_unique<WStandardItem> (TR("UidNever")));
|
||||
colIndex.push_back(cpp14::make_unique<WStandardItem> (std::to_string(UserID::Validity::Marginal)));
|
||||
colText.push_back(cpp14::make_unique<WStandardItem> (TR("UidMarginal")));
|
||||
colIndex.push_back(cpp14::make_unique<WStandardItem> (std::to_string(UserID::Validity::Full)));
|
||||
colText.push_back(cpp14::make_unique<WStandardItem> (TR("UidFull")));
|
||||
}
|
||||
siModel->appendColumn(std::move(colIndex));
|
||||
siModel->appendColumn(std::move(colText));
|
||||
|
||||
17
KeyEdit.h
17
KeyEdit.h
@@ -31,13 +31,15 @@ public:
|
||||
/**
|
||||
* Shows a combobox with all trust levels
|
||||
* @param keyNode
|
||||
* @param keyHasSecret
|
||||
*/
|
||||
void OnOwnerTrustDoubleClicked(WTreeTableNode * keyNode);
|
||||
void OnOwnerTrustDoubleClicked(WTreeTableNode * keyNode, bool keyHasSecret);
|
||||
/**
|
||||
* Saves any changes in trust level
|
||||
* @param keyNode
|
||||
* @param keyHasSecret
|
||||
*/
|
||||
void OnOwnerTrustBlurred(WTreeTableNode * keyNode);
|
||||
void OnOwnerTrustBlurred(WTreeTableNode * keyNode, bool keyHasSecret);
|
||||
/**
|
||||
* If the fingerprint is that of a private key we manage, returns true.
|
||||
* @param fpr
|
||||
@@ -56,8 +58,15 @@ private:
|
||||
K7Main * m_owner;
|
||||
PopupCertifyUserId * m_popupUid;
|
||||
WString m_targetKeyFpr;
|
||||
|
||||
void FillOwnerTrustCombo(WComboBox * cmb);
|
||||
/**
|
||||
* Unknown is common.
|
||||
* \n If keyHasSecret is true, show only Ultimate level.
|
||||
* \n Else, show everything except Ultimate.
|
||||
* \n Undefined is not included.
|
||||
* @param cmb
|
||||
* @param keyHasSecret
|
||||
*/
|
||||
void FillOwnerTrustCombo(WComboBox * cmb, bool keyHasSecret);
|
||||
void CertifyKey();
|
||||
};
|
||||
|
||||
|
||||
32
Tools.cpp
32
Tools.cpp
@@ -13,10 +13,12 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
Tools::Tools() {
|
||||
Tools::Tools()
|
||||
{
|
||||
}
|
||||
|
||||
Tools::~Tools() {
|
||||
Tools::~Tools()
|
||||
{
|
||||
}
|
||||
|
||||
bool Tools::ConfigKeyIdMatchesKey(const GpgME::Key& k, const WString& configKeyId)
|
||||
@@ -27,7 +29,8 @@ bool Tools::ConfigKeyIdMatchesKey(const GpgME::Key& k, const WString& configKeyI
|
||||
|| configKeyId == WString(k.primaryFingerprint()));
|
||||
}
|
||||
|
||||
int Tools::ToInt(const string& s) {
|
||||
int Tools::ToInt(const string& s)
|
||||
{
|
||||
istringstream buffer(s.c_str());
|
||||
int num;
|
||||
buffer >> num;
|
||||
@@ -37,8 +40,8 @@ int Tools::ToInt(const string& s) {
|
||||
WString Tools::TexttualBool(bool value)
|
||||
{
|
||||
const WString res = value
|
||||
? WString::tr("Yes")
|
||||
: WString::tr("No");
|
||||
? WString::tr("Yes")
|
||||
: WString::tr("No");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -55,8 +58,8 @@ WString Tools::GetKeyStatus(const GpgME::Key& k)
|
||||
status += WString(WString::tr("KeyStatusIsDisabled")) + sep + TexttualBool(k.isDisabled()) + nl;
|
||||
status += WString(WString::tr("KeyStatusIsExpired")) + sep + TexttualBool(k.isExpired()) + nl;
|
||||
status += WString(WString::tr("KeyStatusIsRevoked")) + sep + TexttualBool(k.isRevoked()) + nl + nl;
|
||||
status += WString(WString::tr("KeyTypeIsSecret")) + sep + TexttualBool(k.isSecret());
|
||||
|
||||
status += WString(WString::tr("KeyTypeIsSecret")) + sep + TexttualBool(KeyHasSecret(k.primaryFingerprint()));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -70,7 +73,7 @@ WString Tools::GetUidStatus(const GpgME::UserID& uid)
|
||||
status += WString(WString::tr("UserStatusIsNull")) + sep + TexttualBool(uid.isNull()) + nl;
|
||||
status += WString(WString::tr("UserStatusIsInvalid")) + sep + TexttualBool(uid.isInvalid()) + nl;
|
||||
status += WString(WString::tr("UserStatusIsRevoked")) + sep + TexttualBool(uid.isRevoked());
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -86,7 +89,18 @@ WString Tools::GetSigStatus(const GpgME::UserID::Signature& sig)
|
||||
status += WString(WString::tr("SigStatusIsExportable")) + sep + TexttualBool(sig.isExportable()) + nl;
|
||||
status += WString(WString::tr("SigStatusIsExpired")) + sep + TexttualBool(sig.isExpired()) + nl;
|
||||
status += WString(WString::tr("SigStatusIsRevokation")) + sep + TexttualBool(sig.isRevokation());
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool Tools::KeyHasSecret(const WString& fpr)
|
||||
{
|
||||
Error e;
|
||||
GpgMEWorker gpgw;
|
||||
GpgME::Key k = gpgw.FindKey(fpr.toUTF8().c_str(), e, true); // Look for a private key
|
||||
if (e.code() != 0 && e.code() != 16383)
|
||||
{ // 16383 : end of file, when key is not private
|
||||
return false;
|
||||
}
|
||||
return (!k.isNull());
|
||||
}
|
||||
|
||||
1
Tools.h
1
Tools.h
@@ -43,6 +43,7 @@ public:
|
||||
static WString GetKeyStatus(const GpgME::Key& k);
|
||||
static WString GetUidStatus(const GpgME::UserID& uid);
|
||||
static WString GetSigStatus(const GpgME::UserID::Signature& sig);
|
||||
static bool KeyHasSecret(const WString& fpr);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
<message id='TTTDoubleCLick'>Double click to edit</message>
|
||||
<message id='TTTYourKey'>This is your key</message>
|
||||
<message id='OwnerTrustReadOnly'>Owner trust level read only; a primary key coexists and you don't manage it.</message>
|
||||
<message id='OwnerTrustSuccess'>Owner trust level succesfully changed</message>
|
||||
<message id='OwnerTrustFailure'>Owner trust level failed to be changed</message>
|
||||
|
||||
@@ -89,7 +90,7 @@
|
||||
<message id='KeyStatusIsDisabled'>Disabled</message>
|
||||
<message id='KeyStatusIsExpired'>Expired</message>
|
||||
<message id='KeyStatusIsRevoked'>Revoked</message>
|
||||
<message id='KeyTypeIsSecret'>Secret</message>
|
||||
<message id='KeyTypeIsSecret'>Coexists with a secret key</message>
|
||||
|
||||
<message id='UserStatus'>User status</message>
|
||||
<message id='UserStatusIsBad'>Bad</message>
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
<message id='TTTDoubleCLick'>Double cliquez pour éditer</message>
|
||||
<message id='TTTYourKey'>C'est votre clé</message>
|
||||
<message id='OwnerTrustReadOnly'>Confiance dans la certification en lecture seule; une clé primaire coexiste et vous ne la gérez pas.</message>
|
||||
<message id='OwnerTrustSuccess'>Confiance dans la certification changée avec succès</message>
|
||||
<message id='OwnerTrustFailure'>Échec de changement de la confiance dans la certification</message>
|
||||
|
||||
@@ -89,7 +90,7 @@
|
||||
<message id='KeyStatusIsDisabled'>Désactivé</message>
|
||||
<message id='KeyStatusIsExpired'>Expiré</message>
|
||||
<message id='KeyStatusIsRevoked'>Revoqué</message>
|
||||
<message id='KeyTypeIsSecret'>Secret</message>
|
||||
<message id='KeyTypeIsSecret'>Coexiste avec une clé secrète</message>
|
||||
|
||||
<message id='UserStatus'>État de l'utilisateur</message>
|
||||
<message id='UserStatusIsBad'>Mauvais</message>
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<gdb_interceptlist>
|
||||
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
|
||||
</gdb_interceptlist>
|
||||
<gdb_signals>
|
||||
</gdb_signals>
|
||||
<gdb_options>
|
||||
<DebugOptions>
|
||||
</DebugOptions>
|
||||
|
||||
@@ -7,14 +7,9 @@
|
||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||
<group>
|
||||
<file>file:/home/user/Documents/published/K7/PopupDeleter.h</file>
|
||||
<file>file:/home/user/Documents/published/K7/K7Main.h</file>
|
||||
<file>file:/home/user/Documents/published/K7/PopupUploader.h</file>
|
||||
<file>file:/home/user/Documents/published/K7/AppConfig.cpp</file>
|
||||
<file>file:/home/user/Documents/published/K7/K7Main.cpp</file>
|
||||
<file>file:/home/user/Documents/published/K7/PopupCertifyUserId.cpp</file>
|
||||
<file>file:/home/user/Documents/published/K7/PopupUploader.cpp</file>
|
||||
<file>file:/home/user/Documents/published/K7/PopupCertifyUserId.h</file>
|
||||
<file>file:/home/user/Documents/published/K7/PopupDeleter.cpp</file>
|
||||
<file>file:/home/user/Documents/published/K7/main.cpp</file>
|
||||
</group>
|
||||
</open-files>
|
||||
</project-private>
|
||||
|
||||
Reference in New Issue
Block a user