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.

util.lib.lua 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. -- Token authentication
  2. -- Copyright (C) 2015 Atlassian
  3. local hashes = require "util.hashes";
  4. local _M = {};
  5. local function calc_hash(password, appId, appSecret)
  6. local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
  7. if hash ~= nil and room ~= nil and ts ~= nil then
  8. log("debug", "Hash: '%s' room: '%s', ts: '%s'", hash, room, ts);
  9. local toHash = room .. ts .. appId .. appSecret;
  10. log("debug", "to be hashed: '%s'", toHash);
  11. local hash = hashes.sha256(toHash, true);
  12. log("debug", "hash: '%s'", hash);
  13. return hash;
  14. else
  15. log("error", "Invalid password format: '%s'", password);
  16. return nil;
  17. end
  18. end
  19. local function extract_hash(password)
  20. local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
  21. return hash;
  22. end
  23. local function extract_ts(password)
  24. local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
  25. return ts;
  26. end
  27. local function get_utc_timestamp()
  28. return os.time(os.date("!*t")) * 1000;
  29. end
  30. local function verify_timestamp(ts, tokenLifetime)
  31. return get_utc_timestamp() - ts <= tokenLifetime;
  32. end
  33. local function verify_password_impl(password, appId, appSecret, tokenLifetime)
  34. if password == nil then
  35. return nil, "password is missing";
  36. end
  37. if tokenLifetime == nil then
  38. tokenLifetime = 24 * 60 * 60 * 1000;
  39. end
  40. local ts = extract_ts(password);
  41. if ts == nil then
  42. return nil, "timestamp not found in the password";
  43. end
  44. local os_ts = get_utc_timestamp();
  45. log("debug", "System TS: '%s' user TS: %s", tostring(os_ts), tostring(ts));
  46. local isValid = verify_timestamp(ts, tokenLifetime);
  47. if not isValid then
  48. return nil, "token expired";
  49. end
  50. local realHash = calc_hash(password, appId, appSecret);
  51. local givenhash = extract_hash(password);
  52. log("debug", "Compare '%s' to '%s'", tostring(realHash), tostring(givenhash));
  53. if realHash == givenhash then
  54. return true;
  55. else
  56. return nil, "invalid hash";
  57. end
  58. end
  59. function _M.verify_password(password, appId, appSecret, tokenLifetime)
  60. return verify_password_impl(password, appId, appSecret, tokenLifetime);
  61. end
  62. return _M;