Comparison

plugins/mod_tokenauth.lua @ 13638:94462d8f2fa9

mod_tokenauth: Fix expiry lasting one second too much Because the code was using `< now` in a lot of places, things expiring at the current second wouldn't be marked as expired. It isn't noticeable in real-world scenarios but I wanted to create OAuth 2.0 tokens valid for 0 second in integration tests and it wasn't possible. By using `<=` instead of `<`, we make sure tokens don't live a single millisecond more than what they are supposed to.
author Rémi Bardon <remi@remibardon.name>
date Sat, 01 Feb 2025 20:45:28 +0100
parent 13356:bbbda8819331
comparison
equal deleted inserted replaced
13637:c9e11007f10d 13638:94462d8f2fa9
131 local function clear_expired_grant_tokens(grant, now) 131 local function clear_expired_grant_tokens(grant, now)
132 local updated; 132 local updated;
133 now = now or os.time(); 133 now = now or os.time();
134 for secret, token_info in pairs(grant.tokens) do 134 for secret, token_info in pairs(grant.tokens) do
135 local expires = token_info.expires; 135 local expires = token_info.expires;
136 if expires and expires < now then 136 if expires and expires <= now then
137 grant.tokens[secret] = nil; 137 grant.tokens[secret] = nil;
138 updated = true; 138 updated = true;
139 end 139 end
140 end 140 end
141 return updated; 141 return updated;
153 local now = os.time(); 153 local now = os.time();
154 if password_updated_at and grant.created < password_updated_at then 154 if password_updated_at and grant.created < password_updated_at then
155 module:log("debug", "Token grant %s of %s issued before last password change, invalidating it now", grant.id, username); 155 module:log("debug", "Token grant %s of %s issued before last password change, invalidating it now", grant.id, username);
156 token_store:set_key(username, grant.id, nil); 156 token_store:set_key(username, grant.id, nil);
157 return nil, "not-authorized"; 157 return nil, "not-authorized";
158 elseif grant.expires and grant.expires < now then 158 elseif grant.expires and grant.expires <= now then
159 module:log("debug", "Token grant %s of %s expired, cleaning up", grant.id, username); 159 module:log("debug", "Token grant %s of %s expired, cleaning up", grant.id, username);
160 token_store:set_key(username, grant.id, nil); 160 token_store:set_key(username, grant.id, nil);
161 return nil, "expired"; 161 return nil, "expired";
162 end 162 end
163 163
167 return nil, "invalid"; 167 return nil, "invalid";
168 end 168 end
169 169
170 local found_expired = false 170 local found_expired = false
171 for secret_hash, token_info in pairs(grant.tokens) do 171 for secret_hash, token_info in pairs(grant.tokens) do
172 if token_info.expires and token_info.expires < now then 172 if token_info.expires and token_info.expires <= now then
173 module:log("debug", "Token %s of grant %s of %s has expired, cleaning it up", secret_hash:sub(-8), grant.id, username); 173 module:log("debug", "Token %s of grant %s of %s has expired, cleaning it up", secret_hash:sub(-8), grant.id, username);
174 grant.tokens[secret_hash] = nil; 174 grant.tokens[secret_hash] = nil;
175 found_expired = true; 175 found_expired = true;
176 end 176 end
177 end 177 end
178 178
179 if not grant.expires and next(grant.tokens) == nil and grant.accessed + empty_grant_lifetime < now then 179 if not grant.expires and next(grant.tokens) == nil and grant.accessed + empty_grant_lifetime <= now then
180 module:log("debug", "Token %s of %s grant has no tokens, discarding", grant.id, username); 180 module:log("debug", "Token %s of %s grant has no tokens, discarding", grant.id, username);
181 token_store:set_key(username, grant.id, nil); 181 token_store:set_key(username, grant.id, nil);
182 return nil, "expired"; 182 return nil, "expired";
183 elseif found_expired then 183 elseif found_expired then
184 token_store:set_key(username, grant.id, grant); 184 token_store:set_key(username, grant.id, grant);
210 return nil, "not-authorized"; 210 return nil, "not-authorized";
211 end 211 end
212 212
213 -- Check expiry 213 -- Check expiry
214 local now = os.time(); 214 local now = os.time();
215 if token_info.expires and token_info.expires < now then 215 if token_info.expires and token_info.expires <= now then
216 module:log("debug", "Token has expired, cleaning it up"); 216 module:log("debug", "Token has expired, cleaning it up");
217 grant.tokens[secret_hash] = nil; 217 grant.tokens[secret_hash] = nil;
218 token_store:set_key(token_user, token_id, grant); 218 token_store:set_key(token_user, token_id, grant);
219 return nil, "not-authorized"; 219 return nil, "not-authorized";
220 end 220 end