Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 28186ddf19 | |||
| 8dfe7e977a | |||
| b345632a9a | |||
| 34e615d854 | |||
| d8d9ef32ad | |||
| a9ed26e484 | |||
| a76531b90b | |||
| d64e453364 | |||
| af9d642a71 | |||
| 6a659d7475 | |||
| 7da81249f8 | |||
| 8214a4fa79 | |||
| e048bc6712 | |||
| e5cad9be65 | |||
| 1dc0ecd1e9 | |||
| 0c09599d7b | |||
| e95ae66d3c | |||
| 5f9d480f6a | |||
| d34227cae1 | |||
| 72867f8d1e | |||
| 8f04491a4d | |||
| 0371b0f664 | |||
| 02cc212f16 | |||
| 0fe64674ee | |||
| e937ff62fe | |||
| d75d69d5d5 | |||
| f48f9fee2e | |||
| 5c6ffaafd6 | |||
| 3581d90d9d | |||
| 9e1f3862cb | |||
| c2a3f037bb | |||
| bf1aacefcb | |||
| e306cb0797 | |||
| 1c6221d8a0 | |||
| 2e8023158d | |||
| ff98cb4e15 | |||
| 0f01019e06 | |||
| f9b8dfd400 | |||
| 81e872c110 | |||
| 9ed2ca5079 | |||
| e7e9ca54df | |||
| 23a18b1a60 | |||
| 0a88f9c8a9 | |||
| de51ba331e | |||
| d37b2f851d | |||
| f40c5c304d | |||
| 37c75f556d | |||
| ec61c2f3dc | |||
| d02c7d3b3b | |||
| a2dfd2e0b9 | |||
| b4ea1625e4 | |||
| 7655e10ba4 | |||
| b64fff1faa | |||
| f1e04639bb | |||
| 73dbd34f95 | |||
| 6bbae4cea2 | |||
| b95d67aefb | |||
| 73f8aded17 | |||
| fdda572c9a | |||
| e4d6007293 | |||
| df58ee924f | |||
| d9c1befbfc | |||
| b173ca2fd0 | |||
| 27ed8f5647 | |||
| 714bc2d329 | |||
| d9cb6d1af7 | |||
| 583dd15beb | |||
| 604cc9bb3a | |||
| 0fc1aea379 | |||
| 385af01587 | |||
| d9feed54a9 | |||
| b89f3c442c | |||
| 9629601d0b | |||
| e9a053f7ac | |||
| a75966f1a2 | |||
| 43f813d6f8 | |||
| eada3b6e93 | |||
| 90e0293df3 | |||
| bd11a00f8f | |||
| 54af08799d | |||
| b71708aab9 | |||
| a3be28b5c4 | |||
| 743b25448a | |||
| 66c2f45bff | |||
| 8d969a4a9f | |||
| bf62cf3db6 | |||
| 8daea451e3 | |||
| 864188ad65 | |||
| 65260e2449 | |||
| b9926c6796 | |||
| e7575ab63f | |||
| 92913389a5 | |||
| 65be619907 | |||
| ee76581b49 | |||
| 842ec1494c | |||
| 8aa0f7073f | |||
| 8a645a2d3d | |||
| 4a54395561 | |||
| b109c5927e |
@@ -1,3 +1,38 @@
|
||||
# Version 20.12
|
||||
|
||||
- Add support for `SCRAM-SHA-{256,512}-{PLUS}` authentication
|
||||
- Don't use same value in cache for user don't exist and wrong password
|
||||
- outgoing_s2s_ipv*_address: New options to set ipv4/ipv6 outbound s2s out interface
|
||||
- s2s_send_packet: this hook now filters outgoing s2s stanzas
|
||||
- start_room: new hook runs when a room process is started
|
||||
- check_decoded_jwt: new hook to check decoded JWT after success authentication
|
||||
|
||||
* Admin
|
||||
- Docker: Fix DB initialization
|
||||
- New sql_odbc_driver option: choose the mssql ODBC driver
|
||||
- Rebar3: Fully supported. Enable with ./configure --with-rebar=/path/to/rebar3
|
||||
- systemd: start ejabberd in foreground
|
||||
|
||||
* Modules:
|
||||
- MAM: Make sure that jid used as base in mam xml_compress is bare
|
||||
- MAM: Support for MAM Flipped Pages
|
||||
- MUC: Always show MucSub subscribers nicks
|
||||
- MUC: Don't forget not-persistent rooms in load_permanent_rooms
|
||||
- MUC Admin: Better error reporting
|
||||
- MUC Admin: Fix commands with hibernated rooms
|
||||
- MUC Admin: Many improvements in rooms_unused_list/destroy
|
||||
- MUC Admin: create_room_with_opts Store options only if room starts
|
||||
- Pubsub: Remove 'dag' node plugin documentation
|
||||
- Push: Fix API call return type on error
|
||||
- Push: Support cache config changes on reload
|
||||
- Register: Allow for account-removal-only setup again
|
||||
- Roster: Make roster subscriptions work better with invalid roster state in db
|
||||
- Vcard: Fix vCard search by User when using Mnesia
|
||||
- WebAdmin: Allow vhost admins to view WebAdmin menus
|
||||
- WebAdmin: Don't do double utf-8 conversion on translated strings
|
||||
- WebAdmin: Mark dangerous buttons with CSS
|
||||
- WebSocket: Make websocket send put back pressure on c2s process
|
||||
|
||||
# Version 20.07
|
||||
|
||||
* Changes in this version
|
||||
|
||||
+58
-34
@@ -1,4 +1,4 @@
|
||||
REBAR = @ESCRIPT@ rebar
|
||||
REBAR = @ESCRIPT@ @rebar@
|
||||
INSTALL = @INSTALL@
|
||||
SED = @SED@
|
||||
ERL = @ERL@
|
||||
@@ -97,30 +97,50 @@ ifneq ($(INSTALLGROUP),)
|
||||
G_USER=-g $(INSTALLGROUP)
|
||||
endif
|
||||
|
||||
IS_REBAR3:=$(shell expr `$(REBAR) --version | awk -F '[ .]' '/rebar / {print $$2}'` '>=' 3)
|
||||
|
||||
ifeq "$(IS_REBAR3)" "1"
|
||||
SKIPDEPS=
|
||||
LISTDEPS=tree
|
||||
UPDATEDEPS=upgrade
|
||||
DEPSPATTERN="s/ (.*//; /^ / s/.* \([a-z0-9_]*\).*/\1/p;"
|
||||
DEPSBASE=_build
|
||||
DEPSDIR=$(DEPSBASE)/default/lib
|
||||
EBINDIR=$(DEPSDIR)/ejabberd/ebin
|
||||
else
|
||||
SKIPDEPS=skip_deps=true
|
||||
LISTDEPS=-q list-deps
|
||||
UPDATEDEPS=update-deps
|
||||
DEPSPATTERN="/ TAG / s/ .*// p; / REV / s/ .*// p; / BRANCH / s/ .*// p;"
|
||||
DEPSBASE=deps
|
||||
DEPSDIR=$(DEPSBASE)
|
||||
EBINDIR=ebin
|
||||
endif
|
||||
|
||||
all: deps src
|
||||
|
||||
deps: deps/.got
|
||||
deps: $(DEPSDIR)/.got
|
||||
|
||||
deps/.got:
|
||||
rm -rf deps/.got
|
||||
rm -rf deps/.built
|
||||
mkdir -p deps
|
||||
$(REBAR) get-deps && :> deps/.got
|
||||
$(DEPSDIR)/.got:
|
||||
rm -rf $(DEPSDIR)/.got
|
||||
rm -rf $(DEPSDIR)/.built
|
||||
mkdir -p $(DEPSDIR)
|
||||
$(REBAR) get-deps && :> $(DEPSDIR)/.got
|
||||
|
||||
deps/.built: deps/.got
|
||||
$(DEPSDIR)/.built: $(DEPSDIR)/.got
|
||||
$(REBAR) configure-deps
|
||||
$(REBAR) compile && :> deps/.built
|
||||
$(REBAR) compile && :> $(DEPSDIR)/.built
|
||||
|
||||
src: deps/.built
|
||||
$(REBAR) skip_deps=true compile
|
||||
src: $(DEPSDIR)/.built
|
||||
$(REBAR) $(SKIPDEPS) compile
|
||||
|
||||
update:
|
||||
rm -rf deps/.got
|
||||
rm -rf deps/.built
|
||||
$(REBAR) update-deps && :> deps/.got
|
||||
rm -rf $(DEPSDIR)/.got
|
||||
rm -rf $(DEPSDIR)/.built
|
||||
$(REBAR) $(UPDATEDEPS) && :> $(DEPSDIR)/.got
|
||||
|
||||
xref: all
|
||||
$(REBAR) skip_deps=true xref
|
||||
$(REBAR) $(SKIPDEPS) xref
|
||||
|
||||
hooks: all
|
||||
tools/hook_deps.sh ebin
|
||||
@@ -139,10 +159,13 @@ JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wo
|
||||
|
||||
VERSIONED_DEP=$(if $(DEP_$(1)_VERSION),$(DEP_$(1)_VERSION),$(1))
|
||||
|
||||
DEPIX:=$(words $(subst /, ,$(DEPSDIR)))
|
||||
LIBIX:=$(shell expr "$(DEPIX)" + 2)
|
||||
|
||||
ELIXIR_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 5,1000,$(1))
|
||||
DEPS_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 3,1000,$(1))
|
||||
MAIN_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,ejabberd) $(1)
|
||||
TO_DEST_SINGLE=$(if $(subst XdepsX,,X$(word 1,$(1))X),$(call MAIN_TO_DEST,$(1)),$(if $(subst XlibX,,X$(word 3,$(1))X),$(call DEPS_TO_DEST,$(1)),$(call ELIXIR_TO_DEST,$(1))))
|
||||
TO_DEST_SINGLE=$(if $(subst X$(DEPSBASE)X,,X$(word 1,$(1))X),$(call MAIN_TO_DEST,$(1)),$(if $(subst XlibX,,X$(word $(LIBIX),$(1))X),$(call DEPS_TO_DEST,$(wordlist $(DEPIX),1000,$(1))),$(call ELIXIR_TO_DEST,$(wordlist $(DEPIX),1000,$(1)))))
|
||||
TO_DEST=$(foreach path,$(1),$(call JOIN_PATHS,$(call TO_DEST_SINGLE,$(subst /, ,$(path)))))
|
||||
|
||||
FILTER_DIRS=$(foreach path,$(1),$(if $(wildcard $(path)/*),,$(path)))
|
||||
@@ -150,16 +173,16 @@ FILES_WILDCARD=$(call FILTER_DIRS,$(foreach w,$(1),$(wildcard $(w))))
|
||||
|
||||
ifeq ($(MAKECMDGOALS),copy-files-sub)
|
||||
|
||||
DEPS:=$(sort $(shell $(REBAR) -q list-deps|$(SED) -ne '/ TAG / s/ .*// p; / REV / s/ .*// p; / BRANCH / s/ .*// p'))
|
||||
DEPS:=$(sort $(shell QUIET=1 $(REBAR) $(LISTDEPS) | $(SED) -ne $(DEPSPATTERN) ))
|
||||
|
||||
DEPS_FILES=$(call FILES_WILDCARD,$(foreach DEP,$(DEPS),deps/$(DEP)/ebin/*.beam deps/$(DEP)/ebin/*.app deps/$(DEP)/priv/* deps/$(DEP)/priv/lib/* deps/$(DEP)/priv/bin/* deps/$(DEP)/include/*.hrl deps/$(DEP)/COPY* deps/$(DEP)/LICENSE* deps/$(DEP)/lib/*/ebin/*.beam deps/$(DEP)/lib/*/ebin/*.app))
|
||||
DEPS_FILES=$(call FILES_WILDCARD,$(foreach DEP,$(DEPS),$(DEPSDIR)/$(DEP)/ebin/*.beam $(DEPSDIR)/$(DEP)/ebin/*.app $(DEPSDIR)/$(DEP)/priv/* $(DEPSDIR)/$(DEP)/priv/lib/* $(DEPSDIR)/$(DEP)/priv/bin/* $(DEPSDIR)/$(DEP)/include/*.hrl $(DEPSDIR)/$(DEP)/COPY* $(DEPSDIR)/$(DEP)/LICENSE* $(DEPSDIR)/$(DEP)/lib/*/ebin/*.beam $(DEPSDIR)/$(DEP)/lib/*/ebin/*.app))
|
||||
|
||||
BINARIES=deps/epam/priv/bin/epam deps/eimp/priv/bin/eimp deps/fs/priv/mac_listener
|
||||
BINARIES=$(DEPSDIR)/epam/priv/bin/epam $(DEPSDIR)/eimp/priv/bin/eimp $(DEPSDIR)/fs/priv/mac_listener
|
||||
|
||||
DEPS_FILES_FILTERED=$(filter-out $(BINARIES) deps/elixir/ebin/elixir.app,$(DEPS_FILES))
|
||||
DEPS_DIRS=$(sort deps/ $(foreach DEP,$(DEPS),deps/$(DEP)/) $(dir $(DEPS_FILES)))
|
||||
DEPS_FILES_FILTERED=$(filter-out $(BINARIES) $(DEPSDIR)/elixir/ebin/elixir.app,$(DEPS_FILES))
|
||||
DEPS_DIRS=$(sort $(DEPSDIR)/ $(foreach DEP,$(DEPS),$(DEPSDIR)/$(DEP)/) $(dir $(DEPS_FILES)))
|
||||
|
||||
MAIN_FILES=$(filter-out %/configure.beam,$(call FILES_WILDCARD,ebin/*.beam ebin/*.app priv/msgs/*.msg priv/css/*.css priv/img/*.png priv/js/*.js priv/lib/* include/*.hrl COPYING))
|
||||
MAIN_FILES=$(filter-out %/configure.beam,$(call FILES_WILDCARD,$(EBINDIR)/*.beam $(EBINDIR)/*.app priv/msgs/*.msg priv/css/*.css priv/img/*.png priv/js/*.js priv/lib/* include/*.hrl COPYING))
|
||||
MAIN_DIRS=$(sort $(dir $(MAIN_FILES)) priv/bin priv/sql priv/lua)
|
||||
|
||||
define DEP_VERSION_template
|
||||
@@ -168,8 +191,8 @@ endef
|
||||
|
||||
DELETE_TARGET_SO=$(if $(subst X.soX,,X$(suffix $(1))X),,rm -f $(call TO_DEST,$(1));)
|
||||
|
||||
$(foreach DEP,$(DEPS),$(eval $(call DEP_VERSION_template,$(DEP),deps/$(DEP)/ebin/$(DEP).app)))
|
||||
$(eval $(call DEP_VERSION_template,ejabberd,ebin/ejabberd.app))
|
||||
$(foreach DEP,$(DEPS),$(eval $(call DEP_VERSION_template,$(DEP),$(DEPSDIR)/$(DEP)/ebin/$(DEP).app)))
|
||||
$(eval $(call DEP_VERSION_template,ejabberd,$(EBINDIR)/ejabberd.app))
|
||||
|
||||
define COPY_template
|
||||
$(call TO_DEST,$(1)): $(1) $(call TO_DEST,$(dir $(1))) ; $(call DELETE_TARGET_SO, $(1)) $$(INSTALL) -m 644 $(1) $(call TO_DEST,$(1))
|
||||
@@ -206,7 +229,7 @@ copy-files:
|
||||
|
||||
copy-files-sub: copy-files-sub2
|
||||
|
||||
install: all copy-files
|
||||
install: copy-files
|
||||
#
|
||||
# Configuration files
|
||||
$(INSTALL) -d -m 750 $(G_USER) $(ETCDIR)
|
||||
@@ -233,9 +256,9 @@ install: all copy-files
|
||||
$(INSTALL) -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
|
||||
# Elixir binaries
|
||||
[ -d $(BINDIR) ] || $(INSTALL) -d -m 755 $(BINDIR)
|
||||
[ -f deps/elixir/bin/iex ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/iex $(BINDIR)/iex || true
|
||||
[ -f deps/elixir/bin/elixir ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/elixir $(BINDIR)/elixir || true
|
||||
[ -f deps/elixir/bin/mix ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/mix $(BINDIR)/mix || true
|
||||
[ -f $(DEPSDIR)/elixir/bin/iex ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/iex $(BINDIR)/iex || true
|
||||
[ -f $(DEPSDIR)/elixir/bin/elixir ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/elixir $(BINDIR)/elixir || true
|
||||
[ -f $(DEPSDIR)/elixir/bin/mix ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/mix $(BINDIR)/mix || true
|
||||
#
|
||||
# Init script
|
||||
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*g" \
|
||||
@@ -311,8 +334,8 @@ uninstall-all: uninstall-binary
|
||||
rm -rf $(LOGDIR)
|
||||
|
||||
clean:
|
||||
rm -rf deps/.got
|
||||
rm -rf deps/.built
|
||||
rm -rf $(DEPSDIR)/.got
|
||||
rm -rf $(DEPSDIR)/.built
|
||||
rm -rf test/*.beam
|
||||
$(REBAR) clean
|
||||
|
||||
@@ -323,11 +346,12 @@ distclean: clean clean-rel
|
||||
rm -f config.status
|
||||
rm -f config.log
|
||||
rm -rf autom4te.cache
|
||||
rm -rf deps
|
||||
rm -rf ebin
|
||||
rm -rf $(EBINDIR)
|
||||
rm -rf $(DEPSBASE)
|
||||
rm -f Makefile
|
||||
rm -f vars.config
|
||||
rm -f src/ejabberd.app.src
|
||||
rm -f ejabberdctl.example ejabberd.init ejabberd.service
|
||||
[ ! -f ../ChangeLog ] || rm -f ../ChangeLog
|
||||
|
||||
rel: all
|
||||
@@ -338,7 +362,7 @@ TAGS:
|
||||
|
||||
Makefile: Makefile.in
|
||||
|
||||
deps := $(wildcard deps/*/ebin)
|
||||
deps := $(wildcard $(DEPSDIR)/*/ebin)
|
||||
|
||||
dialyzer/erlang.plt:
|
||||
@mkdir -p dialyzer
|
||||
@@ -382,7 +406,7 @@ test:
|
||||
@cat test/README
|
||||
@echo "*************************************************************************"
|
||||
@cd priv && ln -sf ../sql
|
||||
$(REBAR) skip_deps=true ct
|
||||
$(REBAR) $(SKIPDEPS) ct
|
||||
|
||||
.PHONY: src edoc dialyzer Makefile TAGS clean clean-rel distclean rel \
|
||||
install uninstall uninstall-binary uninstall-all translations deps test \
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
{erl_opts, [debug_info]}.
|
||||
{deps, []}.
|
||||
@@ -0,0 +1,9 @@
|
||||
{application, configure_deps,
|
||||
[{description, "A rebar3 plugin to explicitly run configure on dependencies"},
|
||||
{vsn, "0.0.1"},
|
||||
{registered, []},
|
||||
{applications, [kernel, stdlib]},
|
||||
{env,[]},
|
||||
{modules, []},
|
||||
{links, []}
|
||||
]}.
|
||||
@@ -0,0 +1,8 @@
|
||||
-module(configure_deps).
|
||||
|
||||
-export([init/1]).
|
||||
|
||||
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
|
||||
init(State) ->
|
||||
{ok, State1} = configure_deps_prv:init(State),
|
||||
{ok, State1}.
|
||||
@@ -0,0 +1,54 @@
|
||||
-module(configure_deps_prv).
|
||||
|
||||
-export([init/1, do/1, format_error/1]).
|
||||
|
||||
-define(PROVIDER, 'configure-deps').
|
||||
-define(DEPS, [install_deps]).
|
||||
|
||||
%% ===================================================================
|
||||
%% Public API
|
||||
%% ===================================================================
|
||||
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
|
||||
init(State) ->
|
||||
Provider = providers:create([
|
||||
{namespace, default},
|
||||
{name, ?PROVIDER}, % The 'user friendly' name of the task
|
||||
{module, ?MODULE}, % The module implementation of the task
|
||||
{bare, true}, % The task can be run by the user, always true
|
||||
{deps, ?DEPS}, % The list of dependencies
|
||||
{example, "rebar3 configure-deps"}, % How to use the plugin
|
||||
{opts, []}, % list of options understood by the plugin
|
||||
{short_desc, "Explicitly run ./configure for dependencies"},
|
||||
{desc, "A rebar plugin to allow explicitly running ./configure on depdendencies. Useful if dependencies might change prior to compilation when configure is run."}
|
||||
]),
|
||||
{ok, rebar_state:add_provider(State, Provider)}.
|
||||
|
||||
|
||||
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
|
||||
do(State) ->
|
||||
Apps = rebar_state:project_apps(State) ++ lists:usort(rebar_state:all_deps(State)),
|
||||
lists:foreach(fun do_app/1, Apps),
|
||||
{ok, State}.
|
||||
|
||||
exec_configure({'configure-deps', Cmd}, Dir) ->
|
||||
rebar_utils:sh(Cmd, [{cd, Dir}, {use_stdout, true}]);
|
||||
exec_configure(_, Acc) -> Acc.
|
||||
|
||||
parse_pre_hooks({pre_hooks, PreHooks}, Acc) ->
|
||||
lists:foldl(fun exec_configure/2, Acc, PreHooks);
|
||||
parse_pre_hooks(_, Acc) -> Acc.
|
||||
|
||||
parse_additions({add, App, Additions}, {MyApp, Dir}) when App == MyApp ->
|
||||
lists:foldl(fun parse_pre_hooks/2, Dir, Additions),
|
||||
{MyApp, Dir};
|
||||
parse_additions(_, Acc) -> Acc.
|
||||
|
||||
do_app(App) ->
|
||||
Dir = rebar_app_info:dir(App),
|
||||
Opts = rebar_app_info:opts(App),
|
||||
Overrides = rebar_opts:get(Opts, overrides),
|
||||
lists:foldl(fun parse_additions/2, {binary_to_atom(rebar_app_info:name(App), utf8), Dir}, Overrides).
|
||||
|
||||
-spec format_error(any()) -> iolist().
|
||||
format_error(Reason) ->
|
||||
io_lib:format("~p", [Reason]).
|
||||
@@ -4,9 +4,7 @@ defmodule Ejabberd.ConfigFile do
|
||||
def start do
|
||||
[loglevel: 4,
|
||||
log_rotate_size: 10485760,
|
||||
log_rotate_date: "",
|
||||
log_rotate_count: 1,
|
||||
log_rate_limit: 100,
|
||||
auth_method: :internal,
|
||||
max_fsm_queue: 1000,
|
||||
language: "en",
|
||||
|
||||
@@ -28,6 +28,16 @@ else
|
||||
fi
|
||||
])
|
||||
|
||||
AC_ARG_WITH(rebar,
|
||||
AC_HELP_STRING([--with-rebar=bin],
|
||||
[use rebar specified]),
|
||||
[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_rebar" = "X"; then
|
||||
rebar="rebar"
|
||||
else
|
||||
rebar="$with_rebar"
|
||||
fi
|
||||
], [rebar="rebar"])
|
||||
|
||||
AC_PATH_TOOL(ERL, erl, , [${extra_erl_path}$PATH])
|
||||
AC_PATH_TOOL(ERLC, erlc, , [${extra_erl_path}$PATH])
|
||||
AC_PATH_TOOL(EPMD, epmd, , [${extra_erl_path}$PATH])
|
||||
@@ -289,6 +299,7 @@ AC_SUBST(pgsql)
|
||||
AC_SUBST(sqlite)
|
||||
AC_SUBST(pam)
|
||||
AC_SUBST(zlib)
|
||||
AC_SUBST(rebar)
|
||||
AC_SUBST(redis)
|
||||
AC_SUBST(elixir)
|
||||
AC_SUBST(stun)
|
||||
|
||||
@@ -3,13 +3,12 @@ Description=XMPP Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
User=ejabberd
|
||||
Group=ejabberd
|
||||
LimitNOFILE=65536
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
ExecStart=/bin/sh -c '@ctlscriptpath@/ejabberdctl start && @ctlscriptpath@/ejabberdctl started'
|
||||
ExecStart=@ctlscriptpath@/ejabberdctl foreground
|
||||
ExecStop=/bin/sh -c '@ctlscriptpath@/ejabberdctl stop && @ctlscriptpath@/ejabberdctl stopped'
|
||||
ExecReload=@ctlscriptpath@/ejabberdctl reload_config
|
||||
PrivateDevices=true
|
||||
|
||||
@@ -87,10 +87,8 @@ ERL_INETRC="$ETC_DIR"/inetrc
|
||||
|
||||
# define ejabberd parameters
|
||||
EJABBERD_OPTS="$EJABBERD_OPTS\
|
||||
$(sed '/^log_rate_limit/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
|
||||
$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
|
||||
$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
|
||||
$(sed '/^log_rotate_date/!d;s/:[ \t]*\(.[^ ]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")"
|
||||
$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")"
|
||||
[ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
|
||||
EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
|
||||
|
||||
@@ -130,12 +128,12 @@ exec_iex()
|
||||
# usage
|
||||
debugwarning()
|
||||
{
|
||||
if [ "$OSTYPE" != "cygwin" ] && [ "$OSTYPE" != "win32" ]; then
|
||||
if [ "a$TERM" == "a" ] || [ "$TERM" == "dumb" ] ; then
|
||||
echo "Terminal type not supported."
|
||||
echo "You may have to set the TERM environnement variable to fix this."
|
||||
exit 8
|
||||
fi
|
||||
if [ "$OSTYPE" != "cygwin" ] && [ "$OSTYPE" != "win32" ] ; then
|
||||
if [ "a$TERM" = "a" ] || [ "$TERM" = "dumb" ] ; then
|
||||
echo "Terminal type not supported."
|
||||
echo "You may have to set the TERM environment variable to fix this."
|
||||
exit 8
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
|
||||
@@ -65,6 +65,14 @@
|
||||
-define(INPUTT(Type, Name, Value),
|
||||
?INPUT(Type, Name, (translate:translate(Lang, Value)))).
|
||||
|
||||
-define(INPUTD(Type, Name, Value),
|
||||
?XA(<<"input">>,
|
||||
[{<<"type">>, Type}, {<<"name">>, Name},
|
||||
{<<"class">>, <<"btn-danger">>}, {<<"value">>, Value}])).
|
||||
|
||||
-define(INPUTTD(Type, Name, Value),
|
||||
?INPUTD(Type, Name, (translate:translate(Lang, Value)))).
|
||||
|
||||
-define(INPUTS(Type, Name, Value, Size),
|
||||
?XA(<<"input">>,
|
||||
[{<<"type">>, Type}, {<<"name">>, Name},
|
||||
|
||||
@@ -3,7 +3,7 @@ defmodule Ejabberd.Mixfile do
|
||||
|
||||
def project do
|
||||
[app: :ejabberd,
|
||||
version: "20.4.0",
|
||||
version: "20.12.0",
|
||||
description: description(),
|
||||
elixir: "~> 1.4",
|
||||
elixirc_paths: ["lib"],
|
||||
@@ -66,7 +66,10 @@ defmodule Ejabberd.Mixfile do
|
||||
cond_options() ++
|
||||
Enum.map(includes, fn (path) -> {:i, path} end) ++
|
||||
if_version_above('20', [{:d, :DEPRECATED_GET_STACKTRACE}]) ++
|
||||
if_version_below('21', [{:d, :USE_OLD_HTTP_URI}]) ++
|
||||
if_version_below('22', [{:d, :LAGER}]) ++
|
||||
if_version_below('23', [{:d, :USE_OLD_CRYPTO_HMAC}]) ++
|
||||
if_version_below('23', [{:d, :USE_OLD_PG2}]) ++
|
||||
if_function_exported(:erl_error, :format_exception, 6, [{:d, :HAVE_ERL_ERROR}])
|
||||
defines = for {:d, value} <- result, do: {:d, value}
|
||||
result ++ [{:d, :ALL_DEFS, defines}]
|
||||
@@ -85,7 +88,7 @@ defmodule Ejabberd.Mixfile do
|
||||
[{:lager, "~> 3.6.0"},
|
||||
{:p1_utils, "~> 1.0"},
|
||||
{:fast_xml, "~> 1.1"},
|
||||
{:xmpp, ">= 1.4.6"},
|
||||
{:xmpp, ">= 1.5.0"},
|
||||
{:cache_tab, "~> 1.0"},
|
||||
{:stringprep, "~> 1.0"},
|
||||
{:fast_yaml, "~> 1.0"},
|
||||
@@ -142,7 +145,7 @@ defmodule Ejabberd.Mixfile do
|
||||
|
||||
defp package do
|
||||
[# These are the default files included in the package
|
||||
files: ["lib", "src", "priv", "mix.exs", "include", "README.md", "COPYING"],
|
||||
files: ["lib", "src", "priv", "mix.exs", "include", "README.md", "COPYING", "rebar.config", "rebar.config.script"],
|
||||
maintainers: ["ProcessOne"],
|
||||
licenses: ["GPLv2"],
|
||||
links: %{"Site" => "https://www.ejabberd.im",
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
%{
|
||||
"artificery": {:hex, :artificery, "0.4.3", "0bc4260f988dcb9dda4b23f9fc3c6c8b99a6220a331534fdf5bf2fd0d4333b02", [:mix], [], "hexpm", "12e95333a30e20884e937abdbefa3e7f5e05609c2ba8cf37b33f000b9ffc0504"},
|
||||
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm", "fab09b20e3f5db886725544cbcf875b8e73ec93363954eb8a1a9ed834aa8c1f9"},
|
||||
"cache_tab": {:hex, :cache_tab, "1.0.25", "1e94d4d38ad18abd92f0d076bd4bab0f3b7189e28927c358beea0c5c2ea9d2ae", [:rebar3], [{:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "cd04c19ffa1b8ba34611668cea28b1a76536ec2246f5ffb77697a4a0111c70dc"},
|
||||
"cache_tab": {:hex, :cache_tab, "1.0.26", "6f6086ac80b797f54a68773d9d782e054877e217f8f1e2fbc6deb1557cc3e26a", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "a7f0a03e3a9d6275e4a7583a1f3088e6764dd1e362464eaa8e2fcca9c3b235c3"},
|
||||
"distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"},
|
||||
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"},
|
||||
"eimp": {:hex, :eimp, "1.0.17", "3d62a8edf67b204a200c92b099125bada62fc4b2d348fe186e775014df31e6e5", [:rebar3], [{:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "c241c79cf5149d477ba613114d4d95d346f145fade70bdd657b03fd5dc9fcdc5"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
|
||||
"eimp": {:hex, :eimp, "1.0.18", "b6532f90c87741bebdfe62582e2c70caafa1337c3aa7fb85daaba3e9bad4b8a0", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "7df78b25d7c325fe6c4d77901013be2f4341f4207bc7a985fea00a1bea15dd3a"},
|
||||
"epam": {:hex, :epam, "1.0.7", "55889bbfdc5ab9f2e785a710229f34e550784c5ead1960d7839ea77514aef44d", [:rebar3], [], "hexpm", "6b029ebd2b244bc339cbf5cb5908d0f2d50e43f33a6e7f70818912ea5d3fd596"},
|
||||
"eredis": {:hex, :eredis, "1.2.0", "0b8e9cfc2c00fa1374cd107ea63b49be08d933df2cf175e6a89b73dd9c380de4", [:rebar3], [], "hexpm"},
|
||||
"esip": {:hex, :esip, "1.0.37", "eb26a0bceda2019c40fd6ac3935f8d7f76c1a36fdd89ed2e3356696d33503737", [:rebar3], [{:fast_tls, "1.1.8", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stun, "1.0.37", [hex: :stun, repo: "hexpm", optional: false]}], "hexpm", "19bacbf089aaa2c11a59c1daffd7819d7917baf457a8ee67f969a99d76160714"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.22.2", "03a2a58bdd2ba0d83d004507c4ee113b9c521956938298eba16e55cc4aba4a6c", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "cf60e1b3e2efe317095b6bb79651f83a2c1b3edcb4d319c421d7fcda8b3aff26"},
|
||||
"ezlib": {:hex, :ezlib, "1.0.8", "9bd3a4d905c4694da5054aefe0113303c6ad56701f6625bde94b4bcc06e50dc9", [:rebar3], [], "hexpm", "852c2b2fe0166d5e7454fa7667cafcb0dadb9d6571b3808a93cf935c0a39e4ef"},
|
||||
"fast_tls": {:hex, :fast_tls, "1.1.8", "d8f78d433b7cfae0548c2bc00b9ca4f9644ba894834ae34a0d2b39c8c97a316b", [:rebar3], [{:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "6cca3c9b14c2bcacbeb271959adc9f655707b301b7a483438c77c20068121668"},
|
||||
"fast_xml": {:hex, :fast_xml, "1.1.43", "a3b1a14270bae7191e9fcd42628d5987642632a9b28604937c51b55094c387c1", [:rebar3], [{:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "78651c9eedb88322a0359a213a6e68b65d1c88d5738f37650030588599677a32"},
|
||||
"fast_yaml": {:hex, :fast_yaml, "1.0.27", "c6b2fda782d0987f0d5463f42c44a2f220ae88ac1d8eae98f75e260f6c8a9739", [:rebar3], [{:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "51177f885466546bea70eadd9775610f008930b3de61a18901ff223de6e70f30"},
|
||||
"esip": {:hex, :esip, "1.0.39", "ec7705f685df1f9957bb7883c65e959e27b46899a9c9fa7f79e67919fc3e2bbb", [:rebar3], [{:fast_tls, "1.1.10", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stun, "1.0.40", [hex: :stun, repo: "hexpm", optional: false]}], "hexpm", "08f4cfe69e88d60ebbe5ccdaa36fe4f3411086832a19876497972747e089a076"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
|
||||
"ezlib": {:hex, :ezlib, "1.0.9", "b17136b48bcf73962446b06d4427b0b6f2be4550bb5190a18a2979640271e244", [:rebar3], [], "hexpm", "fafc60a0de6e982be38f793da7b220b87a0da2969eba8a878351442b35cc2fde"},
|
||||
"fast_tls": {:hex, :fast_tls, "1.1.10", "c2a14d66d73b589c6d06841f72433611bf0360953b2e9164b1435d045bf1944d", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "17fb7dac5f64b9215b57e5315f4eafd682520d5a821b5b49cbe204882375bb85"},
|
||||
"fast_xml": {:hex, :fast_xml, "1.1.45", "68eeec9a3c5e58de9164dd288523822226955d97013bd8a4d7657cf622eeb076", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "2d8eb7bb642920e63f69501b7bdb596bef135fc4919d9b6895875fa88d8a63e0"},
|
||||
"fast_yaml": {:hex, :fast_yaml, "1.0.29", "02203981b9a387321a88676e8a501935df0d5d95c6b1d08c864fb9a7657c3b5b", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "b6e9ed0203f40079d2c14df6f8ab9dcfdc4a71e023cfb6de732b8d3081084b10"},
|
||||
"goldrush": {:hex, :goldrush, "0.1.9", "f06e5d5f1277da5c413e84d5a2924174182fb108dabb39d5ec548b27424cd106", [:rebar3], [], "hexpm", "99cb4128cffcb3227581e5d4d803d5413fa643f4eb96523f77d9e6937d994ceb"},
|
||||
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
|
||||
"jiffy": {:hex, :jiffy, "1.0.4", "72adeff75c52a2ff07de738f0813768abe7ce158026cc1115a170340259c0caa", [:rebar3], [], "hexpm", "113e5299ee4e6b9f40204256d7bbbd1caf646edeaef31ef0f7f5f842c0dad39e"},
|
||||
"jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm", "6429c4fee52b2dda7861ee19a4f09c8c1ffa213bee3a1ec187828fde95d447ed"},
|
||||
"lager": {:hex, :lager, "3.6.10", "6172b43ab720ac33914ccd0aeb21fdbdf88213847707d4b91e6af57b2ae5c4d2", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm", "5d10499461826b79c5abee18bb594b3949cbdf76d9d9fd7e66d0a558137c21c9"},
|
||||
"luerl": {:hex, :luerl, "0.3.1", "5412807630aac1aaf59ffe5a1bc09259c447b4faeb1d3fe2d4ef41b87676cb04", [:rebar3], [], "hexpm", "1bc011c7297e43aec762e53b17ecb15b0ff29f9546cd153110b343cf5b043f5f"},
|
||||
"makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
|
||||
"mqtree": {:hex, :mqtree, "1.0.10", "224c74694c3720da707eda6c0863dbb21a6a74dd56b606534e511b58dd6aba62", [:rebar3], [{:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "e8d2c37e0fa6c69ba168c0cb8130ae92d3042bafc363cee346cb5602ff17b2fa"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"},
|
||||
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"},
|
||||
"mqtree": {:hex, :mqtree, "1.0.11", "8ea161bd2075cb23840bb4ebc94d33d08e110c82d0771b0482e022e1b7e3377a", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "975a8514ce14550ae945f7c297d2b12269dbfa69db410320163718ad42229adf"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
|
||||
"p1_acme": {:hex, :p1_acme, "1.0.6", "0b007b776331e3d6effe700fa85d63236a98dc4e6e8c3abbbf816d1bec70df3f", [:rebar3], [{:idna, "~>6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jiffy, "~>1.0.1", [hex: :jiffy, repo: "hexpm", optional: false]}, {:jose, "~>1.9.0", [hex: :jose, repo: "hexpm", optional: false]}, {:yconf, "~>1.0.5", [hex: :yconf, repo: "hexpm", optional: false]}], "hexpm", "7cc6528cbbe7a98929e954604ec670de56ca9f7a69a14d22166e8746fbe86f10"},
|
||||
"p1_mysql": {:hex, :p1_mysql, "1.0.16", "ef063cd8cc85fd902568a82839b359fdf3d83b27cd13fbcc4fb3a3edcd728b6b", [:rebar3], [], "hexpm", "e68e861043dc311f35e2bf8b97812b654c3d91488cc4aa3084d45c7366fe1555"},
|
||||
"p1_oauth2": {:hex, :p1_oauth2, "0.6.7", "28a1c3ba36d6ccf5b054604ef4cde47358c835f93a260fb216e9b257ca1a478b", [:rebar3], [], "hexpm", "2768d7659f213b143279fa2c1ee07101df3d24b177eb79cf175afd9fcffd01e2"},
|
||||
"p1_mysql": {:hex, :p1_mysql, "1.0.17", "1fd1eed07a0f1e79851e7a5dc17995ba42af1c1192dff978d5f17c9e096a6d8c", [:rebar3], [], "hexpm", "7da95ba3f36e50e80f6a7f89a0928c0bbe6c0a8c8a7a7432d1aa7349e5964a59"},
|
||||
"p1_oauth2": {:hex, :p1_oauth2, "0.6.8", "22b859f3694da30c45722fae860922150f74cfb149ef6176a67c514093238917", [:rebar3], [], "hexpm", "12a476d809f3123098948ee95676198008e96afbc433070a1382e5aa3d2a7b93"},
|
||||
"p1_pgsql": {:hex, :p1_pgsql, "1.1.10", "e4b19c9768ef4047f9c56090a91bfefc7337abb3809a28aa4a6538eef6ad76b0", [:rebar3], [], "hexpm", "5458c0db9e47425f8cc1f592356a29359267c624785b316b34a46ad7439e9367"},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.20", "559313c0ea267a646317fd122cdfbb041db86b1ed00df91902fd273ce08d4a45", [:rebar3], [], "hexpm", "0b2c98edfe3e82dd49b287a70913f265e09eb630e40774bee88e0a9f06b0c061"},
|
||||
"pkix": {:hex, :pkix, "1.0.6", "f2b64118a25c5f80064b60a235eb299f44dd9b33a554e42df5369eae3d23c12f", [:rebar3], [], "hexpm", "9082d29e9abc965f763f1c7d7e90408dc6de91f5c1886228c3500fedf2ee183c"},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.21", "9d6244bbd4af881e85af71655e8be5720b5b965b1bdd51a35c7871fd4142af9a", [:rebar3], [], "hexpm", "4b9b90e5863f5fed17f06427ba99b2dc37b216e4dd1308891f0903745e2fccbd"},
|
||||
"pkix": {:hex, :pkix, "1.0.7", "a0b8c9011edeba702d7cb73fecef1eabe3ae89b3dcf4b8f33775e4f17a7a1304", [:rebar3], [], "hexpm", "104a9e0ecd9cc0e579d148a028189a6efe6420b241f3d319d8a65d898a078295"},
|
||||
"sqlite3": {:hex, :sqlite3, "1.1.6", "4ea71af0b45908b5f02c9b09e4c87177039ef404f20accb35049cd8924cc417c", [:rebar3], [], "hexpm", "cf9fa59c5b27de0d5d94a2ef464521379e23d8c6e9fa939abf8415c767f514bb"},
|
||||
"stringprep": {:hex, :stringprep, "1.0.22", "c6389cb635930044bc60973925d17abe9f259edba0a3dd155cccae2db79c0c52", [:rebar3], [{:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "956c5909016532d0445f1eb73bb15a1d81bf46ee452b92fdf67993becb5549cf"},
|
||||
"stun": {:hex, :stun, "1.0.37", "30c7012cd2a48de4177283aeb13719f84e8570f0b97b791c476bc384605a4c83", [:rebar3], [{:fast_tls, "1.1.8", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "9f46745405f495446817908fe735fb1e2c38eb776021cbda44cc18cab0b16ede"},
|
||||
"stringprep": {:hex, :stringprep, "1.0.24", "5a2c29785cdc1eaddcba0564cd86020e5e686fe9e66fa47a80a97333f3dc75ea", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "aed7ac217493e5aa2f76066fb7bbfe0d4e94ca1ee72613dc954231422d911266"},
|
||||
"stun": {:hex, :stun, "1.0.40", "9cc25f667f4d36321a259521c3f4848a53bfebed989cf3d761790447daeec41d", [:rebar3], [{:fast_tls, "1.1.10", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "46073f5a05a5d6ca9de1339be990600648228c204b9a690f1b5f5dfd5a895b6a"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
|
||||
"xmpp": {:hex, :xmpp, "1.4.9", "4b33ba41f9efc2eb2c4b89a9c3aac61aa0d2e5efafd681c37caa23a2bc2bc6ad", [:rebar3], [{:ezlib, "1.0.8", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.1.8", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.43", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.20", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.22", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm", "e4958505ff4e2e4cd0aa6a7cb18d19ace7bf4450be8c0b375522fb4ca623c529"},
|
||||
"yconf": {:hex, :yconf, "1.0.7", "941fa712f7c01f0e5649c5cf9b2787853802bc406dc3b6a80417475b1d63d209", [:rebar3], [{:fast_yaml, "1.0.27", [hex: :fast_yaml, repo: "hexpm", optional: false]}], "hexpm", "8b09f5249b9197f0c542eb67a05b9d50e8f98df08c9dac11ce2c80fbabe05e5e"},
|
||||
"xmpp": {:hex, :xmpp, "1.5.0", "23b5b43e1858a5f6c53e204904ef8fb41d0f2419290bcd044fb7dc313fa2e689", [:rebar3], [{:ezlib, "1.0.9", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.1.10", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.45", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.24", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm", "4be95acc98ce3e6b0c67873a14a6f7d6db0fd131d77ccc4d4243f77b12f2945f"},
|
||||
"yconf": {:hex, :yconf, "1.0.9", "32e922e47c3b18b1fa6f7502bfb433d3419e038123982fe7e478f3eb5d9aff0c", [:rebar3], [{:fast_yaml, "1.0.29", [hex: :fast_yaml, repo: "hexpm", optional: false]}], "hexpm", "97ab7b889f92f65447ed2db485324aba382447fa4ce8b57e466ab994da5f6233"},
|
||||
}
|
||||
|
||||
@@ -276,3 +276,11 @@ p.result {
|
||||
*.alignright {
|
||||
text-align: right;
|
||||
}
|
||||
.btn-danger:hover {
|
||||
color: #fff;
|
||||
background-color: #cb2431;
|
||||
}
|
||||
.btn-danger {
|
||||
color: #cb2431;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
+30
-30
@@ -18,49 +18,51 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
{deps, [{base64url, ".*", {git, "https://github.com/dvv/base64url.git", {tag, "v1.0"}}},
|
||||
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.25"}}},
|
||||
{eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.17"}}},
|
||||
{deps, [{base64url, ".*", {git, "https://github.com/dvv/base64url.git", {tag, "1.0.1"}}},
|
||||
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.26"}}},
|
||||
{eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.18"}}},
|
||||
{if_var_true, elixir,
|
||||
{elixir, ".*", {git, "https://github.com/elixir-lang/elixir", {tag, "v1.4.4"}}}},
|
||||
{if_var_true, pam,
|
||||
{epam, ".*", {git, "https://github.com/processone/epam", {tag, "1.0.9"}}}},
|
||||
{epam, ".*", {git, "https://github.com/processone/epam", {tag, "1.0.10"}}}},
|
||||
{if_var_true, redis,
|
||||
{eredis, ".*", {git, "https://github.com/wooga/eredis", {tag, "v1.0.8"}}}},
|
||||
{if_var_true, sip,
|
||||
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.37"}}}},
|
||||
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.39"}}}},
|
||||
{if_var_true, zlib,
|
||||
{ezlib, ".*", {git, "https://github.com/processone/ezlib", {tag, "1.0.8"}}}},
|
||||
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.8"}}},
|
||||
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.43"}}},
|
||||
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.27"}}},
|
||||
{ezlib, ".*", {git, "https://github.com/processone/ezlib", {tag, "1.0.9"}}}},
|
||||
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.10"}}},
|
||||
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.45"}}},
|
||||
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.29"}}},
|
||||
{idna, ".*", {git, "https://github.com/benoitc/erlang-idna", {tag, "6.0.0"}}},
|
||||
{jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "1.0.5"}}},
|
||||
{jose, ".*", {git, "https://github.com/potatosalad/erlang-jose", {tag, "1.9.0"}}},
|
||||
{lager, ".*", {git, "https://github.com/erlang-lager/lager", "3.6.10"}},
|
||||
{lager, ".*", {git, "https://github.com/erlang-lager/lager", {tag, "3.6.10"}}},
|
||||
{if_var_true, tools,
|
||||
{luerl, ".*", {git, "https://github.com/rvirding/luerl", {tag, "v0.3"}}}},
|
||||
{mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.10"}}},
|
||||
{p1_acme, ".*", {git, "https://github.com/processone/p1_acme.git", {tag, "1.0.8"}}},
|
||||
{mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.11"}}},
|
||||
{p1_acme, ".*", {git, "https://github.com/processone/p1_acme.git", {tag, "1.0.10"}}},
|
||||
{if_var_true, mysql,
|
||||
{p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql", {tag, "1.0.16"}}}},
|
||||
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.7"}}},
|
||||
{p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql", {tag, "1.0.17"}}}},
|
||||
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.8"}}},
|
||||
{if_var_true, pgsql,
|
||||
{p1_pgsql, ".*", {git, "https://github.com/processone/p1_pgsql", {tag, "1.1.10"}}}},
|
||||
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.20"}}},
|
||||
{pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.6"}}},
|
||||
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.21"}}},
|
||||
{pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.7"}}},
|
||||
{if_not_rebar3, %% Needed because modules are not fully migrated to new structure and mix
|
||||
{if_var_true, elixir,
|
||||
{rebar_elixir_plugin, ".*", {git, "https://github.com/processone/rebar_elixir_plugin", "0.1.0"}}}},
|
||||
{if_var_true, sqlite,
|
||||
{sqlite3, ".*", {git, "https://github.com/processone/erlang-sqlite3", {tag, "1.1.8"}}}},
|
||||
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.22"}}},
|
||||
{sqlite3, ".*", {git, "https://github.com/processone/erlang-sqlite3", {tag, "v1.1.6"}}}},
|
||||
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.24"}}},
|
||||
{if_var_true, stun,
|
||||
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.37"}}}},
|
||||
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.4.9"}}},
|
||||
{yconf, ".*", {git, "https://github.com/processone/yconf", {tag, "1.0.7"}}}
|
||||
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.40"}}}},
|
||||
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.5.1"}}},
|
||||
{yconf, ".*", {git, "https://github.com/processone/yconf", {tag, "1.0.9"}}}
|
||||
]}.
|
||||
|
||||
{gitonly_deps, [elixir, luerl]}.
|
||||
|
||||
{if_var_true, latest_deps,
|
||||
{floating_deps, [cache_tab,
|
||||
eimp,
|
||||
@@ -89,9 +91,6 @@
|
||||
|
||||
{erl_opts, [nowarn_deprecated_function,
|
||||
{i, "include"},
|
||||
{i, "deps/fast_xml/include"},
|
||||
{i, "deps/p1_utils/include"},
|
||||
{i, "deps/xmpp/include"},
|
||||
{if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
|
||||
{if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}},
|
||||
{if_version_below, "22", {d, 'LAGER'}},
|
||||
@@ -107,6 +106,7 @@
|
||||
{if_var_true, sip, {d, 'SIP'}},
|
||||
{if_var_true, stun, {d, 'STUN'}},
|
||||
{if_have_fun, {erl_error, format_exception, 6}, {d, 'HAVE_ERL_ERROR'}},
|
||||
{if_rebar3, {extra_src_dirs, [sql]}},
|
||||
{src_dirs, [src,
|
||||
{if_var_true, tools, tools},
|
||||
{if_var_true, elixir, include}]}]}.
|
||||
@@ -114,14 +114,17 @@
|
||||
{deps_erl_opts, [{if_var_true, hipe, native}]}.
|
||||
|
||||
{if_rebar3, {plugins, [rebar3_hex, {provider_asn1, "0.2.0"}]}}.
|
||||
{if_rebar3, {project_plugins, [configure_deps]}}.
|
||||
{if_not_rebar3, {plugins, [
|
||||
deps_erl_opts, override_deps_versions2, override_opts, configure_deps,
|
||||
{if_var_true, elixir, rebar_elixir_compiler},
|
||||
{if_var_true, elixir, rebar_exunit}
|
||||
]}}.
|
||||
|
||||
{if_var_true, elixir,
|
||||
{lib_dirs, ["deps/elixir/lib"]}}.
|
||||
{if_rebar3, {if_var_true, elixir,
|
||||
{project_app_dirs, [".", "elixir/lib"]}}}.
|
||||
{if_not_rebar3, {if_var_true, elixir,
|
||||
{lib_dirs, ["deps/elixir/lib"]}}}.
|
||||
{if_var_true, elixir,
|
||||
{src_dirs, ["include"]}}.
|
||||
|
||||
@@ -147,10 +150,7 @@
|
||||
{if_var_false, zlib, "(\"ezlib\":_/_)"}]}.
|
||||
|
||||
{eunit_compile_opts, [{i, "tools"},
|
||||
{i, "include"},
|
||||
{i, "deps/fast_xml/include"},
|
||||
{i, "deps/p1_utils/include"},
|
||||
{i, "deps/xmpp/include"}]}.
|
||||
{i, "include"}]}.
|
||||
|
||||
{cover_enabled, true}.
|
||||
{cover_export_enabled, true}.
|
||||
|
||||
+10
-5
@@ -196,9 +196,14 @@ AppendList2 = fun(Append) ->
|
||||
end,
|
||||
|
||||
Rebar3DepsFilter =
|
||||
fun(DepsList) ->
|
||||
lists:map(fun({DepName, _, {git, _, {tag, Version}}}) ->
|
||||
{DepName, Version};
|
||||
fun(DepsList, GitOnlyDeps) ->
|
||||
lists:map(fun({DepName, _, {git, _, {tag, Version}}} = Dep) ->
|
||||
case lists:member(DepName, GitOnlyDeps) of
|
||||
true ->
|
||||
Dep;
|
||||
_ ->
|
||||
{DepName, Version}
|
||||
end;
|
||||
(Dep) ->
|
||||
Dep
|
||||
end, DepsList)
|
||||
@@ -367,8 +372,8 @@ Rules = [
|
||||
AppendList2(ProcssXrefExclusions), [], []},
|
||||
{[deps], [floating_deps], true,
|
||||
ProcessFloatingDeps, [], []},
|
||||
{[deps], IsRebar3,
|
||||
Rebar3DepsFilter, []},
|
||||
{[deps], [gitonly_deps], IsRebar3,
|
||||
Rebar3DepsFilter, [], []},
|
||||
{[deps], SystemDeps /= false,
|
||||
GlobalDepsFilter, []}
|
||||
],
|
||||
|
||||
+51
-33
@@ -33,7 +33,7 @@
|
||||
set_password/3, check_password/4,
|
||||
check_password/6, check_password_with_authmodule/4,
|
||||
check_password_with_authmodule/6, try_register/3,
|
||||
get_users/0, get_users/1, password_to_scram/1,
|
||||
get_users/0, get_users/1, password_to_scram/2,
|
||||
get_users/2, import_info/0,
|
||||
count_users/1, import/5, import_start/2,
|
||||
count_users/2, get_password/2,
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
-export([auth_modules/1, convert_to_scram/1]).
|
||||
|
||||
-include("scram.hrl").
|
||||
-include_lib("xmpp/include/scram.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-define(SALT_LENGTH, 16).
|
||||
@@ -197,16 +197,21 @@ plain_password_required(Server) ->
|
||||
|
||||
-spec store_type(binary()) -> plain | scram | external.
|
||||
store_type(Server) ->
|
||||
lists:foldl(
|
||||
fun(_, external) -> external;
|
||||
(M, scram) ->
|
||||
case M:store_type(Server) of
|
||||
external -> external;
|
||||
_ -> scram
|
||||
end;
|
||||
(M, plain) ->
|
||||
M:store_type(Server)
|
||||
end, plain, auth_modules(Server)).
|
||||
case auth_modules(Server) of
|
||||
[ejabberd_auth_anonymous] -> external;
|
||||
Modules ->
|
||||
lists:foldl(
|
||||
fun(ejabberd_auth_anonymous, Type) -> Type;
|
||||
(_, external) -> external;
|
||||
(M, scram) ->
|
||||
case M:store_type(Server) of
|
||||
external -> external;
|
||||
_ -> scram
|
||||
end;
|
||||
(M, plain) ->
|
||||
M:store_type(Server)
|
||||
end, plain, Modules)
|
||||
end.
|
||||
|
||||
-spec check_password(binary(), binary(), binary(), binary()) -> boolean().
|
||||
check_password(User, AuthzId, Server, Password) ->
|
||||
@@ -554,7 +559,7 @@ db_try_register(User, Server, Password, Mod) ->
|
||||
case erlang:function_exported(Mod, try_register, 3) of
|
||||
true ->
|
||||
Password1 = case Mod:store_type(Server) of
|
||||
scram -> password_to_scram(Password);
|
||||
scram -> password_to_scram(Server, Password);
|
||||
_ -> Password
|
||||
end,
|
||||
Ret = case use_cache(Mod, Server) of
|
||||
@@ -579,7 +584,7 @@ db_set_password(User, Server, Password, Mod) ->
|
||||
case erlang:function_exported(Mod, set_password, 3) of
|
||||
true ->
|
||||
Password1 = case Mod:store_type(Server) of
|
||||
scram -> password_to_scram(Password);
|
||||
scram -> password_to_scram(Server, Password);
|
||||
_ -> Password
|
||||
end,
|
||||
Ret = case use_cache(Mod, Server) of
|
||||
@@ -605,6 +610,7 @@ db_get_password(User, Server, Mod) ->
|
||||
false when UseCache ->
|
||||
case ets_cache:lookup(cache_tab(Mod), {User, Server}) of
|
||||
{ok, exists} -> error;
|
||||
not_found -> error;
|
||||
Other -> Other
|
||||
end;
|
||||
false ->
|
||||
@@ -621,20 +627,29 @@ db_user_exists(User, Server, Mod) ->
|
||||
case db_get_password(User, Server, Mod) of
|
||||
{ok, _} ->
|
||||
true;
|
||||
not_found ->
|
||||
false;
|
||||
error ->
|
||||
case {Mod:store_type(Server), use_cache(Mod, Server)} of
|
||||
{external, true} ->
|
||||
case ets_cache:lookup(
|
||||
cache_tab(Mod), {User, Server},
|
||||
fun() ->
|
||||
case Mod:user_exists(User, Server) of
|
||||
{CacheTag, true} -> {CacheTag, {ok, exists}};
|
||||
{CacheTag, false} -> {CacheTag, error};
|
||||
{_, {error, _}} = Err -> Err
|
||||
end
|
||||
end) of
|
||||
Val = case ets_cache:lookup(cache_tab(Mod), {User, Server}, error) of
|
||||
error ->
|
||||
ets_cache:update(cache_tab(Mod), {User, Server}, {ok, exists},
|
||||
fun() ->
|
||||
case Mod:user_exists(User, Server) of
|
||||
{CacheTag, true} -> {CacheTag, {ok, exists}};
|
||||
{CacheTag, false} -> {CacheTag, not_found};
|
||||
{_, {error, _}} = Err -> Err
|
||||
end
|
||||
end);
|
||||
Other ->
|
||||
Other
|
||||
end,
|
||||
case Val of
|
||||
{ok, _} ->
|
||||
true;
|
||||
not_found ->
|
||||
false;
|
||||
error ->
|
||||
false;
|
||||
{error, _} = Err ->
|
||||
@@ -743,25 +758,28 @@ is_password_scram_valid(Password, Scram) ->
|
||||
false;
|
||||
_ ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Hash = Scram#scram.hash,
|
||||
Salt = base64:decode(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt, IterationCount),
|
||||
StoredKey = scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
SaltedPassword = scram:salted_password(Hash, Password, Salt, IterationCount),
|
||||
StoredKey = scram:stored_key(Hash, scram:client_key(Hash, SaltedPassword)),
|
||||
base64:decode(Scram#scram.storedkey) == StoredKey
|
||||
end.
|
||||
|
||||
password_to_scram(Password) ->
|
||||
password_to_scram(Password, ?SCRAM_DEFAULT_ITERATION_COUNT).
|
||||
password_to_scram(Host, Password) ->
|
||||
password_to_scram(Host, Password, ?SCRAM_DEFAULT_ITERATION_COUNT).
|
||||
|
||||
password_to_scram(#scram{} = Password, _IterationCount) ->
|
||||
password_to_scram(_Host, #scram{} = Password, _IterationCount) ->
|
||||
Password;
|
||||
password_to_scram(Password, IterationCount) ->
|
||||
password_to_scram(Host, Password, IterationCount) ->
|
||||
Hash = ejabberd_option:auth_scram_hash(Host),
|
||||
Salt = p1_rand:bytes(?SALT_LENGTH),
|
||||
SaltedPassword = scram:salted_password(Password, Salt, IterationCount),
|
||||
StoredKey = scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
ServerKey = scram:server_key(SaltedPassword),
|
||||
SaltedPassword = scram:salted_password(Hash, Password, Salt, IterationCount),
|
||||
StoredKey = scram:stored_key(Hash, scram:client_key(Hash, SaltedPassword)),
|
||||
ServerKey = scram:server_key(Hash, SaltedPassword),
|
||||
#scram{storedkey = base64:encode(StoredKey),
|
||||
serverkey = base64:encode(ServerKey),
|
||||
salt = base64:encode(Salt),
|
||||
hash = Hash,
|
||||
iterationcount = IterationCount}.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -928,7 +946,7 @@ convert_to_scram(Server) ->
|
||||
fun({U, S}) ->
|
||||
case get_password(U, S) of
|
||||
Pass when is_binary(Pass) ->
|
||||
SPass = password_to_scram(Pass),
|
||||
SPass = password_to_scram(Server, Pass),
|
||||
set_password(U, S, SPass);
|
||||
_ ->
|
||||
ok
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
plain_password_required/1]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("jid.hrl").
|
||||
-include_lib("xmpp/include/jid.hrl").
|
||||
|
||||
start(Host) ->
|
||||
ejabberd_hooks:add(sm_register_connection_hook, Host,
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
user_exists/2, use_cache/1
|
||||
]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -102,10 +102,11 @@ check_jwt_token(User, Server, Token) ->
|
||||
error ->
|
||||
false;
|
||||
{ok, SJID} ->
|
||||
try
|
||||
JID = jid:decode(SJID),
|
||||
(JID#jid.luser == User) andalso
|
||||
(JID#jid.lserver == Server)
|
||||
try jid:decode(SJID) of
|
||||
JID ->
|
||||
(JID#jid.luser == User) andalso
|
||||
(JID#jid.lserver == Server) andalso
|
||||
ejabberd_hooks:run_fold(check_decoded_jwt, Server, true, [Fields, Signature, User])
|
||||
catch error:{bad_jid, _} ->
|
||||
false
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
-export([need_transform/1, transform/1]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("scram.hrl").
|
||||
-include_lib("xmpp/include/scram.hrl").
|
||||
-include("ejabberd_auth.hrl").
|
||||
|
||||
-record(reg_users_counter, {vhost = <<"">> :: binary(),
|
||||
@@ -180,6 +180,9 @@ count_users(Server, _) ->
|
||||
|
||||
get_password(User, Server) ->
|
||||
case mnesia:dirty_read(passwd, {User, Server}) of
|
||||
[#passwd{password = {scram, SK, SEK, Salt, IC}}] ->
|
||||
{cache, {ok, #scram{storedkey = SK, serverkey = SEK,
|
||||
salt = Salt, hash = sha, iterationcount = IC}}};
|
||||
[#passwd{password = Password}] ->
|
||||
{cache, {ok, Password}};
|
||||
_ ->
|
||||
@@ -204,7 +207,8 @@ remove_user(User, Server) ->
|
||||
need_transform(#reg_users_counter{}) ->
|
||||
false;
|
||||
need_transform({passwd, {U, S}, Pass}) ->
|
||||
if is_binary(Pass) ->
|
||||
case Pass of
|
||||
_ when is_binary(Pass) ->
|
||||
case store_type(S) of
|
||||
scram ->
|
||||
?INFO_MSG("Passwords in Mnesia table 'passwd' "
|
||||
@@ -213,7 +217,7 @@ need_transform({passwd, {U, S}, Pass}) ->
|
||||
plain ->
|
||||
false
|
||||
end;
|
||||
is_record(Pass, scram) ->
|
||||
{scram, _, _, _, _} ->
|
||||
case store_type(S) of
|
||||
scram ->
|
||||
false;
|
||||
@@ -225,7 +229,19 @@ need_transform({passwd, {U, S}, Pass}) ->
|
||||
"would *fail*", []),
|
||||
false
|
||||
end;
|
||||
is_list(U) orelse is_list(S) orelse is_list(Pass) ->
|
||||
#scram{} ->
|
||||
case store_type(S) of
|
||||
scram ->
|
||||
false;
|
||||
plain ->
|
||||
?WARNING_MSG("Some passwords were stored in the database "
|
||||
"as SCRAM, but 'auth_password_format' "
|
||||
"is not configured as 'scram': some "
|
||||
"authentication mechanisms such as DIGEST-MD5 "
|
||||
"would *fail*", []),
|
||||
false
|
||||
end;
|
||||
_ when is_list(U) orelse is_list(S) orelse is_list(Pass) ->
|
||||
?INFO_MSG("Mnesia table 'passwd' will be converted to binary", []),
|
||||
true
|
||||
end.
|
||||
@@ -255,14 +271,15 @@ transform(#passwd{us = {U, S}, password = Password} = P)
|
||||
[U, S]),
|
||||
P;
|
||||
_ ->
|
||||
Scram = ejabberd_auth:password_to_scram(Password),
|
||||
Scram = ejabberd_auth:password_to_scram(S, Password),
|
||||
P#passwd{password = Scram}
|
||||
end;
|
||||
plain ->
|
||||
P
|
||||
end;
|
||||
transform(#passwd{password = Password} = P)
|
||||
when is_record(Password, scram) ->
|
||||
transform(#passwd{password = {scram, _, _, _, _}} = P) ->
|
||||
P;
|
||||
transform(#passwd{password = #scram{}} = P) ->
|
||||
P.
|
||||
|
||||
import(LServer, [LUser, Password, _TimeStamp]) ->
|
||||
|
||||
+40
-21
@@ -35,7 +35,7 @@
|
||||
remove_user/2, store_type/1, plain_password_required/1,
|
||||
export/1, which_users_exists/2]).
|
||||
|
||||
-include("scram.hrl").
|
||||
-include_lib("xmpp/include/scram.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
-include("ejabberd_auth.hrl").
|
||||
@@ -56,16 +56,19 @@ store_type(Server) ->
|
||||
ejabberd_auth:password_format(Server).
|
||||
|
||||
set_password(User, Server, Password) ->
|
||||
F = fun() ->
|
||||
if is_record(Password, scram) ->
|
||||
set_password_scram_t(
|
||||
User, Server,
|
||||
Password#scram.storedkey, Password#scram.serverkey,
|
||||
Password#scram.salt, Password#scram.iterationcount);
|
||||
true ->
|
||||
set_password_t(User, Server, Password)
|
||||
end
|
||||
end,
|
||||
F =
|
||||
fun() ->
|
||||
case Password of
|
||||
#scram{hash = Hash, storedkey = SK, serverkey = SEK,
|
||||
salt = Salt, iterationcount = IC} ->
|
||||
SK2 = scram_hash_encode(Hash, SK),
|
||||
set_password_scram_t(
|
||||
User, Server,
|
||||
SK2, SEK, Salt, IC);
|
||||
_ ->
|
||||
set_password_t(User, Server, Password)
|
||||
end
|
||||
end,
|
||||
case ejabberd_sql:sql_transaction(Server, F) of
|
||||
{atomic, _} ->
|
||||
{cache, {ok, Password}};
|
||||
@@ -74,14 +77,17 @@ set_password(User, Server, Password) ->
|
||||
end.
|
||||
|
||||
try_register(User, Server, Password) ->
|
||||
Res = if is_record(Password, scram) ->
|
||||
add_user_scram(
|
||||
Server, User,
|
||||
Password#scram.storedkey, Password#scram.serverkey,
|
||||
Password#scram.salt, Password#scram.iterationcount);
|
||||
true ->
|
||||
add_user(Server, User, Password)
|
||||
end,
|
||||
Res =
|
||||
case Password of
|
||||
#scram{hash = Hash, storedkey = SK, serverkey = SEK,
|
||||
salt = Salt, iterationcount = IC} ->
|
||||
SK2 = scram_hash_encode(Hash, SK),
|
||||
add_user_scram(
|
||||
Server, User,
|
||||
SK2, SEK, Salt, IC);
|
||||
_ ->
|
||||
add_user(Server, User, Password)
|
||||
end,
|
||||
case Res of
|
||||
{updated, 1} -> {cache, {ok, Password}};
|
||||
_ -> {nocache, {error, exists}}
|
||||
@@ -106,9 +112,15 @@ get_password(User, Server) ->
|
||||
{selected, [{Password, <<>>, <<>>, 0}]} ->
|
||||
{cache, {ok, Password}};
|
||||
{selected, [{StoredKey, ServerKey, Salt, IterationCount}]} ->
|
||||
{cache, {ok, #scram{storedkey = StoredKey,
|
||||
{Hash, SK} = case StoredKey of
|
||||
<<"sha256:", Rest/binary>> -> {sha256, Rest};
|
||||
<<"sha512:", Rest/binary>> -> {sha512, Rest};
|
||||
Other -> {sha, Other}
|
||||
end,
|
||||
{cache, {ok, #scram{storedkey = SK,
|
||||
serverkey = ServerKey,
|
||||
salt = Salt,
|
||||
hash = Hash,
|
||||
iterationcount = IterationCount}}};
|
||||
{selected, []} ->
|
||||
{cache, error};
|
||||
@@ -126,6 +138,13 @@ remove_user(User, Server) ->
|
||||
|
||||
-define(BATCH_SIZE, 1000).
|
||||
|
||||
scram_hash_encode(Hash, StoreKey) ->
|
||||
case Hash of
|
||||
sha -> StoreKey;
|
||||
sha256 -> <<"sha256:", StoreKey/binary>>;
|
||||
sha512 -> <<"sha512:", StoreKey/binary>>
|
||||
end.
|
||||
|
||||
set_password_scram_t(LUser, LServer,
|
||||
StoredKey, ServerKey, Salt, IterationCount) ->
|
||||
?SQL_UPSERT_T(
|
||||
@@ -282,7 +301,7 @@ export(_Server) ->
|
||||
"password=%(Password)s"])];
|
||||
(Host, #passwd{us = {LUser, LServer}, password = #scram{} = Scram})
|
||||
when LServer == Host ->
|
||||
StoredKey = Scram#scram.storedkey,
|
||||
StoredKey = scram_hash_encode(Scram#scram.hash, Scram#scram.storedkey),
|
||||
ServerKey = Scram#scram.serverkey,
|
||||
Salt = Scram#scram.salt,
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
code_change/4]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("bosh.hrl").
|
||||
|
||||
|
||||
+13
-3
@@ -47,7 +47,7 @@
|
||||
reply/2, copy_state/2, set_timeout/2, route/2, format_reason/2,
|
||||
host_up/1, host_down/1, send_ws_ping/1, bounce_message_queue/2]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("mod_roster.hrl").
|
||||
-include("translate.hrl").
|
||||
@@ -373,16 +373,26 @@ unauthenticated_stream_features(#{lserver := LServer}) ->
|
||||
authenticated_stream_features(#{lserver := LServer}) ->
|
||||
ejabberd_hooks:run_fold(c2s_post_auth_features, LServer, [], [LServer]).
|
||||
|
||||
sasl_mechanisms(Mechs, #{lserver := LServer} = State) ->
|
||||
sasl_mechanisms(Mechs, #{lserver := LServer, stream_encrypted := Encrypted} = State) ->
|
||||
Type = ejabberd_auth:store_type(LServer),
|
||||
Mechs1 = ejabberd_option:disable_sasl_mechanisms(LServer),
|
||||
|
||||
ScramHash = ejabberd_option:auth_scram_hash(LServer),
|
||||
ShaAv = Type == plain orelse (Type == scram andalso ScramHash == sha),
|
||||
Sha256Av = Type == plain orelse (Type == scram andalso ScramHash == sha256),
|
||||
Sha512Av = Type == plain orelse (Type == scram andalso ScramHash == sha512),
|
||||
%% I re-created it from cyrsasl ets magic, but I think it's wrong
|
||||
%% TODO: need to check before 18.09 release
|
||||
lists:filter(
|
||||
fun(<<"ANONYMOUS">>) ->
|
||||
ejabberd_auth_anonymous:is_sasl_anonymous_enabled(LServer);
|
||||
(<<"DIGEST-MD5">>) -> Type == plain;
|
||||
(<<"SCRAM-SHA-1">>) -> Type /= external;
|
||||
(<<"SCRAM-SHA-1">>) -> ShaAv;
|
||||
(<<"SCRAM-SHA-1-PLUS">>) -> ShaAv andalso Encrypted;
|
||||
(<<"SCRAM-SHA-256">>) -> Sha256Av;
|
||||
(<<"SCRAM-SHA-256-PLUS">>) -> Sha256Av andalso Encrypted;
|
||||
(<<"SCRAM-SHA-512">>) -> Sha512Av;
|
||||
(<<"SCRAM-SHA-512-PLUS">>) -> Sha512Av andalso Encrypted;
|
||||
(<<"PLAIN">>) -> true;
|
||||
(<<"X-OAUTH2">>) -> [ejabberd_auth_anonymous] /= ejabberd_auth:auth_modules(LServer);
|
||||
(<<"EXTERNAL">>) -> maps:get(tls_verify, State, false);
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
host_up/1, host_down/1,
|
||||
config_reloaded/0, process_iq/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
-export([init/3]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
|
||||
@@ -364,5 +364,8 @@ parsed_items(List) ->
|
||||
|
||||
-spec route_text(pid(), binary()) -> ok.
|
||||
route_text(Pid, Data) ->
|
||||
Pid ! {text, Data},
|
||||
ok.
|
||||
Pid ! {text_with_reply, Data, self()},
|
||||
receive
|
||||
{text_reply, Pid} ->
|
||||
ok
|
||||
end.
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
oauth_add_client_implicit/3,
|
||||
oauth_remove_client/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("ejabberd_web_admin.hrl").
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
-include("ejabberd_oauth.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("jid.hrl").
|
||||
-include_lib("xmpp/include/jid.hrl").
|
||||
|
||||
init() ->
|
||||
rest:start(ejabberd_config:get_myname()),
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
-include("ejabberd_oauth.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
-include("jid.hrl").
|
||||
-include_lib("xmpp/include/jid.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
init() ->
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
-export([auth_method/0, auth_method/1]).
|
||||
-export([auth_opts/0, auth_opts/1]).
|
||||
-export([auth_password_format/0, auth_password_format/1]).
|
||||
-export([auth_scram_hash/0, auth_scram_hash/1]).
|
||||
-export([auth_use_cache/0, auth_use_cache/1]).
|
||||
-export([c2s_cafile/0, c2s_cafile/1]).
|
||||
-export([c2s_ciphers/0, c2s_ciphers/1]).
|
||||
@@ -91,6 +92,8 @@
|
||||
-export([oom_queue/0]).
|
||||
-export([oom_watermark/0]).
|
||||
-export([outgoing_s2s_families/0, outgoing_s2s_families/1]).
|
||||
-export([outgoing_s2s_ipv4_address/0, outgoing_s2s_ipv4_address/1]).
|
||||
-export([outgoing_s2s_ipv6_address/0, outgoing_s2s_ipv6_address/1]).
|
||||
-export([outgoing_s2s_port/0, outgoing_s2s_port/1]).
|
||||
-export([outgoing_s2s_timeout/0, outgoing_s2s_timeout/1]).
|
||||
-export([pam_service/0, pam_service/1]).
|
||||
@@ -136,6 +139,7 @@
|
||||
-export([sql_connect_timeout/0, sql_connect_timeout/1]).
|
||||
-export([sql_database/0, sql_database/1]).
|
||||
-export([sql_keepalive_interval/0, sql_keepalive_interval/1]).
|
||||
-export([sql_odbc_driver/0, sql_odbc_driver/1]).
|
||||
-export([sql_password/0, sql_password/1]).
|
||||
-export([sql_pool_size/0, sql_pool_size/1]).
|
||||
-export([sql_port/0, sql_port/1]).
|
||||
@@ -235,6 +239,13 @@ auth_password_format() ->
|
||||
auth_password_format(Host) ->
|
||||
ejabberd_config:get_option({auth_password_format, Host}).
|
||||
|
||||
-spec auth_scram_hash() -> 'sha' | 'sha256' | 'sha512'.
|
||||
auth_scram_hash() ->
|
||||
auth_scram_hash(global).
|
||||
-spec auth_scram_hash(global | binary()) -> 'sha' | 'sha256' | 'sha512'.
|
||||
auth_scram_hash(Host) ->
|
||||
ejabberd_config:get_option({auth_scram_hash, Host}).
|
||||
|
||||
-spec auth_use_cache() -> boolean().
|
||||
auth_use_cache() ->
|
||||
auth_use_cache(global).
|
||||
@@ -666,6 +677,20 @@ outgoing_s2s_families() ->
|
||||
outgoing_s2s_families(Host) ->
|
||||
ejabberd_config:get_option({outgoing_s2s_families, Host}).
|
||||
|
||||
-spec outgoing_s2s_ipv4_address() -> 'undefined' | inet:ip4_address().
|
||||
outgoing_s2s_ipv4_address() ->
|
||||
outgoing_s2s_ipv4_address(global).
|
||||
-spec outgoing_s2s_ipv4_address(global | binary()) -> 'undefined' | inet:ip4_address().
|
||||
outgoing_s2s_ipv4_address(Host) ->
|
||||
ejabberd_config:get_option({outgoing_s2s_ipv4_address, Host}).
|
||||
|
||||
-spec outgoing_s2s_ipv6_address() -> 'undefined' | inet:ip6_address().
|
||||
outgoing_s2s_ipv6_address() ->
|
||||
outgoing_s2s_ipv6_address(global).
|
||||
-spec outgoing_s2s_ipv6_address(global | binary()) -> 'undefined' | inet:ip6_address().
|
||||
outgoing_s2s_ipv6_address(Host) ->
|
||||
ejabberd_config:get_option({outgoing_s2s_ipv6_address, Host}).
|
||||
|
||||
-spec outgoing_s2s_port() -> 1..1114111.
|
||||
outgoing_s2s_port() ->
|
||||
outgoing_s2s_port(global).
|
||||
@@ -921,6 +946,13 @@ sql_keepalive_interval() ->
|
||||
sql_keepalive_interval(Host) ->
|
||||
ejabberd_config:get_option({sql_keepalive_interval, Host}).
|
||||
|
||||
-spec sql_odbc_driver() -> binary().
|
||||
sql_odbc_driver() ->
|
||||
sql_odbc_driver(global).
|
||||
-spec sql_odbc_driver(global | binary()) -> binary().
|
||||
sql_odbc_driver(Host) ->
|
||||
ejabberd_config:get_option({sql_odbc_driver, Host}).
|
||||
|
||||
-spec sql_password() -> binary().
|
||||
sql_password() ->
|
||||
sql_password(global).
|
||||
|
||||
@@ -79,6 +79,8 @@ opt_type(auth_opts) ->
|
||||
end;
|
||||
opt_type(auth_password_format) ->
|
||||
econf:enum([plain, scram]);
|
||||
opt_type(auth_scram_hash) ->
|
||||
econf:enum([sha, sha256, sha512]);
|
||||
opt_type(auth_use_cache) ->
|
||||
econf:bool();
|
||||
opt_type(c2s_cafile) ->
|
||||
@@ -271,6 +273,10 @@ opt_type(outgoing_s2s_families) ->
|
||||
(ipv6) -> inet6
|
||||
end, L)
|
||||
end);
|
||||
opt_type(outgoing_s2s_ipv4_address) ->
|
||||
econf:ipv4();
|
||||
opt_type(outgoing_s2s_ipv6_address) ->
|
||||
econf:ipv6();
|
||||
opt_type(outgoing_s2s_port) ->
|
||||
econf:port();
|
||||
opt_type(outgoing_s2s_timeout) ->
|
||||
@@ -371,6 +377,8 @@ opt_type(sql_keepalive_interval) ->
|
||||
econf:timeout(second);
|
||||
opt_type(sql_password) ->
|
||||
econf:binary();
|
||||
opt_type(sql_odbc_driver) ->
|
||||
econf:binary();
|
||||
opt_type(sql_pool_size) ->
|
||||
econf:pos_int();
|
||||
opt_type(sql_port) ->
|
||||
@@ -511,6 +519,7 @@ options() ->
|
||||
fun(Host) -> [ejabberd_config:default_db(Host, ejabberd_auth)] end},
|
||||
{auth_opts, []},
|
||||
{auth_password_format, plain},
|
||||
{auth_scram_hash, sha},
|
||||
{auth_use_cache,
|
||||
fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end},
|
||||
{c2s_cafile, undefined},
|
||||
@@ -587,6 +596,8 @@ options() ->
|
||||
{oom_queue, 10000},
|
||||
{oom_watermark, 80},
|
||||
{outgoing_s2s_families, [inet, inet6]},
|
||||
{outgoing_s2s_ipv4_address, undefined},
|
||||
{outgoing_s2s_ipv6_address, undefined},
|
||||
{outgoing_s2s_port, 5269},
|
||||
{outgoing_s2s_timeout, timer:seconds(10)},
|
||||
{pam_service, <<"ejabberd">>},
|
||||
@@ -645,6 +656,7 @@ options() ->
|
||||
{sql_database, undefined},
|
||||
{sql_keepalive_interval, undefined},
|
||||
{sql_password, <<"">>},
|
||||
{sql_odbc_driver, <<"libtdsodbc.so">>}, % default is FreeTDS driver
|
||||
{sql_pool_size,
|
||||
fun(Host) ->
|
||||
case ejabberd_config:get_option({sql_type, Host}) of
|
||||
|
||||
@@ -378,6 +378,13 @@ doc() ->
|
||||
"value is configured it cannot be changed to plain anymore. "
|
||||
"This format allows clients to authenticate using: "
|
||||
"SASL PLAIN and SASL SCRAM-SHA-1.")}},
|
||||
{auth_scram_hash,
|
||||
#{value => "sha | sha256 | sha512",
|
||||
desc =>
|
||||
?T("Hash algorith that should be used to store password in SCRAM format. "
|
||||
"You shouldn't change this if you are already have passwords generated "
|
||||
"with different algorithm - this will make users that have old password "
|
||||
"being able to use SCRAM auth algorithms.")}},
|
||||
{auth_use_cache,
|
||||
#{value => "true | false",
|
||||
desc =>
|
||||
@@ -386,11 +393,14 @@ doc() ->
|
||||
{c2s_cafile,
|
||||
#{value => ?T("Path"),
|
||||
desc =>
|
||||
?T("Full path to a file containing one or more CA certificates "
|
||||
[?T("Full path to a file containing one or more CA certificates "
|
||||
"in PEM format. All client certificates should be signed by "
|
||||
"one of these root CA certificates and should contain the "
|
||||
"corresponding JID(s) in subjectAltName field. "
|
||||
"There is no default value.")}},
|
||||
"corresponding JID(s) in 'subjectAltName' field. "
|
||||
"There is no default value."), "",
|
||||
?T("You can use http://../toplevel/#host-config[host_config] to specify this option per-vhost."), "",
|
||||
?T("To set a specific file per listener, use the listener's http://../listen-options/#cafile[cafile] option. Please notice that 'c2s_cafile' overrides the listener's 'cafile' option."), ""
|
||||
]}},
|
||||
{c2s_ciphers,
|
||||
#{value => "[Cipher, ...]",
|
||||
desc =>
|
||||
@@ -431,8 +441,10 @@ doc() ->
|
||||
{ca_file,
|
||||
#{value => ?T("Path"),
|
||||
desc =>
|
||||
?T("Path to a file of CA root certificates. "
|
||||
"The default is to use system defined file if possible.")}},
|
||||
[?T("Path to a file of CA root certificates. "
|
||||
"The default is to use system defined file if possible."), "",
|
||||
?T("For server conections, this 'ca_file' option is overriden by the http://../toplevel/#s2s-cafile[s2s_cafile] option."), ""
|
||||
]}},
|
||||
{captcha_cmd,
|
||||
#{value => ?T("Path"),
|
||||
desc =>
|
||||
@@ -915,6 +927,18 @@ doc() ->
|
||||
?T("Specify which address families to try, in what order. "
|
||||
"The default is '[ipv4, ipv6]' which means it first tries "
|
||||
"connecting with IPv4, if that fails it tries using IPv6.")}},
|
||||
{outgoing_s2s_ipv4_address,
|
||||
#{value => "Address",
|
||||
desc =>
|
||||
?T("Specify the IPv4 address that will be used when establishing "
|
||||
"an outgoing S2S IPv4 connection, for example \"127.0.0.1\". "
|
||||
"The default value is 'undefined'.")}},
|
||||
{outgoing_s2s_ipv6_address,
|
||||
#{value => "Address",
|
||||
desc =>
|
||||
?T("Specify the IPv6 address that will be used when establishing "
|
||||
"an outgoing S2S IPv6 connection, for example "
|
||||
"\"::FFFF:127.0.0.1\". The default value is 'undefined'.")}},
|
||||
{outgoing_s2s_port,
|
||||
#{value => "1..65535",
|
||||
desc =>
|
||||
@@ -1048,9 +1072,11 @@ doc() ->
|
||||
{s2s_cafile,
|
||||
#{value => ?T("Path"),
|
||||
desc =>
|
||||
?T("A path to a file with CA root certificates that will "
|
||||
"be used to authenticate s2s connections. If not set "
|
||||
"the value of 'ca_file' will be used.")}},
|
||||
[?T("A path to a file with CA root certificates that will "
|
||||
"be used to authenticate s2s connections. If not set, "
|
||||
"the value of http://../toplevel/#ca-file[ca_file] will be used."), "",
|
||||
?T("You can use http://../toplevel/#host-config[host_config] to specify this option per-vhost."), ""
|
||||
]}},
|
||||
{s2s_ciphers,
|
||||
#{value => "[Cipher, ...]",
|
||||
desc =>
|
||||
@@ -1212,6 +1238,13 @@ doc() ->
|
||||
?T("An interval to make a dummy SQL request to keep alive the "
|
||||
"connections to the database. There is no default value, so no "
|
||||
"keepalive requests are made.")}},
|
||||
{sql_odbc_driver,
|
||||
#{value => "Path",
|
||||
desc =>
|
||||
?T("Path to the ODBC driver to use to connect to a Microsoft SQL "
|
||||
"Server database. This option is only valid if the 'sql_type' "
|
||||
"option is set to 'mssql'. "
|
||||
"The default value is: 'libtdsodbc.so'")}},
|
||||
{sql_password,
|
||||
#{value => ?T("Password"),
|
||||
desc =>
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
|
||||
-define(CHUNK_SIZE, 1024*20). %20k
|
||||
|
||||
-include("scram.hrl").
|
||||
-include_lib("xmpp/include/scram.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
-include("mod_roster.hrl").
|
||||
|
||||
@@ -181,21 +181,32 @@ export_user(User, Server, Fd) ->
|
||||
{<<"password">>, Pass}],
|
||||
children = Els})).
|
||||
|
||||
format_scram_password(#scram{storedkey = StoredKey, serverkey = ServerKey,
|
||||
format_scram_password(#scram{hash = Hash, storedkey = StoredKey, serverkey = ServerKey,
|
||||
salt = Salt, iterationcount = IterationCount}) ->
|
||||
StoredKeyB64 = base64:encode(StoredKey),
|
||||
ServerKeyB64 = base64:encode(ServerKey),
|
||||
SaltB64 = base64:encode(Salt),
|
||||
IterationCountBin = (integer_to_binary(IterationCount)),
|
||||
<<"scram:", StoredKeyB64/binary, ",", ServerKeyB64/binary, ",", SaltB64/binary, ",", IterationCountBin/binary>>.
|
||||
Hash2 = case Hash of
|
||||
sha -> <<>>;
|
||||
sha256 -> <<"sha256,">>;
|
||||
sha512 -> <<"sha512,">>
|
||||
end,
|
||||
<<"scram:", Hash2/binary, StoredKeyB64/binary, ",", ServerKeyB64/binary, ",", SaltB64/binary, ",", IterationCountBin/binary>>.
|
||||
|
||||
parse_scram_password(PassData) ->
|
||||
Split = binary:split(PassData, <<",">>, [global]),
|
||||
[StoredKeyB64, ServerKeyB64, SaltB64, IterationCountBin] = Split,
|
||||
[Hash, StoredKeyB64, ServerKeyB64, SaltB64, IterationCountBin] =
|
||||
case Split of
|
||||
[K1, K2, K3, K4] -> [sha, K1, K2, K3, K4];
|
||||
[<<"sha256">>, K1, K2, K3, K4] -> [sha256, K1, K2, K3, K4];
|
||||
[<<"sha512">>, K1, K2, K3, K4] -> [sha512, K1, K2, K3, K4]
|
||||
end,
|
||||
#scram{
|
||||
storedkey = base64:decode(StoredKeyB64),
|
||||
serverkey = base64:decode(ServerKeyB64),
|
||||
salt = base64:decode(SaltB64),
|
||||
hash = Hash,
|
||||
iterationcount = (binary_to_integer(IterationCountBin))
|
||||
}.
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_router.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
|
||||
-callback init() -> any().
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-record(route_multicast, {domain = <<"">> :: binary() | '_',
|
||||
pid = self() :: pid()}).
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
-export([get_info_s2s_connections/1]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_commands.hrl").
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
@@ -351,8 +351,11 @@ route(Packet) ->
|
||||
{ok, Pid} when is_pid(Pid) ->
|
||||
?DEBUG("Sending to process ~p~n", [Pid]),
|
||||
#jid{lserver = MyServer} = From,
|
||||
ejabberd_hooks:run(s2s_send_packet, MyServer, [Packet]),
|
||||
ejabberd_s2s_out:route(Pid, Packet);
|
||||
case ejabberd_hooks:run_fold(s2s_send_packet, MyServer, Packet,
|
||||
[]) of
|
||||
drop -> ok;
|
||||
Packet1 -> ejabberd_s2s_out:route(Pid, Packet1)
|
||||
end;
|
||||
{error, Reason} ->
|
||||
Lang = xmpp:get_lang(Packet),
|
||||
Err = case Reason of
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
-export([stop_async/1, close/1, close/2, send/2, update_state/2, establish/1,
|
||||
host_up/1, host_down/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-type state() :: xmpp_stream_in:state().
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
%% xmpp_stream_out callbacks
|
||||
-export([tls_options/1, tls_required/1, tls_verify/1, tls_enabled/1,
|
||||
connect_timeout/1, address_families/1, default_port/1,
|
||||
connect_options/3, connect_timeout/1, address_families/1, default_port/1,
|
||||
dns_retries/1, dns_timeout/1,
|
||||
handle_auth_success/2, handle_auth_failure/3, handle_packet/2,
|
||||
handle_stream_end/2, handle_stream_downgraded/2,
|
||||
@@ -39,7 +39,7 @@
|
||||
-export([start/3, start_link/3, connect/1, close/1, close/2, stop_async/1, send/2,
|
||||
route/2, establish/1, update_state/2, host_up/1, host_down/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
@@ -187,6 +187,20 @@ tls_verify(#{server_host := ServerHost} = State) ->
|
||||
tls_enabled(#{server_host := ServerHost}) ->
|
||||
ejabberd_s2s:tls_enabled(ServerHost).
|
||||
|
||||
connect_options(Addr, Opts, #{server_host := ServerHost}) ->
|
||||
BindAddr = case get_addr_type(Addr) of
|
||||
inet ->
|
||||
ejabberd_option:outgoing_s2s_ipv4_address(ServerHost);
|
||||
inet6 ->
|
||||
ejabberd_option:outgoing_s2s_ipv6_address(ServerHost)
|
||||
end,
|
||||
case BindAddr of
|
||||
undefined ->
|
||||
Opts;
|
||||
_ ->
|
||||
[{ip, BindAddr} | Opts]
|
||||
end.
|
||||
|
||||
connect_timeout(#{server_host := ServerHost}) ->
|
||||
ejabberd_option:outgoing_s2s_timeout(ServerHost).
|
||||
|
||||
@@ -318,6 +332,10 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
-spec get_addr_type(inet:ip_address()) -> inet:address_family().
|
||||
get_addr_type({_, _, _, _}) -> inet;
|
||||
get_addr_type({_, _, _, _, _, _, _, _}) -> inet6.
|
||||
|
||||
-spec resend_queue(state()) -> state().
|
||||
resend_queue(State) ->
|
||||
queue_fold(
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
%% API
|
||||
-export([send/2, close/1, close/2, stop_async/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@
|
||||
handle_info/2, terminate/2, code_change/3]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_commands.hrl").
|
||||
-include("ejabberd_sm.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
|
||||
+12
-11
@@ -52,7 +52,7 @@
|
||||
encode_term/1,
|
||||
decode_term/1,
|
||||
odbcinst_config/0,
|
||||
init_mssql/0,
|
||||
init_mssql/1,
|
||||
keep_alive/2,
|
||||
to_list/2,
|
||||
to_array/2]).
|
||||
@@ -349,11 +349,11 @@ init([Host]) ->
|
||||
|
||||
connecting(connect, #state{host = Host} = State) ->
|
||||
ConnectRes = case db_opts(Host) of
|
||||
[mysql | Args] -> apply(fun mysql_connect/8, Args);
|
||||
[pgsql | Args] -> apply(fun pgsql_connect/8, Args);
|
||||
[sqlite | Args] -> apply(fun sqlite_connect/1, Args);
|
||||
[mssql | Args] -> apply(fun odbc_connect/2, Args);
|
||||
[odbc | Args] -> apply(fun odbc_connect/2, Args)
|
||||
[mysql | Args] -> apply(fun mysql_connect/8, Args);
|
||||
[pgsql | Args] -> apply(fun pgsql_connect/8, Args);
|
||||
[sqlite | Args] -> apply(fun sqlite_connect/1, Args);
|
||||
[mssql | Args] -> apply(fun odbc_connect/2, Args);
|
||||
[odbc | Args] -> apply(fun odbc_connect/2, Args)
|
||||
end,
|
||||
case ConnectRes of
|
||||
{ok, Ref} ->
|
||||
@@ -1034,7 +1034,7 @@ mysql_to_odbc({error, MySQLRes})
|
||||
when is_list(MySQLRes) ->
|
||||
{error, list_to_binary(MySQLRes)};
|
||||
mysql_to_odbc({error, MySQLRes}) ->
|
||||
{error, p1_mysql:get_result_reason(MySQLRes)};
|
||||
mysql_to_odbc({error, p1_mysql:get_result_reason(MySQLRes)});
|
||||
mysql_to_odbc(ok) ->
|
||||
ok.
|
||||
|
||||
@@ -1107,7 +1107,7 @@ db_opts(Host) ->
|
||||
SSLOpts = get_ssl_opts(Transport, Host),
|
||||
case Type of
|
||||
mssql ->
|
||||
[mssql, <<"DRIVER=FreeTDS;SERVER=", Server/binary, ";UID=", User/binary,
|
||||
[mssql, <<"DRIVER=ODBC;SERVER=", Server/binary, ";UID=", User/binary,
|
||||
";DATABASE=", DB/binary ,";PWD=", Pass/binary,
|
||||
";PORT=", (integer_to_binary(Port))/binary ,";CLIENT_CHARSET=UTF-8;">>, Timeout];
|
||||
_ ->
|
||||
@@ -1151,9 +1151,10 @@ get_ssl_opts(ssl, Host) ->
|
||||
get_ssl_opts(tcp, _) ->
|
||||
[].
|
||||
|
||||
init_mssql() ->
|
||||
ODBCINST = io_lib:fwrite("[FreeTDS]~n"
|
||||
"Driver = libtdsodbc.so~n", []),
|
||||
init_mssql(Host) ->
|
||||
Driver = ejabberd_option:sql_odbc_driver(Host),
|
||||
ODBCINST = io_lib:fwrite("[ODBC]~n"
|
||||
"Driver = ~s~n", [Driver]),
|
||||
?DEBUG("~ts:~n~ts", [odbcinst_config(), ODBCINST]),
|
||||
case filelib:ensure_dir(odbcinst_config()) of
|
||||
ok ->
|
||||
|
||||
+19
-1
@@ -558,6 +558,11 @@ make_sql_upsert(Table, ParseRes, Pos) ->
|
||||
erl_syntax:integer(90100))],
|
||||
[make_sql_upsert_pgsql901(Table, ParseRes),
|
||||
erl_syntax:atom(ok)]),
|
||||
erl_syntax:clause(
|
||||
[erl_syntax:atom(mysql), erl_syntax:underscore()],
|
||||
[],
|
||||
[make_sql_upsert_mysql(Table, ParseRes),
|
||||
erl_syntax:atom(ok)]),
|
||||
erl_syntax:clause(
|
||||
[erl_syntax:underscore(), erl_syntax:underscore()],
|
||||
none,
|
||||
@@ -628,6 +633,9 @@ make_sql_upsert_update(Table, ParseRes) ->
|
||||
State.
|
||||
|
||||
make_sql_upsert_insert(Table, ParseRes) ->
|
||||
make_sql_upsert_insert_replace(Table, ParseRes, "INSERT").
|
||||
|
||||
make_sql_upsert_insert_replace(Table, ParseRes, Keyword) ->
|
||||
Vals =
|
||||
lists:map(
|
||||
fun({_Field, _, ST}) ->
|
||||
@@ -640,7 +648,7 @@ make_sql_upsert_insert(Table, ParseRes) ->
|
||||
end, ParseRes),
|
||||
State =
|
||||
concat_states(
|
||||
[#state{'query' = [{str, "INSERT INTO "}, {str, Table}, {str, "("}]},
|
||||
[#state{'query' = [{str, Keyword ++" INTO "}, {str, Table}, {str, "("}]},
|
||||
join_states(Fields, ", "),
|
||||
#state{'query' = [{str, ") VALUES ("}]},
|
||||
join_states(Vals, ", "),
|
||||
@@ -648,6 +656,16 @@ make_sql_upsert_insert(Table, ParseRes) ->
|
||||
]),
|
||||
State.
|
||||
|
||||
make_sql_upsert_replace(Table, ParseRes) ->
|
||||
make_sql_upsert_insert_replace(Table, ParseRes, "REPLACE").
|
||||
|
||||
make_sql_upsert_mysql(Table, ParseRes) ->
|
||||
Replace = make_sql_query(make_sql_upsert_replace(Table, ParseRes)),
|
||||
erl_syntax:application(
|
||||
erl_syntax:atom(ejabberd_sql),
|
||||
erl_syntax:atom(sql_query_t),
|
||||
[Replace]).
|
||||
|
||||
make_sql_upsert_pgsql901(Table, ParseRes0) ->
|
||||
ParseRes = lists:map(
|
||||
fun({"family", A2, A3}) -> {"\"family\"", A2, A3};
|
||||
|
||||
@@ -96,7 +96,7 @@ init([Host]) ->
|
||||
sqlite ->
|
||||
check_sqlite_db(Host);
|
||||
mssql ->
|
||||
ejabberd_sql:init_mssql();
|
||||
ejabberd_sql:init_mssql(Host);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
|
||||
@@ -212,8 +212,8 @@ init_logger() ->
|
||||
ok.
|
||||
-else.
|
||||
init_logger() ->
|
||||
case logger:add_primary_filter(stun, {fun ?MODULE:stun_filter/2,
|
||||
?STUN_MAX_LOG_LEVEL}) of
|
||||
case logger:add_primary_filter(ejabberd_stun, {fun ?MODULE:stun_filter/2,
|
||||
?STUN_MAX_LOG_LEVEL}) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, {already_exist, _}} ->
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
|
||||
|
||||
+18
-29
@@ -35,7 +35,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
|
||||
@@ -123,6 +123,11 @@ get_menu_items(Host, cluster, Lang, JID, Level) ->
|
||||
%% Items
|
||||
%% ).
|
||||
|
||||
is_allowed_path(global, RPath, JID) ->
|
||||
is_allowed_path([], RPath, JID);
|
||||
is_allowed_path(Host, RPath, JID) when is_binary(Host) ->
|
||||
is_allowed_path([<<"server">>, Host], RPath, JID);
|
||||
|
||||
is_allowed_path(BasePath, {Path, _}, JID) ->
|
||||
is_allowed_path(BasePath ++ [Path], JID);
|
||||
is_allowed_path(BasePath, {Path, _, _}, JID) ->
|
||||
@@ -134,19 +139,6 @@ is_allowed_path(Path, JID) ->
|
||||
{HostOfRule, AccessRule} = get_acl_rule(Path, 'GET'),
|
||||
any_rules_allowed(HostOfRule, AccessRule, JID).
|
||||
|
||||
%% @spec(Path) -> URL
|
||||
%% where Path = [string()]
|
||||
%% URL = string()
|
||||
%% Convert ["admin", "user", "tom"] -> "/admin/user/tom/"
|
||||
%%path_to_url(Path) ->
|
||||
%% "/" ++ string:join(Path, "/") ++ "/".
|
||||
|
||||
%% @spec(URL) -> Path
|
||||
%% where Path = [string()]
|
||||
%% URL = string()
|
||||
%% Convert "admin/user/tom" -> ["admin", "user", "tom"]
|
||||
url_to_path(URL) -> str:tokens(URL, <<"/">>).
|
||||
|
||||
%%%==================================
|
||||
%%%% process/2
|
||||
|
||||
@@ -938,7 +930,7 @@ user_info(User, Server, Query, Lang) ->
|
||||
end;
|
||||
_ -> translate:translate(Lang, ?T("Online"))
|
||||
end,
|
||||
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("User ~ts")),
|
||||
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("User ~ts"),
|
||||
[us_to_list(US)])))]
|
||||
++
|
||||
case Res of
|
||||
@@ -957,7 +949,7 @@ user_info(User, Server, Query, Lang) ->
|
||||
[?C(LastActivity)] ++
|
||||
UserItems ++
|
||||
[?P,
|
||||
?INPUTT(<<"submit">>, <<"removeuser">>,
|
||||
?INPUTTD(<<"submit">>, <<"removeuser">>,
|
||||
?T("Remove User"))]))].
|
||||
|
||||
user_parse_query(User, Server, Query) ->
|
||||
@@ -1095,7 +1087,7 @@ get_node(global, Node, [], Query, Lang) ->
|
||||
Base = get_base_path(global, Node, 2),
|
||||
MenuItems2 = make_menu_items(global, Node, Base, Lang),
|
||||
[?XC(<<"h1">>,
|
||||
(str:format(translate:translate(Lang, ?T("Node ~p")), [Node])))]
|
||||
(str:translate_and_format(Lang, ?T("Node ~p"), [Node])))]
|
||||
++
|
||||
case Res of
|
||||
ok -> [?XREST(?T("Submitted"))];
|
||||
@@ -1113,11 +1105,11 @@ get_node(global, Node, [], Query, Lang) ->
|
||||
[{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
|
||||
[?INPUTT(<<"submit">>, <<"restart">>, ?T("Restart")),
|
||||
?C(<<" ">>),
|
||||
?INPUTT(<<"submit">>, <<"stop">>, ?T("Stop"))])];
|
||||
?INPUTTD(<<"submit">>, <<"stop">>, ?T("Stop"))])];
|
||||
get_node(Host, Node, [], _Query, Lang) ->
|
||||
Base = get_base_path(Host, Node, 4),
|
||||
MenuItems2 = make_menu_items(Host, Node, Base, Lang),
|
||||
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Node ~p")), [Node]))),
|
||||
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Node ~p"), [Node]))),
|
||||
?XE(<<"ul">>, MenuItems2)];
|
||||
get_node(global, Node, [<<"db">>], Query, Lang) ->
|
||||
case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
|
||||
@@ -1173,7 +1165,7 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
|
||||
end,
|
||||
STables),
|
||||
[?XC(<<"h1">>,
|
||||
(str:format(translate:translate(Lang, ?T("Database Tables at ~p")),
|
||||
(str:translate_and_format(Lang, ?T("Database Tables at ~p"),
|
||||
[Node]))
|
||||
)]
|
||||
++
|
||||
@@ -1211,7 +1203,7 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
|
||||
[?XRES(<<(translate:translate(Lang, ?T("Error")))/binary, ": ",
|
||||
((str:format("~p", [Error])))/binary>>)]
|
||||
end,
|
||||
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Backup of ~p")), [Node])))]
|
||||
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Backup of ~p"), [Node])))]
|
||||
++
|
||||
ResS ++
|
||||
[?XCT(<<"p">>,
|
||||
@@ -1365,7 +1357,7 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) ->
|
||||
TransactionsLogged = ejabberd_cluster:call(Node, mnesia, system_info,
|
||||
[transaction_log_writes]),
|
||||
[?XC(<<"h1">>,
|
||||
(str:format(translate:translate(Lang, ?T("Statistics of ~p")), [Node]))),
|
||||
(str:translate_and_format(Lang, ?T("Statistics of ~p"), [Node]))),
|
||||
?XAE(<<"table">>, [],
|
||||
[?XE(<<"tbody">>,
|
||||
[?XE(<<"tr">>,
|
||||
@@ -1433,7 +1425,7 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
|
||||
FmtLowLevelScript = (?XC(<<"pre">>,
|
||||
(str:format("~p", [LowLevelScript])))),
|
||||
[?XC(<<"h1">>,
|
||||
(str:format(translate:translate(Lang, ?T("Update ~p")), [Node])))]
|
||||
(str:translate_and_format(Lang, ?T("Update ~p"), [Node])))]
|
||||
++
|
||||
case Res of
|
||||
ok -> [?XREST(?T("Submitted"))];
|
||||
@@ -1785,10 +1777,9 @@ make_host_node_menu(_, cluster, _Lang, _JID, _Level) ->
|
||||
make_host_node_menu(Host, Node, Lang, JID, Level) ->
|
||||
HostNodeBase = get_base_path(Host, Node, Level),
|
||||
HostNodeFixed = get_menu_items_hook({hostnode, Host, Node}, Lang),
|
||||
HostNodeBasePath = url_to_path(HostNodeBase),
|
||||
HostNodeFixed2 = [Tuple
|
||||
|| Tuple <- HostNodeFixed,
|
||||
is_allowed_path(HostNodeBasePath, Tuple, JID)],
|
||||
is_allowed_path(Host, Tuple, JID)],
|
||||
{HostNodeBase, iolist_to_binary(atom_to_list(Node)),
|
||||
HostNodeFixed2}.
|
||||
|
||||
@@ -1803,10 +1794,9 @@ make_host_menu(Host, HostNodeMenu, Lang, JID, Level) ->
|
||||
[{<<"nodes">>, ?T("Nodes"), HostNodeMenu},
|
||||
{<<"stats">>, ?T("Statistics")}]
|
||||
++ get_menu_items_hook({host, Host}, Lang),
|
||||
HostBasePath = url_to_path(HostBase),
|
||||
HostFixed2 = [Tuple
|
||||
|| Tuple <- HostFixed,
|
||||
is_allowed_path(HostBasePath, Tuple, JID)],
|
||||
is_allowed_path(Host, Tuple, JID)],
|
||||
{HostBase, Host, HostFixed2}.
|
||||
|
||||
make_node_menu(_Host, cluster, _Lang, _Level) ->
|
||||
@@ -1829,10 +1819,9 @@ make_server_menu(HostMenu, NodeMenu, Lang, JID, Level) ->
|
||||
{<<"nodes">>, ?T("Nodes"), NodeMenu},
|
||||
{<<"stats">>, ?T("Statistics")}]
|
||||
++ get_menu_items_hook(server, Lang),
|
||||
BasePath = url_to_path(Base),
|
||||
Fixed2 = [Tuple
|
||||
|| Tuple <- Fixed,
|
||||
is_allowed_path(BasePath, Tuple, JID)],
|
||||
is_allowed_path(global, Tuple, JID)],
|
||||
{Base, <<"">>, Fixed2}.
|
||||
|
||||
get_menu_items_hook({hostnode, Host, Node}, Lang) ->
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
|
||||
@@ -225,6 +225,16 @@ ws_loop(FrameInfo, Socket, WsHandleLoopPid, SocketMode, Shaper) ->
|
||||
end,
|
||||
erlang:demonitor(Ref),
|
||||
websocket_close(Socket, WsHandleLoopPid, SocketMode, Code);
|
||||
{text_with_reply, Data, Sender} ->
|
||||
SocketMode:send(Socket, encode_frame(Data, 1)),
|
||||
Sender ! {text_reply, self()},
|
||||
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
|
||||
SocketMode, Shaper);
|
||||
{data_with_reply, Data, Sender} ->
|
||||
SocketMode:send(Socket, encode_frame(Data, 2)),
|
||||
Sender ! {data_reply, self()},
|
||||
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
|
||||
SocketMode, Shaper);
|
||||
{text, Data} ->
|
||||
SocketMode:send(Socket, encode_frame(Data, 1)),
|
||||
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("mod_roster.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-record(state,
|
||||
{auth = noauth :: noauth | map(),
|
||||
|
||||
+1
-1
@@ -326,7 +326,7 @@ geturl(Url) ->
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
User = case getenv("PROXY_USER", "", [4]) of
|
||||
User = case getenv("PROXY_USER", "", ":") of
|
||||
[U, Pass] -> [{proxy_auth, {U, Pass}}];
|
||||
_ -> []
|
||||
end,
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
-deprecated([{add_iq_handler, 6}, {handle, 5}, {iqdisc, 1}]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
-module(gen_pubsub_node).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-type(host() :: mod_pubsub:host()).
|
||||
-type(nodeId() :: mod_pubsub:nodeId()).
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
ServerHost :: binary(),
|
||||
Opts :: [any()]) -> atom().
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-callback terminate(Host :: host(), ServerHost :: binary()) -> atom().
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
-export([import_file/1, import_dir/1]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
|
||||
+3
-1
@@ -50,7 +50,7 @@
|
||||
{encode_base64, 1}]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
||||
-type distance_cache() :: #{{string(), string()} => non_neg_integer()}.
|
||||
@@ -212,6 +212,8 @@ encode_base64(Data) ->
|
||||
-spec ip_to_list(inet:ip_address() | undefined |
|
||||
{inet:ip_address(), inet:port_number()}) -> binary().
|
||||
|
||||
ip_to_list({local, _}) ->
|
||||
<<"unix">>;
|
||||
ip_to_list({IP, _Port}) ->
|
||||
ip_to_list(IP);
|
||||
%% This function clause could use inet_parse too:
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
mod_options/1, mod_doc/0]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
start(Host, _Opts) ->
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
-include("mod_roster.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
-include("ejabberd_sm.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
%%%
|
||||
%%% gen_mod
|
||||
@@ -1509,7 +1509,11 @@ send_stanza(FromString, ToString, Stanza) ->
|
||||
To = jid:decode(ToString),
|
||||
CodecOpts = ejabberd_config:codec_options(),
|
||||
Pkt = xmpp:decode(El, ?NS_CLIENT, CodecOpts),
|
||||
ejabberd_router:route(xmpp:set_from_to(Pkt, From, To))
|
||||
Pkt2 = xmpp:set_from_to(Pkt, From, To),
|
||||
State = #{jid => From},
|
||||
ejabberd_hooks:run_fold(user_send_packet, From#jid.lserver,
|
||||
{Pkt2, State}, []),
|
||||
ejabberd_router:route(Pkt2)
|
||||
catch _:{xmpp_codec, Why} ->
|
||||
io:format("incorrect stanza: ~ts~n", [xmpp:format_error(Why)]),
|
||||
{error, Why};
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_commands.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
@@ -363,5 +363,6 @@ mod_options(_) -> [].
|
||||
mod_doc() ->
|
||||
#{desc =>
|
||||
?T("This module can be used to update existing SQL database "
|
||||
"from 'old' to 'new' schema. When the module is loaded "
|
||||
"use 'update_sql' ejabberdctl command.")}.
|
||||
"from the default to the new schema. Check the section "
|
||||
"http://../database-ldap/#default-and-new-schemas[Default and New Schemas] for details. "
|
||||
"When the module is loaded use 'update_sql' ejabberdctl command.")}.
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
announce_all_hosts_motd_delete/1]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_announce.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
get_motd/1, is_motd_user/2, set_motd_user/2, import/3]).
|
||||
-export([need_transform/1, transform/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_announce.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
get_motd/1, is_motd_user/2, set_motd_user/2, import/3,
|
||||
export/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_announce.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
-export([pubsub_publish_item/6, vcard_iq_convert/1, vcard_iq_publish/1,
|
||||
get_sm_features/5]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("pubsub.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
-export([filter_packet/1, filter_offline_msg/1, filter_subscription/2]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
disco_features/5, mod_options/1, mod_doc/0]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("bosh.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_caps.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
-export([list/2]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-type direction() :: sent | received.
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
c2s_copy_session/2, c2s_session_resumed/1]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-define(CSI_QUEUE_MAX, 100).
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
depends/2, mod_doc/0]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_sm.hrl").
|
||||
-include("translate.hrl").
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
@@ -663,7 +663,7 @@ get_outgoing_s2s(Host, Lang) ->
|
||||
Host == FH orelse str:suffix(DotHost, FH)],
|
||||
lists:map(
|
||||
fun (T) ->
|
||||
Name = str:format(tr(Lang, ?T("To ~ts")),[T]),
|
||||
Name = str:translate_and_format(Lang, ?T("To ~ts"),[T]),
|
||||
#disco_item{jid = jid:make(Host),
|
||||
node = <<"outgoing s2s/", T/binary>>,
|
||||
name = Name}
|
||||
@@ -675,7 +675,7 @@ get_outgoing_s2s(Host, Lang, To) ->
|
||||
lists:map(
|
||||
fun ({F, _T}) ->
|
||||
Node = <<"outgoing s2s/", To/binary, "/", F/binary>>,
|
||||
Name = str:format(tr(Lang, ?T("From ~ts")), [F]),
|
||||
Name = str:translate_and_format(Lang, ?T("From ~ts"), [F]),
|
||||
#disco_item{jid = jid:make(Host), node = Node, name = Name}
|
||||
end,
|
||||
lists:keysort(
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
disco_local_identity/5, disco_sm_identity/5]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-type route_type() :: ejabberd_sm | ejabberd_local.
|
||||
|
||||
+3
-2
@@ -42,7 +42,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("mod_roster.hrl").
|
||||
|
||||
@@ -499,7 +499,8 @@ mod_doc() ->
|
||||
"by those modules.")}},
|
||||
{name,
|
||||
#{value => ?T("Name"),
|
||||
desc => ?T("Any arbitrary name of the contact.")}},
|
||||
desc => ?T("The field 'var' name that will be defined. "
|
||||
"See XEP-0157 for some standardized names.")}},
|
||||
{urls,
|
||||
#{value => "[URI, ...]",
|
||||
desc => ?T("A list of contact URIs, such as "
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("ejabberd_commands.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-define(CLEAN_INTERVAL, timer:minutes(10)).
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
-export([start/2, stop/1, reload/3, process/2, depends/2,
|
||||
mod_options/1, mod_doc/0]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
expand_host/2]).
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
%% ejabberd_hooks callback.
|
||||
-export([handle_slot_request/6]).
|
||||
|
||||
-include("jid.hrl").
|
||||
-include_lib("xmpp/include/jid.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% gen_mod callbacks.
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
register_user/2, depends/2, privacy_check_packet/4]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
-include("mod_last.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
%% hooks
|
||||
-export([c2s_unauthenticated_packet/2, c2s_stream_features/2]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-type c2s_state() :: ejabberd_c2s:state().
|
||||
|
||||
+10
-6
@@ -44,7 +44,7 @@
|
||||
is_empty_for_user/2, is_empty_for_room/3, check_create_room/4,
|
||||
process_iq/3, store_mam_message/7, make_id/0, wrap_as_mucsub/2, select/7]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("mod_muc_room.hrl").
|
||||
-include("ejabberd_commands.hrl").
|
||||
@@ -687,11 +687,11 @@ process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang,
|
||||
#mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
|
||||
Txt = ?T("Unsupported <index/> element"),
|
||||
xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
|
||||
#mam_query{rsm = RSM, xmlns = NS} ->
|
||||
#mam_query{rsm = RSM, flippage = FlipPage, xmlns = NS} ->
|
||||
case parse_query(SubEl, Lang) of
|
||||
{ok, Query} ->
|
||||
NewRSM = limit_max(RSM, NS),
|
||||
select_and_send(LServer, Query, NewRSM, IQ, MsgType);
|
||||
select_and_send(LServer, Query, NewRSM, FlipPage, IQ, MsgType);
|
||||
{error, Err} ->
|
||||
xmpp:make_error(IQ, Err)
|
||||
end
|
||||
@@ -1017,7 +1017,7 @@ maybe_activate_mam(LUser, LServer) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) ->
|
||||
select_and_send(LServer, Query, RSM, FlipPage, #iq{from = From, to = To} = IQ, MsgType) ->
|
||||
Ret = case MsgType of
|
||||
chat ->
|
||||
select(LServer, From, From, Query, RSM, MsgType);
|
||||
@@ -1027,7 +1027,11 @@ select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) ->
|
||||
case Ret of
|
||||
{Msgs, IsComplete, Count} ->
|
||||
SortedMsgs = lists:keysort(2, Msgs),
|
||||
send(SortedMsgs, Count, IsComplete, IQ);
|
||||
SortedMsgs2 = case FlipPage of
|
||||
true -> lists:reverse(SortedMsgs);
|
||||
false -> SortedMsgs
|
||||
end,
|
||||
send(SortedMsgs2, Count, IsComplete, IQ);
|
||||
{error, _} ->
|
||||
Txt = ?T("Database failure"),
|
||||
Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
|
||||
@@ -1134,7 +1138,7 @@ select_with_mucsub_fallback(LServer, JidRequestor, JidArchive, Query, RSM, Flags
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
SubRoomJids = [Jid || {Jid, _} <- SubRooms],
|
||||
SubRoomJids = [Jid || {Jid, _, _} <- SubRooms],
|
||||
{E2, A2, C2} =
|
||||
lists:foldl(
|
||||
fun(MucJid, {E0, A0, C0}) ->
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
is_empty_for_user/2, is_empty_for_room/3]).
|
||||
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("mod_mam.hrl").
|
||||
|
||||
|
||||
+3
-3
@@ -33,7 +33,7 @@
|
||||
is_empty_for_user/2, is_empty_for_room/3, select_with_mucsub/6]).
|
||||
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_mam.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
@@ -221,7 +221,7 @@ select_with_mucsub(LServer, JidRequestor, #jid{luser = LUser} = JidArchive,
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
[jid:encode(Jid) || {Jid, _} <- SubRooms]
|
||||
[jid:encode(Jid) || {Jid, _, _} <- SubRooms]
|
||||
end,
|
||||
{Query, CountQuery} = make_sql_query(LUser, LServer, MAMQuery, RSM, Extra),
|
||||
do_select_query(LServer, JidRequestor, JidArchive, RSM, chat, Query, CountQuery, Flags).
|
||||
@@ -256,7 +256,7 @@ do_select_query(LServer, JidRequestor, #jid{luser = LUser} = JidArchive, RSM,
|
||||
{Res, true}
|
||||
end,
|
||||
MucState = #state{config = #config{anonymous = true}},
|
||||
JidArchiveS = jid:encode(JidArchive),
|
||||
JidArchiveS = jid:encode(jid:remove_resource(JidArchive)),
|
||||
{lists:flatmap(
|
||||
fun([TS, XML, PeerBin, Kind, Nick]) ->
|
||||
case make_archive_el(JidArchiveS, TS, XML, PeerBin, Kind, Nick,
|
||||
|
||||
+4
-3
@@ -29,7 +29,7 @@
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-export([start/2, stop/1, mod_opt_type/1, mod_options/1, depends/2, reload/3]).
|
||||
@@ -103,10 +103,11 @@ user_receive_packet({Packet, #{jid := #jid{lserver = LServer}} = C2SState}) ->
|
||||
push(LServer, user_receive_packet),
|
||||
{Packet, C2SState}.
|
||||
|
||||
-spec s2s_send_packet(stanza()) -> any().
|
||||
-spec s2s_send_packet(stanza()) -> stanza().
|
||||
s2s_send_packet(Packet) ->
|
||||
#jid{lserver = LServer} = xmpp:get_from(Packet),
|
||||
push(LServer, s2s_send_packet).
|
||||
push(LServer, s2s_send_packet),
|
||||
Packet.
|
||||
|
||||
-spec s2s_receive_packet({stanza(), ejabberd_s2s_in:state()}) ->
|
||||
{stanza(), ejabberd_s2s_in:state()}.
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
process_mam_query/1,
|
||||
process_pubsub_query/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@
|
||||
remove_user/2,
|
||||
process_iq/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("mqtt.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-record(state, {vsn = ?VSN :: integer(),
|
||||
version :: undefined | mqtt_version(),
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3, format_status/2]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
|
||||
+30
-23
@@ -68,14 +68,14 @@
|
||||
can_use_nick/4,
|
||||
get_subscribed_rooms/2,
|
||||
procname/2,
|
||||
route/1]).
|
||||
route/1, unhibernate_room/3]).
|
||||
|
||||
-export([init/1, handle_call/3, handle_cast/2,
|
||||
handle_info/2, terminate/2, code_change/3,
|
||||
mod_opt_type/1, mod_options/1, depends/2]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_muc.hrl").
|
||||
-include("mod_muc_room.hrl").
|
||||
-include("translate.hrl").
|
||||
@@ -107,7 +107,7 @@
|
||||
-callback count_online_rooms_by_user(binary(), binary(), binary()) -> non_neg_integer().
|
||||
-callback get_online_rooms_by_user(binary(), binary(), binary()) -> [{binary(), binary()}].
|
||||
-callback get_subscribed_rooms(binary(), binary(), jid()) ->
|
||||
{ok, [{jid(), [binary()]}]} | {error, db_failure}.
|
||||
{ok, [{jid(), binary(), [binary()]}]} | {error, db_failure}.
|
||||
|
||||
-optional_callbacks([get_subscribed_rooms/3]).
|
||||
|
||||
@@ -526,6 +526,18 @@ extract_password(#iq{} = IQ) ->
|
||||
false
|
||||
end.
|
||||
|
||||
-spec unhibernate_room(binary(), binary(), binary()) -> {ok, pid()} | error.
|
||||
unhibernate_room(ServerHost, Host, Room) ->
|
||||
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
||||
case RMod:find_online_room(ServerHost, Room, Host) of
|
||||
error ->
|
||||
case load_room(RMod, Host, ServerHost, Room) of
|
||||
{ok, _} = R -> R;
|
||||
_ -> error
|
||||
end;
|
||||
{ok, _} = R2 -> R2
|
||||
end.
|
||||
|
||||
-spec route_to_room(stanza(), binary()) -> ok.
|
||||
route_to_room(Packet, ServerHost) ->
|
||||
From = xmpp:get_from(Packet),
|
||||
@@ -701,8 +713,8 @@ process_mucsub(#iq{type = get, from = From, to = To, lang = Lang,
|
||||
ServerHost = ejabberd_router:host_of_route(Host),
|
||||
case get_subscribed_rooms(ServerHost, Host, From) of
|
||||
{ok, Subs} ->
|
||||
List = [#muc_subscription{jid = JID, events = Nodes}
|
||||
|| {JID, Nodes} <- Subs],
|
||||
List = [#muc_subscription{jid = JID, nick = Nick, events = Nodes}
|
||||
|| {JID, Nick, Nodes} <- Subs],
|
||||
xmpp:make_iq_result(IQ, #muc_subscriptions{list = List});
|
||||
{error, _} ->
|
||||
Txt = ?T("Database failure"),
|
||||
@@ -790,18 +802,13 @@ load_permanent_rooms(Hosts, ServerHost, Opts) ->
|
||||
lists:foreach(
|
||||
fun(R) ->
|
||||
{Room, _} = R#muc_room.name_host,
|
||||
case proplists:get_bool(persistent, R#muc_room.opts) of
|
||||
true ->
|
||||
case RMod:find_online_room(ServerHost, Room, Host) of
|
||||
error ->
|
||||
start_room(RMod, Host, ServerHost, Access,
|
||||
Room, HistorySize, RoomShaper,
|
||||
R#muc_room.opts, QueueType);
|
||||
{ok, _} ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
forget_room(ServerHost, Host, Room)
|
||||
case RMod:find_online_room(ServerHost, Room, Host) of
|
||||
error ->
|
||||
start_room(RMod, Host, ServerHost, Access,
|
||||
Room, HistorySize, RoomShaper,
|
||||
R#muc_room.opts, QueueType);
|
||||
{ok, _} ->
|
||||
ok
|
||||
end
|
||||
end, get_rooms(ServerHost, Host))
|
||||
end, Hosts);
|
||||
@@ -951,13 +958,13 @@ get_room_disco_item({Name, Host, Pid}, {Filter, JID, Lang}) ->
|
||||
Err
|
||||
end.
|
||||
|
||||
-spec get_subscribed_rooms(binary(), jid()) -> {ok, [{jid(), [binary()]}]} | {error, any()}.
|
||||
-spec get_subscribed_rooms(binary(), jid()) -> {ok, [{jid(), binary(), [binary()]}]} | {error, any()}.
|
||||
get_subscribed_rooms(Host, User) ->
|
||||
ServerHost = ejabberd_router:host_of_route(Host),
|
||||
get_subscribed_rooms(ServerHost, Host, User).
|
||||
|
||||
-spec get_subscribed_rooms(binary(), binary(), jid()) ->
|
||||
{ok, [{jid(), [binary()]}]} | {error, any()}.
|
||||
{ok, [{jid(), binary(), [binary()]}]} | {error, any()}.
|
||||
get_subscribed_rooms(ServerHost, Host, From) ->
|
||||
LServer = jid:nameprep(ServerHost),
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
@@ -969,15 +976,15 @@ get_subscribed_rooms(ServerHost, Host, From) ->
|
||||
fun({Name, _, Pid}) when Pid == self() ->
|
||||
USR = jid:split(BareFrom),
|
||||
case erlang:get(muc_subscribers) of
|
||||
#{USR := #subscriber{nodes = Nodes}} ->
|
||||
[{jid:make(Name, Host), Nodes}];
|
||||
#{USR := #subscriber{nodes = Nodes, nick = Nick}} ->
|
||||
[{jid:make(Name, Host), Nick, Nodes}];
|
||||
_ ->
|
||||
[]
|
||||
end;
|
||||
({Name, _, Pid}) ->
|
||||
case mod_muc_room:is_subscribed(Pid, BareFrom) of
|
||||
{true, Nodes} ->
|
||||
[{jid:make(Name, Host), Nodes}];
|
||||
{true, Nick, Nodes} ->
|
||||
[{jid:make(Name, Host), Nick, Nodes}];
|
||||
false -> []
|
||||
end;
|
||||
(_) ->
|
||||
|
||||
+228
-183
@@ -44,7 +44,7 @@
|
||||
web_page_host/3, mod_options/1, get_commands_spec/0, find_hosts/1]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_muc.hrl").
|
||||
-include("mod_muc_room.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
@@ -264,7 +264,11 @@ get_commands_spec() ->
|
||||
|
||||
#ejabberd_commands{name = send_direct_invitation, tags = [muc_room],
|
||||
desc = "Send a direct invitation to several destinations",
|
||||
longdesc = "Password and Message can also be: none. Users JIDs are separated with : ",
|
||||
longdesc = "Since ejabberd 20.10, this command is "
|
||||
"asynchronous: the API call may return before the "
|
||||
"server has send all the invitations.\n\n"
|
||||
"Password and Message can also be: none. "
|
||||
"Users JIDs are separated with : ",
|
||||
module = ?MODULE, function = send_direct_invitation,
|
||||
args_desc = ["Room name", "MUC service", "Password, or none",
|
||||
"Reason text, or none", "Users JIDs separated with : characters"],
|
||||
@@ -401,12 +405,25 @@ build_summary_room(Name, Host, Pid) ->
|
||||
}.
|
||||
|
||||
muc_register_nick(Nick, FromBinary, Service) ->
|
||||
ServerHost = get_room_serverhost(Service),
|
||||
From = jid:decode(FromBinary),
|
||||
Lang = <<"en">>,
|
||||
case mod_muc:iq_set_register_info(ServerHost, Service, From, Nick, Lang) of
|
||||
{result, undefined} -> ok;
|
||||
E -> E
|
||||
try {get_room_serverhost(Service), jid:decode(FromBinary)} of
|
||||
{ServerHost, From} ->
|
||||
Lang = <<"en">>,
|
||||
case mod_muc:iq_set_register_info(ServerHost, Service, From, Nick, Lang) of
|
||||
{result, undefined} -> ok;
|
||||
{error, #stanza_error{reason = 'conflict'}} ->
|
||||
throw({error, "Nick already registered"});
|
||||
{error, _} ->
|
||||
throw({error, "Database error"})
|
||||
end
|
||||
catch
|
||||
error:{invalid_domain, _} ->
|
||||
throw({error, "Invalid 'service'"});
|
||||
error:{unregistered_route, _} ->
|
||||
throw({error, "Invalid 'service'"});
|
||||
error:{bad_jid, _} ->
|
||||
throw({error, "Invalid 'jid'"});
|
||||
_ ->
|
||||
throw({error, "Internal error"})
|
||||
end.
|
||||
|
||||
muc_unregister_nick(FromBinary, Service) ->
|
||||
@@ -503,7 +520,7 @@ get_sort_query2(Q) ->
|
||||
|
||||
make_rooms_page(Host, Lang, {Sort_direction, Sort_column}) ->
|
||||
Service = find_service(Host),
|
||||
Rooms_names = get_rooms(Service),
|
||||
Rooms_names = get_online_rooms(Service),
|
||||
Rooms_infos = build_info_rooms(Rooms_names),
|
||||
Rooms_sorted = sort_rooms(Sort_direction, Sort_column, Rooms_infos),
|
||||
Rooms_prepared = prepare_rooms_infos(Rooms_sorted),
|
||||
@@ -628,53 +645,58 @@ create_room(Name1, Host1, ServerHost) ->
|
||||
create_room_with_opts(Name1, Host1, ServerHost, []).
|
||||
|
||||
create_room_with_opts(Name1, Host1, ServerHost1, CustomRoomOpts) ->
|
||||
true = (error /= (Name = jid:nodeprep(Name1))),
|
||||
true = (error /= (Host = jid:nodeprep(Host1))),
|
||||
true = (error /= (ServerHost = jid:nodeprep(ServerHost1))),
|
||||
case {jid:nodeprep(Name1), jid:nodeprep(Host1), jid:nodeprep(ServerHost1)} of
|
||||
{error, _, _} ->
|
||||
throw({error, "Invalid 'name'"});
|
||||
{_, error, _} ->
|
||||
throw({error, "Invalid 'host'"});
|
||||
{_, _, error} ->
|
||||
throw({error, "Invalid 'serverhost'"});
|
||||
{Name, Host, ServerHost} ->
|
||||
%% Get the default room options from the muc configuration
|
||||
DefRoomOpts = mod_muc_opt:default_room_options(ServerHost),
|
||||
%% Change default room options as required
|
||||
FormattedRoomOpts = [format_room_option(Opt, Val) || {Opt, Val}<-CustomRoomOpts],
|
||||
RoomOpts = lists:ukeymerge(1,
|
||||
lists:keysort(1, FormattedRoomOpts),
|
||||
lists:keysort(1, DefRoomOpts)),
|
||||
|
||||
%% Get the default room options from the muc configuration
|
||||
DefRoomOpts = mod_muc_opt:default_room_options(ServerHost),
|
||||
%% Change default room options as required
|
||||
FormattedRoomOpts = [format_room_option(Opt, Val) || {Opt, Val}<-CustomRoomOpts],
|
||||
RoomOpts = lists:ukeymerge(1,
|
||||
lists:keysort(1, FormattedRoomOpts),
|
||||
lists:keysort(1, DefRoomOpts)),
|
||||
|
||||
%% Store the room on the server, it is not started yet though at this point
|
||||
case lists:keyfind(persistent, 1, RoomOpts) of
|
||||
{persistent, true} ->
|
||||
mod_muc:store_room(ServerHost, Host, Name, RoomOpts);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
%% Get all remaining mod_muc parameters that might be utilized
|
||||
Access = mod_muc_opt:access(ServerHost),
|
||||
AcCreate = mod_muc_opt:access_create(ServerHost),
|
||||
AcAdmin = mod_muc_opt:access_admin(ServerHost),
|
||||
AcPer = mod_muc_opt:access_persistent(ServerHost),
|
||||
AcMam = mod_muc_opt:access_mam(ServerHost),
|
||||
HistorySize = mod_muc_opt:history_size(ServerHost),
|
||||
RoomShaper = mod_muc_opt:room_shaper(ServerHost),
|
||||
QueueType = mod_muc_opt:queue_type(ServerHost),
|
||||
|
||||
%% Get all remaining mod_muc parameters that might be utilized
|
||||
Access = mod_muc_opt:access(ServerHost),
|
||||
AcCreate = mod_muc_opt:access_create(ServerHost),
|
||||
AcAdmin = mod_muc_opt:access_admin(ServerHost),
|
||||
AcPer = mod_muc_opt:access_persistent(ServerHost),
|
||||
AcMam = mod_muc_opt:access_mam(ServerHost),
|
||||
HistorySize = mod_muc_opt:history_size(ServerHost),
|
||||
RoomShaper = mod_muc_opt:room_shaper(ServerHost),
|
||||
QueueType = mod_muc_opt:queue_type(ServerHost),
|
||||
|
||||
%% If the room does not exist yet in the muc_online_room
|
||||
case mod_muc:find_online_room(Name, Host) of
|
||||
error ->
|
||||
%% Start the room
|
||||
{ok, Pid} = mod_muc_room:start(
|
||||
Host,
|
||||
ServerHost,
|
||||
{Access, AcCreate, AcAdmin, AcPer, AcMam},
|
||||
Name,
|
||||
HistorySize,
|
||||
RoomShaper,
|
||||
RoomOpts,
|
||||
QueueType),
|
||||
mod_muc:register_online_room(Name, Host, Pid),
|
||||
ok;
|
||||
{ok, _} ->
|
||||
error
|
||||
%% If the room does not exist yet in the muc_online_room
|
||||
case get_room_pid(Name, Host) of
|
||||
room_not_found ->
|
||||
%% Store the room on the server, it is not started yet though at this point
|
||||
case lists:keyfind(persistent, 1, RoomOpts) of
|
||||
{persistent, true} ->
|
||||
mod_muc:store_room(ServerHost, Host, Name, RoomOpts);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
%% Start the room
|
||||
{ok, Pid} = mod_muc_room:start(
|
||||
Host,
|
||||
ServerHost,
|
||||
{Access, AcCreate, AcAdmin, AcPer, AcMam},
|
||||
Name,
|
||||
HistorySize,
|
||||
RoomShaper,
|
||||
RoomOpts,
|
||||
QueueType),
|
||||
mod_muc:register_online_room(Name, Host, Pid),
|
||||
ok;
|
||||
_ ->
|
||||
throw({error, "Room already exists"})
|
||||
end
|
||||
end.
|
||||
|
||||
%% Create the room only in the database.
|
||||
@@ -688,12 +710,22 @@ muc_create_room(ServerHost, {Name, Host, _}, DefRoomOpts) ->
|
||||
%% @doc Destroy the room immediately.
|
||||
%% If the room has participants, they are not notified that the room was destroyed;
|
||||
%% they will notice when they try to chat and receive an error that the room doesn't exist.
|
||||
destroy_room(Name, Service) ->
|
||||
case mod_muc:find_online_room(Name, Service) of
|
||||
{ok, Pid} ->
|
||||
mod_muc_room:destroy(Pid);
|
||||
error ->
|
||||
error
|
||||
destroy_room(Name1, Service1) ->
|
||||
case {jid:nodeprep(Name1), jid:nodeprep(Service1)} of
|
||||
{error, _} ->
|
||||
throw({error, "Invalid 'name'"});
|
||||
{_, error} ->
|
||||
throw({error, "Invalid 'service'"});
|
||||
{Name, Service} ->
|
||||
case get_room_pid(Name, Service) of
|
||||
room_not_found ->
|
||||
throw({error, "Room doesn't exists"});
|
||||
invalid_service ->
|
||||
throw({error, "Invalid 'service'"});
|
||||
Pid ->
|
||||
mod_muc_room:destroy(Pid),
|
||||
ok
|
||||
end
|
||||
end.
|
||||
|
||||
destroy_room({N, H, SH}) ->
|
||||
@@ -714,7 +746,7 @@ destroy_rooms_file(Filename) ->
|
||||
Rooms = read_rooms(F, RJID, []),
|
||||
file:close(F),
|
||||
[destroy_room(A) || A <- Rooms],
|
||||
ok.
|
||||
ok.
|
||||
|
||||
read_rooms(_F, eof, L) ->
|
||||
L;
|
||||
@@ -758,7 +790,7 @@ create_rooms_file(Filename) ->
|
||||
%% Read the default room options defined for the first virtual host
|
||||
DefRoomOpts = mod_muc_opt:default_room_options(ejabberd_config:get_myname()),
|
||||
[muc_create_room(ejabberd_config:get_myname(), A, DefRoomOpts) || A <- Rooms],
|
||||
ok.
|
||||
ok.
|
||||
|
||||
|
||||
%%---------------------------------
|
||||
@@ -786,7 +818,7 @@ rooms_report(Method, Action, Service, Days) ->
|
||||
|
||||
muc_unused(Method, Action, Service, Last_allowed) ->
|
||||
%% Get all required info about all existing rooms
|
||||
Rooms_all = get_rooms(Service),
|
||||
Rooms_all = get_all_rooms(Service),
|
||||
|
||||
%% Decide which ones pass the requirements
|
||||
Rooms_pass = decide_rooms(Method, Rooms_all, Last_allowed),
|
||||
@@ -802,14 +834,35 @@ muc_unused(Method, Action, Service, Last_allowed) ->
|
||||
%%---------------
|
||||
%% Get info
|
||||
|
||||
get_rooms(ServiceArg) ->
|
||||
get_online_rooms(ServiceArg) ->
|
||||
Hosts = find_services(ServiceArg),
|
||||
lists:flatmap(
|
||||
fun(Host) ->
|
||||
[{RoomName, RoomHost, ejabberd_router:host_of_route(Host), Pid}
|
||||
|| {RoomName, RoomHost, Pid} <- mod_muc:get_online_rooms(Host)]
|
||||
ServerHost = get_room_serverhost(Host),
|
||||
[{RoomName, RoomHost, ServerHost, Pid}
|
||||
|| {RoomName, RoomHost, Pid} <- mod_muc:get_online_rooms(Host)]
|
||||
end, Hosts).
|
||||
|
||||
get_all_rooms(Host) ->
|
||||
ServerHost = ejabberd_router:host_of_route(Host),
|
||||
OnlineRooms = get_online_rooms(Host),
|
||||
OnlineMap = lists:foldl(
|
||||
fun({Room, _, _, _}, Map) ->
|
||||
Map#{Room => 1}
|
||||
end, #{}, OnlineRooms),
|
||||
|
||||
Mod = gen_mod:db_mod(ServerHost, mod_muc),
|
||||
StoredRooms = lists:filtermap(
|
||||
fun(#muc_room{name_host = {Room, _}, opts = Opts}) ->
|
||||
case maps:is_key(Room, OnlineMap) of
|
||||
true ->
|
||||
false;
|
||||
_ ->
|
||||
{true, {Room, Host, ServerHost, Opts}}
|
||||
end
|
||||
end, Mod:get_rooms(ServerHost, Host)),
|
||||
OnlineRooms ++ StoredRooms.
|
||||
|
||||
get_room_config(Room_pid) ->
|
||||
{ok, R} = mod_muc_room:get_config(Room_pid),
|
||||
R.
|
||||
@@ -826,45 +879,55 @@ decide_rooms(Method, Rooms, Last_allowed) ->
|
||||
lists:filter(Decide, Rooms).
|
||||
|
||||
decide_room(unused, {_Room_name, _Host, ServerHost, Room_pid}, Last_allowed) ->
|
||||
C = get_room_config(Room_pid),
|
||||
Persistent = C#config.persistent,
|
||||
|
||||
S = get_room_state(Room_pid),
|
||||
Just_created = S#state.just_created,
|
||||
|
||||
Room_users = S#state.users,
|
||||
Num_users = maps:size(Room_users),
|
||||
|
||||
History = (S#state.history)#lqueue.queue,
|
||||
Ts_now = calendar:universal_time(),
|
||||
HistorySize = mod_muc_opt:history_size(ServerHost),
|
||||
{Has_hist, Last} = case p1_queue:is_empty(History) of
|
||||
true when (HistorySize == 0) or (Just_created == true) ->
|
||||
{false, 0};
|
||||
true ->
|
||||
Ts_diff = (erlang:system_time(microsecond)
|
||||
- Just_created) div 1000000,
|
||||
{false, Ts_diff};
|
||||
false ->
|
||||
Last_message = get_queue_last(History),
|
||||
Ts_last = calendar:now_to_universal_time(
|
||||
element(4, Last_message)),
|
||||
Ts_diff =
|
||||
calendar:datetime_to_gregorian_seconds(Ts_now)
|
||||
- calendar:datetime_to_gregorian_seconds(Ts_last),
|
||||
{true, Ts_diff}
|
||||
end,
|
||||
case {Persistent, Just_created, Num_users, Has_hist, seconds_to_days(Last)} of
|
||||
{_true, JC, 0, _, Last_days}
|
||||
when (Last_days >= Last_allowed) and (JC /= true) ->
|
||||
NodeStartTime = erlang:system_time(microsecond) -
|
||||
1000000*(erlang:monotonic_time(second)-ejabberd_config:get_node_start()),
|
||||
OnlyHibernated = case mod_muc_opt:hibernation_timeout(ServerHost) of
|
||||
Value when Value < Last_allowed*24*60*60*1000 ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
end,
|
||||
{Just_created, Num_users} =
|
||||
case Room_pid of
|
||||
Pid when is_pid(Pid) andalso OnlyHibernated ->
|
||||
{0, 0};
|
||||
Pid when is_pid(Pid) ->
|
||||
case mod_muc_room:get_state(Room_pid) of
|
||||
{ok, #state{just_created = JD, users = U}} ->
|
||||
{JD, maps:size(U)};
|
||||
_ ->
|
||||
{0, 0}
|
||||
end;
|
||||
Opts ->
|
||||
case lists:keyfind(hibernation_time, 1, Opts) of
|
||||
false ->
|
||||
{NodeStartTime, 0};
|
||||
{_, T} ->
|
||||
{T, 0}
|
||||
end
|
||||
end,
|
||||
Last = case Just_created of
|
||||
true ->
|
||||
0;
|
||||
_ ->
|
||||
(erlang:system_time(microsecond)
|
||||
- Just_created) div 1000000
|
||||
end,
|
||||
case {Num_users, seconds_to_days(Last)} of
|
||||
{0, Last_days} when (Last_days >= Last_allowed) ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
end;
|
||||
decide_room(empty, {Room_name, Host, ServerHost, _Room_pid}, _Last_allowed) ->
|
||||
decide_room(empty, {Room_name, Host, ServerHost, Room_pid}, _Last_allowed) ->
|
||||
case gen_mod:is_loaded(ServerHost, mod_mam) of
|
||||
true ->
|
||||
Room_options = get_room_options(Room_name, Host),
|
||||
Room_options = case Room_pid of
|
||||
_ when is_pid(Room_pid) ->
|
||||
get_room_options(Room_pid);
|
||||
Opts ->
|
||||
Opts
|
||||
end,
|
||||
case lists:keyfind(<<"mam">>, 1, Room_options) of
|
||||
{<<"mam">>, <<"true">>} ->
|
||||
mod_mam:is_empty_for_room(ServerHost, Room_name, Host);
|
||||
@@ -887,13 +950,20 @@ act_on_rooms(Method, Action, Rooms) ->
|
||||
end,
|
||||
lists:foreach(Delete, Rooms).
|
||||
|
||||
act_on_room(Method, destroy, {N, H, SH, Pid}) ->
|
||||
act_on_room(Method, destroy, {N, H, _SH, Pid}) ->
|
||||
Message = iolist_to_binary(io_lib:format(
|
||||
<<"Room destroyed by rooms_~s_destroy.">>, [Method])),
|
||||
mod_muc_room:destroy(Pid, Message),
|
||||
mod_muc:room_destroyed(H, N, Pid, SH),
|
||||
mod_muc:forget_room(SH, H, N);
|
||||
|
||||
case Pid of
|
||||
V when is_pid(V) ->
|
||||
mod_muc_room:destroy(Pid, Message);
|
||||
_ ->
|
||||
case get_room_pid(N, H) of
|
||||
Pid2 when is_pid(Pid2) ->
|
||||
mod_muc_room:destroy(Pid2, Message);
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end;
|
||||
act_on_room(_Method, list, _) ->
|
||||
ok.
|
||||
|
||||
@@ -904,8 +974,8 @@ act_on_room(_Method, list, _) ->
|
||||
|
||||
get_room_occupants(Room, Host) ->
|
||||
case get_room_pid(Room, Host) of
|
||||
room_not_found -> throw({error, room_not_found});
|
||||
Pid -> get_room_occupants(Pid)
|
||||
Pid when is_pid(Pid) -> get_room_occupants(Pid);
|
||||
_ -> throw({error, room_not_found})
|
||||
end.
|
||||
|
||||
get_room_occupants(Pid) ->
|
||||
@@ -920,11 +990,11 @@ get_room_occupants(Pid) ->
|
||||
|
||||
get_room_occupants_number(Room, Host) ->
|
||||
case get_room_pid(Room, Host) of
|
||||
room_not_found ->
|
||||
throw({error, room_not_found});
|
||||
Pid ->
|
||||
Pid when is_pid(Pid )->
|
||||
S = get_room_state(Pid),
|
||||
maps:size(S#state.users)
|
||||
maps:size(S#state.users);
|
||||
_ ->
|
||||
throw({error, room_not_found})
|
||||
end.
|
||||
|
||||
%%----------------------------
|
||||
@@ -933,13 +1003,16 @@ get_room_occupants_number(Room, Host) ->
|
||||
%% http://xmpp.org/extensions/xep-0249.html
|
||||
|
||||
send_direct_invitation(RoomName, RoomService, Password, Reason, UsersString) ->
|
||||
RoomJid = jid:make(RoomName, RoomService),
|
||||
XmlEl = build_invitation(Password, Reason, RoomJid),
|
||||
Users = get_users_to_invite(RoomJid, UsersString),
|
||||
[send_direct_invitation(RoomJid, UserJid, XmlEl)
|
||||
|| UserJid <- Users],
|
||||
timer:sleep(1000),
|
||||
ok.
|
||||
case jid:make(RoomName, RoomService) of
|
||||
error ->
|
||||
throw({error, "Invalid 'roomname' or 'service'"});
|
||||
RoomJid ->
|
||||
XmlEl = build_invitation(Password, Reason, RoomJid),
|
||||
Users = get_users_to_invite(RoomJid, UsersString),
|
||||
[send_direct_invitation(RoomJid, UserJid, XmlEl)
|
||||
|| UserJid <- Users],
|
||||
ok
|
||||
end.
|
||||
|
||||
get_users_to_invite(RoomJid, UsersString) ->
|
||||
UsersStrings = binary:split(UsersString, <<":">>, [global]),
|
||||
@@ -993,7 +1066,9 @@ send_direct_invitation(FromJid, UserJid, Msg) ->
|
||||
change_room_option(Name, Service, OptionString, ValueString) ->
|
||||
case get_room_pid(Name, Service) of
|
||||
room_not_found ->
|
||||
room_not_found;
|
||||
throw({error, "Room not found"});
|
||||
invalid_service ->
|
||||
throw({error, "Invalid 'service'"});
|
||||
Pid ->
|
||||
{Option, Value} = format_room_option(OptionString, ValueString),
|
||||
change_room_option(Pid, Option, Value)
|
||||
@@ -1033,12 +1108,21 @@ format_room_option(OptionString, ValueString) ->
|
||||
{Option, Value}.
|
||||
|
||||
%% @doc Get the Pid of an existing MUC room, or 'room_not_found'.
|
||||
-spec get_room_pid(binary(), binary()) -> {ok, pid()} | room_not_found | invalid_service.
|
||||
get_room_pid(Name, Service) ->
|
||||
case mod_muc:find_online_room(Name, Service) of
|
||||
error ->
|
||||
room_not_found;
|
||||
{ok, Pid} ->
|
||||
Pid
|
||||
try get_room_serverhost(Service) of
|
||||
ServerHost ->
|
||||
case mod_muc:unhibernate_room(ServerHost, Service, Name) of
|
||||
error ->
|
||||
room_not_found;
|
||||
{ok, Pid} ->
|
||||
Pid
|
||||
end
|
||||
catch
|
||||
error:{invalid_domain, _} ->
|
||||
invalid_service;
|
||||
error:{unregistered_route, _} ->
|
||||
invalid_service
|
||||
end.
|
||||
|
||||
%% It is required to put explicitly all the options because
|
||||
@@ -1081,8 +1165,8 @@ change_option(Option, Value, Config) ->
|
||||
|
||||
get_room_options(Name, Service) ->
|
||||
case get_room_pid(Name, Service) of
|
||||
room_not_found -> [];
|
||||
Pid -> get_room_options(Pid)
|
||||
Pid when is_pid(Pid) -> get_room_options(Pid);
|
||||
_ -> []
|
||||
end.
|
||||
|
||||
get_room_options(Pid) ->
|
||||
@@ -1106,8 +1190,8 @@ get_options(Config) ->
|
||||
%% [{JID::string(), Domain::string(), Role::string(), Reason::string()}]
|
||||
%% @doc Get the affiliations of the room Name@Service.
|
||||
get_room_affiliations(Name, Service) ->
|
||||
case mod_muc:find_online_room(Name, Service) of
|
||||
{ok, Pid} ->
|
||||
case get_room_pid(Name, Service) of
|
||||
Pid when is_pid(Pid) ->
|
||||
%% Get the PID of the online room, then request its state
|
||||
{ok, StateData} = mod_muc_room:get_state(Pid),
|
||||
Affiliations = maps:to_list(StateData#state.affiliations),
|
||||
@@ -1117,7 +1201,7 @@ get_room_affiliations(Name, Service) ->
|
||||
({{Uname, Domain, _Res}, Aff}) when is_atom(Aff)->
|
||||
{Uname, Domain, Aff, <<>>}
|
||||
end, Affiliations);
|
||||
error ->
|
||||
_ ->
|
||||
throw({error, "The room does not exist."})
|
||||
end.
|
||||
|
||||
@@ -1130,13 +1214,13 @@ get_room_affiliations(Name, Service) ->
|
||||
%% @doc Get affiliation of a user in the room Name@Service.
|
||||
|
||||
get_room_affiliation(Name, Service, JID) ->
|
||||
case mod_muc:find_online_room(Name, Service) of
|
||||
{ok, Pid} ->
|
||||
case get_room_pid(Name, Service) of
|
||||
Pid when is_pid(Pid) ->
|
||||
%% Get the PID of the online room, then request its state
|
||||
{ok, StateData} = mod_muc_room:get_state(Pid),
|
||||
UserJID = jid:decode(JID),
|
||||
mod_muc_room:get_affiliation(UserJID, StateData);
|
||||
error ->
|
||||
_ ->
|
||||
throw({error, "The room does not exist."})
|
||||
end.
|
||||
|
||||
@@ -1154,14 +1238,21 @@ get_room_affiliation(Name, Service, JID) ->
|
||||
%% In any other case the action will be to create the affiliation.
|
||||
set_room_affiliation(Name, Service, JID, AffiliationString) ->
|
||||
Affiliation = misc:binary_to_atom(AffiliationString),
|
||||
case mod_muc:find_online_room(Name, Service) of
|
||||
{ok, Pid} ->
|
||||
case get_room_pid(Name, Service) of
|
||||
Pid when is_pid(Pid) ->
|
||||
%% Get the PID for the online room so we can get the state of the room
|
||||
{ok, StateData} = mod_muc_room:change_item(Pid, jid:decode(JID), affiliation, Affiliation, <<"">>),
|
||||
mod_muc:store_room(StateData#state.server_host, StateData#state.host, StateData#state.room, make_opts(StateData)),
|
||||
ok;
|
||||
error ->
|
||||
error
|
||||
case mod_muc_room:change_item(Pid, jid:decode(JID), affiliation, Affiliation, <<"">>) of
|
||||
{ok, _} ->
|
||||
ok;
|
||||
{error, not_found} ->
|
||||
throw({error, "Room doesn't exists"});
|
||||
{error, _} ->
|
||||
throw({error, "Unable to perform change"})
|
||||
end;
|
||||
room_not_found ->
|
||||
throw({error, "Room doesn't exists"});
|
||||
invalid_service ->
|
||||
throw({error, "Invalid 'service'"})
|
||||
end.
|
||||
|
||||
%%%
|
||||
@@ -1232,52 +1323,6 @@ get_subscribers(Name, Host) ->
|
||||
throw({error, "The room does not exist"})
|
||||
end.
|
||||
|
||||
%% Copied from mod_muc_room.erl
|
||||
get_config_opt_name(Pos) ->
|
||||
Fs = [config|record_info(fields, config)],
|
||||
lists:nth(Pos, Fs).
|
||||
-define(MAKE_CONFIG_OPT(Opt),
|
||||
{get_config_opt_name(Opt), element(Opt, Config)}).
|
||||
make_opts(StateData) ->
|
||||
Config = StateData#state.config,
|
||||
Subscribers = maps:fold(
|
||||
fun(_LJID, Sub, Acc) ->
|
||||
[{Sub#subscriber.jid,
|
||||
Sub#subscriber.nick,
|
||||
Sub#subscriber.nodes}|Acc]
|
||||
end, [], StateData#state.subscribers),
|
||||
[?MAKE_CONFIG_OPT(#config.title), ?MAKE_CONFIG_OPT(#config.description),
|
||||
?MAKE_CONFIG_OPT(#config.allow_change_subj),
|
||||
?MAKE_CONFIG_OPT(#config.allow_query_users),
|
||||
?MAKE_CONFIG_OPT(#config.allow_private_messages),
|
||||
?MAKE_CONFIG_OPT(#config.allow_private_messages_from_visitors),
|
||||
?MAKE_CONFIG_OPT(#config.allow_visitor_status),
|
||||
?MAKE_CONFIG_OPT(#config.allow_visitor_nickchange),
|
||||
?MAKE_CONFIG_OPT(#config.public), ?MAKE_CONFIG_OPT(#config.public_list),
|
||||
?MAKE_CONFIG_OPT(#config.persistent),
|
||||
?MAKE_CONFIG_OPT(#config.moderated),
|
||||
?MAKE_CONFIG_OPT(#config.members_by_default),
|
||||
?MAKE_CONFIG_OPT(#config.members_only),
|
||||
?MAKE_CONFIG_OPT(#config.allow_user_invites),
|
||||
?MAKE_CONFIG_OPT(#config.password_protected),
|
||||
?MAKE_CONFIG_OPT(#config.captcha_protected),
|
||||
?MAKE_CONFIG_OPT(#config.password), ?MAKE_CONFIG_OPT(#config.anonymous),
|
||||
?MAKE_CONFIG_OPT(#config.logging), ?MAKE_CONFIG_OPT(#config.max_users),
|
||||
?MAKE_CONFIG_OPT(#config.allow_voice_requests),
|
||||
?MAKE_CONFIG_OPT(#config.allow_subscription),
|
||||
?MAKE_CONFIG_OPT(#config.mam),
|
||||
?MAKE_CONFIG_OPT(#config.presence_broadcast),
|
||||
?MAKE_CONFIG_OPT(#config.voice_request_min_interval),
|
||||
?MAKE_CONFIG_OPT(#config.vcard),
|
||||
{captcha_whitelist,
|
||||
(?SETS):to_list((StateData#state.config)#config.captcha_whitelist)},
|
||||
{affiliations,
|
||||
maps:to_list(StateData#state.affiliations)},
|
||||
{subject, StateData#state.subject},
|
||||
{subject_author, StateData#state.subject_author},
|
||||
{subscribers, Subscribers}].
|
||||
|
||||
|
||||
%%----------------------------
|
||||
%% Utils
|
||||
%%----------------------------
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@
|
||||
mod_opt_type/1, mod_options/1, depends/2, mod_doc/0]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_muc_room.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
-include("mod_muc.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
|
||||
-record(state, {}).
|
||||
|
||||
+19
-12
@@ -66,7 +66,7 @@
|
||||
code_change/4]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("mod_muc_room.hrl").
|
||||
-include("ejabberd_stacktrace.hrl").
|
||||
@@ -223,7 +223,7 @@ unsubscribe(Pid, JID) ->
|
||||
{error, ?T("Conference room does not exist")}
|
||||
end.
|
||||
|
||||
-spec is_subscribed(pid(), jid()) -> {true, [binary()]} | false.
|
||||
-spec is_subscribed(pid(), jid()) -> {true, binary(), [binary()]} | false.
|
||||
is_subscribed(Pid, JID) ->
|
||||
try p1_fsm:sync_send_all_state_event(Pid, {is_subscribed, JID})
|
||||
catch _:{_, {p1_fsm, _, _}} -> false
|
||||
@@ -282,6 +282,7 @@ init([Host, ServerHost, Access, Room, HistorySize,
|
||||
[Room, Host, jid:encode(Creator)]),
|
||||
add_to_log(room_existence, created, State1),
|
||||
add_to_log(room_existence, started, State1),
|
||||
ejabberd_hooks:run(start_room, ServerHost, [ServerHost, Room, Host]),
|
||||
{ok, normal_state, reset_hibernate_timer(State1)};
|
||||
init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueType]) ->
|
||||
process_flag(trap_exit, true),
|
||||
@@ -296,6 +297,7 @@ init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueType])
|
||||
room_queue = RoomQueue,
|
||||
room_shaper = Shaper}),
|
||||
add_to_log(room_existence, started, State),
|
||||
ejabberd_hooks:run(start_room, ServerHost, [ServerHost, Room, Host]),
|
||||
{ok, normal_state, reset_hibernate_timer(State)}.
|
||||
|
||||
normal_state({route, <<"">>,
|
||||
@@ -710,6 +712,7 @@ handle_sync_event({process_item_change, Item, UJID}, _From, StateName, StateData
|
||||
{error, _} = Err ->
|
||||
{reply, Err, StateName, StateData};
|
||||
NSD ->
|
||||
store_room(NSD),
|
||||
{reply, {ok, NSD}, StateName, NSD}
|
||||
end;
|
||||
handle_sync_event(get_subscribers, _From, StateName, StateData) ->
|
||||
@@ -759,7 +762,7 @@ handle_sync_event({muc_unsubscribe, From}, _From, StateName,
|
||||
end;
|
||||
handle_sync_event({is_subscribed, From}, _From, StateName, StateData) ->
|
||||
IsSubs = try maps:get(jid:split(From), StateData#state.subscribers) of
|
||||
#subscriber{nodes = Nodes} -> {true, Nodes}
|
||||
#subscriber{nick = Nick, nodes = Nodes} -> {true, Nick, Nodes}
|
||||
catch _:{badkey, _} -> false
|
||||
end,
|
||||
{reply, IsSubs, StateName, StateData};
|
||||
@@ -1442,7 +1445,8 @@ get_error_text(#stanza_error{text = Txt}) ->
|
||||
make_reason(Packet, From, StateData, Reason1) ->
|
||||
#user{nick = FromNick} = maps:get(jid:tolower(From), StateData#state.users),
|
||||
Condition = get_error_condition(xmpp:get_error(Packet)),
|
||||
str:format(Reason1, [FromNick, Condition]).
|
||||
Reason2 = unicode:characters_to_list(Reason1),
|
||||
str:format(Reason2, [FromNick, Condition]).
|
||||
|
||||
-spec expulse_participant(stanza(), jid(), state(), binary()) ->
|
||||
state().
|
||||
@@ -2717,9 +2721,9 @@ add_message_to_history(FromNick, FromJID, Packet, StateData) ->
|
||||
Q1 = lqueue_in({FromNick, TSPacket, false,
|
||||
TimeStamp, Size},
|
||||
StateData#state.history),
|
||||
StateData#state{history = Q1};
|
||||
StateData#state{history = Q1, just_created = erlang:system_time(microsecond)};
|
||||
_ ->
|
||||
StateData
|
||||
StateData#state{just_created = erlang:system_time(microsecond)}
|
||||
end.
|
||||
|
||||
-spec send_history(jid(), [lqueue_elem()], state()) -> ok.
|
||||
@@ -3491,8 +3495,8 @@ get_config(Lang, StateData, From) ->
|
||||
DefaultRoomMaxUsers = get_default_room_maxusers(StateData),
|
||||
Config = StateData#state.config,
|
||||
MaxUsersRoom = get_max_users(StateData),
|
||||
Title = str:format(
|
||||
translate:translate(Lang, ?T("Configuration of room ~s")),
|
||||
Title = str:translate_and_format(
|
||||
Lang, ?T("Configuration of room ~s"),
|
||||
[jid:encode(StateData#state.jid)]),
|
||||
Fs = [{roomname, Config#config.title},
|
||||
{roomdesc, Config#config.description},
|
||||
@@ -3948,6 +3952,7 @@ make_opts(StateData) ->
|
||||
maps:to_list(StateData#state.affiliations)},
|
||||
{subject, StateData#state.subject},
|
||||
{subject_author, StateData#state.subject_author},
|
||||
{hibernation_time, erlang:system_time(microsecond)},
|
||||
{subscribers, Subscribers}].
|
||||
|
||||
expand_opts(CompactOpts) ->
|
||||
@@ -3971,13 +3976,15 @@ expand_opts(CompactOpts) ->
|
||||
SubjectAuthor = proplists:get_value(subject_author, CompactOpts, <<"">>),
|
||||
Subject = proplists:get_value(subject, CompactOpts, <<"">>),
|
||||
Subscribers = proplists:get_value(subscribers, CompactOpts, []),
|
||||
HibernationTime = proplists:get_value(hibernation_time, CompactOpts, 0),
|
||||
[{subject, Subject},
|
||||
{subject_author, SubjectAuthor},
|
||||
{subscribers, Subscribers}
|
||||
{subscribers, Subscribers},
|
||||
{hibernation_time, HibernationTime}
|
||||
| lists:reverse(Opts1)].
|
||||
|
||||
config_fields() ->
|
||||
[subject, subject_author, subscribers | record_info(fields, config)].
|
||||
[subject, subject_author, subscribers, hibernate_time | record_info(fields, config)].
|
||||
|
||||
-spec destroy_room(muc_destroy(), state()) -> {result, undefined, stop}.
|
||||
destroy_room(DEl, StateData) ->
|
||||
@@ -4059,7 +4066,7 @@ make_disco_info(_From, StateData) ->
|
||||
end,
|
||||
#disco_info{identities = [#identity{category = <<"conference">>,
|
||||
type = <<"text">>,
|
||||
name = get_title(StateData)}],
|
||||
name = (StateData#state.config)#config.title}],
|
||||
features = Feats}.
|
||||
|
||||
-spec process_iq_disco_info(jid(), iq(), state()) ->
|
||||
@@ -4312,7 +4319,7 @@ process_iq_mucsub(From, #iq{type = get, lang = Lang,
|
||||
fun(_, #subscriber{jid = J, nick = N, nodes = Nodes}, Acc) ->
|
||||
case ShowJid of
|
||||
true ->
|
||||
[#muc_subscription{jid = J, events = Nodes}|Acc];
|
||||
[#muc_subscription{jid = J, nick = N, events = Nodes}|Acc];
|
||||
_ ->
|
||||
[#muc_subscription{nick = N, events = Nodes}|Acc]
|
||||
end
|
||||
|
||||
+4
-4
@@ -40,7 +40,7 @@
|
||||
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
||||
get_affiliations/3, search_affiliation/4]).
|
||||
|
||||
-include("jid.hrl").
|
||||
-include_lib("xmpp/include/jid.hrl").
|
||||
-include("mod_muc.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
@@ -410,11 +410,11 @@ get_subscribed_rooms(LServer, Host, Jid) ->
|
||||
JidS = jid:encode(Jid),
|
||||
case ejabberd_sql:sql_query(
|
||||
LServer,
|
||||
?SQL("select @(room)s, @(nodes)s from muc_room_subscribers "
|
||||
?SQL("select @(room)s, @(nick)s, @(nodes)s from muc_room_subscribers "
|
||||
"where jid=%(JidS)s and host=%(Host)s")) of
|
||||
{selected, Subs} ->
|
||||
{ok, [{jid:make(Room, Host), ejabberd_sql:decode_term(Nodes)}
|
||||
|| {Room, Nodes} <- Subs]};
|
||||
{ok, [{jid:make(Room, Host), Nick, ejabberd_sql:decode_term(Nodes)}
|
||||
|| {Room, Nick, Nodes} <- Subs]};
|
||||
_Error ->
|
||||
{error, db_failure}
|
||||
end.
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-record(multicastc, {rserver :: binary(),
|
||||
response,
|
||||
|
||||
+13
-10
@@ -69,7 +69,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
|
||||
@@ -988,7 +988,7 @@ user_queue(User, Server, Query, Lang) ->
|
||||
end,
|
||||
Hdrs = get_messages_subset(User, Server, HdrsAll),
|
||||
FMsgs = format_user_queue(Hdrs),
|
||||
PageTitle = str:format(translate:translate(Lang, ?T("~ts's Offline Messages Queue")), [us_to_list(US)]),
|
||||
PageTitle = str:translate_and_format(Lang, ?T("~ts's Offline Messages Queue"), [us_to_list(US)]),
|
||||
(?H1GL(PageTitle, <<"modules/#mod-offline">>, <<"mod_offline">>))
|
||||
++ [?XREST(?T("Submitted"))] ++
|
||||
[?XAE(<<"form">>,
|
||||
@@ -1008,7 +1008,7 @@ user_queue(User, Server, Query, Lang) ->
|
||||
true -> FMsgs
|
||||
end)]),
|
||||
?BR,
|
||||
?INPUTT(<<"submit">>, <<"delete">>,
|
||||
?INPUTTD(<<"submit">>, <<"delete">>,
|
||||
?T("Delete Selected"))])].
|
||||
|
||||
user_queue_parse_query(LUser, LServer, Query) ->
|
||||
@@ -1070,14 +1070,17 @@ get_messages_subset2(Max, Length, MsgsAll) ->
|
||||
webadmin_user(Acc, User, Server, Lang) ->
|
||||
QueueLen = count_offline_messages(jid:nodeprep(User),
|
||||
jid:nameprep(Server)),
|
||||
FQueueLen = [?AC(<<"queue/">>,
|
||||
(integer_to_binary(QueueLen)))],
|
||||
FQueueLen = ?C(integer_to_binary(QueueLen)),
|
||||
FQueueView = ?AC(<<"queue/">>,
|
||||
?T("View Queue")),
|
||||
Acc ++
|
||||
[?XCT(<<"h3">>, ?T("Offline Messages:"))] ++
|
||||
FQueueLen ++
|
||||
[?C(<<" ">>),
|
||||
?INPUTT(<<"submit">>, <<"removealloffline">>,
|
||||
?T("Remove All Offline Messages"))].
|
||||
[?XCT(<<"h3">>, ?T("Offline Messages:")),
|
||||
FQueueLen,
|
||||
?C(<<" | ">>),
|
||||
FQueueView,
|
||||
?C(<<" | ">>),
|
||||
?INPUTTD(<<"submit">>, <<"removealloffline">>,
|
||||
?T("Remove All Offline Messages"))].
|
||||
|
||||
-spec delete_all_msgs(binary(), binary()) -> {atomic, any()}.
|
||||
delete_all_msgs(User, Server) ->
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
remove_all_messages/2, count_messages/2, import/1]).
|
||||
-export([need_transform/1, transform/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_offline.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
read_message/3, remove_message/3, read_all_messages/2,
|
||||
remove_all_messages/2, count_messages/2, import/1, export/1]).
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_offline.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_sql_pt.hrl").
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
|
||||
-record(pres_counter,
|
||||
{dir, start, count, logged = false}).
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
mod_opt_type/1, mod_options/1, depends/2]).
|
||||
|
||||
-include("logger.hrl").
|
||||
-include("xmpp.hrl").
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user