fetchCustomProviderConfig collects the provider configuration from the given discovery endpoint and determines whether the cached configuration needs to be refreshed by comparing the new metadata with the cached value
(ctx context.Context, discoveryURL string)
| 468 | // fetchCustomProviderConfig collects the provider configuration from the given discovery endpoint and determines |
| 469 | // whether the cached configuration needs to be refreshed by comparing the new metadata with the cached value |
| 470 | func (op *OIDCProvider) fetchCustomProviderConfig(ctx context.Context, discoveryURL string) (metadata ProviderMetadata, ttl time.Duration, refresh bool, err error) { |
| 471 | if discoveryURL == "" { |
| 472 | return ProviderMetadata{}, MaxProviderConfigSyncInterval, false, ErrEmptyDiscoveryURL |
| 473 | } |
| 474 | base.DebugfCtx(ctx, base.KeyAuth, "Fetching custom provider config from %s", base.UD(discoveryURL)) |
| 475 | req, err := http.NewRequest(http.MethodGet, discoveryURL, nil) |
| 476 | if err != nil { |
| 477 | base.InfofCtx(ctx, base.KeyAuth, "Error building new request for URL %s: %v", base.UD(discoveryURL), err) |
| 478 | return ProviderMetadata{}, MaxProviderConfigSyncInterval, false, err |
| 479 | } |
| 480 | client := base.GetHttpClient(op.InsecureSkipVerify) |
| 481 | resp, err := client.Do(req) |
| 482 | if err != nil { |
| 483 | base.InfofCtx(ctx, base.KeyAuth, "Error invoking calling discovery URL %s: %v", base.UD(discoveryURL), err) |
| 484 | return ProviderMetadata{}, MaxProviderConfigSyncInterval, false, err |
| 485 | } |
| 486 | |
| 487 | defer func() { |
| 488 | _ = resp.Body.Close() |
| 489 | }() |
| 490 | if resp.StatusCode != http.StatusOK { |
| 491 | body, err := io.ReadAll(resp.Body) |
| 492 | if err != nil { |
| 493 | err = fmt.Errorf("unsuccessful response and could not read returned response body: %w", err) |
| 494 | } else { |
| 495 | err = fmt.Errorf("unsuccessful response: %v", body) |
| 496 | } |
| 497 | return ProviderMetadata{}, MaxProviderConfigSyncInterval, false, err |
| 498 | } |
| 499 | |
| 500 | ttl, _, err = cacheable(resp.Header) |
| 501 | if err != nil { |
| 502 | base.InfofCtx(ctx, base.KeyAuth, "Failed to determine whether provider metadata can be cached, error: %v", err) |
| 503 | } |
| 504 | |
| 505 | // If the metadata expiry is zero or greater than 24 hours, the next sync should start in 24 hours. |
| 506 | if ttl == 0 || ttl > MaxProviderConfigSyncInterval { |
| 507 | ttl = MaxProviderConfigSyncInterval |
| 508 | } |
| 509 | // If the expiry is less than 1 minute, the next sync should start in the next minute. |
| 510 | if ttl < MinProviderConfigSyncInterval { |
| 511 | ttl = MinProviderConfigSyncInterval |
| 512 | } |
| 513 | |
| 514 | bodyBytes, err := io.ReadAll(resp.Body) |
| 515 | if err != nil { |
| 516 | return ProviderMetadata{}, MaxProviderConfigSyncInterval, false, err |
| 517 | } |
| 518 | |
| 519 | if err := base.JSONUnmarshal(bodyBytes, &metadata); err != nil { |
| 520 | err = base.ErrInvalidJSON |
| 521 | base.InfofCtx(ctx, base.KeyAuth, "Error parsing body during discovery sync: %v", err) |
| 522 | return ProviderMetadata{}, MaxProviderConfigSyncInterval, false, err |
| 523 | } |
| 524 | |
| 525 | if reflect.DeepEqual(op.metadata, metadata) { |
| 526 | base.InfofCtx(ctx, base.KeyAuth, "No change in discovery config detected at this time, next sync will be after %v", ttl) |
| 527 | return metadata, ttl, false, nil |