Uses JWT for token generation in prosody plugin.

This commit is contained in:
paweldomas
2015-11-18 12:49:36 -06:00
parent 029ccf3b31
commit d666fbb6a4
3 changed files with 35 additions and 65 deletions

View File

@@ -1,76 +1,38 @@
-- Token authentication
-- Copyright (C) 2015 Atlassian
local hashes = require "util.hashes";
local jwt = require "luajwt";
local _M = {};
local function calc_hash(password, appId, appSecret)
local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
if hash ~= nil and room ~= nil and ts ~= nil then
log("debug", "Hash: '%s' room: '%s', ts: '%s'", hash, room, ts);
local toHash = room .. ts .. appId .. appSecret;
log("debug", "to be hashed: '%s'", toHash);
local hash = hashes.sha256(toHash, true);
log("debug", "hash: '%s'", hash);
return hash;
else
log("error", "Invalid password format: '%s'", password);
return nil;
end
end
local function verify_password_impl(password, appId, appSecret, roomName)
local function extract_hash(password)
local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
return hash;
end
local function extract_ts(password)
local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
return ts;
end
local function get_utc_timestamp()
return os.time(os.date("!*t")) * 1000;
end
local function verify_timestamp(ts, tokenLifetime)
return get_utc_timestamp() - ts <= tokenLifetime;
end
local function verify_password_impl(password, appId, appSecret, tokenLifetime)
if password == nil then
return nil, "password is missing";
end
if tokenLifetime == nil then
tokenLifetime = 24 * 60 * 60 * 1000;
local claims, err = jwt.decode(password, appSecret, true);
if claims == nil then
return nil, err;
end
local ts = extract_ts(password);
if ts == nil then
return nil, "timestamp not found in the password";
local issClaim = claims["iss"];
if issClaim == nil then
return nil, "Issuer field is missing";
end
local os_ts = get_utc_timestamp();
log("debug", "System TS: '%s' user TS: %s", tostring(os_ts), tostring(ts));
local isValid = verify_timestamp(ts, tokenLifetime);
if not isValid then
return nil, "token expired";
if issClaim ~= appId then
return nil, "Invalid application ID('iss' claim)";
end
local realHash = calc_hash(password, appId, appSecret);
local givenhash = extract_hash(password);
log("debug", "Compare '%s' to '%s'", tostring(realHash), tostring(givenhash));
if realHash == givenhash then
return true;
else
return nil, "invalid hash";
local roomClaim = claims["room"];
if roomClaim == nil then
return nil, "Room field is missing";
end
if roomName ~= nil and roomName ~= roomClaim then
return nil, "Invalid room name('room' claim)";
end
return true;
end
function _M.verify_password(password, appId, appSecret, tokenLifetime)
return verify_password_impl(password, appId, appSecret, tokenLifetime);
function _M.verify_password(password, appId, appSecret, roomName)
return verify_password_impl(password, appId, appSecret, roomName);
end
return _M;