[Rt-commit] rt branch, 4.4/admin-gpg-keys, repushed
? sunnavy
sunnavy at bestpractical.com
Tue Nov 20 13:48:33 EST 2018
The branch 4.4/admin-gpg-keys was deleted and repushed:
was dacd7a6cb5bd65b729a0937ddbdcc2fee69665fe
now 42f4508fc420d774da792f2868e0d8372d034f59
1: 70d9d4b1b ! 1: b432e61b3 Add admin page to manage GnuPG keys
@@ -19,6 +19,19 @@
+ );
+}
+
++sub TrustKey {
++ my $self = shift;
++ my $key = shift;
++ my $level = shift;
++
++ $level++; # the level format in --import-ownertrust input is +1
++
++ return $self->CallGnuPG(
++ Command => "--import-ownertrust",
++ Content => "$key:$level:\n",
++ );
++}
++
sub GnuPGPath {
state $cache = RT->Config->Get('GnuPG')->{'GnuPG'};
$cache = $_[1] if @_ > 1;
@@ -83,13 +96,12 @@
+<&|/Widgets/TitleBox, title => loc('Import Keys') &>
+
+<form action="<% RT->Config->Get('WebPath')%>/Admin/Tools/GnuPG.html" name="ImportKeys" method="POST" enctype="multipart/form-data">
-+ <input type="hidden" name="Action" value="Import" />
+ <table>
+% my %options = RT->Config->Get('GnuPGOptions');
+% if ( $options{'keyserver'} ) {
+ <tr>
+ <td align="right"><&|/l&>Key</&>:</td>
-+ <td><input name="ImportKey" value="<% $ARGS{ImportKey} // '' %>" size="40" /></td>
++ <td><input name="Key" value="<% $ARGS{Key} // '' %>" size="40" /></td>
+ </tr>
+% }
+ <tr>
@@ -97,7 +109,7 @@
+ <td><textarea name="Content" rows="8" cols="72"><% $ARGS{Content} // '' %></textarea></td>
+ </tr>
+ </table>
-+ <& /Elements/Submit, Label => loc('Import') &>
++ <& /Elements/Submit, Name => 'Import', Label => loc('Import') &>
+</form>
+
+</&>
@@ -105,21 +117,40 @@
+<&|/Widgets/TitleBox, title => loc('GnuPG Public Keys') &>
+
+% if ( $public{info} && @{$public{info}} ) {
-+<form action="<% RT->Config->Get('WebPath')%>/Admin/Tools/GnuPG.html" name="DeletePublicKeys" method="POST" enctype="multipart/form-data">
-+ <input type="hidden" name="Action" value="DeletePublicKey" />
-+ <table>
-+ <tr>
-+ <th><input type="checkbox" name="DeletePublicKeyAll" value="1" onclick="setCheckbox(this, 'DeletePublicKey')"></th>
++<form action="<% RT->Config->Get('WebPath')%>/Admin/Tools/GnuPG.html" name="PublicKeys" method="POST" enctype="multipart/form-data">
++ <table>
++ <tr>
++ <th><input type="checkbox" name="PublicKeyAll" value="1" onclick="setCheckbox(this, 'PublicKey')"></th>
+ <th><% loc('Summary') %></th>
++ <th><% loc('Trust Level') %></th>
+ </tr>
+% for my $item ( @{$public{info}} ) {
+ <tr>
-+ <td><input type="checkbox" name="DeletePublicKey" value="<% $item->{Fingerprint} %>" <% $delete{$item->{Fingerprint}} ? 'checked="checked"' : '' |n %> /></td>
++ <td><input type="checkbox" name="PublicKey" value="<% $item->{Fingerprint} %>" <% $delete{$item->{Fingerprint}} ? 'checked="checked"' : '' |n %> /></td>
+ <td><% $item->{Formatted} %></td>
-+ </tr>
-+% }
-+ </table>
-+ <& /Elements/Submit, Label => loc('Delete'), CheckboxNameRegex => '/^DeletePublicKey(All)?$/', CheckAll => 1, ClearAll => 1 &>
++ <td><% $owner_trust_level{$item->{OwnerTrustChar}} || loc('Not set') %></td>
++ </tr>
++% }
++ </table>
++
++ <hr />
++ <table>
++ <tr>
++ <td class="label"><% loc('Trust Level' ) %></td>
++ <td class="value">
++ <select name="OwnerTrustLevel">
++ <option value="" <% $OwnerTrustLevel eq '' ? 'selected="selected"' : '' |n %> >-</option>
++ <option value="1" <% $OwnerTrustLevel eq 1 ? 'selected="selected"' : '' |n %> ><% $owner_trust_level{1} %></option>
++ <option value="2" <% $OwnerTrustLevel eq 2 ? 'selected="selected"' : '' |n %> ><% $owner_trust_level{2} %></option>
++ <option value="3" <% $OwnerTrustLevel eq 3 ? 'selected="selected"' : '' |n %> ><% $owner_trust_level{3} %></option>
++ <option value="4" <% $OwnerTrustLevel eq 4 ? 'selected="selected"' : '' |n %> ><% $owner_trust_level{4} %></option>
++ <option value="5" <% $OwnerTrustLevel eq 5 ? 'selected="selected"' : '' |n %> ><% $owner_trust_level{5} %></option>
++ </select>
++ </td>
++ </tr>
++ </table>
++ <& /Elements/Submit, Label => loc('Delete'), Name => 'DeletePublic', CheckboxNameRegex => '/^PublicKey(All)?$/', CheckAll => 1, ClearAll => 1 &>
++ <& /Elements/Submit, Label => loc('Save Changes'), Name => 'TrustPublic' &>
+</form>
+% } else {
+<p><&|/l&>No public keys found.</&>
@@ -130,21 +161,21 @@
+<&|/Widgets/TitleBox, title => loc('GnuPG Private Keys') &>
+
+% if ( $private{info} && @{$private{info}} ) {
-+<form action="<% RT->Config->Get('WebPath')%>/Admin/Tools/GnuPG.html" name="DeletePrivateKeys" method="POST" enctype="multipart/form-data">
-+ <input type="hidden" name="Action" value="DeletePrivateKey" />
-+ <table>
-+ <tr>
-+ <th><input type="checkbox" name="DeletePrivateKeyAll" value="1" onclick="setCheckbox(this, 'DeletePrivateKey')"></th>
++<form action="<% RT->Config->Get('WebPath')%>/Admin/Tools/GnuPG.html" name="PrivateKeys" method="POST" enctype="multipart/form-data">
++ <table>
++ <tr>
++ <th><input type="checkbox" name="PrivateKeyAll" value="1" onclick="setCheckbox(this, 'DeletePrivateKey')"></th>
+ <th><% loc('Summary') %></th>
+ </tr>
+% for my $item ( @{$private{info}} ) {
+ <tr>
-+ <td><input type="checkbox" name="DeletePrivateKey" value="<% $item->{Fingerprint} %>" <% $delete{$item->{Fingerprint}} ? 'checked="checked"' : '' |n %> /></td>
++ <td><input type="checkbox" name="PrivateKey" value="<% $item->{Fingerprint} %>" <% $delete{$item->{Fingerprint}} ? 'checked="checked"' : '' |n %> /></td>
+ <td><% $item->{Formatted} %></td>
+ </tr>
+% }
+ </table>
-+ <& /Elements/Submit, Label => loc('Delete'), CheckboxNameRegex => '/^DeletePrivateKey(All)?$/', CheckAll => 1, ClearAll => 1 &>
++ <hr />
++ <& /Elements/Submit, Label => loc('Delete'), Name => 'DeletePrivate', CheckboxNameRegex => '/^PrivateKey(All)?$/', CheckAll => 1, ClearAll => 1 &>
+</form>
+% } else {
+<p><&|/l&>No private keys found.</&>
@@ -159,14 +190,29 @@
+}
+
+my @results;
-+
+my %delete;
+
++my %owner_trust_level = (
++ 1 => loc("I don't know or won't say"),
++ 2 => loc("I do NOT trust"),
++ 3 => loc("I trust marginally"),
++ 4 => loc("I trust fully"),
++ 5 => loc("I trust ultimately"),
++
++ q => loc("I don't know or won't say"),
++ n => loc("I do NOT trust"),
++ m => loc("I trust marginally"),
++ f => loc("I trust fully"),
++ u => loc("I trust ultimately"),
++);
++
+require RT::Crypt::GnuPG;
+
-+if ( $Action eq 'Import' ) {
-+ if ( $ARGS{ImportKey} ) {
-+ my %ret = RT::Crypt::GnuPG->ReceiveKey( $ARGS{ImportKey} );
++if ( $ARGS{Import} ) {
++
++ # show admin detailed imported messages
++ if ( $ARGS{Key} ) {
++ my %ret = RT::Crypt::GnuPG->ReceiveKey( $ARGS{Key} );
+ push @results, split /\n+/, $ret{logger};
+ }
+
@@ -175,16 +221,41 @@
+ push @results, split /\n+/, $ret{logger};
+ }
+}
-+elsif ( $Action =~ /^Delete(?:Public|Private)Key$/ ) {
-+ if ( $ARGS{$Action} ) {
-+ for my $key ( ref $ARGS{$Action} ? @{ $ARGS{$Action} } : $ARGS{$Action} ) {
++elsif ( $ARGS{TrustPublic} ) {
++ if ( length $ARGS{OwnerTrustLevel} && $ARGS{PublicKey} ) {
++ for my $key ( ref $ARGS{PublicKey} ? @{ $ARGS{PublicKey} } : $ARGS{PublicKey} ) {
++ my %ret = RT::Crypt::GnuPG->TrustKey( $key, $ARGS{OwnerTrustLevel} );
++ if ( $ret{exit_code} == 0 ) {
++ if ( $ret{logger} ) {
++
++ # success messages are like "changing ownertrust
++ # from 6 to 4", which is useless and misleading to
++ # end users, so we hide them here.
++
++ RT->Logger->debug( $ret{logger} );
++ push @results, loc( "Key [_1] trust level is updated", substr( $key, -8 ) );
++ }
++ }
++ elsif ( $ret{logger} ) {
++ push @results, split /\n+/, $ret{logger};
++ }
++ }
++ }
++}
++else {
++ for my $type (qw/Public Private/) {
++ next unless $ARGS{"Delete$type"};
++ my $value = $ARGS{"${type}Key"};
++ for my $key ( ref $value ? @$value : $value ) {
+ $delete{$key} ||= 1;
+ my %ret = RT::Crypt::GnuPG->DeleteKey($key);
-+ if ( $ret{logger} ) {
++
++ if ( $ret{exit_code} == 0 ) {
++ # delete is silent, no extra debug messages
++ push @results, loc( "Key [_1] is deleted", substr( $key, -8 ) );
++ }
++ elsif ( $ret{logger} ) {
+ push @results, split /\n+/, $ret{logger};
-+ }
-+ else {
-+ push @results, loc( "Key [_1] is deleted", substr( $key, -8 ) );
+ }
+ }
+ }
@@ -201,7 +272,7 @@
+</%INIT>
+
+<%ARGS>
-+$Action => 'List'
++$OwnerTrustLevel => ''
+</%ARGS>
diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
2: dacd7a6cb ! 2: 42f4508fc Test admin page of "Manage GnuPG Keys"
@@ -25,19 +25,29 @@
+ { form_name => 'ImportKeys',
+ fields =>
+ { Content => RT::Test->file_content( [ 't', 'data', 'gnupg', 'keys', 'recipient-at-example.com.public.key' ] ), },
++ button => 'Import',
+ },
+ 'Import keys for rt-test at example.com'
+);
+
+$m->text_contains('public key "Test User <recipient at example.com>" imported');
+$m->text_contains('Test User <recipient at example.com> (93EB9DE7)');
++$m->text_contains('Test User <recipient at example.com> (93EB9DE7)');
+$m->text_lacks('No public keys found');
+$m->text_contains('No private keys found');
++$m->content_contains( '<td>Not set</td>', 'Default trust level' );
+
-+$m->form_name('DeletePublicKeys');
-+$m->tick( 'DeletePublicKey', '7232A3C60F796865796370A54855ED8893EB9DE7' );
-+$m->submit_form_ok( undef, 'Delete keys for recipient at example.com' );
++$m->form_name('PublicKeys');
++$m->tick( 'PublicKey', '7232A3C60F796865796370A54855ED8893EB9DE7' );
++$m->submit_form_ok( { fields => { OwnerTrustLevel => 4 }, button => 'TrustPublic' }, 'Delete keys for recipient at example.com' );
++$m->text_contains('Key 93EB9DE7 trust level is updated');
++$m->content_contains( '<td>I trust fully</td>', 'Updated trust level' );
+
++$m->form_name('PublicKeys');
++$m->tick( 'PublicKey', '7232A3C60F796865796370A54855ED8893EB9DE7' );
++$m->submit_form_ok( { button => 'DeletePublic' }, 'Delete keys for recipient at example.com' );
++
++$m->text_contains('Key 93EB9DE7 is deleted');
+$m->text_contains('No public keys found');
+$m->text_contains('No private keys found');
+
@@ -45,6 +55,7 @@
+ { form_name => 'ImportKeys',
+ fields =>
+ { Content => RT::Test->file_content( [ 't', 'data', 'gnupg', 'keys', 'rt-test-at-example.com.2.secret.key' ] ), },
++ button => 'Import',
+ },
+ 'Import keys for rt-test at example.com'
+);
@@ -56,10 +67,11 @@
+$m->text_lacks('No public keys found');
+$m->text_lacks('No private keys found');
+
-+$m->form_name('DeletePrivateKeys');
-+$m->tick( 'DeletePrivateKey', '4CFD3F7DCD464852DB980F26C798591AA831DBFB' );
-+$m->submit_form_ok( undef, 'Delete keys for rt-test at example.com' );
++$m->form_name('PrivateKeys');
++$m->tick( 'PrivateKey', '4CFD3F7DCD464852DB980F26C798591AA831DBFB' );
++$m->submit_form_ok( { button => 'DeletePrivate' }, 'Delete keys for rt-test at example.com' );
+
++$m->text_contains('Key A831DBFB is deleted');
+$m->text_contains('No public keys found');
+$m->text_contains('No private keys found');
+
More information about the rt-commit
mailing list