Compare commits
3 Commits
3042a02a17
...
37b106e73c
| Author | SHA1 | Date | |
|---|---|---|---|
|
37b106e73c
|
|||
|
c3f1f97e1a
|
|||
|
4a677178e8
|
34
app/controllers/web_key_directory_controller.rb
Normal file
34
app/controllers/web_key_directory_controller.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
class WebKeyDirectoryController < WellKnownController
|
||||
before_action :allow_cross_origin_requests, only: [ :show ]
|
||||
|
||||
# /.well-known/openpgpkey/hu/:hashed_username(.txt)
|
||||
def show
|
||||
@user = User.find_by(cn: params[:l])
|
||||
|
||||
if @user.nil? ||
|
||||
@user.pgp_pubkey.empty? ||
|
||||
!@user.pgp_pubkey_contains_user_address?
|
||||
http_status :not_found and return
|
||||
end
|
||||
|
||||
if params[:hashed_username] != @user.wkd_hash
|
||||
http_status :unprocessable_entity and return
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.text do
|
||||
response.headers['Content-Type'] = 'text/plain'
|
||||
render plain: @user.pgp_pubkey
|
||||
end
|
||||
|
||||
format.any do
|
||||
key = @user.gnupg_key.export
|
||||
send_data key, filename: "#{@user.wkd_hash}.pem",
|
||||
type: "application/octet-stream"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
end
|
||||
@@ -89,13 +89,47 @@
|
||||
</section>
|
||||
|
||||
<section class="sm:flex-1 sm:pt-0">
|
||||
<% if @avatar.present? %>
|
||||
<h3>LDAP<h3>
|
||||
<p>
|
||||
<img src="data:image/jpeg;base64,<%= @avatar %>" class="h-48 w-48" />
|
||||
</p>
|
||||
<% end %>
|
||||
<!-- <h3>Actions</h3> -->
|
||||
<h3>LDAP</h3>
|
||||
<table class="divided">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Avatar</th>
|
||||
<td>
|
||||
<% if @avatar.present? %>
|
||||
<img src="data:image/jpeg;base64,<%= @avatar %>" class="h-48 w-48" />
|
||||
<% else %>
|
||||
—
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Display name</th>
|
||||
<td><%= @user.display_name || "—" %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="align-top">PGP key</th>
|
||||
<td class="align-top leading-5">
|
||||
<% if @user.pgp_pubkey.present? %>
|
||||
<span class="font-mono" title="<%= @user.pgp_fpr %>">
|
||||
<% if @user.pgp_pubkey_contains_user_address? %>
|
||||
<%= link_to wkd_key_url(hashed_username: @user.wkd_hash, l: @user.cn, format: :txt),
|
||||
class: "ks-text-link", target: "_blank" do %>
|
||||
<%= "#{@user.pgp_fpr[0, 8]}…#{@user.pgp_fpr[-8..-1]}" %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= "#{@user.pgp_fpr[0, 8]}…#{@user.pgp_fpr[-8..-1]}" %>
|
||||
<% end %>
|
||||
</span><br />
|
||||
<% @user.gnupg_key.uids.each do |uid| %>
|
||||
<%= uid.uid %><br />
|
||||
<% end %>
|
||||
<% else %>
|
||||
—
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<h3>E-Mail Password</h3>
|
||||
<%= form_for(@user, url: reset_email_password_settings_path, method: "post") do |f| %>
|
||||
<%= hidden_field_tag :section, "email" %>
|
||||
<p class="mb-8">
|
||||
<p class="mb-6">
|
||||
Use the following button to generate a new email password:
|
||||
</p>
|
||||
<p class="hidden initial-visible">
|
||||
|
||||
@@ -70,10 +70,11 @@ Rails.application.routes.draw do
|
||||
|
||||
get '.well-known/webfinger', to: 'webfinger#show'
|
||||
get '.well-known/nostr', to: 'well_known#nostr'
|
||||
get '.well-known/lnurlp/:username', to: 'lnurlpay#index', as: 'lightning_address'
|
||||
get '.well-known/keysend/:username', to: 'lnurlpay#keysend', as: 'lightning_address_keysend'
|
||||
get '.well-known/lnurlp/:username', to: 'lnurlpay#index', as: :lightning_address
|
||||
get '.well-known/keysend/:username', to: 'lnurlpay#keysend', as: :lightning_address_keysend
|
||||
get '.well-known/openpgpkey/hu/:hashed_username(.:format)', to: 'web_key_directory#show', as: :wkd_key
|
||||
|
||||
get 'lnurlpay/:username/invoice', to: 'lnurlpay#invoice', as: 'lnurlpay_invoice'
|
||||
get 'lnurlpay/:username/invoice', to: 'lnurlpay#invoice', as: :lnurlpay_invoice
|
||||
|
||||
post 'webhooks/lndhub', to: 'webhooks#lndhub'
|
||||
|
||||
|
||||
13
db/seeds/admin.asc
Normal file
13
db/seeds/admin.asc
Normal file
@@ -0,0 +1,13 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEZvGiUxYJKwYBBAHaRw8BAQdARPZXLqyB3nylJuzuARlOJxqc9mchMKHI4Cy+
|
||||
hPWlzja0GEFkbWluIDxhZG1pbkBrb3Ntb3Mub3JnPoiZBBMWCgBBFiEE0pie1+fG
|
||||
ImdZwzGnwgEYSg8AulYFAmbxolMCGwMFCQWjmoAFCwkIBwICIgIGFQoJCAsCBBYC
|
||||
AwECHgcCF4AACgkQwgEYSg8AulaldAEA7yzh7XRCdIJDHgLUvKHsy2NnyLaDD1Tl
|
||||
hyZWbl5og0IBAJAQ2Dm82YXMdUK3X1OGlK8KH5O4E5lSFY4+8/xx0UEJuDgEZvGi
|
||||
UxIKKwYBBAGXVQEFAQEHQJc8pzzeIF7Hm5z1eseRAqGvFa+V1BIDf+1XQzuJhhxi
|
||||
AwEIB4h+BBgWCgAmFiEE0pie1+fGImdZwzGnwgEYSg8AulYFAmbxolMCGwwFCQWj
|
||||
moAACgkQwgEYSg8AulbLtgEApZvuDqSP77lrl1jmtCAJEEZk/ofsRFkf1g3U3Zhm
|
||||
9PcA/1+AbcyqjLTcqIPjHmZyGEPiaAvEsBzbPKEPiL3JYhkG
|
||||
=45sx
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
BIN
spec/fixtures/files/pgp_key_valid_jimmy.pem
vendored
Normal file
BIN
spec/fixtures/files/pgp_key_valid_jimmy.pem
vendored
Normal file
Binary file not shown.
84
spec/requests/web_key_directory_spec.rb
Normal file
84
spec/requests/web_key_directory_spec.rb
Normal file
@@ -0,0 +1,84 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe "OpenPGP Web Key Directory", type: :request do
|
||||
describe "non-existent user" do
|
||||
it "returns a 404 status" do
|
||||
get "/.well-known/openpgpkey/hu/fmb8gw3n4zdj4xpwaziki4mwcxr1368i?l=aristotle"
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
describe "user without pubkey" do
|
||||
let(:user) { create :user, cn: 'bernd', ou: 'kosmos.org' }
|
||||
|
||||
it "returns a 404 status" do
|
||||
get "/.well-known/openpgpkey/hu/kp95h369c89sx8ia1hn447i868nqyz4t?l=bernd"
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
describe "user with pubkey" do
|
||||
let(:alice) { create :user, id: 2, cn: "alice", email: "alice@example.com" }
|
||||
let(:jimmy) { create :user, id: 3, cn: "jimmy", email: "jimmy@example.com" }
|
||||
let(:valid_key_alice) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_valid_alice.asc") }
|
||||
let(:valid_key_jimmy) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_valid_jimmy.asc") }
|
||||
let(:fingerprint_alice) { "EB85BB5FA33A75E15E944E63F231550C4F47E38E" }
|
||||
let(:fingerprint_jimmy) { "316BF516236DAF77236B15F6057D93972FB862C3" }
|
||||
let(:invalid_key) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_invalid.asc") }
|
||||
|
||||
before do
|
||||
GPGME::Key.import(valid_key_alice)
|
||||
GPGME::Key.import(valid_key_jimmy)
|
||||
alice.update pgp_fpr: fingerprint_alice
|
||||
jimmy.update pgp_fpr: fingerprint_jimmy
|
||||
end
|
||||
|
||||
after do
|
||||
alice.gnupg_key.delete!
|
||||
jimmy.gnupg_key.delete!
|
||||
end
|
||||
|
||||
describe "pubkey does not contain user address" do
|
||||
before do
|
||||
allow_any_instance_of(User).to receive(:ldap_entry)
|
||||
.and_return({ pgp_key: valid_key_alice })
|
||||
end
|
||||
|
||||
it "returns a 404 status" do
|
||||
get "/.well-known/openpgpkey/hu/kei1q4tipxxu1yj79k9kfukdhfy631xe?l=alice"
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
describe "pubkey contains user address" do
|
||||
before do
|
||||
allow_any_instance_of(User).to receive(:ldap_entry)
|
||||
.and_return({ pgp_key: valid_key_jimmy })
|
||||
end
|
||||
|
||||
it "returns the pubkey in binary format" do
|
||||
get "/.well-known/openpgpkey/hu/yuca4ky39mhwkjo78qb8zjgbfj1hg3yf?l=jimmy"
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.headers['Content-Type']).to eq("application/octet-stream")
|
||||
expected_binary_data = File.binread("#{Rails.root}/spec/fixtures/files/pgp_key_valid_jimmy.pem")
|
||||
expect(response.body).to eq(expected_binary_data)
|
||||
end
|
||||
|
||||
context "with .txt extension" do
|
||||
it "returns the pubkey as ASCII Armor plain text" do
|
||||
get "/.well-known/openpgpkey/hu/yuca4ky39mhwkjo78qb8zjgbfj1hg3yf.txt?l=jimmy"
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to eq(valid_key_jimmy)
|
||||
expect(response.headers['Content-Type']).to eq("text/plain")
|
||||
end
|
||||
end
|
||||
|
||||
context "invalid URL" do
|
||||
it "returns a 422 status" do
|
||||
get "/.well-known/openpgpkey/hu/123456abcdef?l=alice"
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user