jabber_admin 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.editorconfig +30 -0
- data/.gitignore +4 -2
- data/.rubocop.yml +35 -0
- data/.simplecov +5 -0
- data/.travis.yml +8 -6
- data/.yardopts +4 -0
- data/CHANGELOG.md +49 -0
- data/Gemfile +4 -2
- data/Makefile +108 -0
- data/README.md +145 -21
- data/Rakefile +5 -3
- data/bin/config.rb +11 -0
- data/bin/console +3 -3
- data/docker-compose.yml +15 -0
- data/jabber_admin.gemspec +34 -27
- data/lib/jabber_admin.rb +97 -34
- data/lib/jabber_admin/api_call.rb +110 -20
- data/lib/jabber_admin/commands.rb +6 -12
- data/lib/jabber_admin/commands/ban_account.rb +11 -10
- data/lib/jabber_admin/commands/create_room.rb +15 -10
- data/lib/jabber_admin/commands/create_room_with_opts.rb +20 -14
- data/lib/jabber_admin/commands/get_vcard.rb +84 -0
- data/lib/jabber_admin/commands/muc_register_nick.rb +26 -0
- data/lib/jabber_admin/commands/register.rb +16 -11
- data/lib/jabber_admin/commands/registered_users.rb +18 -0
- data/lib/jabber_admin/commands/restart.rb +8 -5
- data/lib/jabber_admin/commands/send_direct_invitation.rb +19 -16
- data/lib/jabber_admin/commands/send_stanza.rb +21 -0
- data/lib/jabber_admin/commands/send_stanza_c2s.rb +28 -0
- data/lib/jabber_admin/commands/set_nickname.rb +22 -0
- data/lib/jabber_admin/commands/set_presence.rb +37 -0
- data/lib/jabber_admin/commands/set_room_affiliation.rb +26 -0
- data/lib/jabber_admin/commands/set_vcard.rb +68 -0
- data/lib/jabber_admin/commands/subscribe_room.rb +19 -12
- data/lib/jabber_admin/commands/unregister.rb +13 -7
- data/lib/jabber_admin/commands/unsubscribe_room.rb +10 -7
- data/lib/jabber_admin/configuration.rb +6 -1
- data/lib/jabber_admin/exceptions.rb +41 -0
- data/lib/jabber_admin/version.rb +19 -1
- metadata +120 -25
- data/lib/jabber_admin/initializer.rb +0 -5
@@ -2,17 +2,18 @@
|
|
2
2
|
|
3
3
|
module JabberAdmin
|
4
4
|
module Commands
|
5
|
-
|
6
|
-
#
|
7
|
-
# https://
|
5
|
+
# Ban an account by kicking sessions and set random password.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2KW9xVt
|
8
8
|
class BanAccount
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# @param [
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
)
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param user [String] user JID wo/ resource (eg. +tom@localhost+)
|
13
|
+
# @param reason [String] the banning reason (eg. +Spamming other users+)
|
14
|
+
def self.call(callable, user:, reason:)
|
15
|
+
uid, host = user.split('@')
|
16
|
+
callable.call('ban_account', user: uid, host: host, reason: reason)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
@@ -2,17 +2,22 @@
|
|
2
2
|
|
3
3
|
module JabberAdmin
|
4
4
|
module Commands
|
5
|
-
|
6
|
-
#
|
7
|
-
# https://
|
5
|
+
# Create a new room (MUC).
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2rB8DFR
|
8
8
|
class CreateRoom
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# *Note:* this command should not be used in the bang-variant, due to raw
|
12
|
+
# result string in the response. (the response body is not zero/one like
|
13
|
+
# on almost all commands)
|
14
|
+
#
|
15
|
+
# @param callable [Proc, #call] the callable to call
|
16
|
+
# @param room [String] room JID (eg. +room1@conference.localhost+)
|
17
|
+
# @param host [String] the jabber host (eg. +localhost+)
|
18
|
+
def self.call(callable, room:, host:)
|
19
|
+
name, service = room.split('@')
|
20
|
+
callable.call('create_room', name: name, service: service, host: host)
|
16
21
|
end
|
17
22
|
end
|
18
23
|
end
|
@@ -2,21 +2,27 @@
|
|
2
2
|
|
3
3
|
module JabberAdmin
|
4
4
|
module Commands
|
5
|
-
|
6
|
-
#
|
7
|
-
# https://
|
5
|
+
# Create a new room (MUC) with additional options.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2IBEfVO
|
8
8
|
class CreateRoomWithOpts
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# @param [
|
12
|
-
# @param
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param room [String] room JID (eg. +room1@conference.localhost+)
|
13
|
+
# @param host [String] the jabber host (eg. +localhost+)
|
14
|
+
# @param options pass additional +symbol: value+ pairs
|
15
|
+
def self.call(callable, room:, host:, **options)
|
16
|
+
name, service = room.split('@')
|
17
|
+
options = options.map do |key, value|
|
18
|
+
Hash['name', key.to_s, 'value', value.to_s]
|
19
|
+
end
|
20
|
+
|
21
|
+
callable.call('create_room_with_opts',
|
22
|
+
name: name,
|
23
|
+
service: service,
|
24
|
+
host: host,
|
25
|
+
options: options)
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JabberAdmin
|
4
|
+
module Commands
|
5
|
+
# Get content from a vCard.
|
6
|
+
#
|
7
|
+
# Examples:
|
8
|
+
#
|
9
|
+
# JabberAdmin.get_vcard!(
|
10
|
+
# :fn, 'n.given', 'org.orgunit[]', 'u.known[]',
|
11
|
+
# user: 'ac865680-9681-45da-8fee-8584053dde5b@jabber.local'
|
12
|
+
# )
|
13
|
+
# # => {:fn=>"Max Mustermann",
|
14
|
+
# # "n.given"=>"Max",
|
15
|
+
# # "org.orgunit"=>["Marketing", "Production"],
|
16
|
+
# # "u.known"=>nil}
|
17
|
+
#
|
18
|
+
# **Heads up!** ejabberd version 18.01 has a bug at the +get_vcard2_multi+
|
19
|
+
# command, which just returns the first element of possible multiple
|
20
|
+
# values. (in an array)
|
21
|
+
#
|
22
|
+
# @see https://bit.ly/2SLkEWi
|
23
|
+
# @see https://bit.ly/34T71dm
|
24
|
+
# @see https://bit.ly/3nKqiGL
|
25
|
+
class GetVcard
|
26
|
+
# Pass the correct data to the given callable.
|
27
|
+
#
|
28
|
+
# @param callable [Proc, #call] the callable to call
|
29
|
+
# @param keys [Array<String, Symbol>, String, Symbol] name of the
|
30
|
+
# vCard field (+n.family+ for multiple levels)
|
31
|
+
# @param user [String] user JID wo/ resource (eg. +tom@localhost+)
|
32
|
+
# @return [Hash] the vCard details
|
33
|
+
#
|
34
|
+
# rubocop:disable Metrics/MethodLength because the ejabberd REST API is
|
35
|
+
# hard to use in complex scenarios, so we have to work around it
|
36
|
+
# rubocop:disable Metrics/AbcSize dito
|
37
|
+
# rubocop:disable Metrics/CyclomaticComplexity dito
|
38
|
+
# rubocop:disable Metrics/PerceivedComplexity dito
|
39
|
+
def self.call(callable, *keys, user:)
|
40
|
+
uid, host = user.split('@')
|
41
|
+
val = proc do |key|
|
42
|
+
parts = key.to_s.upcase.split('.')
|
43
|
+
args = { name: parts.shift }
|
44
|
+
meth = 'get_vcard'
|
45
|
+
|
46
|
+
unless parts.empty?
|
47
|
+
args[:subname] = parts.shift
|
48
|
+
meth = 'get_vcard2'
|
49
|
+
|
50
|
+
if args[:subname].end_with? '[]'
|
51
|
+
meth += '_multi'
|
52
|
+
args[:subname].delete_suffix!('[]')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
res = JSON.parse(callable.call(meth, check_res_body: false,
|
57
|
+
user: uid,
|
58
|
+
host: host,
|
59
|
+
**args).body)
|
60
|
+
|
61
|
+
res.is_a?(Hash) ? res['content'] : res
|
62
|
+
rescue JabberAdmin::CommandError => e
|
63
|
+
# When ejabberd tells us there was no value, it does this the hard way
|
64
|
+
next if e.response.body.include? 'error_no_value_found_in_vcard'
|
65
|
+
|
66
|
+
raise e
|
67
|
+
end
|
68
|
+
|
69
|
+
# When just one key is requested, we return the value directly
|
70
|
+
return val[keys.first] if keys.count == 1
|
71
|
+
|
72
|
+
# When multiple keys are requested, we assemble a hash
|
73
|
+
keys.map do |key|
|
74
|
+
res_key = key.is_a?(String) ? key.delete_suffix('[]') : key
|
75
|
+
[res_key, val[key]]
|
76
|
+
end.to_h
|
77
|
+
end
|
78
|
+
# rubocop:enable Metrics/MethodLength
|
79
|
+
# rubocop:enable Metrics/AbcSize
|
80
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
81
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JabberAdmin
|
4
|
+
module Commands
|
5
|
+
# Register a nick to a user JID in the MUC service of a server.
|
6
|
+
#
|
7
|
+
# *Note*: On ejabberd <= 18.01 this command always returns a error code,
|
8
|
+
# even when the command was successful under the hood. (See:
|
9
|
+
# https://bit.ly/2L1CpvE)
|
10
|
+
#
|
11
|
+
# @see https://bit.ly/2G9EBNQ
|
12
|
+
class MucRegisterNick
|
13
|
+
# Pass the correct data to the given callable.
|
14
|
+
#
|
15
|
+
# @param callable [Proc, #call] the callable to call
|
16
|
+
# @param user [String] user JID wo/ resource (eg. +tom@localhost+)
|
17
|
+
# @param nick [String] the user nickname (eg. +TomTom+)
|
18
|
+
def self.call(callable, user:, nick:)
|
19
|
+
callable.call('muc_register_nick',
|
20
|
+
nick: nick,
|
21
|
+
jid: user,
|
22
|
+
serverhost: user.split('@').last)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -2,18 +2,23 @@
|
|
2
2
|
|
3
3
|
module JabberAdmin
|
4
4
|
module Commands
|
5
|
-
|
6
|
-
#
|
7
|
-
# https://
|
5
|
+
# Register a new user on the XMPP service.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2wyhAox
|
8
8
|
class Register
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# @param [
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
)
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param user [String] user JID wo/ resource (eg. +tom@localhost+)
|
13
|
+
# @param password [String] the new plain password for the user
|
14
|
+
# (eg. +secret+)
|
15
|
+
def self.call(callable, user:, password:)
|
16
|
+
uid, host = user.split('@')
|
17
|
+
callable.call('register',
|
18
|
+
check_res_body: false,
|
19
|
+
user: uid,
|
20
|
+
host: host,
|
21
|
+
password: password)
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JabberAdmin
|
4
|
+
module Commands
|
5
|
+
# List all registered users on the ejabberd vhost.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2KhwT6Z
|
8
|
+
class RegisteredUsers
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param host [String] the jabber vhost (eg. +localhost+)
|
13
|
+
def self.call(callable, host:)
|
14
|
+
callable.call('registered_users', check_res_body: false, host: host)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,12 +2,15 @@
|
|
2
2
|
|
3
3
|
module JabberAdmin
|
4
4
|
module Commands
|
5
|
-
|
6
|
-
#
|
7
|
-
# https://
|
5
|
+
# Restart ejabberd service gracefully.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2G7YEwd
|
8
8
|
class Restart
|
9
|
-
|
10
|
-
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
def self.call(callable)
|
13
|
+
callable.call('restart')
|
11
14
|
end
|
12
15
|
end
|
13
16
|
end
|
@@ -2,23 +2,26 @@
|
|
2
2
|
|
3
3
|
module JabberAdmin
|
4
4
|
module Commands
|
5
|
-
|
6
|
-
#
|
7
|
-
# https://
|
5
|
+
# Send a direct invitation to several destinations.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2wuTpr2
|
8
8
|
class SendDirectInvitation
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# @param [
|
12
|
-
# @param [
|
13
|
-
# @param [
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param room [String] room JID (eg. +room1@conference.localhost+)
|
13
|
+
# @param users [Array<String>] user JIDs wo/ resource
|
14
|
+
# (eg. +tom@localhost+)
|
15
|
+
# @param password [String] a optional room password
|
16
|
+
# @param reason [String] the reason for the invitation
|
17
|
+
def self.call(callable, room:, users:, password: '', reason: '')
|
18
|
+
name, service = room.split('@')
|
19
|
+
callable.call('send_direct_invitation',
|
20
|
+
name: name,
|
21
|
+
service: service,
|
22
|
+
password: password,
|
23
|
+
reason: reason,
|
24
|
+
users: users.join(':'))
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JabberAdmin
|
4
|
+
module Commands
|
5
|
+
# Send a stanza; provide From JID and valid To JID.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2rzxyK1
|
8
|
+
class SendStanza
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param from [String] user JID wo/ resource (eg. +tom@localhost+)
|
13
|
+
# @param to [String] user/room JID wo/ resource (eg. +bob@localhost+)
|
14
|
+
# @param stanza [String] the XML stanz to send
|
15
|
+
# (eg. <tt><message><ext attr='value'/></message></tt>)
|
16
|
+
def self.call(callable, from:, to:, stanza:)
|
17
|
+
callable.call('send_stanza', from: from, to: to, stanza: stanza)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JabberAdmin
|
4
|
+
module Commands
|
5
|
+
# Send a message (stanza) as if sent from a c2s session.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2wwUcYr
|
8
|
+
class SendStanzaC2s
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param user [String] user JID w/ resource (eg. +tom@localhost/bot+)
|
13
|
+
# @param stanza [String] the XML stanz to send
|
14
|
+
# (eg. <tt><message to='user1@localhost'>
|
15
|
+
# <ext attr='value'/></message></tt>)
|
16
|
+
def self.call(callable, user:, stanza:)
|
17
|
+
uid, host = user.split('@')
|
18
|
+
host, resource = host.split('/')
|
19
|
+
resource ||= 'bot'
|
20
|
+
callable.call('send_stanza_c2s',
|
21
|
+
user: uid,
|
22
|
+
host: host,
|
23
|
+
resource: resource,
|
24
|
+
stanza: stanza)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JabberAdmin
|
4
|
+
module Commands
|
5
|
+
# Set nickname in a user's vCard.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2rBdyqc
|
8
|
+
class SetNickname
|
9
|
+
# Pass the correct data to the given callable.
|
10
|
+
#
|
11
|
+
# @param callable [Proc, #call] the callable to call
|
12
|
+
# @param user [String] user JID wo/ resource (eg. +tom@localhost+)
|
13
|
+
# @param nick [String] the user nickname (eg. +TomTom+)
|
14
|
+
def self.call(callable, user:, nick:)
|
15
|
+
uid, host = user.split('@')
|
16
|
+
callable.call(
|
17
|
+
'set_nickname', user: uid, host: host, nickname: nick
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JabberAdmin
|
4
|
+
module Commands
|
5
|
+
# Send a stanza; provide From JID and valid To JID.
|
6
|
+
#
|
7
|
+
# @see https://bit.ly/2rzxyK1
|
8
|
+
class SetPresence
|
9
|
+
# @param callable [Proc, #call] the callable to call
|
10
|
+
# @param user [String] user JID w/ resource (eg. +tom@localhost/bot+)
|
11
|
+
# @param type [String] the presence type
|
12
|
+
# (eg. +available+, +error+, +probe+)
|
13
|
+
# @param show [String] the showed presence
|
14
|
+
# (eg. +away+, +chat+, +dnd+, +xa+)
|
15
|
+
# @param status [String] the user status (eg. +I'm online+)
|
16
|
+
# @param priority [String] presence priority (eg. +7+)
|
17
|
+
#
|
18
|
+
# rubocop:disable Metrics/ParameterLists because of the mapping
|
19
|
+
# rubocop:disable Metrics/MethodLength because of the mapping
|
20
|
+
def self.call(callable, user:, type: 'available', show: 'chat',
|
21
|
+
status: '', priority: '7')
|
22
|
+
uid, host = user.split('@')
|
23
|
+
host, resource = host.split('/')
|
24
|
+
resource ||= 'bot'
|
25
|
+
callable.call('set_presence',
|
26
|
+
user: uid,
|
27
|
+
host: host,
|
28
|
+
resource: resource,
|
29
|
+
type: type,
|
30
|
+
show: show,
|
31
|
+
status: status,
|
32
|
+
priority: priority)
|
33
|
+
end
|
34
|
+
# rubocop:enable Metrics/ParameterLists, Metrics/MethodLength
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|