Implement sq key userid revoke --name and --email.

- User ID is an OpenPGP concept, whereas users think in names and
    email addresses.

  - See #30.
This commit is contained in:
Justus Winter 2024-08-16 16:10:09 +02:00
parent bf056997a9
commit 8c96a9e5d0
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
2 changed files with 45 additions and 7 deletions

View File

@ -198,6 +198,7 @@ instead of the current time.",
)]
#[clap(group(ArgGroup::new("cert_input").args(&["cert_file", "cert"]).required(true)))]
#[clap(group(ArgGroup::new("revoker_input").args(&["revoker_file", "revoker"])))]
#[clap(group(ArgGroup::new("cert-userid").args(&["name", "email", "userid"]).required(true)))]
pub struct RevokeCommand {
#[clap(
long,
@ -249,18 +250,39 @@ for the file to contain more than one certificate.",
)]
pub revoker_file: Option<FileOrStdin>,
#[clap(
long = "name",
value_name = "NAME",
help = "Revoke the given name user ID",
long_help = "\
Revoke the given name user ID. Must match a user ID exactly. To revoke
a user ID that contains more than just a name, use `--userid`.",
)]
pub name: Option<String>,
#[clap(
long = "email",
value_name = "ADDRESS",
help = "Revoke the given email address user ID",
long_help = "\
Revoke the given email address user ID. Must match a user ID exactly.
To revoke a user ID that contains more than just an email address name,
use `--userid`.",
)]
pub email: Option<String>,
#[clap(
long,
value_name = "USERID",
help = "The user ID to revoke",
help = "Revoke the given user ID",
long_help = "\
The user ID to revoke.
Revoke the given user ID.
By default, this must exactly match a self-signed User ID. Use \
`--force` to generate a revocation certificate for a User ID that is \
not self signed."
)]
pub userid: String,
pub userid: Option<String>,
#[clap(
value_enum,

View File

@ -35,7 +35,13 @@ use crate::cli::types::FileOrStdout;
use crate::common::NULL_POLICY;
use crate::common::RevocationOutput;
use crate::common::get_secret_signer;
use crate::common::userid::{lint_userids, lint_names, lint_emails};
use crate::common::userid::{
lint_email,
lint_emails,
lint_name,
lint_names,
lint_userids,
};
use crate::parse_notations;
/// Handle the revocation of a User ID
@ -51,7 +57,7 @@ impl UserIDRevocation {
/// Create a new UserIDRevocation
pub fn new(
sq: &Sq,
userid: String,
uid: UserID,
force: bool,
cert: Cert,
revoker: Option<Cert>,
@ -62,7 +68,7 @@ impl UserIDRevocation {
let (revoker, mut signer)
= get_secret_signer(sq, &cert, revoker.as_ref())?;
let uid = UserID::from(userid.as_str());
let userid = String::from_utf8_lossy(uid.value()).to_string();
let revocation_packet = {
// Create a revocation for a User ID.
@ -516,6 +522,16 @@ pub fn userid_revoke(
panic!("clap enforces --cert or --cert-file");
};
let userid = if let Some(n) = command.name {
lint_name(&n)?;
UserID::from(n)
} else if let Some(e) = command.email {
lint_email(&e)?;
UserID::from_address(None, None, e)?
} else {
UserID::from(command.userid.expect("one of the three must be given"))
};
let revoker = if let Some(file) = command.revoker_file {
let br = file.open()?;
Some(Cert::from_buffered_reader(br)?)
@ -529,7 +545,7 @@ pub fn userid_revoke(
let revocation = UserIDRevocation::new(
&sq,
command.userid,
userid,
sq.force,
cert,
revoker,