src/web/usercookie.lua

changeset 0
6279a7d40ae7
equal deleted inserted replaced
-1:000000000000 0:6279a7d40ae7
1 local hmac_sha256 = require"util.hashes".hmac_sha256;
2 local base64_encode = require"util.encodings".base64.encode;
3 local base64_decode = require"util.encodings".base64.decode;
4 local datetime = require"util.datetime";
5 local t_insert = table.insert;
6
7 local function generate(user, expires, key)
8 local data = ("%s %s"):format(datetime.date(expires), user);
9 local signature = hmac_sha256(key, data);
10 return base64_encode(data .. signature);
11 end
12
13 local function verify(cookie, key)
14 if not cookie then
15 return nil, "no value";
16 end
17 cookie = base64_decode(cookie);
18 if not cookie then
19 return nil, "invalid armor";
20 end
21 local data = cookie:sub(1, -33)
22 if cookie:sub(-32) ~= hmac_sha256(key, data) then
23 return nil, "invalid signature";
24 end
25 if data < datetime.date() then
26 return nil, "expired";
27 end
28 return data:sub(12); -- Strip date
29 end
30
31 local function cookiedecode(s)
32 local r = {};
33 if not s then return r; end
34 for k, v in s:gmatch("([%w!#$%%&'*+%-.^_`|~]+)=\"?([%w!#-+--/:<-@%]-`_]+)\"?") do
35 r[k] = v;
36 t_insert(r, { name = k, value = v });
37 end
38 return r;
39 end
40
41 return {
42 decode = cookiedecode;
43 generate = generate;
44 verify = verify;
45 };

mercurial