-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod_auth_surycat.lua
126 lines (109 loc) · 3.5 KB
/
mod_auth_surycat.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
-- Simple SQL Authentication module for Prosody IM
-- Copyright (C) 2011 Tomasz Sterna <tomek@xiaoka.com>
-- Copyright (C) 2011 Waqas Hussain <waqas20@gmail.com>
-- Copyright (C) 2013 Guilhem Lettron <guilhem.lettron@optiflows.com>
--
local log = require "util.logger".init("auth_sql");
local new_sasl = require "util.sasl".new;
local DBI = require "DBI"
local connection;
local params = module:get_option("auth_sql", module:get_option("sql"));
local resolve_relative_path = require "core.configmanager".resolve_relative_path;
local function test_connection()
if not connection then return nil; end
if connection:ping() then
return true;
else
module:log("debug", "Database connection closed");
connection = nil;
end
end
local function connect()
if not test_connection() then
prosody.unlock_globals();
local dbh, err = DBI.Connect(
params.driver, params.database,
params.username, params.password,
params.host, params.port
);
prosody.lock_globals();
if not dbh then
module:log("debug", "Database connection failed: %s", tostring(err));
return nil, err;
end
module:log("debug", "Successfully connected to database");
dbh:autocommit(true); -- don't run in transaction
connection = dbh;
return connection;
end
end
do -- process options to get a db connection
params = params or { driver = "SQLite3" };
if params.driver == "SQLite3" then
params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite");
end
assert(params.driver and params.database, "Both the SQL driver and the database need to be specified");
assert(connect());
end
local function getsql(sql, ...)
if params.driver == "PostgreSQL" then
sql = sql:gsub("`", "\"");
end
if not test_connection() then connect(); end
-- do prepared statement stuff
local stmt, err = connection:prepare(sql);
if not stmt and not test_connection() then error("connection failed"); end
if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end
-- run query
local ok, err = stmt:execute(...);
if not ok and not test_connection() then error("connection failed"); end
if not ok then return nil, err; end
return stmt;
end
local function get_password(username)
local stmt, err = getsql("SELECT `password` FROM `agentstore_agent` WHERE `name`=? AND `realm`=?", username, module.host);
if stmt then
for row in stmt:rows(true) do
return row.password;
end
end
end
provider = {};
function provider.test_password(username, password)
return password and get_password(username) == password;
end
function provider.get_password(username)
return get_password(username);
end
function provider.set_password(username, password)
return nil, "Setting password is not supported.";
end
function provider.user_exists(username)
return get_password(username) and true;
end
function provider.create_user(username, password)
return nil, "Account creation/modification not supported.";
end
function provider.get_sasl_handler()
local profile = {
plain = function(sasl, username, realm)
local password = get_password(username);
if not password then return "", nil; end
return password, true;
end
};
return new_sasl(module.host, profile);
end
function provider.users()
local stmt, err = getsql("SELECT `name` FROM `agentstore_agent` WHERE `realm`=?", module.host);
if stmt then
local next, state = stmt:rows(true)
return function()
for row in next, state do
return row.username;
end
end
end
return stmt, err;
end
module:provides("auth", provider);