Advertisement
Guest User

Untitled

a guest
Jul 1st, 2015
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.06 KB | None | 0 0
  1. -- Based on Simple SQL Authentication module for Prosody IM
  2. -- Copyright (C) 2011 Tomasz Sterna <tomek@xiaoka.com>
  3. -- Copyright (C) 2011 Waqas Hussain <waqas20@gmail.com>
  4. --
  5. -- 25/05/2014: Modified for Diaspora by Anahuac de Paula Gil - anahuac@anahuac.eu
  6. -- 06/08/2014: Cleaned up and fixed SASL auth by Jonne Haß <me@jhass.eu>
  7. -- 22/11/2014: Allow token authentication by Jonne Haß <me@jhass.eu>
  8.  
  9. local log = require "util.logger".init("auth_diaspora")
  10. local new_sasl = require "util.sasl".new
  11. local DBI = require "DBI"
  12. local bcrypt = require "bcrypt"
  13.  
  14. local connection
  15. local params = module:get_option("auth_diaspora", module:get_option("auth_sql", module:get_option("sql")))
  16.  
  17. local resolve_relative_path = require "core.configmanager".resolve_relative_path
  18.  
  19. local function test_connection()
  20. if not connection then return nil; end
  21. if connection:ping() then
  22. return true
  23. else
  24. module:log("debug", "Database connection closed")
  25. connection = nil
  26. end
  27. end
  28.  
  29. local function set_encoding(conn)
  30. if params.driver ~= "MySQL" then return; end
  31. local set_names_query = "SET NAMES '%s';"
  32. local stmt = assert(conn:prepare("SET NAMES 'utf8mb4' COLLATE 'utf8_bin';"));
  33. assert(stmt:execute());
  34. end
  35.  
  36. local function connect()
  37. if not test_connection() then
  38. prosody.unlock_globals()
  39. local dbh, err = DBI.Connect(
  40. params.driver, params.database,
  41. params.username, params.password,
  42. params.host, params.port
  43. )
  44. prosody.lock_globals()
  45. if not dbh then
  46. module:log("debug", "Database connection failed: %s", tostring(err))
  47. return nil, err
  48. end
  49. set_encoding(dbh);
  50. module:log("debug", "Successfully connected to database");
  51. dbh:autocommit(true); -- don't run in transaction
  52. connection = dbh
  53. return connection
  54. end
  55. end
  56.  
  57. do -- process options to get a db connection
  58. params = params or { driver = "SQLite3" }
  59.  
  60. if params.driver == "SQLite3" then
  61. params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite")
  62. end
  63.  
  64. assert(params.driver and params.database, "Both the SQL driver and the database need to be specified")
  65.  
  66. assert(connect())
  67. end
  68.  
  69. local function getsql(sql, ...)
  70. if params.driver == "PostgreSQL" then
  71. sql = sql:gsub("`", "\"")
  72. elseif params.driver == "MySQL" then
  73. sql = sql:gsub(";$", " CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';")
  74. end
  75. if not test_connection() then connect(); end
  76. -- do prepared statement stuff
  77. local stmt, err = connection:prepare(sql)
  78. if not stmt and not test_connection() then error("connection failed"); end
  79. if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end
  80. -- run query
  81. local ok, err = stmt:execute(...)
  82. if not ok and not test_connection() then error("connection failed"); end
  83. if not ok then return nil, err; end
  84.  
  85. return stmt
  86. end
  87.  
  88. local function get_password(username)
  89. local stmt, err = getsql("SELECT encrypted_password FROM users WHERE username = ?", username)
  90. if stmt then
  91. for row in stmt:rows(true) do
  92. return row.encrypted_password
  93. end
  94. end
  95. end
  96.  
  97. local function get_token(username)
  98. local stmt, err = getsql("SELECT authentication_token FROM users WHERE username = ?", username)
  99. if stmt then
  100. for row in stmt:rows(true) do
  101. return row.authentication_token
  102. end
  103. end
  104. end
  105.  
  106. local function test_password(username, password)
  107. -- pepper imported from diaspora/config/initializers/devise.rb
  108. local pepper = "065eb8798b181ff0ea2c5c16aee0ff8b70e04e2ee6bd6e08b49da46924223e39127d5335e466207d42bf2a045c12be5f90e92012a4f05f7fc6d9f3c875f4c95b"
  109. -- adding pepper to the regular password
  110. local pw_plus_pepper = password .. pepper
  111.  
  112. -- Getting password from Diaspora database
  113. local pw_stored = get_password(username)
  114.  
  115. -- Comparing password. If fail aborts
  116. return password and pw_stored and bcrypt.verify(pw_plus_pepper, pw_stored)
  117. end
  118.  
  119. local function test_token(username, token)
  120. local stored_token = get_token(username)
  121. return stored_token and token == stored_token
  122. end
  123.  
  124.  
  125. provider = {};
  126.  
  127. function provider.test_password(username, password)
  128. return test_password(username, password) or test_token(username, password)
  129. end
  130.  
  131. function provider.get_password(username)
  132. return get_password(username)
  133. end
  134.  
  135. function provider.set_password(username, password)
  136. return nil, "Setting password is not supported."
  137. end
  138.  
  139. function provider.user_exists(username)
  140. return get_password(username) and true
  141. end
  142.  
  143. function provider.create_user(username, password)
  144. return nil, "Account creation/modification not supported."
  145. end
  146.  
  147. function provider.get_sasl_handler()
  148. local profile = {
  149. plain_test = function(sasl, username, password, realm)
  150. return provider.test_password(username, password), true
  151. end
  152. }
  153. return new_sasl(module.host, profile)
  154. end
  155.  
  156. function provider.users()
  157. local stmt, err = getsql("SELECT username FROM users WHERE username != ''")
  158. if stmt then
  159. local next, state = stmt:rows(true)
  160. return function()
  161. for row in next, state do
  162. return row.username
  163. end
  164. end
  165. end
  166. return stmt, err
  167. end
  168.  
  169.  
  170. module:provides("auth", provider)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement