diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2017-09-28 10:36:14 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2017-09-28 10:36:14 +0200 |
commit | 202c08a1339594c482d21c4ff65b5547fc52297a (patch) | |
tree | c080a85496199145d730ab3d72f8a5be63caf90c | |
parent | c2f36fbbfcd7c2d686950ea6d72b88311c040575 (diff) | |
download | sourceyard-202c08a1339594c482d21c4ff65b5547fc52297a.tar.gz sourceyard-202c08a1339594c482d21c4ff65b5547fc52297a.tar.bz2 |
Use file upload to accept new GPG keys
* lib/Sourceyard/Schema/Result/GPG_Keys.pm: Inflate the gpg_key
column to PublicKey, instead of the PublicKeySet.
* lib/App/Sourceyard/GPG/PublicKey.pm (new): Accept keyword
arguments. All callers updated.
* lib/Sourceyard/Controller/User.pm: Use file upload instead of
copy-paste for accepting new keys.
* templates/user/gpg_keys.html.ep: Likewise.
-rw-r--r-- | lib/App/Sourceyard/GPG/PublicKey.pm | 31 | ||||
-rw-r--r-- | lib/App/Sourceyard/GPG/PublicKeySet.pm | 4 | ||||
-rw-r--r-- | lib/Sourceyard/Controller/User.pm | 30 | ||||
-rw-r--r-- | lib/Sourceyard/Schema/Result/GPG_Keys.pm | 19 | ||||
-rw-r--r-- | templates/user/gpg_keys.html.ep | 22 |
5 files changed, 71 insertions, 35 deletions
diff --git a/lib/App/Sourceyard/GPG/PublicKey.pm b/lib/App/Sourceyard/GPG/PublicKey.pm index 2514484..4947d21 100644 --- a/lib/App/Sourceyard/GPG/PublicKey.pm +++ b/lib/App/Sourceyard/GPG/PublicKey.pm @@ -55,7 +55,7 @@ sub _convdate { my $datestr = shift; return undef unless defined $datestr; - + if ($datestr =~ /^(?<Y>\d{4}) (?<m>\d{2}) (?<d>\d{2}) @@ -76,12 +76,29 @@ sub _convdate { sub new { my $class = shift; - my %info = (); - @info{@ATTRIBUTES} = map { defined($_) && $_ eq '' ? undef : $_ } @_; - $info{uid} = [ $info{uid} ] if $info{uid}; - $info{creation_date} = _convdate($info{creation_date}); - $info{expiry_date} = _convdate($info{expiry_date}); - return bless \%info, $class; + my $self = bless {}, $class; + local %_ = @_; + my $v; + + if ($v = delete $_{blob}) { + $self->blob($v); + } + if ($v = delete $_{all}) { + @{$self}{@ATTRIBUTES} = map { + defined($_) && $_ eq '' ? undef : $_ + } @$v; + } + foreach my $attr (@ATTRIBUTES) { + if ($v = delete $_{$attr}) { + $self->{$attr} = $v; + } + } + $self->{uid} = [ $self->{uid} ] if $self->{uid}; + $self->{creation_date} = _convdate($self->{creation_date}); + $self->{expiry_date} = _convdate($self->{expiry_date}); + + croak "unrecogized keywords" unless keys(%_) == 0; + return $self; } sub fingerprint { diff --git a/lib/App/Sourceyard/GPG/PublicKeySet.pm b/lib/App/Sourceyard/GPG/PublicKeySet.pm index 93d4bb2..c724823 100644 --- a/lib/App/Sourceyard/GPG/PublicKeySet.pm +++ b/lib/App/Sourceyard/GPG/PublicKeySet.pm @@ -77,10 +77,10 @@ sub _parse { my $type = shift @fields; if ($type eq 'pub') { push @{$self->{_pubkeys}}, - new App::Sourceyard::GPG::PublicKey($type, @fields); + new App::Sourceyard::GPG::PublicKey(all => [ $type, @fields ]); } elsif ($type eq 'sub') { $self->pubkey(-1)->addsubkey( - new App::Sourceyard::GPG::PublicKey($type, @fields) + new App::Sourceyard::GPG::PublicKey(all => [ $type, @fields ]) ); } elsif ($type eq 'fpr') { if ($self->pubkey(-1)->subkey) { diff --git a/lib/Sourceyard/Controller/User.pm b/lib/Sourceyard/Controller/User.pm index 43aa3ce..780723a 100644 --- a/lib/Sourceyard/Controller/User.pm +++ b/lib/Sourceyard/Controller/User.pm @@ -141,21 +141,25 @@ sub gpg_keys { last; } } - if (my $s = $self->param("key_new")) { - my $mesg; - if ($s = $user->validate_gpg_key($s, \$mesg)) { - foreach my $key ($s->pubkeys) { - $self->db->resultset('GPG_Keys') - ->create({ - user_id => $user->user_id, - gpg_key => $key->blob - }); - } - $self->{_sy_update} = 1; + + if (my $upload = $self->param('ascfile')) { + if ($self->req->is_limit_exceeded) { + $self->stash('error_msg', 'File is too big'); } else { - $self->stash('error_msg', "Invalid GPG key: $mesg"); + my $mesg; + if (my $s = $user->validate_gpg_key($upload->slurp, \$mesg)) { + foreach my $key ($s->pubkeys) { + $self->db->resultset('GPG_Keys') + ->create({ + user_id => $user->user_id, + gpg_key => $key->blob + }); + } + $self->{_sy_update} = 1; + } else { + $self->stash('error_msg', "Invalid GPG key: $mesg"); + } } - $self->param(key_new => undef); } } $self->render; diff --git a/lib/Sourceyard/Schema/Result/GPG_Keys.pm b/lib/Sourceyard/Schema/Result/GPG_Keys.pm index 88f458f..b9606aa 100644 --- a/lib/Sourceyard/Schema/Result/GPG_Keys.pm +++ b/lib/Sourceyard/Schema/Result/GPG_Keys.pm @@ -5,6 +5,7 @@ use warnings; use base 'DBIx::Class::Core'; use App::Sourceyard::GPG::PublicKeySet; +use Carp; __PACKAGE__->table('gpg_keys'); __PACKAGE__->add_columns( @@ -25,7 +26,23 @@ __PACKAGE__->belongs_to('user_id' => 'Sourceyard::Schema::Result::User'); __PACKAGE__->inflate_column('gpg_key', { inflate => sub { my ($value, $object) = @_; - return new App::Sourceyard::GPG::PublicKeySet($value); + my $pks = new App::Sourceyard::GPG::PublicKeySet($value); + if ($pks->status == PKS_SYSERR) { + croak "system error: " . join("\n", $pks->error); + } + if ($pks->status == PKS_INVALID) { + return new App::Sourceyard::GPG::PublicKey( + type => 'pub', + blob => $object + ); + } + if ($pks->status == PKS_EMPTY) { + return new App::Sourceyard::GPG::PublicKey( + type => 'pub', + blob => '' + ); + } + shift @{[$pks->pubkeys()]}; }, deflate => sub { my ($value, $object) = @_; diff --git a/templates/user/gpg_keys.html.ep b/templates/user/gpg_keys.html.ep index 0b01a16..094638c 100644 --- a/templates/user/gpg_keys.html.ep +++ b/templates/user/gpg_keys.html.ep @@ -19,18 +19,18 @@ <tbody> <tr> <td> - <%= $k->gpg_key->pubkey->keyid %> + <%= $k->gpg_key->keyid %> </td> <td> - <%= $k->gpg_key->pubkey->fingerprint %> + <%= $k->gpg_key->fingerprint %> </td> <td> - <%= ${[$k->gpg_key->pubkey->uid]}[0] %> + <%= ${[$k->gpg_key->uid]}[0] %> </td> <td> <span class="smaller"> - (<%= $k->gpg_key->pubkey->length %> bits, - <%= $k->gpg_key->pubkey->algoname %>)</span> + (<%= $k->gpg_key->length %> bits, + <%= $k->gpg_key->algoname %>)</span> </td> <td> %# %= text_field "key_$i" => $k->gpg_key->blob, size => '100' @@ -41,13 +41,11 @@ </tbody> </table> % } - <h3>Add new key</h3> - <div class="input"> -%= text_area "key_new", cols => 70, rows => 10, wrap => 'virtual' - <div class="center"> - %= submit_button 'Add' - </div> - </div> % end +<h3>Upload new key</h3> +%= form_for 'gpg_keys' => (method => 'POST', enctype => 'multipart/form-data') => begin +%= file_field 'ascfile', accept => 'text/plain' +%= submit_button 'Upload' +% end </div> |