Allow to add and revoke user identities.
Using a popup with required parameters.
This commit is contained in:
@@ -38,6 +38,7 @@ mutex gs_fileWriteMutex;
|
|||||||
"canEditUidValidity" : true,
|
"canEditUidValidity" : true,
|
||||||
"canEditExpiryTime" : true,
|
"canEditExpiryTime" : true,
|
||||||
"canCreateKeys" : true,
|
"canCreateKeys" : true,
|
||||||
|
"canAddRevokeUids" : true,
|
||||||
"privKeyIds" : [
|
"privKeyIds" : [
|
||||||
"fullKeyId1",
|
"fullKeyId1",
|
||||||
"fullKeyId2"
|
"fullKeyId2"
|
||||||
@@ -172,6 +173,17 @@ bool AppConfig::CanCreateKeys() const
|
|||||||
return cnObject.get("canCreateKeys");
|
return cnObject.get("canCreateKeys");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppConfig::CanAddRevokeUid() const
|
||||||
|
{
|
||||||
|
const WString commonName = GetSubjectDnAttribute(WSslCertificate::DnAttributeName::CommonName);
|
||||||
|
if (!m_SubjectCNObject.contains(commonName.toUTF8()))
|
||||||
|
return false;
|
||||||
|
Json::Object cnObject = m_SubjectCNObject.get(commonName.toUTF8());
|
||||||
|
if (!cnObject.contains("canAddRevokeUids"))
|
||||||
|
return false;
|
||||||
|
return cnObject.get("canAddRevokeUids");
|
||||||
|
}
|
||||||
|
|
||||||
bool AppConfig::UpdateSecretKeyOwnership(const WString& fpr, bool own)
|
bool AppConfig::UpdateSecretKeyOwnership(const WString& fpr, bool own)
|
||||||
{
|
{
|
||||||
const WString commonName = GetSubjectDnAttribute(WSslCertificate::DnAttributeName::CommonName);
|
const WString commonName = GetSubjectDnAttribute(WSslCertificate::DnAttributeName::CommonName);
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool CanCreateKeys() const;
|
bool CanCreateKeys() const;
|
||||||
|
/**
|
||||||
|
* Allows to add or revoke a user identity to a key. It deos not mean
|
||||||
|
* deleting an identity.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool CanAddRevokeUid() const;
|
||||||
/**
|
/**
|
||||||
* Disown the user of the secret key, or grants him ownership. It just adds
|
* Disown the user of the secret key, or grants him ownership. It just adds
|
||||||
* or remove fpr from the private key array, without any further check. The
|
* or remove fpr from the private key array, without any further check. The
|
||||||
|
|||||||
18
K7Main.cpp
18
K7Main.cpp
@@ -314,7 +314,7 @@ void K7Main::OnKeyAnchorClicked(WAnchor * source)
|
|||||||
DisplaySubKeys(id, secret);
|
DisplaySubKeys(id, secret);
|
||||||
if (m_config->CanDelete()) // m_btnDelete is NULL otherwise
|
if (m_config->CanDelete()) // m_btnDelete is NULL otherwise
|
||||||
m_btnDelete->setHidden(!m_keyringIO->CanKeyBeDeleted(id));
|
m_btnDelete->setHidden(!m_keyringIO->CanKeyBeDeleted(id));
|
||||||
|
|
||||||
m_keyringIO->PrepareExport(id, secret);
|
m_keyringIO->PrepareExport(id, secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,20 +340,28 @@ void K7Main::DisplayUids(const WString& fullKeyID, bool secret)
|
|||||||
rootNode->setChildCountPolicy(ChildCountPolicy::Enabled);
|
rootNode->setChildCountPolicy(ChildCountPolicy::Enabled);
|
||||||
m_ttbUids->setTreeRoot(unique_ptr<WTreeTableNode> (rootNode), TR("UIDs"));
|
m_ttbUids->setTreeRoot(unique_ptr<WTreeTableNode> (rootNode), TR("UIDs"));
|
||||||
rootNode->expand();
|
rootNode->expand();
|
||||||
vector<WString> privateKeys = m_config->PrivateKeyIds();
|
vector<WString> ourKeys = m_config->PrivateKeyIds();
|
||||||
|
bool canAddRevokeUid = m_config->CanAddRevokeUid()
|
||||||
|
&& Tools::KeyHasSecret(k.primaryFingerprint())
|
||||||
|
&& Tools::IsOurKey(k.primaryFingerprint(), ourKeys);
|
||||||
for (uint i = 0; i < k.numUserIDs(); i++)
|
for (uint i = 0; i < k.numUserIDs(); i++)
|
||||||
{
|
{
|
||||||
UserID uid = k.userID(i);
|
UserID uid = k.userID(i);
|
||||||
WTreeTableNode * uidNode = new WTreeTableNode(uid.name());
|
WTreeTableNode * uidNode = new WTreeTableNode(uid.name());
|
||||||
uidNode->setToolTip(Tools::GetUidStatus(uid));
|
uidNode->setToolTip(Tools::GetUidStatus(uid));
|
||||||
TreeTableNodeText * ttntUidEmail = new TreeTableNodeText(uid.email(), uidNode, 1);
|
WText * lblUidEmail = new WText(uid.email());
|
||||||
uidNode->setColumnWidget(1, unique_ptr<TreeTableNodeText> (ttntUidEmail));
|
if (canAddRevokeUid)
|
||||||
|
{
|
||||||
|
lblUidEmail->setToolTip(TR("TTTDoubleCLick"));
|
||||||
|
lblUidEmail->doubleClicked().connect(std::bind(&KeyEdit::OnUidEmailClicked, m_keyEdit, uidNode, WString(k.primaryFingerprint())));
|
||||||
|
}
|
||||||
|
uidNode->setColumnWidget(1, unique_ptr<WText> (lblUidEmail));
|
||||||
// Show key certify popup on double click
|
// Show key certify popup on double click
|
||||||
WText * lblUidValidity = new WText(UidValidities[uid.validity()]);
|
WText * lblUidValidity = new WText(UidValidities[uid.validity()]);
|
||||||
if (m_config->CanEditUidValidity())
|
if (m_config->CanEditUidValidity())
|
||||||
{
|
{
|
||||||
lblUidValidity->setToolTip(TR("TTTDoubleCLick"));
|
lblUidValidity->setToolTip(TR("TTTDoubleCLick"));
|
||||||
lblUidValidity->doubleClicked().connect(std::bind(&KeyEdit::OnUidValidityClicked, m_keyEdit, uidNode, privateKeys, WString(k.primaryFingerprint())));
|
lblUidValidity->doubleClicked().connect(std::bind(&KeyEdit::OnUidValidityClicked, m_keyEdit, uidNode, ourKeys, WString(k.primaryFingerprint())));
|
||||||
}
|
}
|
||||||
uidNode->setColumnWidget(2, unique_ptr<WText> (lblUidValidity));
|
uidNode->setColumnWidget(2, unique_ptr<WText> (lblUidValidity));
|
||||||
TreeTableNodeText * ttntUidComment = new TreeTableNodeText(uid.comment(), uidNode, 3);
|
TreeTableNodeText * ttntUidComment = new TreeTableNodeText(uid.comment(), uidNode, 3);
|
||||||
|
|||||||
58
KeyEdit.cpp
58
KeyEdit.cpp
@@ -22,6 +22,7 @@ KeyEdit::KeyEdit(K7Main * owner)
|
|||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
m_popupUid = NULL;
|
m_popupUid = NULL;
|
||||||
m_popupExpiryTime = NULL;
|
m_popupExpiryTime = NULL;
|
||||||
|
m_popupAddUid = NULL;
|
||||||
m_targetUidValidityKeyFpr = WString::Empty;
|
m_targetUidValidityKeyFpr = WString::Empty;
|
||||||
m_expiryEditedKeyFpr = WString::Empty;
|
m_expiryEditedKeyFpr = WString::Empty;
|
||||||
}
|
}
|
||||||
@@ -200,3 +201,60 @@ void KeyEdit::SetExpiryTime()
|
|||||||
m_owner->DisplaySubKeys(m_expiryEditedKeyFpr, true);
|
m_owner->DisplaySubKeys(m_expiryEditedKeyFpr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeyEdit::OnUidEmailClicked(WTreeTableNode* uidNode, const WString& keyFpr)
|
||||||
|
{
|
||||||
|
WText * lblEmail = static_cast<WText*> (uidNode->columnWidget(1));
|
||||||
|
if (keyFpr != m_addUidKeyFpr)
|
||||||
|
{
|
||||||
|
delete m_popupAddUid;
|
||||||
|
m_popupAddUid = new PopupAddUid(lblEmail, m_owner->m_tmwMessage);
|
||||||
|
m_popupAddUid->Create();
|
||||||
|
m_addUidKeyFpr = keyFpr;
|
||||||
|
m_popupAddUid->GetApplyButton()->clicked().connect(this, &KeyEdit::AddOrRevokeUid);
|
||||||
|
}
|
||||||
|
WText * lblName = uidNode->label();
|
||||||
|
WText * lblComment = static_cast<WText*> (uidNode->columnWidget(3));
|
||||||
|
m_popupAddUid->SetNodeIdentity(lblName->text(), lblEmail->text(),
|
||||||
|
lblComment->text());
|
||||||
|
m_popupAddUid->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyEdit::AddOrRevokeUid()
|
||||||
|
{
|
||||||
|
if (!m_popupAddUid->Validate())
|
||||||
|
{
|
||||||
|
m_owner->m_tmwMessage->SetText(TR("InvalidInput"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const WString name = m_popupAddUid->GetName();
|
||||||
|
const WString email = m_popupAddUid->GetEmail();
|
||||||
|
const WString comment = m_popupAddUid->GetComment();
|
||||||
|
const WString passphrase = m_popupAddUid->GetPassphrase();
|
||||||
|
|
||||||
|
Error e;
|
||||||
|
GpgMEWorker gpgw;
|
||||||
|
if (m_popupAddUid->WhatToDo() == PopupAddUid::What::Revoke)
|
||||||
|
{
|
||||||
|
e = gpgw.RevokeUserID(m_addUidKeyFpr.toUTF8().c_str(),
|
||||||
|
passphrase.toUTF8(),
|
||||||
|
name.toUTF8(), email.toUTF8(), comment.toUTF8());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = gpgw.AddUserID(m_addUidKeyFpr.toUTF8().c_str(),
|
||||||
|
passphrase.toUTF8(),
|
||||||
|
name.toUTF8(), email.toUTF8(), comment.toUTF8());
|
||||||
|
}
|
||||||
|
m_popupAddUid->hide();
|
||||||
|
if (e.code() != 0)
|
||||||
|
{
|
||||||
|
m_popupAddUid->ShowPassphrase(true);
|
||||||
|
m_owner->m_tmwMessage->SetText(e.asString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_popupAddUid->ShowPassphrase(false);
|
||||||
|
}
|
||||||
|
// Key certifications are not listed on this refresh !
|
||||||
|
m_owner->DisplayUids(m_addUidKeyFpr, true);
|
||||||
|
}
|
||||||
|
|||||||
16
KeyEdit.h
16
KeyEdit.h
@@ -15,17 +15,19 @@
|
|||||||
#include <Wt/WComboBox.h>
|
#include <Wt/WComboBox.h>
|
||||||
#include "PopupCertifyUserId.h"
|
#include "PopupCertifyUserId.h"
|
||||||
#include "PopupExpiryTime.h"
|
#include "PopupExpiryTime.h"
|
||||||
|
#include "PopupAddUid.h"
|
||||||
|
|
||||||
using namespace Wt;
|
using namespace Wt;
|
||||||
|
|
||||||
class K7Main;
|
class K7Main;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some key editing functionalities are or will be implemented here. For now,
|
* Some key editing functionalities are or will be implemented here.
|
||||||
* only owner trust level and key certification are implemented.
|
* Owner trust level, key certification adding and revoking user identities are
|
||||||
* Is a pseudo-extension of K7Main. Both classes are friends to each other, and
|
* implemented.
|
||||||
|
* \n Is a pseudo-extension of K7Main. Both classes are friends to each other, and
|
||||||
* everything is private here.
|
* everything is private here.
|
||||||
* Does not manage keyring.
|
* \n Does not manage keyring.
|
||||||
*/
|
*/
|
||||||
class KeyEdit : public WObject
|
class KeyEdit : public WObject
|
||||||
{
|
{
|
||||||
@@ -43,6 +45,9 @@ private:
|
|||||||
PopupExpiryTime * m_popupExpiryTime;
|
PopupExpiryTime * m_popupExpiryTime;
|
||||||
WString m_expiryEditedKeyFpr;
|
WString m_expiryEditedKeyFpr;
|
||||||
|
|
||||||
|
PopupAddUid * m_popupAddUid;
|
||||||
|
WString m_addUidKeyFpr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unknown is common.
|
* Unknown is common.
|
||||||
* \n If keyHasSecret is true, show only Ultimate level.
|
* \n If keyHasSecret is true, show only Ultimate level.
|
||||||
@@ -54,6 +59,7 @@ private:
|
|||||||
void FillOwnerTrustCombo(WComboBox * cmb, bool keyHasSecret);
|
void FillOwnerTrustCombo(WComboBox * cmb, bool keyHasSecret);
|
||||||
void CertifyKey();
|
void CertifyKey();
|
||||||
void SetExpiryTime();
|
void SetExpiryTime();
|
||||||
|
void AddOrRevokeUid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a combobox with all trust levels
|
* Shows a combobox with all trust levels
|
||||||
@@ -81,6 +87,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
void OnExpiryClicked(WTreeTableNode * subkeyNode, const WString& keyFpr);
|
void OnExpiryClicked(WTreeTableNode * subkeyNode, const WString& keyFpr);
|
||||||
|
|
||||||
|
void OnUidEmailClicked(WTreeTableNode * uidNode, const WString& keyFpr);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* KEYEDIT_H */
|
#endif /* KEYEDIT_H */
|
||||||
|
|||||||
161
PopupAddUid.cpp
Normal file
161
PopupAddUid.cpp
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* File: PopupAddUid.cpp
|
||||||
|
* Author: SET - nmset@yandex.com
|
||||||
|
* License : GPL v2
|
||||||
|
* Copyright SET - © 2019
|
||||||
|
*
|
||||||
|
* Created on November 16, 2020, 3:59 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PopupAddUid.h"
|
||||||
|
#include "global.h"
|
||||||
|
#include <Wt/WHBoxLayout.h>
|
||||||
|
#include <Wt/WVBoxLayout.h>
|
||||||
|
#include <Wt/WGridLayout.h>
|
||||||
|
#include <Wt/WRadioButton.h>
|
||||||
|
#include <Wt/WRegExpValidator.h>
|
||||||
|
|
||||||
|
PopupAddUid::PopupAddUid(WWidget * anchorWidget,
|
||||||
|
TransientMessageWidget * txtMessage,
|
||||||
|
const WLength& width)
|
||||||
|
: WPopupWidget(cpp14::make_unique<WContainerWidget>())
|
||||||
|
{
|
||||||
|
m_tmwMessage = txtMessage;
|
||||||
|
m_cwMain = NULL;
|
||||||
|
m_leName = NULL;
|
||||||
|
m_leEmail = NULL;
|
||||||
|
m_leComment = NULL;
|
||||||
|
m_lePassphrase = NULL;
|
||||||
|
m_btnApply = NULL;
|
||||||
|
|
||||||
|
m_nodeName = WString::Empty;
|
||||||
|
m_nodeEmail = WString::Empty;
|
||||||
|
m_nodeComment = WString::Empty;
|
||||||
|
|
||||||
|
setTransient(true);
|
||||||
|
setAnchorWidget(anchorWidget);
|
||||||
|
setWidth(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupAddUid::~PopupAddUid()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopupAddUid::Create()
|
||||||
|
{
|
||||||
|
m_cwMain = static_cast<WContainerWidget*> (implementation());
|
||||||
|
m_cwMain->setStyleClass("popup");
|
||||||
|
WVBoxLayout * vblMain = new WVBoxLayout();
|
||||||
|
m_cwMain->setLayout(unique_ptr<WVBoxLayout> (vblMain));
|
||||||
|
WGridLayout * grlMain = new WGridLayout();
|
||||||
|
grlMain->setColumnStretch(1, 1);
|
||||||
|
vblMain->addLayout(unique_ptr<WGridLayout> (grlMain));
|
||||||
|
|
||||||
|
WText * lblName = new WText(TR("Name"));
|
||||||
|
grlMain->addWidget(unique_ptr<WText> (lblName), 0, 0);
|
||||||
|
m_leName = new WLineEdit();
|
||||||
|
grlMain->addWidget(unique_ptr<WLineEdit> (m_leName), 0, 1);
|
||||||
|
WText * lblEmail = new WText(TR("Email"));
|
||||||
|
grlMain->addWidget(unique_ptr<WText> (lblEmail), 1, 0);
|
||||||
|
m_leEmail = new WLineEdit();
|
||||||
|
grlMain->addWidget(unique_ptr<WLineEdit> (m_leEmail), 1, 1);
|
||||||
|
WText * lblComment = new WText(TR("Comment"));
|
||||||
|
grlMain->addWidget(unique_ptr<WText> (lblComment), 2, 0);
|
||||||
|
m_leComment = new WLineEdit();
|
||||||
|
grlMain->addWidget(unique_ptr<WLineEdit> (m_leComment), 2, 1);
|
||||||
|
m_lblPassphrase = new WText(TR("Passphrase"));
|
||||||
|
grlMain->addWidget(unique_ptr<WText> (m_lblPassphrase), 3, 0);
|
||||||
|
m_lePassphrase = new WLineEdit();
|
||||||
|
m_lePassphrase->setEchoMode(EchoMode::Password);
|
||||||
|
grlMain->addWidget(unique_ptr<WLineEdit> (m_lePassphrase), 3, 1);
|
||||||
|
|
||||||
|
WHBoxLayout * hblWhat = new WHBoxLayout();
|
||||||
|
WRadioButton * rbAdd = new WRadioButton(WString(TR("AddUid")));
|
||||||
|
hblWhat->addWidget(unique_ptr<WRadioButton> (rbAdd));
|
||||||
|
WRadioButton * rbRevoke = new WRadioButton(WString(TR("RevokeUid")));
|
||||||
|
hblWhat->addWidget(unique_ptr<WRadioButton> (rbRevoke));
|
||||||
|
m_bgWhat = make_shared<WButtonGroup>();
|
||||||
|
m_bgWhat->addButton(rbAdd, What::Add);
|
||||||
|
m_bgWhat->addButton(rbRevoke, What::Revoke);
|
||||||
|
m_bgWhat->setCheckedButton(rbAdd);
|
||||||
|
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblWhat));
|
||||||
|
|
||||||
|
m_cbConfirm = new WCheckBox(TR("Confirm"));
|
||||||
|
vblMain->addWidget(unique_ptr<WCheckBox> (m_cbConfirm));
|
||||||
|
|
||||||
|
WHBoxLayout * hblButtons = new WHBoxLayout();
|
||||||
|
WPushButton * btnClose = new WPushButton(TR("Close"));
|
||||||
|
hblButtons->addWidget(unique_ptr<WPushButton> (btnClose));
|
||||||
|
m_btnApply = new WPushButton(TR("Apply"));
|
||||||
|
hblButtons->addWidget(unique_ptr<WPushButton> (m_btnApply));
|
||||||
|
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblButtons));
|
||||||
|
|
||||||
|
m_bgWhat->checkedChanged().connect(this, &PopupAddUid::OnButtonGroupWhat);
|
||||||
|
btnClose->clicked().connect(this, &WPopupWidget::hide);
|
||||||
|
this->hidden().connect(m_cbConfirm, &WCheckBox::setUnChecked);
|
||||||
|
|
||||||
|
// From WRegExpValidator docs
|
||||||
|
shared_ptr<WRegExpValidator> validator
|
||||||
|
= make_shared<WRegExpValidator>
|
||||||
|
("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}");
|
||||||
|
validator->setMandatory(true);
|
||||||
|
m_leEmail->setValidator(validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopupAddUid::ShowPassphrase(bool show)
|
||||||
|
{
|
||||||
|
// See comments in PopupCertifyUserId::ShowPassphrase
|
||||||
|
if (show)
|
||||||
|
{
|
||||||
|
m_lblPassphrase->show();
|
||||||
|
m_lePassphrase->show();
|
||||||
|
m_lePassphrase->setText(WString::Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_lblPassphrase->hide();
|
||||||
|
m_lePassphrase->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopupAddUid::OnButtonGroupWhat(WRadioButton * btn)
|
||||||
|
{
|
||||||
|
m_leName->setDisabled(m_bgWhat->checkedId() == What::Revoke);
|
||||||
|
m_leEmail->setDisabled(m_bgWhat->checkedId() == What::Revoke);
|
||||||
|
m_leComment->setDisabled(m_bgWhat->checkedId() == What::Revoke);
|
||||||
|
|
||||||
|
m_leName->setText(m_nodeName);
|
||||||
|
if (m_bgWhat->checkedId() == What::Revoke)
|
||||||
|
{
|
||||||
|
m_leEmail->setText(m_nodeEmail);
|
||||||
|
m_leComment->setText(m_nodeComment);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_leEmail->setText(WString::Empty);
|
||||||
|
m_leComment->setText(WString::Empty);
|
||||||
|
}
|
||||||
|
m_cbConfirm->setUnChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopupAddUid::SetNodeIdentity(const WString& name, const WString& email,
|
||||||
|
const WString& comment)
|
||||||
|
{
|
||||||
|
m_nodeName = name;
|
||||||
|
m_nodeEmail = email;
|
||||||
|
m_nodeComment = comment;
|
||||||
|
OnButtonGroupWhat(m_bgWhat->checkedButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopupAddUid::Validate() const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* It's pointless to check if a passphrase is provided as the loopback
|
||||||
|
* passphrase provider won't ever be called as long as gpg-agent holds a
|
||||||
|
* valid passphrase from a previous transaction.
|
||||||
|
*/
|
||||||
|
if (m_bgWhat->checkedId() == What::Revoke)
|
||||||
|
return (m_cbConfirm->isChecked());
|
||||||
|
return (m_cbConfirm->isChecked()
|
||||||
|
&& (m_leEmail->validate() == ValidationState::Valid));
|
||||||
|
}
|
||||||
124
PopupAddUid.h
Normal file
124
PopupAddUid.h
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* File: PopupAddUid.h
|
||||||
|
* Author: SET - nmset@yandex.com
|
||||||
|
* License : GPL v2
|
||||||
|
* Copyright SET - © 2019
|
||||||
|
*
|
||||||
|
* Created on November 16, 2020, 3:59 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef POPUPADDUID_H
|
||||||
|
#define POPUPADDUID_H
|
||||||
|
|
||||||
|
#include <Wt/WPopupWidget.h>
|
||||||
|
#include <Wt/WContainerWidget.h>
|
||||||
|
#include <Wt/WText.h>
|
||||||
|
#include <Wt/WLineEdit.h>
|
||||||
|
#include <Wt/WCheckBox.h>
|
||||||
|
#include <Wt/WPushButton.h>
|
||||||
|
#include <Wt/WButtonGroup.h>
|
||||||
|
#include "TransientMessageWidget.h"
|
||||||
|
|
||||||
|
using namespace Wt;
|
||||||
|
|
||||||
|
class PopupAddUid : public WPopupWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum What
|
||||||
|
{
|
||||||
|
Revoke = 0, Add
|
||||||
|
};
|
||||||
|
PopupAddUid(WWidget * anchorWidget, TransientMessageWidget * txtMessage,
|
||||||
|
const WLength& width = 400);
|
||||||
|
virtual ~PopupAddUid();
|
||||||
|
void Create();
|
||||||
|
|
||||||
|
const WString GetName() const
|
||||||
|
{
|
||||||
|
return m_leName->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPGME enforces a rightly formatted email address here.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const WString GetEmail() const
|
||||||
|
{
|
||||||
|
return m_leEmail->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
const WString GetComment() const
|
||||||
|
{
|
||||||
|
return m_leComment->text();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Add or revoke uid.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const What WhatToDo() const
|
||||||
|
{
|
||||||
|
return (What) m_bgWhat->checkedId();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Controls visibility of passphrase widgets.
|
||||||
|
* \n Need not be always visible as the passphrase is cached by gpg-agent.
|
||||||
|
* \n During that caching period, a wrong input passphrase will not be looked
|
||||||
|
* for by GPG engine, and may be confusing.
|
||||||
|
* @param show
|
||||||
|
*/
|
||||||
|
void ShowPassphrase(bool show = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to forward the passphrase to the loopback passphrase provider.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const string GetPassphrase()
|
||||||
|
{
|
||||||
|
return m_lePassphrase->text().toUTF8();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caller binds its function here.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
WPushButton* GetApplyButton()
|
||||||
|
{
|
||||||
|
return m_btnApply;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Identity values from the tree table node. Should not be modified here
|
||||||
|
* once assigned. Only KeyEdit::OnUidEmailClicked should do that.
|
||||||
|
* @param name
|
||||||
|
* @param email
|
||||||
|
* @param comment
|
||||||
|
*/
|
||||||
|
void SetNodeIdentity(const WString& name, const WString& email,
|
||||||
|
const WString& comment);
|
||||||
|
/**
|
||||||
|
* Confirmation is mandatory.
|
||||||
|
* \n If adding a uid, a rightly formatted email address is required.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool Validate() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TransientMessageWidget * m_tmwMessage;
|
||||||
|
WContainerWidget * m_cwMain;
|
||||||
|
WLineEdit * m_leName;
|
||||||
|
WLineEdit * m_leEmail;
|
||||||
|
WLineEdit * m_leComment;
|
||||||
|
WText * m_lblPassphrase;
|
||||||
|
WLineEdit * m_lePassphrase;
|
||||||
|
shared_ptr<WButtonGroup> m_bgWhat;
|
||||||
|
WCheckBox * m_cbConfirm;
|
||||||
|
WPushButton * m_btnApply;
|
||||||
|
|
||||||
|
// Identity values from the tree table node.
|
||||||
|
WString m_nodeName, m_nodeEmail, m_nodeComment;
|
||||||
|
|
||||||
|
void OnButtonGroupWhat(WRadioButton * btn);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* POPUPADDUID_H */
|
||||||
|
|
||||||
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
It is developed in C++ as a NetBeans project on the [WebToolkit](https://www.webtoolkit.eu/)(Wt) libraries.
|
It is developed in C++ as a NetBeans project on the [WebToolkit](https://www.webtoolkit.eu/)(Wt) libraries.
|
||||||
|
|
||||||
It allows to view, import, export, create, delete keys. Certification trust level, secret key expiry date can also be changed, and user identities can be certified.
|
It allows to view, import, export, create, delete keys. Certification trust level, secret key expiry date can also be changed, and user identities can be added, revoked and certified.
|
||||||
Export concerns public keys only; secret keys cannot be technically exported on a web server.
|
Export concerns public keys only; secret keys cannot be technically exported on a web server.
|
||||||
Adding user identities is not (yet) implemented.
|
|
||||||
|
|
||||||
Available keys can then be used by other Wt applications, or web applications based on other libraries, to encrypt and sign data. As such, it suits my personal needs.
|
Available keys can then be used by other Wt applications, or web applications based on other libraries, to encrypt and sign data. As such, it suits my personal needs.
|
||||||
|
|
||||||
|
|||||||
@@ -132,4 +132,9 @@
|
|||||||
|
|
||||||
<message id='Export'>Export</message>
|
<message id='Export'>Export</message>
|
||||||
<message id='TTTExport'>Exporting secret keys is technically impossible</message>
|
<message id='TTTExport'>Exporting secret keys is technically impossible</message>
|
||||||
|
|
||||||
|
<message id='AddUid'>Add an identity</message>
|
||||||
|
<message id='RevokeUid'>Revoke identity</message>
|
||||||
|
<message id='InvalidInput'>Input is invalid</message>
|
||||||
|
|
||||||
</messages>
|
</messages>
|
||||||
@@ -132,4 +132,9 @@
|
|||||||
|
|
||||||
<message id='Export'>Exporter</message>
|
<message id='Export'>Exporter</message>
|
||||||
<message id='TTTExport'>L'export des clés secrètes est techniquement impossible</message>
|
<message id='TTTExport'>L'export des clés secrètes est techniquement impossible</message>
|
||||||
|
|
||||||
|
<message id='AddUid'>Ajouter une identité</message>
|
||||||
|
<message id='RevokeUid'>Revoquer une identité</message>
|
||||||
|
<message id='InvalidInput'>Saisie invalide</message>
|
||||||
|
|
||||||
</messages>
|
</messages>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"canEditUidValidity" : true,
|
"canEditUidValidity" : true,
|
||||||
"canEditExpiryTime" : true,
|
"canEditExpiryTime" : true,
|
||||||
"canCreateKeys" : true,
|
"canCreateKeys" : true,
|
||||||
|
"canAddRevokeUids" : true,
|
||||||
"privKeyIds" : [
|
"privKeyIds" : [
|
||||||
"FullKeyId1",
|
"FullKeyId1",
|
||||||
"FullKeyId2"
|
"FullKeyId2"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ OBJECTFILES= \
|
|||||||
${OBJECTDIR}/KeyEdit.o \
|
${OBJECTDIR}/KeyEdit.o \
|
||||||
${OBJECTDIR}/KeyringIO.o \
|
${OBJECTDIR}/KeyringIO.o \
|
||||||
${OBJECTDIR}/LoopbackPassphraseProvider.o \
|
${OBJECTDIR}/LoopbackPassphraseProvider.o \
|
||||||
|
${OBJECTDIR}/PopupAddUid.o \
|
||||||
${OBJECTDIR}/PopupCertifyUserId.o \
|
${OBJECTDIR}/PopupCertifyUserId.o \
|
||||||
${OBJECTDIR}/PopupCreate.o \
|
${OBJECTDIR}/PopupCreate.o \
|
||||||
${OBJECTDIR}/PopupDeleter.o \
|
${OBJECTDIR}/PopupDeleter.o \
|
||||||
@@ -112,6 +113,11 @@ ${OBJECTDIR}/LoopbackPassphraseProvider.o: LoopbackPassphraseProvider.cpp
|
|||||||
${RM} "$@.d"
|
${RM} "$@.d"
|
||||||
$(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LoopbackPassphraseProvider.o LoopbackPassphraseProvider.cpp
|
$(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LoopbackPassphraseProvider.o LoopbackPassphraseProvider.cpp
|
||||||
|
|
||||||
|
${OBJECTDIR}/PopupAddUid.o: PopupAddUid.cpp
|
||||||
|
${MKDIR} -p ${OBJECTDIR}
|
||||||
|
${RM} "$@.d"
|
||||||
|
$(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupAddUid.o PopupAddUid.cpp
|
||||||
|
|
||||||
${OBJECTDIR}/PopupCertifyUserId.o: PopupCertifyUserId.cpp
|
${OBJECTDIR}/PopupCertifyUserId.o: PopupCertifyUserId.cpp
|
||||||
${MKDIR} -p ${OBJECTDIR}
|
${MKDIR} -p ${OBJECTDIR}
|
||||||
${RM} "$@.d"
|
${RM} "$@.d"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ OBJECTFILES= \
|
|||||||
${OBJECTDIR}/KeyEdit.o \
|
${OBJECTDIR}/KeyEdit.o \
|
||||||
${OBJECTDIR}/KeyringIO.o \
|
${OBJECTDIR}/KeyringIO.o \
|
||||||
${OBJECTDIR}/LoopbackPassphraseProvider.o \
|
${OBJECTDIR}/LoopbackPassphraseProvider.o \
|
||||||
|
${OBJECTDIR}/PopupAddUid.o \
|
||||||
${OBJECTDIR}/PopupCertifyUserId.o \
|
${OBJECTDIR}/PopupCertifyUserId.o \
|
||||||
${OBJECTDIR}/PopupCreate.o \
|
${OBJECTDIR}/PopupCreate.o \
|
||||||
${OBJECTDIR}/PopupDeleter.o \
|
${OBJECTDIR}/PopupDeleter.o \
|
||||||
@@ -112,6 +113,11 @@ ${OBJECTDIR}/LoopbackPassphraseProvider.o: LoopbackPassphraseProvider.cpp
|
|||||||
${RM} "$@.d"
|
${RM} "$@.d"
|
||||||
$(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LoopbackPassphraseProvider.o LoopbackPassphraseProvider.cpp
|
$(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LoopbackPassphraseProvider.o LoopbackPassphraseProvider.cpp
|
||||||
|
|
||||||
|
${OBJECTDIR}/PopupAddUid.o: PopupAddUid.cpp
|
||||||
|
${MKDIR} -p ${OBJECTDIR}
|
||||||
|
${RM} "$@.d"
|
||||||
|
$(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupAddUid.o PopupAddUid.cpp
|
||||||
|
|
||||||
${OBJECTDIR}/PopupCertifyUserId.o: PopupCertifyUserId.cpp
|
${OBJECTDIR}/PopupCertifyUserId.o: PopupCertifyUserId.cpp
|
||||||
${MKDIR} -p ${OBJECTDIR}
|
${MKDIR} -p ${OBJECTDIR}
|
||||||
${RM} "$@.d"
|
${RM} "$@.d"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ OBJECTFILES= \
|
|||||||
${OBJECTDIR}/KeyEdit.o \
|
${OBJECTDIR}/KeyEdit.o \
|
||||||
${OBJECTDIR}/KeyringIO.o \
|
${OBJECTDIR}/KeyringIO.o \
|
||||||
${OBJECTDIR}/LoopbackPassphraseProvider.o \
|
${OBJECTDIR}/LoopbackPassphraseProvider.o \
|
||||||
|
${OBJECTDIR}/PopupAddUid.o \
|
||||||
${OBJECTDIR}/PopupCertifyUserId.o \
|
${OBJECTDIR}/PopupCertifyUserId.o \
|
||||||
${OBJECTDIR}/PopupCreate.o \
|
${OBJECTDIR}/PopupCreate.o \
|
||||||
${OBJECTDIR}/PopupDeleter.o \
|
${OBJECTDIR}/PopupDeleter.o \
|
||||||
@@ -112,6 +113,11 @@ ${OBJECTDIR}/LoopbackPassphraseProvider.o: LoopbackPassphraseProvider.cpp
|
|||||||
${RM} "$@.d"
|
${RM} "$@.d"
|
||||||
$(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LoopbackPassphraseProvider.o LoopbackPassphraseProvider.cpp
|
$(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/LoopbackPassphraseProvider.o LoopbackPassphraseProvider.cpp
|
||||||
|
|
||||||
|
${OBJECTDIR}/PopupAddUid.o: PopupAddUid.cpp
|
||||||
|
${MKDIR} -p ${OBJECTDIR}
|
||||||
|
${RM} "$@.d"
|
||||||
|
$(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupAddUid.o PopupAddUid.cpp
|
||||||
|
|
||||||
${OBJECTDIR}/PopupCertifyUserId.o: PopupCertifyUserId.cpp
|
${OBJECTDIR}/PopupCertifyUserId.o: PopupCertifyUserId.cpp
|
||||||
${MKDIR} -p ${OBJECTDIR}
|
${MKDIR} -p ${OBJECTDIR}
|
||||||
${RM} "$@.d"
|
${RM} "$@.d"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<itemPath>KeyEdit.h</itemPath>
|
<itemPath>KeyEdit.h</itemPath>
|
||||||
<itemPath>KeyringIO.h</itemPath>
|
<itemPath>KeyringIO.h</itemPath>
|
||||||
<itemPath>LoopbackPassphraseProvider.h</itemPath>
|
<itemPath>LoopbackPassphraseProvider.h</itemPath>
|
||||||
|
<itemPath>PopupAddUid.h</itemPath>
|
||||||
<itemPath>PopupCertifyUserId.h</itemPath>
|
<itemPath>PopupCertifyUserId.h</itemPath>
|
||||||
<itemPath>PopupCreate.h</itemPath>
|
<itemPath>PopupCreate.h</itemPath>
|
||||||
<itemPath>PopupDeleter.h</itemPath>
|
<itemPath>PopupDeleter.h</itemPath>
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
<itemPath>KeyEdit.cpp</itemPath>
|
<itemPath>KeyEdit.cpp</itemPath>
|
||||||
<itemPath>KeyringIO.cpp</itemPath>
|
<itemPath>KeyringIO.cpp</itemPath>
|
||||||
<itemPath>LoopbackPassphraseProvider.cpp</itemPath>
|
<itemPath>LoopbackPassphraseProvider.cpp</itemPath>
|
||||||
|
<itemPath>PopupAddUid.cpp</itemPath>
|
||||||
<itemPath>PopupCertifyUserId.cpp</itemPath>
|
<itemPath>PopupCertifyUserId.cpp</itemPath>
|
||||||
<itemPath>PopupCreate.cpp</itemPath>
|
<itemPath>PopupCreate.cpp</itemPath>
|
||||||
<itemPath>PopupDeleter.cpp</itemPath>
|
<itemPath>PopupDeleter.cpp</itemPath>
|
||||||
@@ -120,6 +122,10 @@
|
|||||||
</item>
|
</item>
|
||||||
<item path="LoopbackPassphraseProvider.h" ex="false" tool="3" flavor2="0">
|
<item path="LoopbackPassphraseProvider.h" ex="false" tool="3" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
|
<item path="PopupAddUid.cpp" ex="false" tool="1" flavor2="0">
|
||||||
|
</item>
|
||||||
|
<item path="PopupAddUid.h" ex="false" tool="3" flavor2="0">
|
||||||
|
</item>
|
||||||
<item path="PopupCertifyUserId.cpp" ex="false" tool="1" flavor2="0">
|
<item path="PopupCertifyUserId.cpp" ex="false" tool="1" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
<item path="PopupCertifyUserId.h" ex="false" tool="3" flavor2="0">
|
<item path="PopupCertifyUserId.h" ex="false" tool="3" flavor2="0">
|
||||||
@@ -232,6 +238,10 @@
|
|||||||
</item>
|
</item>
|
||||||
<item path="LoopbackPassphraseProvider.h" ex="false" tool="3" flavor2="0">
|
<item path="LoopbackPassphraseProvider.h" ex="false" tool="3" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
|
<item path="PopupAddUid.cpp" ex="false" tool="1" flavor2="0">
|
||||||
|
</item>
|
||||||
|
<item path="PopupAddUid.h" ex="false" tool="3" flavor2="0">
|
||||||
|
</item>
|
||||||
<item path="PopupCertifyUserId.cpp" ex="false" tool="1" flavor2="0">
|
<item path="PopupCertifyUserId.cpp" ex="false" tool="1" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
<item path="PopupCertifyUserId.h" ex="false" tool="3" flavor2="0">
|
<item path="PopupCertifyUserId.h" ex="false" tool="3" flavor2="0">
|
||||||
@@ -348,6 +358,10 @@
|
|||||||
</item>
|
</item>
|
||||||
<item path="LoopbackPassphraseProvider.h" ex="false" tool="3" flavor2="0">
|
<item path="LoopbackPassphraseProvider.h" ex="false" tool="3" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
|
<item path="PopupAddUid.cpp" ex="false" tool="1" flavor2="0">
|
||||||
|
</item>
|
||||||
|
<item path="PopupAddUid.h" ex="false" tool="3" flavor2="0">
|
||||||
|
</item>
|
||||||
<item path="PopupCertifyUserId.cpp" ex="false" tool="1" flavor2="0">
|
<item path="PopupCertifyUserId.cpp" ex="false" tool="1" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
<item path="PopupCertifyUserId.h" ex="false" tool="3" flavor2="0">
|
<item path="PopupCertifyUserId.h" ex="false" tool="3" flavor2="0">
|
||||||
|
|||||||
Reference in New Issue
Block a user