Mercurial > prosody-hg
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 |
| parents | bbbda8819331 |
| children |
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 |
