327 lines
11 KiB
Ruby
327 lines
11 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe User, type: :model do
|
|
let(:user) { create :user, cn: "philipp", ou: "kosmos.org", email: "philipp@example.com" }
|
|
let(:dn) { "cn=philipp,ou=kosmos.org,cn=users,dc=kosmos,dc=org" }
|
|
|
|
describe "#address" do
|
|
it "returns the user address" do
|
|
expect(user.address).to eq("philipp@kosmos.org")
|
|
end
|
|
end
|
|
|
|
describe "#mastodon_address" do
|
|
context "Mastodon service not configured" do
|
|
before do
|
|
Setting.mastodon_enabled = false
|
|
end
|
|
|
|
it "returns nil" do
|
|
expect(user.mastodon_address).to be_nil
|
|
end
|
|
end
|
|
|
|
context "Mastodon service configured" do
|
|
before do
|
|
Setting.mastodon_enabled = true
|
|
end
|
|
|
|
describe "domain is the same as primary domain" do
|
|
it "returns the user address" do
|
|
expect(user.mastodon_address).to eq("philipp@kosmos.org")
|
|
end
|
|
end
|
|
|
|
describe "domain is different from primary domain" do
|
|
before do
|
|
Setting.mastodon_address_domain = "kosmos.social"
|
|
end
|
|
|
|
it "returns the user address" do
|
|
expect(user.mastodon_address).to eq("philipp@kosmos.social")
|
|
end
|
|
end
|
|
|
|
describe "username contains hyphen/dash" do
|
|
let(:jammy) { build :user, cn: "jammy-jellyfish", ou: "kosmos.org" }
|
|
|
|
it "returns the user address" do
|
|
expect(jammy.mastodon_address).to eq("jammy_jellyfish@kosmos.org")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#is_admin?" do
|
|
it "returns true when admin flag is set in LDAP" do
|
|
expect(Devise::LDAP::Adapter).to receive(:get_ldap_param)
|
|
.with(user.cn, :admin)
|
|
.and_return("true")
|
|
|
|
expect(user.is_admin?).to be true
|
|
end
|
|
|
|
it "returns false when admin flag is not set in LDAP" do
|
|
expect(Devise::LDAP::Adapter).to receive(:get_ldap_param)
|
|
.with(user.cn, :admin)
|
|
.and_return(nil)
|
|
|
|
expect(user.is_admin?).to be false
|
|
end
|
|
end
|
|
|
|
describe "#services_enabled" 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,
|
|
services_enabled: ["discourse", "ejabberd", "email", "gitea", "wiki"]
|
|
})
|
|
expect(user.services_enabled).to eq(["discourse", "ejabberd", "email", "gitea", "wiki"])
|
|
end
|
|
end
|
|
|
|
describe "#service_enabled?" do
|
|
before do
|
|
allow(user).to receive(:ldap_entry).and_return({
|
|
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
|
|
services_enabled: ["ejabberd", "gitea"]
|
|
})
|
|
end
|
|
|
|
it "returns true or false" do
|
|
expect(user.service_enabled?("gitea")).to be(true)
|
|
expect(user.service_enabled?("email")).to be(false)
|
|
end
|
|
|
|
it "returns false when service is not enabled" do
|
|
expect(user.service_enabled?(:gitea)).to be(true)
|
|
expect(user.service_enabled?(:email)).to be(false)
|
|
end
|
|
end
|
|
|
|
describe "#enable_service" do
|
|
before do
|
|
allow(user).to receive(:ldap_entry).and_return({
|
|
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
|
|
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, :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, :serviceEnabled, ["discourse", "ejabberd", "gitea", "wiki"]).and_return(true)
|
|
|
|
user.enable_service([:ejabberd, :wiki])
|
|
end
|
|
end
|
|
|
|
describe "#disable_service" do
|
|
before do
|
|
allow(user).to receive(:ldap_entry).and_return({
|
|
uid: user.cn, ou: user.ou, mail: user.email, admin: nil,
|
|
services_enabled: ["discourse", "ejabberd", "gitea"]
|
|
})
|
|
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, :serviceEnabled, ["discourse", "gitea"]).and_return(true)
|
|
|
|
user.disable_service(:ejabberd)
|
|
end
|
|
|
|
it "removes multiple services from the LDAP entry" do
|
|
expect_any_instance_of(LdapService).to receive(:replace_attribute)
|
|
.with(dn, :serviceEnabled, ["discourse"]).and_return(true)
|
|
|
|
user.disable_service([:ejabberd, "gitea"])
|
|
end
|
|
end
|
|
|
|
describe "#disable_all_services" do
|
|
before do
|
|
allow(user).to receive(:dn).and_return(dn)
|
|
end
|
|
|
|
it "removes all services from the LDAP entry" do
|
|
expect_any_instance_of(LdapService).to receive(:delete_attribute)
|
|
.with(dn, :service).and_return(true)
|
|
|
|
user.disable_all_services
|
|
end
|
|
end
|
|
|
|
describe "#devise_after_confirmation" do
|
|
include ActiveJob::TestHelper
|
|
|
|
let(:user) { create :user, cn: "willherschel", ou: "kosmos.org", email: "will@hrsch.el" }
|
|
|
|
before do
|
|
allow(user).to receive(:ldap_entry).and_return({
|
|
uid: "willherschel", ou: "kosmos.org", mail: "will@hrsch.el"
|
|
})
|
|
end
|
|
|
|
after { clear_enqueued_jobs }
|
|
|
|
it "enables default services" do
|
|
expect(user).to receive(:enable_service).with(Setting.default_services)
|
|
user.send :devise_after_confirmation
|
|
end
|
|
|
|
it "enqueues a job to set default chatroom bookmarks for XMPP" do
|
|
allow(user).to receive(:enable_service).and_return(true)
|
|
user.send :devise_after_confirmation
|
|
|
|
job = enqueued_jobs.select{|j| j['job_class'] == "XmppSetDefaultBookmarksJob"}.first
|
|
expect(job['arguments'][0]['_aj_globalid']).to eq('gid://akkounts/User/1')
|
|
end
|
|
|
|
context "for invited user with xmpp enabled" do
|
|
let(:guest) { create :user, id: 2, cn: "isaacnewton", ou: "kosmos.org", email: "newt@example.com" }
|
|
|
|
before do
|
|
Invitation.create! user: user, invited_user_id: guest.id, used_at: DateTime.now
|
|
allow_any_instance_of(User).to receive(:enable_service)
|
|
allow(guest).to receive(:ldap_entry).and_return({
|
|
uid: "isaacnewton", ou: "kosmos.org", mail: "newt@example.com"
|
|
})
|
|
end
|
|
|
|
it "enqueues jobs to exchange XMPP contacts between inviter and invitee" do
|
|
guest.send :devise_after_confirmation
|
|
|
|
job = enqueued_jobs.select{|j| j['job_class'] == "XmppExchangeContactsJob"}.first
|
|
expect(job["arguments"][0]['_aj_globalid']).to eq('gid://akkounts/User/1')
|
|
expect(job["arguments"][1]['_aj_globalid']).to eq('gid://akkounts/User/2')
|
|
end
|
|
end
|
|
|
|
context "for email address update of existing account" do
|
|
before do
|
|
allow(user).to receive(:ldap_entry)
|
|
.and_return({ uid: "willherschel", ou: "kosmos.org", mail: "willyboy@aol.com" })
|
|
allow(user).to receive(:dn)
|
|
.and_return("cn=willherschel,ou=kosmos.org,cn=users,dc=kosmos,dc=org")
|
|
allow(LdapManager::UpdateEmail).to receive(:call)
|
|
end
|
|
|
|
it "updates the LDAP 'mail' attribute" do
|
|
expect(LdapManager::UpdateEmail).to receive(:call)
|
|
.with(dn: "cn=willherschel,ou=kosmos.org,cn=users,dc=kosmos,dc=org", address: "will@hrsch.el")
|
|
user.send :devise_after_confirmation
|
|
end
|
|
|
|
it "does not re-enable default services" do
|
|
expect(user).not_to receive(:enable_service)
|
|
user.send :devise_after_confirmation
|
|
end
|
|
|
|
it "does not enqueue any delayed jobs" do
|
|
user.send :devise_after_confirmation
|
|
expect(enqueued_jobs).to be_empty
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#nostr_pubkey" do
|
|
before do
|
|
allow(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
|
|
allow(user).to receive(:ldap_entry)
|
|
.and_return({ nostr_key: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3" })
|
|
end
|
|
|
|
it "encodes the hexadecimal pubkey to bech32" do
|
|
expect(user.nostr_pubkey_bech32).to eq("npub1qlsc3g0lsl8pw8230w8d9wm6xxcax3f6pkemz5measrmwfxjxteslf2hac")
|
|
end
|
|
end
|
|
|
|
describe "OpenPGP key" 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
|
|
allow(alice).to receive(:ldap_entry).and_return({ pgp_key: valid_key_alice })
|
|
allow(jimmy).to receive(:ldap_entry).and_return({ pgp_key: valid_key_jimmy })
|
|
end
|
|
|
|
after do
|
|
alice.gnupg_key.delete!
|
|
jimmy.gnupg_key.delete!
|
|
end
|
|
|
|
describe "#acceptable_pgp_key_format" do
|
|
it "validates the record when the key is valid" do
|
|
alice.pgp_pubkey = valid_key_alice
|
|
expect(alice).to be_valid
|
|
end
|
|
|
|
it "adds a validation error when the key is not valid" do
|
|
user.pgp_pubkey = invalid_key
|
|
expect(user).to_not be_valid
|
|
expect(user.errors[:pgp_pubkey]).to be_present
|
|
end
|
|
end
|
|
|
|
describe "#pgp_pubkey" do
|
|
it "returns the raw pubkey from LDAP" do
|
|
expect(alice.pgp_pubkey).to eq(valid_key_alice)
|
|
end
|
|
end
|
|
|
|
describe "#gnupg_key" do
|
|
subject { alice.gnupg_key }
|
|
|
|
it "returns a GPGME::Key object from the system's GPG keyring" do
|
|
expect(subject).to be_a(GPGME::Key)
|
|
expect(subject.fingerprint).to eq(fingerprint_alice)
|
|
expect(subject.email).to eq("alice@openpgp.example")
|
|
end
|
|
end
|
|
|
|
describe "#pgp_pubkey_contains_user_address?" do
|
|
it "returns false when the user address is one of the UIDs of the key" do
|
|
expect(alice.pgp_pubkey_contains_user_address?).to eq(false)
|
|
end
|
|
|
|
it "returns true when the user address is missing from the UIDs of the key" do
|
|
expect(jimmy.pgp_pubkey_contains_user_address?).to eq(true)
|
|
end
|
|
end
|
|
|
|
describe "wkd_hash" do
|
|
it "returns a z-base32 encoded SHA-1 digest of the username" do
|
|
expect(alice.wkd_hash).to eq("kei1q4tipxxu1yj79k9kfukdhfy631xe")
|
|
end
|
|
end
|
|
end
|
|
end
|