Software /
code /
prosody
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 |