Create LDAP users asynchronously
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
35e2c8cd30
commit
8ad85636d9
|
@ -39,3 +39,6 @@ yarn-debug.log*
|
||||||
|
|
||||||
# Ignore local dotenv config file
|
# Ignore local dotenv config file
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# Ignore redis dumps from sidekiq
|
||||||
|
dump.rdb
|
||||||
|
|
|
@ -38,6 +38,10 @@ Running the dev server:
|
||||||
|
|
||||||
bundle exec rails server
|
bundle exec rails server
|
||||||
|
|
||||||
|
Running the background workers (requires Redis):
|
||||||
|
|
||||||
|
bundle exec sidekiq -C config/sidekiq.yml
|
||||||
|
|
||||||
Running all specs:
|
Running all specs:
|
||||||
|
|
||||||
bundle exec rspec
|
bundle exec rspec
|
||||||
|
@ -62,6 +66,11 @@ manual LDIF imports etc. (or provide a staging instance)
|
||||||
* [devise_ldap_authenticatable](https://github.com/cschiewek/devise_ldap_authenticatable)
|
* [devise_ldap_authenticatable](https://github.com/cschiewek/devise_ldap_authenticatable)
|
||||||
* [net/ldap](https://www.rubydoc.info/gems/net-ldap/Net/LDAP)
|
* [net/ldap](https://www.rubydoc.info/gems/net-ldap/Net/LDAP)
|
||||||
|
|
||||||
|
### Asynchronous jobs/workers
|
||||||
|
|
||||||
|
* [Sidekiq](https://github.com/mperham/sidekiq/wiki/)
|
||||||
|
* [ActiveJob](https://github.com/mperham/sidekiq/wiki/Active-Job)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[GNU Affero General Public License v3.0](https://choosealicense.com/licenses/agpl-3.0/)
|
[GNU Affero General Public License v3.0](https://choosealicense.com/licenses/agpl-3.0/)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
class CreateLdapUserJob < ApplicationJob
|
||||||
|
queue_as :default
|
||||||
|
|
||||||
|
def perform(username, domain, email, hashed_pw)
|
||||||
|
dn = "cn=#{username},ou=#{domain},cn=users,dc=kosmos,dc=org"
|
||||||
|
attr = {
|
||||||
|
objectclass: ["top", "account", "person", "extensibleObject"],
|
||||||
|
cn: username,
|
||||||
|
sn: username,
|
||||||
|
uid: username,
|
||||||
|
mail: email,
|
||||||
|
userPassword: hashed_pw
|
||||||
|
}
|
||||||
|
|
||||||
|
ldap_client.add(dn: dn, attributes: attr)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ldap_client
|
||||||
|
ldap_client ||= Net::LDAP.new host: ldap_config['host'],
|
||||||
|
port: ldap_config['port'],
|
||||||
|
encryption: ldap_config['ssl'],
|
||||||
|
auth: {
|
||||||
|
method: :simple,
|
||||||
|
username: ldap_config['admin_user'],
|
||||||
|
password: ldap_config['admin_password']
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def ldap_config
|
||||||
|
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
|
||||||
|
end
|
||||||
|
end
|
|
@ -33,33 +33,10 @@ class CreateAccount < ApplicationService
|
||||||
@invitation.update! invited_user_id: user_id, used_at: DateTime.now
|
@invitation.update! invited_user_id: user_id, used_at: DateTime.now
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO move to confirmation
|
||||||
def add_ldap_document
|
def add_ldap_document
|
||||||
dn = "cn=#{@username},ou=kosmos.org,cn=users,dc=kosmos,dc=org"
|
hashed_pw = Devise.ldap_auth_password_builder.call(@password)
|
||||||
attr = {
|
CreateLdapUserJob.perform_later(@username, "kosmos.org", @email, hashed_pw)
|
||||||
objectclass: ["top", "account", "person", "extensibleObject"],
|
|
||||||
cn: @username,
|
|
||||||
sn: @username,
|
|
||||||
uid: @username,
|
|
||||||
mail: @email,
|
|
||||||
userPassword: Devise.ldap_auth_password_builder.call(@password)
|
|
||||||
}
|
|
||||||
|
|
||||||
ldap_client.add(dn: dn, attributes: attr)
|
|
||||||
end
|
|
||||||
|
|
||||||
def ldap_client
|
|
||||||
ldap_client ||= Net::LDAP.new host: ldap_config['host'],
|
|
||||||
port: ldap_config['port'],
|
|
||||||
encryption: ldap_config['ssl'],
|
|
||||||
auth: {
|
|
||||||
method: :simple,
|
|
||||||
username: ldap_config['admin_user'],
|
|
||||||
password: ldap_config['admin_password']
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def ldap_config
|
|
||||||
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def exchange_xmpp_contacts
|
def exchange_xmpp_contacts
|
||||||
|
|
|
@ -41,5 +41,6 @@ module Akkounts
|
||||||
end
|
end
|
||||||
|
|
||||||
config.active_job.queue_adapter = :sidekiq
|
config.active_job.queue_adapter = :sidekiq
|
||||||
|
config.action_mailer.deliver_later_queue_name = nil # use "default" queue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,4 +49,6 @@ Rails.application.configure do
|
||||||
protocol: "https",
|
protocol: "https",
|
||||||
from: "accounts@kosmos.org"
|
from: "accounts@kosmos.org"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.active_job.queue_adapter = :test
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CreateLdapUserJob, type: :job do
|
||||||
|
let(:ldap_client_mock) { instance_double(Net::LDAP) }
|
||||||
|
|
||||||
|
subject(:job) {
|
||||||
|
described_class.any_instance.stub(:ldap_client).and_return(ldap_client_mock)
|
||||||
|
described_class.perform_later(
|
||||||
|
'halfinney', 'kosmos.org', 'halfinney@example.com',
|
||||||
|
'remember-remember-the-5th-of-november'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
it "creates a new document with the correct attributes" do
|
||||||
|
ldap_client_mock.should_receive(:add).with(
|
||||||
|
dn: "cn=halfinney,ou=kosmos.org,cn=users,dc=kosmos,dc=org",
|
||||||
|
attributes: {
|
||||||
|
objectclass: ["top", "account", "person", "extensibleObject"],
|
||||||
|
cn: "halfinney",
|
||||||
|
sn: "halfinney",
|
||||||
|
uid: "halfinney",
|
||||||
|
mail: "halfinney@example.com",
|
||||||
|
userPassword: "remember-remember-the-5th-of-november"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
perform_enqueued_jobs { job }
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
clear_enqueued_jobs
|
||||||
|
clear_performed_jobs
|
||||||
|
end
|
||||||
|
end
|
|
@ -69,5 +69,6 @@ RSpec.configure do |config|
|
||||||
config.include Devise::Test::ControllerHelpers, :type => :controller
|
config.include Devise::Test::ControllerHelpers, :type => :controller
|
||||||
config.include Warden::Test::Helpers
|
config.include Warden::Test::Helpers
|
||||||
config.include FactoryBot::Syntax::Methods
|
config.include FactoryBot::Syntax::Methods
|
||||||
|
config.include ActiveJob::TestHelper, type: :job
|
||||||
config.extend ControllerMacros, :type => :controller
|
config.extend ControllerMacros, :type => :controller
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,6 @@ require 'webmock/rspec'
|
||||||
require 'json'
|
require 'json'
|
||||||
|
|
||||||
RSpec.describe CreateAccount, type: :model do
|
RSpec.describe CreateAccount, type: :model do
|
||||||
let(:ldap_client_mock) { instance_double(Net::LDAP) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
allow(service).to receive(:ldap_client).and_return(ldap_client_mock)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#create_user_in_database" do
|
describe "#create_user_in_database" do
|
||||||
let(:service) { CreateAccount.new(
|
let(:service) { CreateAccount.new(
|
||||||
username: 'isaacnewton',
|
username: 'isaacnewton',
|
||||||
|
@ -48,26 +42,28 @@ RSpec.describe CreateAccount, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#add_ldap_document" do
|
describe "#add_ldap_document" do
|
||||||
|
include ActiveJob::TestHelper
|
||||||
|
|
||||||
let(:service) { CreateAccount.new(
|
let(:service) { CreateAccount.new(
|
||||||
username: 'halfinney',
|
username: 'halfinney',
|
||||||
email: 'halfinney@example.com',
|
email: 'halfinney@example.com',
|
||||||
password: 'remember-remember-the-5th-of-november'
|
password: 'remember-remember-the-5th-of-november'
|
||||||
)}
|
)}
|
||||||
|
|
||||||
it "creates a new document with the correct attributes" do
|
it "enqueues a job to create the LDAP user document" do
|
||||||
expect(ldap_client_mock).to receive(:add).with(
|
|
||||||
dn: "cn=halfinney,ou=kosmos.org,cn=users,dc=kosmos,dc=org",
|
|
||||||
attributes: {
|
|
||||||
objectclass: ["top", "account", "person", "extensibleObject"],
|
|
||||||
cn: "halfinney",
|
|
||||||
sn: "halfinney",
|
|
||||||
uid: "halfinney",
|
|
||||||
mail: "halfinney@example.com",
|
|
||||||
userPassword: /^{SSHA512}.{171}=/
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
service.send(:add_ldap_document)
|
service.send(:add_ldap_document)
|
||||||
|
|
||||||
|
expect(enqueued_jobs.size).to eq(1)
|
||||||
|
|
||||||
|
args = enqueued_jobs.first['arguments']
|
||||||
|
expect(args[0]).to eq('halfinney')
|
||||||
|
expect(args[1]).to eq('kosmos.org')
|
||||||
|
expect(args[2]).to eq('halfinney@example.com')
|
||||||
|
expect(args[3]).to match(/^{SSHA512}.{171}=/)
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
clear_enqueued_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue