• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

processone / ejabberd / 1212

18 Nov 2025 12:37PM UTC coverage: 33.784% (+0.003%) from 33.781%
1212

push

github

badlop
mod_conversejs: Improve link to conversejs in WebAdmin (#4495)

Until now, the WebAdmin menu included a link to the first request handler
with mod_conversejs that the admin configured in ejabberd.yml
That link included the authentication credentials hashed as URI arguments
if using HTTPS. Then process/2 extracted those arguments and passed them
as autologin options to Converse.

From now, mod_conversejs automatically adds a request_handler nested in
webadmin subpath. The webadmin menu links to that converse URI; this allows
to access the HTTP auth credentials, no need to explicitly pass them.
process/2 extracts this HTTP auth and passes autologin options to Converse.
Now scram password storage is supported too.

This minimum configuration allows WebAdmin to access Converse:

listen:
  -
    port: 5443
    module: ejabberd_http
    tls: true
    request_handlers:
      /admin: ejabberd_web_admin
      /ws: ejabberd_http_ws
modules:
  mod_conversejs:
    conversejs_resources: "/home/conversejs/12.0.0/dist"

0 of 12 new or added lines in 1 file covered. (0.0%)

11290 existing lines in 174 files now uncovered.

15515 of 45924 relevant lines covered (33.78%)

1277.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

4.0
/src/mod_shared_roster_sql.erl
1
%%%-------------------------------------------------------------------
2
%%% File    : mod_shared_roster_sql.erl
3
%%% Author  : Evgeny Khramtsov <ekhramtsov@process-one.net>
4
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
5
%%%
6
%%%
7
%%% ejabberd, Copyright (C) 2002-2025   ProcessOne
8
%%%
9
%%% This program is free software; you can redistribute it and/or
10
%%% modify it under the terms of the GNU General Public License as
11
%%% published by the Free Software Foundation; either version 2 of the
12
%%% License, or (at your option) any later version.
13
%%%
14
%%% This program is distributed in the hope that it will be useful,
15
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
16
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
%%% General Public License for more details.
18
%%%
19
%%% You should have received a copy of the GNU General Public License along
20
%%% with this program; if not, write to the Free Software Foundation, Inc.,
21
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
%%%
23
%%%----------------------------------------------------------------------
24

25
-module(mod_shared_roster_sql).
26

27

28
-behaviour(mod_shared_roster).
29

30
%% API
31
-export([init/2, list_groups/1, groups_with_opts/1, create_group/3,
32
         delete_group/2, get_group_opts/2, set_group_opts/3,
33
         get_user_groups/2, get_group_explicit_users/2,
34
         get_user_displayed_groups/3, is_user_in_group/3,
35
         add_user_to_group/3, remove_user_from_group/3, import/3,
36
         export/1]).
37
-export([sql_schemas/0]).
38

39
-include_lib("xmpp/include/jid.hrl").
40
-include("mod_roster.hrl").
41
-include("mod_shared_roster.hrl").
42
-include("ejabberd_sql_pt.hrl").
43

44
%%%===================================================================
45
%%% API
46
%%%===================================================================
47
init(Host, _Opts) ->
UNCOV
48
    ejabberd_sql_schema:update_schema(Host, ?MODULE, sql_schemas()),
4✔
UNCOV
49
    ok.
4✔
50

51
sql_schemas() ->
UNCOV
52
    [#sql_schema{
4✔
53
        version = 1,
54
        tables =
55
            [#sql_table{
56
                name = <<"sr_group">>,
57
                columns =
58
                    [#sql_column{name = <<"name">>, type = text},
59
                     #sql_column{name = <<"server_host">>, type = text},
60
                     #sql_column{name = <<"opts">>, type = text},
61
                     #sql_column{name = <<"created_at">>, type = timestamp,
62
                                 default = true}],
63
                indices = [#sql_index{
64
                              columns = [<<"server_host">>, <<"name">>],
65
                              unique = true}]},
66
             #sql_table{
67
                name = <<"sr_user">>,
68
                columns =
69
                    [#sql_column{name = <<"jid">>, type = text},
70
                     #sql_column{name = <<"server_host">>, type = text},
71
                     #sql_column{name = <<"grp">>, type = text},
72
                     #sql_column{name = <<"created_at">>, type = timestamp,
73
                                 default = true}],
74
                indices = [#sql_index{
75
                              columns = [<<"server_host">>,
76
                                         <<"jid">>, <<"grp">>],
77
                              unique = true},
78
                           #sql_index{
79
                              columns = [<<"server_host">>, <<"grp">>]}]}]}].
80

81
list_groups(Host) ->
82
    case ejabberd_sql:sql_query(
×
83
           Host,
84
           ?SQL("select @(name)s from sr_group where %(Host)H")) of
×
85
        {selected, Rs} -> [G || {G} <- Rs];
×
86
        _ -> []
×
87
    end.
88

89
groups_with_opts(Host) ->
90
    case ejabberd_sql:sql_query(
×
91
           Host,
92
           ?SQL("select @(name)s, @(opts)s from sr_group where %(Host)H"))
×
93
        of
94
      {selected, Rs} ->
95
          [{G, mod_shared_roster:opts_to_binary(ejabberd_sql:decode_term(Opts))}
×
96
           || {G, Opts} <- Rs];
×
97
      _ -> []
×
98
    end.
99

100
create_group(Host, Group, Opts) ->
101
    SOpts = misc:term_to_expr(Opts),
×
102
    F = fun () ->
×
103
                ?SQL_UPSERT_T(
×
104
                   "sr_group",
105
                   ["!name=%(Group)s",
106
                    "!server_host=%(Host)s",
107
                    "opts=%(SOpts)s"])
108
        end,
109
    ejabberd_sql:sql_transaction(Host, F).
×
110

111
delete_group(Host, Group) ->
112
    F = fun () ->
×
113
                ejabberd_sql:sql_query_t(
×
114
                  ?SQL("delete from sr_group where name=%(Group)s and %(Host)H")),
×
115
                ejabberd_sql:sql_query_t(
×
116
                  ?SQL("delete from sr_user where grp=%(Group)s and %(Host)H"))
×
117
        end,
118
    case ejabberd_sql:sql_transaction(Host, F) of
×
119
        {atomic,{updated,_}} -> {atomic, ok};
×
120
        Res -> Res
×
121
    end.
122

123
get_group_opts(Host, Group) ->
124
    case catch ejabberd_sql:sql_query(
×
125
                 Host,
126
                 ?SQL("select @(opts)s from sr_group"
×
127
                      " where name=%(Group)s and %(Host)H")) of
128
        {selected, [{SOpts}]} ->
129
            {ok, mod_shared_roster:opts_to_binary(ejabberd_sql:decode_term(SOpts))};
×
130
        _ -> error
×
131
    end.
132

133
set_group_opts(Host, Group, Opts) ->
134
    SOpts = misc:term_to_expr(Opts),
×
135
    F = fun () ->
×
136
                ?SQL_UPSERT_T(
×
137
                   "sr_group",
138
                   ["!name=%(Group)s",
139
                    "!server_host=%(Host)s",
140
                    "opts=%(SOpts)s"])
141
        end,
142
    ejabberd_sql:sql_transaction(Host, F).
×
143

144
get_user_groups(US, Host) ->
145
    SJID = make_jid_s(US),
×
146
    case catch ejabberd_sql:sql_query(
×
147
                 Host,
148
                 ?SQL("select @(grp)s from sr_user"
×
149
                      " where jid=%(SJID)s and %(Host)H")) of
150
        {selected, Rs} -> [G || {G} <- Rs];
×
151
        _ -> []
×
152
    end.
153

154
get_group_explicit_users(Host, Group) ->
155
    case catch ejabberd_sql:sql_query(
×
156
                 Host,
157
                 ?SQL("select @(jid)s from sr_user"
×
158
                      " where grp=%(Group)s and %(Host)H")) of
159
        {selected, Rs} ->
160
            lists:map(
×
161
              fun({JID}) ->
162
                      {U, S, _} = jid:tolower(jid:decode(JID)),
×
163
                      {U, S}
×
164
              end, Rs);
165
        _ ->
166
            []
×
167
    end.
168

169
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
170
    SJID = make_jid_s(LUser, LServer),
×
171
    case catch ejabberd_sql:sql_query(
×
172
                 LServer,
173
                 ?SQL("select @(grp)s from sr_user"
×
174
                      " where jid=%(SJID)s and %(LServer)H")) of
175
        {selected, Rs} ->
176
            [{Group, proplists:get_value(Group, GroupsOpts, [])}
×
177
             || {Group} <- Rs];
×
178
        _ -> []
×
179
    end.
180

181
is_user_in_group(US, Group, Host) ->
182
    SJID = make_jid_s(US),
×
183
    case catch ejabberd_sql:sql_query(
×
184
                 Host,
185
                 ?SQL("select @(jid)s from sr_user where jid=%(SJID)s"
×
186
                      " and %(Host)H and grp=%(Group)s")) of
187
        {selected, []} -> false;
×
188
        _ -> true
×
189
    end.
190

191
add_user_to_group(Host, US, Group) ->
192
    SJID = make_jid_s(US),
×
193
    ejabberd_sql:sql_query(
×
194
      Host,
195
      ?SQL_INSERT(
×
196
         "sr_user",
197
         ["jid=%(SJID)s",
198
          "server_host=%(Host)s",
199
          "grp=%(Group)s"])).
200

201
remove_user_from_group(Host, US, Group) ->
202
    SJID = make_jid_s(US),
×
203
    F = fun () ->
×
204
                ejabberd_sql:sql_query_t(
×
205
                  ?SQL("delete from sr_user where jid=%(SJID)s and %(Host)H"
×
206
                       " and grp=%(Group)s")),
207
                ok
×
208
        end,
209
    ejabberd_sql:sql_transaction(Host, F).
×
210

211
export(_Server) ->
212
    [{sr_group,
×
213
      fun(Host, #sr_group{group_host = {Group, LServer}, opts = Opts})
214
            when LServer == Host ->
215
              SOpts = misc:term_to_expr(Opts),
×
216
              [?SQL("delete from sr_group where name=%(Group)s and %(Host)H;"),
×
217
               ?SQL_INSERT(
×
218
                  "sr_group",
219
                  ["name=%(Group)s",
220
                   "server_host=%(Host)s",
221
                   "opts=%(SOpts)s"])];
222
         (_Host, _R) ->
223
              []
×
224
      end},
225
     {sr_user,
226
      fun(Host, #sr_user{us = {U, S}, group_host = {Group, LServer}})
227
            when LServer == Host ->
228
              SJID = make_jid_s(U, S),
×
229
              [?SQL("select @(jid)s from sr_user where jid=%(SJID)s"
×
230
                    " and %(Host)H and grp=%(Group)s;"),
231
               ?SQL_INSERT(
×
232
                  "sr_user",
233
                  ["jid=%(SJID)s",
234
                   "server_host=%(Host)s",
235
                   "grp=%(Group)s"])];
236
         (_Host, _R) ->
237
              []
×
238
      end}].
239

240
import(_, _, _) ->
241
    ok.
×
242

243
%%%===================================================================
244
%%% Internal functions
245
%%%===================================================================
246
make_jid_s(U, S) ->
247
    jid:encode(jid:tolower(jid:make(U, S))).
×
248

249
make_jid_s({U, S}) -> make_jid_s(U, S).
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc