2 -- Copyright (C) 2012 Florian Zeitz
3 -- Copyright (C) 2019 Kim Alvefur
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
9 local encodings
= require
"util.encodings";
10 assert(encodings
.confusable
, "This module requires that Prosody be built with ICU");
11 local skeleton
= encodings
.confusable
.skeleton
;
13 local usage
= require
"util.prosodyctl".show_usage
;
14 local usermanager
= require
"core.usermanager";
15 local storagemanager
= require
"core.storagemanager";
18 function module
.load()
19 if module
.host
~= "*" then
20 skeletons
= module
:open_store("skeletons");
24 module
:hook("user-registered", function(user
)
25 local skel
= skeleton(user
.username
);
26 local ok
, err
= skeletons
:set(skel
, { username
= user
.username
});
28 module
:log("error", "Unable to store mimicry data (%q => %q): %s", user
.username
, skel
, err
);
32 module
:hook("user-deleted", function(user
)
33 local skel
= skeleton(user
.username
);
34 local ok
, err
= skeletons
:set(skel
, nil);
35 if not ok
and err
then
36 module
:log("error", "Unable to clear mimicry data (%q): %s", skel
, err
);
40 module
:hook("user-registering", function(user
)
41 local existing
, err
= skeletons
:get(skeleton(user
.username
));
43 module
:log("debug", "Attempt to register username '%s' which could be confused with '%s'", user
.username
, existing
.username
);
46 module
:log("error", "Unable to check if new username '%s' can be confused with any existing user: %s", err
);
50 function module
.command(arg
)
51 if (arg
[1] ~= "bootstrap" or not arg
[2]) then
52 usage("mod_mimicking bootstrap <host>", "Initialize username mimicry database");
58 local host_session
= prosody
.hosts
[host
];
59 if not host_session
then
60 return "No such host";
63 storagemanager
.initialize_host(host
);
64 usermanager
.initialize_host(host
);
66 skeletons
= storagemanager
.open(host
, "skeletons");
69 for user
in usermanager
.users(host
) do
70 local skel
= skeleton(user
);
71 local existing
, err
= skeletons
:get(skel
);
72 if existing
and existing
.username
~= user
then
73 module
:log("warn", "Existing usernames '%s' and '%s' are confusable", existing
.username
, user
);
75 module
:log("error", "Error checking for existing mimicry data (%q = %q): %s", user
, skel
, err
);
77 local ok
, err
= skeletons
:set(skel
, { username
= user
});
81 module
:log("error", "Unable to store mimicry data (%q => %q): %s", user
, skel
, err
);
84 module
:log("info", "%d usernames indexed", count
);