mirror of https://github.com/sipwise/prosody.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
5.3 KiB
175 lines
5.3 KiB
--
|
|
-- Copyright (C) 2013 Sipwise GmbH <development@sipwise.com>
|
|
--
|
|
-- This project is MIT/X11 licensed. Please see the
|
|
-- COPYING file in the source package for more information.
|
|
--
|
|
local nodeprep = require "util.encodings".stringprep.nodeprep;
|
|
local jid_split = require "util.jid".split;
|
|
local sql = module:require("sql");
|
|
local st = require "util.stanza";
|
|
local template = require "util.template";
|
|
local array = require "util.array";
|
|
local rex = require "rex_pcre";
|
|
|
|
local get_reply = template[[
|
|
<query xmlns='jabber:iq:search'>
|
|
<instructions>Please enter a phone number</instructions>
|
|
<nick/>
|
|
</query>
|
|
]].apply({});
|
|
|
|
local usr_replacements_query = [[
|
|
SELECT vrr.match_pattern, vrr.replace_pattern FROM provisioning.voip_preferences vp
|
|
LEFT JOIN provisioning.voip_usr_preferences vup ON vup.attribute_id = vp.id
|
|
LEFT JOIN provisioning.voip_subscribers vs ON vs.id = vup.subscriber_id
|
|
LEFT JOIN provisioning.voip_domains vd ON vd.id = vs.domain_id
|
|
LEFT JOIN provisioning.voip_rewrite_rule_sets vrrs ON vrrs.callee_in_dpid = vup.value
|
|
LEFT JOIN provisioning.voip_rewrite_rules vrr ON vrr.set_id = vrrs.id AND vrr.direction = 'in' AND vrr.field = 'callee'
|
|
WHERE vp.attribute = 'rewrite_callee_in_dpid' AND vs.username = ? AND vd.domain = ?
|
|
ORDER BY vrr.priority ASC;
|
|
]];
|
|
|
|
local dom_replacements_query = [[
|
|
SELECT vrr.match_pattern, vrr.replace_pattern FROM provisioning.voip_preferences vp
|
|
LEFT JOIN provisioning.voip_dom_preferences vdp ON vdp.attribute_id = vp.id
|
|
LEFT JOIN provisioning.voip_domains vd ON vd.id = vdp.domain_id
|
|
LEFT JOIN provisioning.voip_rewrite_rule_sets vrrs ON vrrs.callee_in_dpid = vdp.value
|
|
LEFT JOIN provisioning.voip_rewrite_rules vrr ON vrr.set_id = vrrs.id AND vrr.direction = 'in' AND vrr.field = 'callee'
|
|
WHERE vp.attribute = 'rewrite_callee_in_dpid' AND vd.domain = ?
|
|
ORDER BY vrr.priority ASC;
|
|
]];
|
|
|
|
local locale_query = [[
|
|
SELECT vp.attribute, vup.value FROM provisioning.voip_preferences vp
|
|
LEFT JOIN provisioning.voip_usr_preferences vup ON vup.attribute_id = vp.id
|
|
LEFT JOIN provisioning.voip_subscribers vs ON vs.id = vup.subscriber_id
|
|
LEFT JOIN provisioning.voip_domains vd ON vd.id = vs.domain_id
|
|
WHERE (vp.attribute = 'ac' or vp.attribute = 'cc')
|
|
AND vs.username = ?
|
|
AND vd.domain = ?;
|
|
]];
|
|
|
|
local lookup_query = [[
|
|
SELECT username,domain FROM kamailio.dbaliases
|
|
WHERE alias_username=?;
|
|
]];
|
|
|
|
local mod_sql = module:require("sql");
|
|
local params = module:get_option("auth_sql", {
|
|
driver = "MySQL",
|
|
database = "provisioning",
|
|
username = "prosody",
|
|
password = "PW_PROSODY",
|
|
host = "localhost"
|
|
});
|
|
engine = mod_sql:create_engine(params);
|
|
engine:execute("SET NAMES 'utf8' COLLATE 'utf8_bin';");
|
|
|
|
function normalize_number(user, host, number)
|
|
local locale_info = {};
|
|
for row in engine:select(locale_query, user, host) do
|
|
locale_info["caller_"..row[1]] = row[2];
|
|
end
|
|
|
|
local replacement_regexes = {};
|
|
local usr_pref = 0;
|
|
for row in engine:select(usr_replacements_query, user, host) do
|
|
usr_pref = 1;
|
|
local patt, repl = row[1], row[2]
|
|
:gsub("%$avp%(s:([a-zA-Z_]+)%)", locale_info)
|
|
:gsub("\\", "%%"):gsub("%%%%", "\\");
|
|
table.insert(replacement_regexes, { patt, repl });
|
|
end
|
|
if usr_pref == 0 then
|
|
for row in engine:select(dom_replacements_query, host) do
|
|
local patt, repl = row[1], row[2]
|
|
:gsub("%$avp%(s:([a-zA-Z_]+)%)", locale_info)
|
|
:gsub("\\", "%%"):gsub("%%%%", "\\");
|
|
table.insert(replacement_regexes, { patt, repl });
|
|
end
|
|
end
|
|
|
|
for _, rule in ipairs(replacement_regexes) do
|
|
local new_number, n_matches = rex.gsub(number, rule[1], rule[2]);
|
|
if n_matches > 0 then
|
|
number = new_number;
|
|
break;
|
|
end
|
|
end
|
|
return number;
|
|
end
|
|
|
|
function search_by_number(number)
|
|
local results = {};
|
|
for result in engine:select(lookup_query, number) do
|
|
table.insert(results, result[1].."@"..result[2]);
|
|
end
|
|
return results;
|
|
end
|
|
|
|
module:depends("disco");
|
|
module:add_feature("jabber:iq:search");
|
|
|
|
module:hook("iq/host/jabber:iq:search:query", function(event)
|
|
local origin, stanza = event.origin, event.stanza;
|
|
|
|
if stanza.attr.type == "get" then
|
|
return origin.send(st.reply(stanza):add_child(get_reply));
|
|
else
|
|
local user, host = jid_split(stanza.attr.from);
|
|
local number = stanza.tags[1]:get_child_text("nick");
|
|
|
|
-- Reconnect to DB if necessary
|
|
if not engine.conn:ping() then
|
|
engine.conn = nil;
|
|
engine:connect();
|
|
end
|
|
|
|
number = normalize_number(user, host, number);
|
|
|
|
local reply = st.reply(stanza):query("jabber:iq:search");
|
|
|
|
for _, jid in ipairs(search_by_number(number)) do
|
|
reply:tag("item", { jid = jid }):up();
|
|
end
|
|
|
|
return origin.send(reply);
|
|
end
|
|
end);
|
|
|
|
function module.command(arg)
|
|
local jid = require "util.jid";
|
|
local warn = prosodyctl.show_warning;
|
|
local command = arg[1];
|
|
if not command then
|
|
warn("Valid subcommands: normalize");
|
|
return 0;
|
|
end
|
|
table.remove(arg, 1);
|
|
if command == "normalize" then
|
|
if #arg ~= 2 then
|
|
warn("Usage: normalize USER@HOST NUMBER");
|
|
return 1;
|
|
end
|
|
local user_jid, number = arg[1], arg[2];
|
|
local user, host = jid.prepped_split(user_jid);
|
|
if not (user and host) then
|
|
warn("Invalid JID: "..user_jid);
|
|
return 1;
|
|
end
|
|
print(normalize_number(user, host, number));
|
|
elseif command == "query" then
|
|
if #arg ~= 1 then
|
|
warn("Usage: query NUMBER");
|
|
warn(" NUMBER must be normalized (see 'normalize' command)");
|
|
return 1;
|
|
end
|
|
local results = search_by_number(arg[1]);
|
|
for _, jid in ipairs(results) do
|
|
print("", jid);
|
|
end
|
|
end
|
|
return 0;
|
|
end
|