如何防止用户向群组发送消息,但继续接收来自该群组的消息(只读)?

Posted

技术标签:

【中文标题】如何防止用户向群组发送消息,但继续接收来自该群组的消息(只读)?【英文标题】:How to prevent an user from sending messages to a group, but keep receiving messages from that group (read only)? 【发布时间】:2020-04-15 01:34:26 【问题描述】:

我正在使用 ejabberd 20.03 和 MucSub 方法。

我尝试设置 affiliation = 'none' 但用户仍然可以向 muc 发送消息。详情:

ejabberd.yml:

...
modules:
  mod_adhoc: 
  mod_admin_extra: 
  mod_announce:
    access: announce
  mod_avatar: 
  mod_blocking: 
  mod_bosh: 
  mod_caps: 
  mod_carboncopy: 
  mod_client_state: 
  mod_configure: 
  mod_disco: 
  mod_fail2ban:
    c2s_auth_ban_lifetime: 10
  mod_http_api: 
  mod_http_upload:
    put_url: https://@HOST@:5443/upload
  mod_last: 
  mod_mam:
    ## Mnesia is limited to 2GB, better to use an SQL backend
    ## For small servers SQLite is a good fit and is very easy
    ## to configure. Uncomment this when you have SQL configured:
    db_type: sql
    assume_mam_usage: true
    default: always
  mod_mqtt: 
  mod_muc:
    access:
      - allow
    access_admin:
      - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    access_mam:
      - allow
    default_room_options:
      allow_query_users: false
      allow_subscription: true  # enable MucSub
      mam: true
      persistent: true
      public: false
      public_list: false
  mod_muc_admin: 
  mod_offline:
    access_max_user_messages: max_user_offline_messages
  mod_privacy: 
  mod_private: 
  mod_proxy65:
    access: local
    max_connections: 5
  mod_pubsub:
    access_createnode: pubsub_createnode
    plugins:
      - flat
      - pep
    force_node_config:
      ## Avoid buggy clients to make their bookmarks public
      storage:bookmarks:
        access_model: whitelist
  mod_push: 
  mod_push_keepalive: 
  mod_register:
    ## Only accept registration requests from the "trusted"
    ## network (see access_rules section above).
    ## Think twice before enabling registration from any
    ## address. See the Jabber SPAM Manifesto for details:
    ## https://github.com/ge0rg/jabber-spam-fighting-manifesto
    ip_access: trusted_network
  mod_roster:
    versioning: true
  mod_s2s_dialback: 
  mod_shared_roster: 
  mod_stream_mgmt:
    resend_on_timeout: if_offline
  mod_vcard: 
  mod_vcard_xupdate: 
  mod_version:
    show_os: false

房间设置:

[title,<<"500">>,
 description,<<"500">>,
 allow_change_subj,false,
 allow_query_users,false,
 allow_private_messages,false,
 allow_private_messages_from_visitors,anyone,
 allow_visitor_status,true,
 allow_visitor_nickchange,true,
 public,false,
 public_list,false,
 persistent,true,
 moderated,true,
 members_by_default,true,
 members_only,true,
 allow_user_invites,false,
 password_protected,true,
 captcha_protected,false,
 password,<<"_500_">>,
 anonymous,false,
 logging,false,
 max_users,200,
 allow_voice_requests,true,
 allow_subscription,true,
 mam,true,
 presence_broadcast,[moderator,participant,visitor],
 voice_request_min_interval,1800,
 vcard,<<"
<vCard
    xmlns='vcard-temp'>
    <TITLE>Room Title</TITLE>
    <DESC>Room Description</DESC>
</vCard>">>,
 vcard_xupdate,<<>>,
 pubsub,<<>>,
 lang,<<"en">>,
 captcha_whitelist,[],
 affiliations,[<<"21112">>,<<"domain.com">>,<<>>,
                 admin,<<>>,
                <<"21247">>,<<"domain.com">>,<<>>,
                 member,<<>>,
                <<"21966">>,<<"domain.com">>,<<>>,
                 member,<<>>,
                <<"admin">>,<<"domain.com">>,<<>>,
                 owner,<<>>],
 subject,[],
 subject_author,<<>>]

我希望用户 21112(房间管理员)能够将用户 21247(房间成员)设置为阻止 21247 向房间发送消息,但 21247 仍然可以从房间接收消息的状态。我试过了:

    使用用户 21112 登录并发送以下节:
<iq from="21112@domain.com/14965894906297405984175442" id="revoke_voice_c4ec85d0-7f14-11ea-8f19-77e4dd9aaad8" to="500@conference.domain.com" type="set"
    xmlns="jabber:client">
    <query
        xmlns="http://jabber.org/protocol/muc#admin">
        <item nick="21247" role="visitor"/>
    </query>
</iq>

并收到错误:

<iq
    xmlns='jabber:client' xml:lang='en'
    to='21112@domain.com/14965894906297405984175442'
    from='500@conference.domain.com'
    type='error'
    id='revoke_voice_c4ec85d0-7f14-11ea-8f19-77e4dd9aaad8'>
    <query
        xmlns='http://jabber.org/protocol/muc#admin'>
        <item nick='21247' role='visitor'/>
    </query>
    <error code='405' type='cancel'>
        <not-allowed
            xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
            <text xml:lang='en'
                xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Changing role/affiliation is not allowed
            </text>
        </error>
    </iq>

我不知道为什么会返回上面的错误。我已经阅读了房间配置以及 MucSub 方法,我想知道这是否是因为 MucSub 实现。我不知道。然后我只是将用户 21247 隶属关系设置为“无”,但他仍然能够向房间发送消息。节:

<iq from="21112@domain.com/14965894906297405984175442" 
    id="change_affiliation" 
    to="500@conference.domain.com" 
    type="set"
    xmlns="jabber:client">
    <query
        xmlns="http://jabber.org/protocol/muc#admin">
        <item affiliation="none" jid="21247@domain.com" nick="21247"/>
    </query>
</iq>
<iq
    xmlns='jabber:client' 
    xml:lang='en' 
    to='21112@domain.com/14965894906297405984175442' 
    from='500@conference.domain.com' 
    type='result' 
    id='change_affiliation'/>

据我了解,由于我设置了 affiliation = 'none',我预计用户 21247 无法向房间发送消息,但仍然可以接收新消息,因为他是房间的订阅者 (MucSub)。有没有人有想法来实现我的目标?

【问题讨论】:

我尝试设置 affiliation = 'none' 我应该用更多细节来编辑问题。现在就做。 @Badlop,我根据 XEP-0045 的第 9.5 节设置了发送节的附属关系。 【参考方案1】:

啊,我明白你的意思了。没错,在当前的 MucSub 实现中,没有办法限制订阅者向房间发送消息。

我已经填写了一个问题,解释了这个案例并提供了一个补丁。通过该补丁,房间配置允许订阅者接收消息但不发送消息。

如果您能够应用补丁,请编译并安装 ejabberd: https://github.com/processone/ejabberd/issues/3222

【讨论】:

谢谢,我试试!这是我掌握 ejabberd 源代码和工作流程的好机会。现在(紧急需求),我将在客户端上阻止它。

以上是关于如何防止用户向群组发送消息,但继续接收来自该群组的消息(只读)?的主要内容,如果未能解决你的问题,请参考以下文章

向群组发送推送通知

使用Python创建自定义机器人向群组人员发送消息

linux中如何用指令将用户加入到群组中

MultiUserChat 发送和接收消息错误

skpy 向用户提及的群组发送消息

让 Telegram Bot 回复特定消息