Mercurial > prosody-modules
annotate mod_auth_sql/mod_auth_sql.lua @ 398:fdd4f5ab029a
mod_auth_sql: Cleanup.
| author | Waqas Hussain <waqas20@gmail.com> |
|---|---|
| date | Wed, 10 Aug 2011 04:42:50 +0500 |
| parents | c416db434e5b |
| children | 4e0d36941ba1 |
| 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> |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
3 -- |
|
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 local log = require "util.logger".init("auth_sql"); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
6 local new_sasl = require "util.sasl".new; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
7 local nodeprep = require "util.encodings".stringprep.nodeprep; |
| 398 | 8 local DBI = require "DBI" |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
9 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
10 local connection; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
11 local params = module:get_option("sql"); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
12 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
13 local resolve_relative_path = require "core.configmanager".resolve_relative_path; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
14 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
15 local function test_connection() |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
16 if not connection then return nil; end |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
17 if connection:ping() then |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
18 return true; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
19 else |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
20 module:log("debug", "Database connection closed"); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
21 connection = nil; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
22 end |
|
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 local function connect() |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
25 if not test_connection() then |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
26 prosody.unlock_globals(); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
27 local dbh, err = DBI.Connect( |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
28 params.driver, params.database, |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
29 params.username, params.password, |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
30 params.host, params.port |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
31 ); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
32 prosody.lock_globals(); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
33 if not dbh then |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
34 module:log("debug", "Database connection failed: %s", tostring(err)); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
35 return nil, err; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
36 end |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
37 module:log("debug", "Successfully connected to database"); |
|
371
c416db434e5b
Do not run in transaction.
Tomasz Sterna <tomek@xiaoka.com>
parents:
367
diff
changeset
|
38 dbh:autocommit(true); -- don't run in transaction |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
39 connection = dbh; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
40 return connection; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
41 end |
|
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 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
44 do -- process options to get a db connection |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
45 params = params or { driver = "SQLite3" }; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
46 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
47 if params.driver == "SQLite3" then |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
48 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
|
49 end |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
50 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
51 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
|
52 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
53 assert(connect()); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
54 end |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
55 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
56 local function getsql(sql, ...) |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
57 if params.driver == "PostgreSQL" then |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
58 sql = sql:gsub("`", "\""); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
59 end |
|
371
c416db434e5b
Do not run in transaction.
Tomasz Sterna <tomek@xiaoka.com>
parents:
367
diff
changeset
|
60 if not test_connection() then connect(); end |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
61 -- do prepared statement stuff |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
62 local stmt, err = connection:prepare(sql); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
63 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
|
64 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
|
65 -- run query |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
66 local ok, err = stmt:execute(...); |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
67 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
|
68 if not ok then return nil, err; end |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
69 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
70 return stmt; |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
71 end |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
72 |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
73 |
| 398 | 74 provider = { name = "sql" }; |
|
367
a6dee73a11e7
Implemented password and user existence check in mod_auth_sql
Tomasz Sterna <tomek@xiaoka.com>
parents:
366
diff
changeset
|
75 |
| 398 | 76 function provider.test_password(username, password) |
| 77 local stmt, err = getsql("SELECT `username` FROM `authreg` WHERE `username`=? AND `password`=? AND `realm`=?", | |
| 78 username, password, module.host); | |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
79 |
| 398 | 80 if not stmt then return nil, err; end |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
81 |
| 398 | 82 for row in stmt:rows(true) do |
| 83 return true; | |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
84 end |
| 398 | 85 end |
|
367
a6dee73a11e7
Implemented password and user existence check in mod_auth_sql
Tomasz Sterna <tomek@xiaoka.com>
parents:
366
diff
changeset
|
86 |
| 398 | 87 function provider.get_password(username) |
| 88 local stmt, err = getsql("SELECT `password` FROM `authreg` WHERE `username`=? AND `realm`=?", | |
| 89 username, module.host); | |
|
367
a6dee73a11e7
Implemented password and user existence check in mod_auth_sql
Tomasz Sterna <tomek@xiaoka.com>
parents:
366
diff
changeset
|
90 |
| 398 | 91 if not stmt then return nil, err; end |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
92 |
| 398 | 93 for row in stmt:rows(true) do |
| 94 return row.password; | |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
95 end |
| 398 | 96 end |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
97 |
| 398 | 98 function provider.set_password(username, password) |
| 99 return nil, "Setting password is not supported."; | |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
100 end |
|
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
101 |
| 398 | 102 function provider.user_exists(username) |
| 103 local stmt, err = getsql("SELECT `username` FROM `authreg` WHERE `username`=? AND `realm`=?", | |
| 104 username, module.host); | |
| 105 | |
| 106 if not stmt then return nil, err; end | |
| 107 | |
| 108 for row in stmt:rows(true) do | |
| 109 return true; | |
| 110 end | |
| 111 end | |
| 112 | |
| 113 function provider.create_user(username, password) | |
| 114 return nil, "Account creation/modification not supported."; | |
| 115 end | |
|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
116 |
| 398 | 117 function provider.get_sasl_handler() |
| 118 local profile = { | |
| 119 plain = function(sasl, username, realm) | |
| 120 local prepped_username = nodeprep(username); | |
| 121 if not prepped_username then | |
| 122 module:log("debug", "NODEprep failed on username: %s", username); | |
| 123 return "", nil; | |
| 124 end | |
| 125 local password = provider.get_password(prepped_username); | |
| 126 if not password then return "", nil; end | |
| 127 return password, true; | |
| 128 end | |
| 129 }; | |
| 130 return new_sasl(module.host, profile); | |
| 131 end | |
| 132 | |
| 133 module:add_item("auth-provider", provider); |
