diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index e6a450c..701d090 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -112,6 +112,11 @@ section { padding: 1em 2em; } +textarea { + width: 100%; + min-height: 10rem; +} + nav h1 { margin: 0; font-size: .9rem; diff --git a/app/controllers/keys_controller.rb b/app/controllers/keys_controller.rb index 7ad593c..ea269f3 100644 --- a/app/controllers/keys_controller.rb +++ b/app/controllers/keys_controller.rb @@ -15,13 +15,27 @@ def create redirect_to handle_key_path(handle_id: @handle.name, id: @key.fingerprint) end + def edit + @key = @handle.keys.find_by_fingerprint(params[:id]) + end + + def update + @key = @handle.keys.find_by_fingerprint(params[:id]) + if @key.update(key_params) + redirect_to handle_key_path(handle_id: @handle.name, id: @key.fingerprint) + else + flash[:notice] = "not a valid public key" + redirect_to edit_handle_key_path(handle_id: @handle.name, id: @key.fingerprint) + end + end + def show - @key = Handle.find_by_name(params[:handle_id]).keys.find_by_fingerprint(params[:id]) + @key = @handle.keys.find_by_fingerprint(params[:id]) @proof = @key.proofs.key.first || @key.proofs.new end def claim - @key = Handle.find_by_name(params[:handle_id]).keys.find_by_fingerprint(params[:key_id]) + @key = @handle.keys.find_by_fingerprint(params[:key_id]) end private diff --git a/app/models/key.rb b/app/models/key.rb index b63c9e7..42e82b9 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -17,10 +17,15 @@ def set_kind_and_fingerprint else 'minisign' end + begin self.fingerprint = if kind&.match(/ssh/) SSHData::PublicKey.parse_openssh(content).fingerprint(md5: true) else Minisign::PublicKey.new(content).key_id end + rescue + throw :abort + end + end end diff --git a/app/views/keys/edit.html.erb b/app/views/keys/edit.html.erb new file mode 100644 index 0000000..8bbdf98 --- /dev/null +++ b/app/views/keys/edit.html.erb @@ -0,0 +1,6 @@ +

Public Key ID: <%= @key.fingerprint %>

+ +<%= form_with model: @key, url: handle_key_path(handle_id: @handle.name, id: @key.fingerprint), method: :patch do |f| %> + <%= f.text_area :content, value: @key.content %> + <%= f.submit %> +<% end %> diff --git a/app/views/keys/show.html.erb b/app/views/keys/show.html.erb index 7c55453..d55ef16 100644 --- a/app/views/keys/show.html.erb +++ b/app/views/keys/show.html.erb @@ -1,7 +1,13 @@

Public Key ID: <%= @key.fingerprint %>

+ +
<%= @key.content %>
-<%= link_to "curl/raw", handle_key_path(handle_id: @handle.name, id: @key.fingerprint, format: 'txt') %> +<%= link_to "$ curl/raw", handle_key_path(handle_id: @handle.name, id: @key.fingerprint, format: 'txt') %> + <% if @key.proofs.first.persisted? %> +<% if current_handle == @handle.name %> + <%= link_to "± edit key", edit_handle_key_path(handle_id: @handle.name, id: @key.fingerprint) %> +<% end %>

This key has been verified! <%= link_to "View proof", handle_key_proof_path(handle_id: @handle.name, key_id: @key.fingerprint) %> diff --git a/spec/features/adding_keys_spec.rb b/spec/features/adding_keys_spec.rb index e4ebe79..76b3bd9 100644 --- a/spec/features/adding_keys_spec.rb +++ b/spec/features/adding_keys_spec.rb @@ -11,3 +11,46 @@ expect(page).to have_current_path(new_handle_key_path(handle_id: 'jshawl')) end end + +describe 'Editing Keys' do + it 'only shows a link to edit if logged in' do + @handle = Handle.create(name: 'jshawl') + @key = @handle.keys.create(content: KEYS::MINISIGN) + visit handle_key_path(handle_id: 'jshawl', id: @key.fingerprint) + expect(page).not_to have_content('edit key') + end + it 'only shows a link for current login handle when the key is verified' do + @handle = Handle.create(name: 'jshawl') + @key = @handle.keys.create(content: KEYS::MINISIGN) + allow_any_instance_of(ApplicationHelper).to receive(:current_handle).and_return('jshawl2') + visit handle_key_path(handle_id: 'jshawl', id: @key.fingerprint) + expect(page).not_to have_content('edit key') + + allow_any_instance_of(ApplicationHelper).to receive(:current_handle).and_return('jshawl') + visit handle_key_path(handle_id: 'jshawl', id: @key.fingerprint) + expect(page).not_to have_content('edit key') + + @proof = @key.proofs.create(signature: fixture('claim.txt.minisig'), claim: fixture('claim.txt')) + allow_any_instance_of(ApplicationHelper).to receive(:current_handle).and_return('jshawl') + visit handle_key_path(handle_id: 'jshawl', id: @key.fingerprint) + expect(page).to have_content('edit key') + end + it 'can update keys' do + @handle = Handle.create(name: 'jshawl') + @key = @handle.keys.create(content: KEYS::MINISIGN) + @proof = @key.proofs.create(signature: fixture('claim.txt.minisig'), claim: fixture('claim.txt')) + allow_any_instance_of(ApplicationHelper).to receive(:current_handle).and_return('jshawl') + visit edit_handle_key_path(handle_id: 'jshawl', id: @key.fingerprint) + click_on("Update Key") + end + it 'prevents irreversible issues' do + @handle = Handle.create(name: 'jshawl') + @key = @handle.keys.create(content: KEYS::MINISIGN) + @proof = @key.proofs.create(signature: fixture('claim.txt.minisig'), claim: fixture('claim.txt')) + allow_any_instance_of(ApplicationHelper).to receive(:current_handle).and_return('jshawl') + visit edit_handle_key_path(handle_id: 'jshawl', id: @key.fingerprint) + fill_in("key_content", with: "abcdefg") + click_on("Update Key") + expect(page).to have_content("not a valid public key") + end +end