Mercurial > prosody-modules
annotate mod_auth_sql/mod_auth_sql.lua @ 871:e4a03e58f896
Log and return failure if user record not found in bind
author | Rob Hoelz <rob@hoelz.ro> |
---|---|
date | Mon, 10 Dec 2012 22:16:18 +0100 |
parents | cdc67f4efde2 |
children | 490cb9161c81 |
rev | line source |
---|---|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
1 -- Simple SQL Authentication module for Prosody IM |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
2 -- Copyright (C) 2011 Tomasz Sterna <tomek@xiaoka.com> |
399
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
3 -- Copyright (C) 2011 Waqas Hussain <waqas20@gmail.com> |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
4 -- |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
5 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
6 local log = require "util.logger".init("auth_sql"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
7 local new_sasl = require "util.sasl".new; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
8 local nodeprep = require "util.encodings".stringprep.nodeprep; |
398 | 9 local DBI = require "DBI" |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
10 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
11 local connection; |
500
bd08727378be
mod_auth_sql: Read option 'auth_sql' (thanks rdnzlc)
Matthew Wild <mwild1@gmail.com>
parents:
461
diff
changeset
|
12 local params = module:get_option("auth_sql", module:get_option("sql")); |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
13 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
14 local resolve_relative_path = require "core.configmanager".resolve_relative_path; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
15 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
16 local function test_connection() |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
17 if not connection then return nil; end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
18 if connection:ping() then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
19 return true; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
20 else |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
21 module:log("debug", "Database connection closed"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
22 connection = nil; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
23 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
24 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
25 local function connect() |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
26 if not test_connection() then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
27 prosody.unlock_globals(); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
28 local dbh, err = DBI.Connect( |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
29 params.driver, params.database, |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
30 params.username, params.password, |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
31 params.host, params.port |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
32 ); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
33 prosody.lock_globals(); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
34 if not dbh then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
35 module:log("debug", "Database connection failed: %s", tostring(err)); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
36 return nil, err; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
37 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
38 module:log("debug", "Successfully connected to database"); |
371
c416db434e5b
Do not run in transaction.
Tomasz Sterna <tomek@xiaoka.com>
parents:
367
diff
changeset
|
39 dbh:autocommit(true); -- don't run in transaction |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
40 connection = dbh; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
41 return connection; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
42 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
43 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
44 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
45 do -- process options to get a db connection |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
46 params = params or { driver = "SQLite3" }; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
47 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
48 if params.driver == "SQLite3" then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
49 params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
50 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
51 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
52 assert(params.driver and params.database, "Both the SQL driver and the database need to be specified"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
53 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
54 assert(connect()); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
55 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
56 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
57 local function getsql(sql, ...) |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
58 if params.driver == "PostgreSQL" then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
59 sql = sql:gsub("`", "\""); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
60 end |
371
c416db434e5b
Do not run in transaction.
Tomasz Sterna <tomek@xiaoka.com>
parents:
367
diff
changeset
|
61 if not test_connection() then connect(); end |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
62 -- do prepared statement stuff |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
63 local stmt, err = connection:prepare(sql); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
64 if not stmt and not test_connection() then error("connection failed"); end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
65 if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
66 -- run query |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
67 local ok, err = stmt:execute(...); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
68 if not ok and not test_connection() then error("connection failed"); end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
69 if not ok then return nil, err; end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
70 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
71 return stmt; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
72 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
73 |
399
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
74 local function get_password(username) |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
75 local stmt, err = getsql("SELECT `password` FROM `authreg` WHERE `username`=? AND `realm`=?", username, module.host); |
399
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
76 if stmt then |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
77 for row in stmt:rows(true) do |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
78 return row.password; |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
79 end |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
80 end |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
81 end |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
82 |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
83 |
814
881ec9919144
mod_auth_*: Use module:provides(), and don't explicitly specify provider.name.
Waqas Hussain <waqas20@gmail.com>
parents:
500
diff
changeset
|
84 provider = {}; |
367
a6dee73a11e7
Implemented password and user existence check in mod_auth_sql
Tomasz Sterna <tomek@xiaoka.com>
parents:
366
diff
changeset
|
85 |
398 | 86 function provider.test_password(username, password) |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
87 return password and get_password(username) == password; |
398 | 88 end |
89 function provider.get_password(username) | |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
90 return get_password(username); |
398 | 91 end |
92 function provider.set_password(username, password) | |
93 return nil, "Setting password is not supported."; | |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
94 end |
398 | 95 function provider.user_exists(username) |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
96 return get_password(username) and true; |
398 | 97 end |
98 function provider.create_user(username, password) | |
99 return nil, "Account creation/modification not supported."; | |
100 end | |
101 function provider.get_sasl_handler() | |
102 local profile = { | |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
103 plain = function(sasl, username, realm) |
398 | 104 local prepped_username = nodeprep(username); |
105 if not prepped_username then | |
106 module:log("debug", "NODEprep failed on username: %s", username); | |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
107 return "", nil; |
398 | 108 end |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
109 local password = get_password(prepped_username); |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
110 if not password then return "", nil; end |
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
111 return password, true; |
398 | 112 end |
113 }; | |
461
bbea8081c865
Revert various changes accidentally included in previous commit
Kim Alvefur <zash@zash.se>
parents:
455
diff
changeset
|
114 return new_sasl(module.host, profile); |
398 | 115 end |
116 | |
843
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
117 function provider.users() |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
118 local stmt, err = getsql("SELECT `username` FROM `authreg` WHERE `realm`=?", module.host); |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
119 if stmt then |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
120 local next, state = stmt:rows(true) |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
121 return function() |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
122 for row in next, state do |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
123 return row.username; |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
124 end |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
125 end |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
126 end |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
127 return stmt, err; |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
128 end |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
129 |
cdc67f4efde2
mod_auth_sql: Add users iterator
Kim Alvefur <zash@zash.se>
parents:
814
diff
changeset
|
130 |
814
881ec9919144
mod_auth_*: Use module:provides(), and don't explicitly specify provider.name.
Waqas Hussain <waqas20@gmail.com>
parents:
500
diff
changeset
|
131 module:provides("auth", provider); |