Merge pull request 'Add custom LDAP attributes to schema' (#181) from feature/custom_ldap_attributes into master
All checks were successful
continuous-integration/drone/push Build is passing

Reviewed-on: #181
Reviewed-by: greg <greg@noreply.kosmos.org>
This commit was merged in pull request #181.
This commit is contained in:
2024-03-19 14:46:44 +00:00
24 changed files with 317 additions and 117 deletions

View File

@@ -1,15 +1,19 @@
require 'rails_helper'
RSpec.describe 'Experimental Settings', type: :feature do
RSpec.describe 'Nostr Settings', type: :feature do
let(:user) { create :user, cn: 'jimmy', ou: 'kosmos.org' }
before do
login_as user, scope: :user
allow_any_instance_of(User).to receive(:dn)
.and_return("cn=#{user.cn},ou=kosmos.org,cn=users,dc=kosmos,dc=org")
allow_any_instance_of(User).to receive(:nostr_pubkey).and_return(nil)
end
describe 'Adding a nostr pubkey' do
scenario 'Without nostr browser extension available' do
visit setting_path(:experiments)
visit setting_path(:nostr)
expect(page).to have_content("No browser extension found")
expect(page).to have_css('button[data-settings--nostr-pubkey-target=setPubkey]:disabled')
end
@@ -22,19 +26,22 @@ RSpec.describe 'Experimental Settings', type: :feature do
context "With pubkey configured" do
before do
user.update! nostr_pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3"
allow_any_instance_of(User).to receive(:nostr_pubkey)
.and_return("ce273cbfb0d4e3e06930773a337c1459e4849efd4cb4c751b906a561c98a6d09")
end
scenario 'Remove nostr pubkey from account' do
visit setting_path(:experiments)
visit setting_path(:nostr)
expect(page).to have_field("nostr_public_key",
with: "npub1qlsc3g0lsl8pw8230w8d9wm6xxcax3f6pkemz5measrmwfxjxteslf2hac",
with: "npub1ecnne0as6n37q6fswuarxlq5t8jgf8hafj6vw5deq6jkrjv2d5ysnehu73",
disabled: true)
expect(LdapManager::UpdateNostrKey).to receive(:call).with(
dn: "cn=jimmy,ou=kosmos.org,cn=users,dc=kosmos,dc=org",
pubkey: nil
)
click_link "Remove"
expect(page).to_not have_field("nostr_public_key")
expect(page).to have_content("verify your public key")
expect(user.reload.nostr_pubkey).to be_nil
end
end
end

View File

@@ -66,7 +66,7 @@ RSpec.describe User, type: :model do
it "returns the entries from the LDAP service attribute" do
expect(user).to receive(:ldap_entry).and_return({
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
service: ["discourse", "email", "gitea", "wiki", "xmpp"]
services_enabled: ["discourse", "email", "gitea", "wiki", "xmpp"]
})
expect(user.services_enabled).to eq(["discourse", "email", "gitea", "wiki", "xmpp"])
end
@@ -76,21 +76,21 @@ RSpec.describe User, type: :model do
before do
allow(user).to receive(:ldap_entry).and_return({
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
service: ["discourse", "gitea"]
services_enabled: ["discourse", "gitea"]
})
allow(user).to receive(:dn).and_return(dn)
end
it "adds the service to the LDAP entry" do
expect_any_instance_of(LdapService).to receive(:replace_attribute)
.with(dn, :service, ["discourse", "gitea", "wiki"]).and_return(true)
.with(dn, :serviceEnabled, ["discourse", "gitea", "wiki"]).and_return(true)
user.enable_service(:wiki)
end
it "adds multiple service to the LDAP entry" do
expect_any_instance_of(LdapService).to receive(:replace_attribute)
.with(dn, :service, ["discourse", "gitea", "wiki", "xmpp"]).and_return(true)
.with(dn, :serviceEnabled, ["discourse", "gitea", "wiki", "xmpp"]).and_return(true)
user.enable_service([:wiki, :xmpp])
end
@@ -100,21 +100,21 @@ RSpec.describe User, type: :model do
before do
allow(user).to receive(:ldap_entry).and_return({
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
service: ["discourse", "gitea", "xmpp"]
services_enabled: ["discourse", "gitea", "xmpp"]
})
allow(user).to receive(:dn).and_return(dn)
end
it "removes the service from the LDAP entry" do
expect_any_instance_of(LdapService).to receive(:replace_attribute)
.with(dn, :service, ["discourse", "gitea"]).and_return(true)
.with(dn, :serviceEnabled, ["discourse", "gitea"]).and_return(true)
user.disable_service(:xmpp)
end
it "removes multiple services from the LDAP entry" do
expect_any_instance_of(LdapService).to receive(:replace_attribute)
.with(dn, :service, ["discourse"]).and_return(true)
.with(dn, :serviceEnabled, ["discourse"]).and_return(true)
user.disable_service([:xmpp, "gitea"])
end
@@ -206,9 +206,21 @@ RSpec.describe User, type: :model do
end
end
describe "#nostr_pubkey" do
before do
allow_any_instance_of(User).to receive(:ldap_entry)
.and_return({ nostr_key: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3" })
end
it "returns the raw pubkey from LDAP" do
expect(user.nostr_pubkey).to eq("07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3")
end
end
describe "#nostr_pubkey_bech32" do
before do
user.update! nostr_pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3"
allow_any_instance_of(User).to receive(:ldap_entry)
.and_return({ nostr_key: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3" })
end
it "encodes the hexadecimal pubkey to bech32" do

View File

@@ -2,14 +2,23 @@ require 'rails_helper'
RSpec.describe "Settings", type: :request do
let(:user) { create :user, cn: 'mark', ou: 'kosmos.org' }
let(:other_user) { create :user, id: 2, cn: 'markymark', ou: 'kosmos.org', email: 'markymark@interscope.com' }
before do
login_as user, :scope => :user
allow_any_instance_of(User).to receive(:dn)
.and_return("cn=#{user.cn},ou=kosmos.org,cn=users,dc=kosmos,dc=org")
allow_any_instance_of(User).to receive(:nostr_pubkey).and_return(nil)
allow(LdapManager::FetchUserByNostrKey).to receive(:call).with(
pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3"
).and_return(nil)
end
describe "GET /settings/experiments" do
describe "GET /settings/nostr" do
it "works" do
get setting_path(:experiments)
get setting_path(:nostr)
expect(response).to have_http_status(200)
end
end
@@ -22,6 +31,11 @@ RSpec.describe "Settings", type: :request do
context "With valid data" do
before do
expect(LdapManager::UpdateNostrKey).to receive(:call).with(
dn: "cn=mark,ou=kosmos.org,cn=users,dc=kosmos,dc=org",
pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3"
).and_return(0)
post set_nostr_pubkey_settings_path, params: {
signed_event: {
id: "84f266bbd784551aaa9e35cb0aceb4ee59182a1dab9ab279d9e40dd56ecbbdd3",
@@ -41,41 +55,17 @@ RSpec.describe "Settings", type: :request do
expect(response).to have_http_status(200)
end
it "saves the pubkey" do
expect(user.nostr_pubkey).to eq("07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3")
it "informs the user about the success" do
expect(flash[:success]).to eq("Public key verification successful")
end
end
context "With wrong username" do
context "With key already in use by someone else" do
before do
post set_nostr_pubkey_settings_path, params: {
signed_event: {
id: "2e1e20ee762d6a5b5b30835eda9ca03146e4baf82490e53fd75794c08de08ac0",
pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3",
created_at: 1678255391,
kind: 1,
content: "Connect my public key to admin@kosmos.org (confirmation rMjWEmvcvtTlQkMd)",
sig: "2ace19c9db892ac6383848721a3e08b13d90d689fdeac60d9633a623d3f08eb7e0d468f1b3e928d1ea979477c2ec46ee6cdb2d053ef2e4ed3c0630a51d249029"
}
}.to_json, headers: {
"CONTENT_TYPE" => "application/json",
"HTTP_ACCEPT" => "application/json"
}
end
it "returns a 422 status" do
expect(response).to have_http_status(422)
end
it "does not save the pubkey" do
expect(user.nostr_pubkey).to be_nil
end
end
context "With wrong shared secret" do
before do
session_stub = { shared_secret: "ho-chi-minh" }
allow_any_instance_of(SettingsController).to receive(:session).and_return(session_stub)
expect(LdapManager::FetchUserByNostrKey).to receive(:call).with(
pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3"
).and_return(other_user)
expect(LdapManager::UpdateNostrKey).not_to receive(:call)
post set_nostr_pubkey_settings_path, params: {
signed_event: {
@@ -96,8 +86,67 @@ RSpec.describe "Settings", type: :request do
expect(response).to have_http_status(422)
end
it "does not save the pubkey" do
expect(user.nostr_pubkey).to be_nil
it "informs the user about the failure" do
expect(flash[:alert]).to eq("Public key already in use for a different account")
end
end
context "With wrong username" do
before do
expect(LdapManager::UpdateNostrKey).not_to receive(:call)
post set_nostr_pubkey_settings_path, params: {
signed_event: {
id: "2e1e20ee762d6a5b5b30835eda9ca03146e4baf82490e53fd75794c08de08ac0",
pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3",
created_at: 1678255391,
kind: 1,
content: "Connect my public key to admin@kosmos.org (confirmation rMjWEmvcvtTlQkMd)",
sig: "2ace19c9db892ac6383848721a3e08b13d90d689fdeac60d9633a623d3f08eb7e0d468f1b3e928d1ea979477c2ec46ee6cdb2d053ef2e4ed3c0630a51d249029"
}
}.to_json, headers: {
"CONTENT_TYPE" => "application/json",
"HTTP_ACCEPT" => "application/json"
}
end
it "returns a 422 status" do
expect(response).to have_http_status(422)
end
it "informs the user about the failure" do
expect(flash[:alert]).to eq("Public key could not be verified")
end
end
context "With wrong shared secret" do
before do
session_stub = { shared_secret: "ho-chi-minh" }
allow_any_instance_of(SettingsController).to receive(:session).and_return(session_stub)
expect(LdapManager::UpdateNostrKey).not_to receive(:call)
post set_nostr_pubkey_settings_path, params: {
signed_event: {
id: "84f266bbd784551aaa9e35cb0aceb4ee59182a1dab9ab279d9e40dd56ecbbdd3",
pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3",
created_at: 1678254161,
kind: 1,
content: "Connect my public key to mark@kosmos.org (confirmation rMjWEmvcvtTlQkMd)",
sig: "96796d420547d6e2c7be5de82a2ce7a48be99aac6415464a6081859ac1a9017305accc0228c630466a57d45ec1c3b456376eb538b76dfdaa2397e3258be02fdd"
}
}.to_json, headers: {
"CONTENT_TYPE" => "application/json",
"HTTP_ACCEPT" => "application/json"
}
end
it "returns a 422 status" do
expect(response).to have_http_status(422)
end
it "informs the user about the failure" do
expect(flash[:alert]).to eq("Public key could not be verified")
end
end
end

View File

@@ -19,6 +19,11 @@ RSpec.describe "Well-known URLs", type: :request do
context "user does not have a nostr pubkey configured" do
let(:user) { create :user, cn: 'spongebob', ou: 'kosmos.org' }
before do
allow_any_instance_of(User).to receive(:ldap_entry)
.and_return({ nostr_key: nil })
end
it "returns a 404 status" do
get "/.well-known/nostr.json?name=spongebob"
expect(response).to have_http_status(:not_found)
@@ -26,8 +31,12 @@ RSpec.describe "Well-known URLs", type: :request do
end
context "user with nostr pubkey" do
let(:user) { create :user, cn: 'bobdylan', ou: 'kosmos.org', nostr_pubkey: '438d35a6750d0dd6b75d032af8a768aad76b62f0c70ecb45f9c4d9e63540f7f4' }
before { user.save! }
let(:user) { create :user, cn: 'bobdylan', ou: 'kosmos.org' }
before do
user.save!
allow_any_instance_of(User).to receive(:nostr_pubkey)
.and_return('438d35a6750d0dd6b75d032af8a768aad76b62f0c70ecb45f9c4d9e63540f7f4')
end
it "returns a NIP-05 response" do
get "/.well-known/nostr.json?name=bobdylan"