| 162 | .detail("Token", token.toStringRef(arena).toStringView()) |
| 163 | |
| 164 | bool TokenCacheImpl::validateAndAdd(double currentTime, StringRef token, NetworkAddress const& peer) { |
| 165 | Arena arena; |
| 166 | authz::jwt::TokenRef t; |
| 167 | if (!authz::jwt::parseToken(arena, t, token)) { |
| 168 | CODE_PROBE(true, "Token can't be parsed"); |
| 169 | TraceEvent(SevWarn, "InvalidToken") |
| 170 | .detail("From", peer) |
| 171 | .detail("Reason", "ParseError") |
| 172 | .detail("Token", token.toString()); |
| 173 | return false; |
| 174 | } |
| 175 | auto key = FlowTransport::transport().getPublicKeyByName(t.keyId); |
| 176 | if (!key.present()) { |
| 177 | CODE_PROBE(true, "Token referencing non-existing key"); |
| 178 | TRACE_INVALID_PARSED_TOKEN("UnknownKey", t); |
| 179 | return false; |
| 180 | } else if (!t.issuedAtUnixTime.present()) { |
| 181 | CODE_PROBE(true, "Token has no issued-at field"); |
| 182 | TRACE_INVALID_PARSED_TOKEN("NoIssuedAt", t); |
| 183 | return false; |
| 184 | } else if (!t.expiresAtUnixTime.present()) { |
| 185 | CODE_PROBE(true, "Token has no expiration time"); |
| 186 | TRACE_INVALID_PARSED_TOKEN("NoExpirationTime", t); |
| 187 | return false; |
| 188 | } else if (double(t.expiresAtUnixTime.get()) <= currentTime) { |
| 189 | CODE_PROBE(true, "Expired token"); |
| 190 | TRACE_INVALID_PARSED_TOKEN("Expired", t); |
| 191 | return false; |
| 192 | } else if (!t.notBeforeUnixTime.present()) { |
| 193 | CODE_PROBE(true, "Token has no not-before field"); |
| 194 | TRACE_INVALID_PARSED_TOKEN("NoNotBefore", t); |
| 195 | return false; |
| 196 | } else if (double(t.notBeforeUnixTime.get()) > currentTime) { |
| 197 | CODE_PROBE(true, "Tokens not-before is in the future"); |
| 198 | TRACE_INVALID_PARSED_TOKEN("TokenNotYetValid", t); |
| 199 | return false; |
| 200 | } else if (!t.tenants.present()) { |
| 201 | CODE_PROBE(true, "Token with no tenants"); |
| 202 | TRACE_INVALID_PARSED_TOKEN("NoTenants", t); |
| 203 | return false; |
| 204 | } else if (!authz::jwt::verifyToken(token, key.get())) { |
| 205 | CODE_PROBE(true, "Token with invalid signature"); |
| 206 | TRACE_INVALID_PARSED_TOKEN("InvalidSignature", t); |
| 207 | return false; |
| 208 | } else { |
| 209 | CacheEntry c; |
| 210 | c.expirationTime = t.expiresAtUnixTime.get(); |
| 211 | c.tenants.reserve(c.arena, t.tenants.get().size()); |
| 212 | for (auto tenant : t.tenants.get()) { |
| 213 | c.tenants.push_back_deep(c.arena, tenant); |
| 214 | } |
| 215 | cache.insert(StringRef(c.arena, token), c); |
| 216 | return true; |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | bool TokenCacheImpl::validate(TenantNameRef name, StringRef token) { |
| 221 | NetworkAddress peer = FlowTransport::transport().currentDeliveryPeerAddress(); |
nothing calls this directly
no test coverage detected