Exchange XMPP contacts when invitee signs up
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
Basti 2020-12-08 19:16:08 +01:00
parent 8a0d89ef60
commit ee72a32c7e
Signed by untrusted user: basti
GPG Key ID: 9F88009D31D99C72
6 changed files with 82 additions and 10 deletions

View File

@ -1,8 +1 @@
LDAP_HOST=192.168.33.10
LDAP_PORT=389
#
# Production LDAP server:
#
# LDAP_HOST=ldap.kosmos.org
# LDAP_PORT=636
# LDAP_USE_TLS=true
EJABBERD_API_URL='https://xmpp.kosmos.org/api'

1
.env.test Normal file
View File

@ -0,0 +1 @@
EJABBERD_API_URL='http://xmpp.example.com/api'

View File

@ -21,7 +21,7 @@ gem 'jbuilder', '~> 2.7'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
gem 'dotenv-rails', groups: [:development, :test]
gem 'dotenv-rails'
gem 'warden'
gem 'devise'

View File

@ -10,7 +10,11 @@ class CreateAccount < ApplicationService
def call
user = create_user_in_database
add_ldap_document
update_invitation(user.id) if @invitation.present?
if @invitation.present?
update_invitation(user.id)
exchange_xmpp_contacts
end
end
private
@ -57,4 +61,23 @@ class CreateAccount < ApplicationService
def ldap_config
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
end
def exchange_xmpp_contacts
#TODO enable in development when we have easy setup of ejabberd etc.
return if Rails.env.development?
ejabberd = EjabberdApiClient.new
inviter = @invitation.user
ejabberd.add_rosteritem({
"localuser": @username, "localhost": @domain,
"user": inviter.cn, "host": inviter.ou,
"nick": inviter.cn, "group": "Friends", "subs": "both"
})
ejabberd.add_rosteritem({
"localuser": inviter.cn, "localhost": inviter.ou,
"user": @username, "host": @domain,
"nick": @username, "group": "Friends", "subs": "both"
})
end
end

View File

@ -0,0 +1,20 @@
class EjabberdApiClient
def initialize
@base_url = ENV["EJABBERD_API_URL"]
end
def post(endpoint, payload)
res = Faraday.post("#{@base_url}/#{endpoint}", payload,
"Content-Type" => "application/json")
if res.status != 200
Rails.logger.error "[ejabberd] API request failed:"
Rails.logger.error res.body
#TODO add some kind of exception tracking/notifications
end
end
def add_rosteritem(payload)
post "add_rosteritem", payload
end
end

View File

@ -1,4 +1,6 @@
require 'rails_helper'
require 'webmock/rspec'
require 'json'
RSpec.describe CreateAccount, type: :model do
let(:ldap_client_mock) { instance_double(Net::LDAP) }
@ -68,4 +70,37 @@ RSpec.describe CreateAccount, type: :model do
service.send(:add_ldap_document)
end
end
describe "#exchange_xmpp_contacts" do
let(:inviter) { create :user, cn: "willherschel", ou: "kosmos.org" }
let(:invitation) { create :invitation, user: inviter }
let(:service) { CreateAccount.new(
username: 'isaacnewton',
email: 'isaacnewton@example.com',
password: 'bright-ideas-in-autumn',
invitation: invitation
)}
before do
stub_request(:post, "http://xmpp.example.com/api/add_rosteritem")
.to_return(status: 200, body: "", headers: {})
end
it "posts add_rosteritem commands to the ejabberd API" do
service.send(:exchange_xmpp_contacts)
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
.with { |req| req.body == {
localuser: "isaacnewton", localhost: "kosmos.org",
user: "willherschel", host: "kosmos.org",
nick: "willherschel", group: "Friends", subs: "both"
}}
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
.with { |req| req.body == {
localuser: "willherschel", localhost: "kosmos.org",
user: "isaacnewton", host: "kosmos.org",
nick: "isaacnewton", group: "Friends", subs: "both"
}}
end
end
end