Commit 57150363 authored by o@immerda.ch's avatar o@immerda.ch
Browse files

implement support for wkd api

parent c795e6bc
......@@ -68,3 +68,5 @@ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'rest-client'
gem 'zxcvbn-ruby', require: 'zxcvbn'
gem 'gpgme'
......@@ -83,6 +83,8 @@ GEM
ffi (1.10.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
gpgme (2.0.18)
mini_portile2 (~> 2.3)
highline (2.0.2)
http-cookie (1.0.3)
domain_name (~> 0.5)
......@@ -241,6 +243,7 @@ DEPENDENCIES
capybara (>= 2.15, < 4.0)
chromedriver-helper
coffee-rails (~> 4.2)
gpgme
i18n-tasks
jbuilder (~> 2.5)
listen (>= 3.0.5, < 3.2)
......@@ -264,4 +267,4 @@ RUBY VERSION
ruby 2.5.1p57
BUNDLED WITH
1.16.6
1.17.3
......@@ -34,13 +34,17 @@ module ApiBackend
auth.merge(data)
end
def connection_resource(what)
RestClient::Resource.new("#{IAPI::Endpoint}/#{sanitize(what)}",
:ssl_client_cert => IAPI::Cert,
:ssl_client_key => IAPI::Key,
:ssl_ca_file => IAPI::CA,
:verify_ssl => OpenSSL::SSL::VERIFY_PEER)
end
def post(what, data = {})
data = merge_token(data)
res = RestClient::Resource.new("#{IAPI::Endpoint}/#{sanitize(what)}",
:ssl_client_cert => IAPI::Cert,
:ssl_client_key => IAPI::Key,
:ssl_ca_file => IAPI::CA,
:verify_ssl => OpenSSL::SSL::VERIFY_PEER)
res = connection_resource(what)
begin
response = res.post(data.to_json, content_type: :json)
res = JSON.parse(response)
......@@ -58,12 +62,8 @@ module ApiBackend
def get(what, data = {})
data = merge_token(data)
puts data
res = RestClient::Resource.new("#{IAPI::Endpoint}/#{sanitize(what)}",
:ssl_client_cert => IAPI::Cert,
:ssl_client_key => IAPI::Key,
:ssl_ca_file => IAPI::CA,
:verify_ssl => OpenSSL::SSL::VERIFY_PEER)
res = connection_resource(what)
puts res
begin
response = res.get(:params => data)
res = JSON.parse(response)
......
module WkdBackend
class TheBackendImplementation
def sanitize(parts)
parts.map{|v| URI.encode(v)}.join("/")
end
def connection_resource(what)
RestClient::Resource.new("#{WKD::Endpoint}/#{sanitize(what)}",
:ssl_client_cert => WKD::Cert,
:ssl_client_key => WKD::Key,
:ssl_ca_file => WKD::CA,
:verify_ssl => OpenSSL::SSL::VERIFY_PEER
)
end
def fetch(email)
connection_resource([email]).get
rescue RestClient::NotFound
nil
end
def update(email, key)
connection_resource([email]).post(key)
end
def delete(email)
connection_resource([email]).delete()
end
end
def wkd
@the_api ||= TheBackendImplementation.new()
end
end
class WkdController < ApplicationController
include WkdBackend
class WrongUids < RuntimeError
end
def get_key_info(key)
if key
Dir.mktmpdir do |tmpdir|
ENV['GNUPGHOME'] = tmpdir
GPGME::Key.import(key)
key = GPGME::Key.find("").first
uids = key.uids.select{|u| u.email == current_user}
if uids.empty?
all_uids = key.uids.map{|u| "#{u.name} <#{u.email}>"}.join(", ")
raise WrongUids.new(all_uids)
end
uids = uids.map{|u| "#{u.name} <#{u.email}>"}.join(", ")
["#{key.fingerprint} #{uids}", key.export(armor: true).to_s]
end
end
end
def fetch_current_key
res = wkd.fetch(current_user)
info = get_key_info(res)
if info
@key = info.first
end
rescue
flash[:notice] = :failed
@error = true
end
def show
fetch_current_key
end
def update
if params[:delete]
begin
wkd.delete(current_user)
flash[:notice] = :success
rescue
flash[:notice] = :failed
end
else
k = params[:gpg_key]
begin
k = get_key_info(k)
if k
new_key = k.first
new_key_raw = k.second
if params[:confirm]
begin
wkd.update(current_user, new_key_raw)
flash[:notice] = :success
rescue
flash[:notice] = :failed
end
else
@new_key = new_key
@new_key_raw = new_key_raw
end
end
rescue WrongUids => wrong_uids
@wrong_uids = wrong_uids
end
end
fetch_current_key
render 'show'
end
end
......@@ -31,6 +31,11 @@
<br /><%= t(:app_passwords_short_help) %>
</li>
<% end %>
<% if feature_toggle?('wkd') %>
<li><%= link_to (t :wkd) , wkd_path %>
<br /><%= t(:wkd_short_help) %>
</li>
<% end %>
<li style='padding-top:10px'><%= link_to (t :delete_account) , delete_account_path %>
</li>
</ul>
......
<h3><%= @page_title = t(:wkd) %></h3>
<% if @key %>
<p>
<i><%= t(:wkd_existing_key) %></i>
<br />
<%= @key %>
<br />
<br />
</p>
<% end %>
<% if @wrong_uids %>
<p style="border:dashed; padding:10px">
<%= t(:wkd_wrong_uids) %>
<br />
<%= @wrong_uids %>
</p>
<br />
<% end %>
<p>
<% if @new_key %>
<%= t(:wkd_confirm_key) %>
<%= form_tag(wkd_path, method: "post") do %>
<%= hidden_field_tag(:gpg_key, '', value: @new_key_raw) %>
<%= hidden_field_tag(:confirm, '', value: true) %>
<b><%= @new_key %></b>
<br />
<br />
<%= submit_tag(@key ? t(:overwrite) : t(:submit)) %>
<% end %>
<% elsif (!@key && !@error) || params[:show_upd] %>
<%= t(:wkd_set_key) %>
<%= form_tag(wkd_path, method: "post") do %>
<%= text_area_tag(:gpg_key, nil, rows: 25, cols: 70, style: 'width:auto') %>
<br />
<%= submit_tag(@key ? t(:overwrite) : t(:submit)) %>
<% end %>
<% elsif @key %>
<br />
<%= form_tag(wkd_path, method: "get") do %>
<%= hidden_field_tag(:show_upd, '', value: 1) %>
<%= submit_tag(t(:update)) %>
<% end %>
<%= form_tag(wkd_path, method: "post") do %>
<%= hidden_field_tag(:delete, '', value: true) %>
<%= submit_tag(t(:delete)) %>
<% end %>
<% end %>
</p>
<%= link_to t(:back), root_path %>
module WKD
c = ::Config['wkd'] || {}
Endpoint = c['endpoint']
CA = c['ca']
Cert = OpenSSL::X509::Certificate.new(File.read(c['cert'])) if c != {}
Key = OpenSSL::PKey::RSA.new(File.read(c['key'])) if c != {}
end
......@@ -168,6 +168,13 @@ de:
jid_exists_already: Dieser Name ist bereits vergeben
failed: Etwas ist schief gegangen!
wkd: GPG Schlüsselverzeichniss
wkd_short_help: Damit dein GPG Schlüssel automatisch gefunden wird, wenn Andere dir ein Mail schicken wollen, publizieren wir ihn in einem Web Key Directory (WKD).
wkd_set_key: Füge hier einen GPG public key ein, um ihn in unserem Web Key Directory (WKD) zu publizieren. Es können nur Schlüssel für deine Haupt Adresse publiziert werden.
wkd_wrong_uids: "Dieser Key kann nicht publiziert werden. Er lautet nicht auf das Konto mit dem du angemeldet bist, sondern auf:"
wkd_confirm_key: Möchtest du den folgenden Schlüssel publizieren?
wkd_existing_key: "Aktuell ist folgender Schlüssel publiziert:"
activerecord:
errors:
messages:
......
......@@ -54,6 +54,9 @@ Rails.application.routes.draw do
get 'tfa/webauthn/:name/delete', to: redirect('tfa')
end
get '/wkd', to: 'wkd#show'
post '/wkd', to: 'wkd#update'
root to: 'welcome#index'
get '/welcome', to: 'welcome#index'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment