esl / MongooseIM

MongooseIM is Erlang Solutions' robust, scalable and efficient XMPP server, aimed at large installations. Specifically designed for enterprise purposes, it is fault-tolerant and can utilise the resources of multiple clustered machines.
Other
1.66k stars 426 forks source link

Can I send a iq stanza from admin rest api? #3517

Closed theowenyoung closed 2 years ago

theowenyoung commented 2 years ago

MongooseIM version: 5.0 Installed from: docker

Describe the issue.

Hi, I want to block user2 from user1 through the reset API, I found https://esl.github.io/MongooseDocs/latest/rest-api/Administration-backend/ has an endpoint: /api/stanzas,

but it seems that the API need a <message> body, Can I send a <iq> stanza? or any other thing that I can do about using rest API to block someone?

arcusfelis commented 2 years ago

Hi,

POST request body needs to be:

{
  "stanza": "<message from=\"alice@wonderlant.lit\" to=\"bob@wonderlant.lit\"><body>whatever</body></message>"
}

where "stanza" is an arbitrary stanza to route (iqs are fine). Yea, that row in docs is called message, but it has parameter body type (request body, not <body/>).

arcusfelis commented 2 years ago

be aware, your IQ get result would not get back to you though. And there is no way to ensure IQ set succeeds.

theowenyoung commented 2 years ago

Send: api/stanzas

{
    "stanza":"<iq from='user1@example.com/admin' type='set' id='block1'><block xmlns='urn:xmpp:blocking'><item jid='user2@example.com'/></block></iq>"
}

Receive:

both from and to are required

I tried send:

{
    "stanza":"<iq from='user1@example.com/admin' to='example.com' type='set' id='block1'><block xmlns='urn:xmpp:blocking'><item jid='user2@example.com'/></block></iq>"
}

Receive 204, the log say :Local server does not implement this feature

arcusfelis commented 2 years ago

Add to attribute to the first iq (should be a bare user jid). Ensure that mod_blocking module is enabled.

On Tue, 25 Jan 2022, 16:12 Owen Young, @.***> wrote:

Send: api/stanzas

{ "stanza":"<iq @./admin' type='set' id='block1'><item @.'/>" }

Receive:

both from and to are required

I tried send:

{ "stanza":"<iq @./admin' type='set' id='block1'><item @.'/>" }

Receive 204, the log say :Local server does not implement this feature

— Reply to this email directly, view it on GitHub https://github.com/esl/MongooseIM/issues/3517#issuecomment-1021290270, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE4GNCZ6I3RCI2GIMRBY5TUX24WFANCNFSM5MYLHRNA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

theowenyoung commented 2 years ago

Yes, I'm sure mod_blocking is enabled.

When I tried to block user2 from user1, which bare id should I use for to?

I tried both user2@example.com ,user1@example.com, Both log the same error:

<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Unknown xmlns=urn:xmpp:blocking for host=example.com</text></error></iq>

arcusfelis commented 2 years ago

Could you provide your config? It still seams there's no iq handler for this combination of xmlns and hostname.

On Tue, 25 Jan 2022, 16:54 Owen Young, @.***> wrote:

Yes, I'm sure mod_blocking is enabled.

When I tried to block user2 from user1, which bare id should I use for to?

I tried both @. @., Both log the same error:

<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Unknown xmlns=urn:xmpp:blocking for host=example.com

— Reply to this email directly, view it on GitHub https://github.com/esl/MongooseIM/issues/3517#issuecomment-1021333439, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE4GNEK3WK6XUVIDPWJOG3UX3BSJANCNFSM5MYLHRNA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

theowenyoung commented 2 years ago

I also tested in the client, and blocking function works fine. when I sent <iq from='user1@example.com/admin' type='set' id='block1'><block xmlns='urn:xmpp:blocking'><item jid='user2@example.com'/></block></iq>

But I don't know how to do this in server rest api.

[general]
all_metrics_are_global = false
default_server_domain = "example.com"
hosts = ["example.com"]
loglevel = "debug"
max_fsm_queue = 1000
rdbms_server_type = "pgsql"
# registration_timeout = "infinity"
sm_backend = "mnesia"
[[listen.http]]
port = 5280
# tls.certfile = "/etc/nginx/ssl/example.com.crt"
# tls.keyfile = "/etc/nginx/ssl/example.com.key"
transport.max_connections = 1024
transport.num_acceptors = 10
[[listen.http.handlers.mod_bosh]]
host = "_"
path = "/bosh"

[[listen.http.handlers.mod_websockets]]
host = "_"
path = "/ws"

[listen.http.handlers.mod_websockets.service]
access = "all"
password = "bxxxxxaEd1D8nd"
shaper_rule = "fast"

[[listen.http]]
port = 5443
tls.certfile = "/etc/nginx/ssl/example.com.crt"
tls.keyfile = "/etc/nginx/ssl/example.com.key"
transport.max_connections = 1024
transport.num_acceptors = 10

[[listen.http.handlers.mod_bosh]]
host = "_"
path = "/bosh"

[[listen.http.handlers.mod_websockets]]
host = "_"
path = "/ws"

[[listen.http]]
port = 8088
transport.max_connections = 1024
transport.num_acceptors = 10

[[listen.http.handlers.mongoose_api_admin]]
host = "example.com"
path = "/api"
[[listen.http.handlers.mongoose_domain_handler]]
host = "example.com"
path = "/api"

[[listen.http]]
port = 8089
protocol.compress = true
tls.certfile = "/etc/nginx/ssl/example.com.crt"
tls.keyfile = "/etc/nginx/ssl/example.com.key"
transport.max_connections = 1024
transport.num_acceptors = 10

[[listen.http.handlers.lasse_handler]]
host = "_"
module = "mongoose_client_api_sse"
path = "/api/sse"

[[listen.http.handlers.mongoose_client_api_messages]]
host = "_"
path = "/api/messages/[:with]"

[[listen.http.handlers.mongoose_client_api_contacts]]
host = "_"
path = "/api/contacts/[:jid]"

[[listen.http.handlers.mongoose_client_api_rooms]]
host = "_"
path = "/api/rooms/[:id]"

[[listen.http.handlers.mongoose_client_api_rooms_config]]
host = "_"
path = "/api/rooms/[:id]/config"

[[listen.http.handlers.mongoose_client_api_rooms_users]]
host = "_"
path = "/api/rooms/:id/users/[:user]"

[[listen.http.handlers.mongoose_client_api_rooms_messages]]
host = "_"
path = "/api/rooms/[:id]/messages"

[[listen.http.handlers.cowboy_swagger_redirect_handler]]
host = "_"
path = "/api-docs"

[[listen.http.handlers.cowboy_swagger_json_handler]]
host = "_"
path = "/api-docs/swagger.json"

[[listen.http.handlers.cowboy_static]]
app = "cowboy_swagger"
content_path = "swagger"
host = "_"
path = "/api-docs/[...]"
type = "priv_dir"

[[listen.http]]
port = 5288
transport.max_connections = 1024
transport.num_acceptors = 10

[[listen.http.handlers.mongoose_api]]
handlers = ["mongoose_api_metrics", "mongoose_api_users"]
host = "example.com"
path = "/api"

[[listen.c2s]]
access = "c2s"
max_stanza_size = 65536
port = 5222
shaper = "c2s_shaper"
tls.certfile = "/etc/nginx/ssl/example.com.full.pem"
tls.mode = "starttls_required"

[[listen.s2s]]
max_stanza_size = 131072
port = 5269
shaper = "s2s_shaper"

[[listen.service]]
access = "all"
password = "!z(ww$S6vpJmKxlM7L7^9JP6Lnw!slYT"
port = 8888
shaper_rule = "fast"

[auth]
methods = ["jwt", "rdbms"]
sasl_external = ["standard"]
sasl_mechanisms = ["plain"]
[auth.rdbms]
users_number_estimate = true
[auth.jwt]
algorithm = "RS256"
username_key = "sub"
[auth.jwt.secret]
file = '/configs/jwt-public.pem'
#[outgoing_pools.redis.global_distrib]
#  scope = "single_host"
#  host = "example.com"
#  workers = 10
#
[outgoing_pools.rdbms.default]
scope = "global"
workers = 5

[outgoing_pools.rdbms.default.connection]
database = "xmpp"
driver = "pgsql"
host = "db"
password = "49Q5fsXq7VIDsdhVHDRpN3he9FPEaflt"
username = "postgres"

[services.service_admin_extra]
submods = [
  "node",
  "accounts",
  "sessions",
  "vcard",
  "gdpr",
  "upload",
  "roster",
  "last",
  "private",
  "stanza",
  "stats",
  "domain",
]

[services.service_mongoose_system_metrics]
initial_report = 300_000
periodic_report = 10_800_000

[modules.mod_ping]
send_pings = true
[modules.mod_inbox]

[modules.mod_http_upload]
backend = "s3"
expiration_time = 120
host = "upload.@HOST@"
max_file_size = 10485760

[modules.mod_http_upload.s3]

access_key_id = "xxxxxxx"
# add_acl = true
bucket_url = "https://example.com"
region = "ap-xxxx-1"
secret_access_key = "xxxx"
[modules.mod_adhoc]

[modules.mod_disco]
users_can_see_hidden_services = true
[modules.mod_commands]
[modules.mod_mam_meta]
archive_chat_markers = true
no_stanzaid_element = true
rdbms_message_format = "simple"
[modules.mod_mam_meta.pm] # defining this section enables PM support

[modules.mod_cache_users]

[modules.mod_muc_commands]

[modules.mod_muc_light_commands]

[modules.mod_last]

[modules.mod_stream_management]
ack_freq = 10
[modules.mod_offline]
backend = "rdbms"

[modules.mod_privacy]

[modules.mod_blocking]

[modules.mod_private]

[modules.mod_register]
access = "register"
ip_access = [
  {address = "127.0.0.0/8", policy = "allow"},
  {address = "172.17.0.0/16", policy = "allow"},
]
welcome_message = {body = "xxx", subject = "xxx"}

[modules.mod_roster]
store_current_id = true
versioning = true

[modules.mod_sic]

[modules.mod_vcard]
backend = "rdbms"
host = "vjud.@HOST@"
[modules.mod_bosh]

[modules.mod_carboncopy]

[shaper.normal]
max_rate = 1000

[shaper.fast]
max_rate = 50_000

[shaper.mam_shaper]
max_rate = 1

[shaper.mam_global_shaper]
max_rate = 10000

[acl]
local = [
  {user_regexp = ""},
]

[access]
max_user_sessions = [
  {acl = "all", value = 10},
]

max_user_offline_messages = [
  {acl = "admin", value = 5000},
  {acl = "all", value = 1000},
]

local = [
  {acl = "local", value = "allow"},
]

c2s = [
  {acl = "blocked", value = "deny"},
  {acl = "all", value = "allow"},
]

c2s_shaper = [
  {acl = "admin", value = "none"},
  {acl = "all", value = "normal"},
]

s2s_shaper = [
  {acl = "all", value = "fast"},
]

muc_admin = [
  {acl = "admin", value = "allow"},
]

muc_create = [
  {acl = "local", value = "allow"},
]

muc = [
  {acl = "all", value = "allow"},
]

register = [
  {acl = "all", value = "allow"},
]

mam_set_prefs = [
  {acl = "all", value = "default"},
]

mam_get_prefs = [
  {acl = "all", value = "default"},
]

mam_lookup_messages = [
  {acl = "all", value = "default"},
]

mam_set_prefs_shaper = [
  {acl = "all", value = "mam_shaper"},
]

mam_get_prefs_shaper = [
  {acl = "all", value = "mam_shaper"},
]

mam_lookup_messages_shaper = [
  {acl = "all", value = "mam_shaper"},
]

mam_set_prefs_global_shaper = [
  {acl = "all", value = "mam_global_shaper"},
]

mam_get_prefs_global_shaper = [
  {acl = "all", value = "mam_global_shaper"},
]

mam_lookup_messages_global_shaper = [
  {acl = "all", value = "mam_global_shaper"},
]

[s2s]
certfile = "/etc/nginx/ssl/example.com.full.pem"
default_policy = "deny"
outgoing.port = 5269
use_starttls = "optional"
arcusfelis commented 2 years ago

I think you need to send something like that:

<iq from='user1@example.com/admin' to='user1@example.com' type='set' id='block1'><block xmlns='urn:xmpp:blocking'><item jid='user2@example.com'/></block></iq>
theowenyoung commented 2 years ago

Not working…

Unknown xmlns=urn:xmpp:blocking for host=example.com

arcusfelis commented 2 years ago

Oh, try set the attribute to to="example.com" (without username)

On Tue, 25 Jan 2022, 20:44 Owen Young, @.***> wrote:

Not working…

Unknown xmlns=urn:xmpp:blocking for host=example.com

— Reply to this email directly, view it on GitHub https://github.com/esl/MongooseIM/issues/3517#issuecomment-1021545526, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE4GNHQRHWWKKDCA2GKVXTUX34QHANCNFSM5MYLHRNA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

theowenyoung commented 2 years ago

I tried that first, not worked.

https://github.com/esl/MongooseIM/issues/3517#issuecomment-1021290270

Receive 204, the log say :Local server does not implement this feature

chrzaszcz commented 2 years ago

Hi @theowenyoung, you are right, neither XEP-0016: Privacy Lists nor XEP-0191: Blocking Command can be used with the current REST API. This is because the logic for handling privacy settings is hardcoded in the ejabberd_c2s module and it is only accessible over XMPP.

If you want a HTTP-based API that allows this functionality, there are two potential solutions: