// Copyright © 2023 Ory Corp // SPDX-License-Identifier: Apache-2.0 package oidc import ( "context" "slices" gooidc "github.com/coreos/go-oidc/v3/oidc" "golang.org/x/oauth2" ) var _ OAuth2Provider = (*ProviderGoogle)(nil) type ProviderGoogle struct { *ProviderGenericOIDC JWKSUrl string } func NewProviderGoogle( config *Configuration, reg Dependencies, ) Provider { config.IssuerURL = "https://accounts.google.com" return &ProviderGoogle{ ProviderGenericOIDC: &ProviderGenericOIDC{ config: config, reg: reg, }, JWKSUrl: "https://www.googleapis.com/oauth2/v3/certs", } } func (g *ProviderGoogle) oauth2ConfigFromEndpoint(ctx context.Context, endpoint oauth2.Endpoint) *oauth2.Config { scope := g.config.Scope if !slices.Contains(scope, gooidc.ScopeOpenID) { scope = append(scope, gooidc.ScopeOpenID) } scope = slices.DeleteFunc(slices.Clone(scope), func(s string) bool { return s == gooidc.ScopeOfflineAccess }) return &oauth2.Config{ ClientID: g.config.ClientID, ClientSecret: g.config.ClientSecret, Endpoint: endpoint, Scopes: scope, RedirectURL: g.config.Redir(g.reg.Config().OIDCRedirectURIBase(ctx)), } } func (g *ProviderGoogle) OAuth2(ctx context.Context) (*oauth2.Config, error) { p, err := g.provider(ctx) if err != nil { return nil, err } endpoint := p.Endpoint() return g.oauth2ConfigFromEndpoint(ctx, endpoint), nil } func (g *ProviderGoogle) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption { scope := g.config.Scope options := g.ProviderGenericOIDC.AuthCodeURLOptions(r) if slices.Contains(scope, gooidc.ScopeOfflineAccess) { options = append(options, oauth2.AccessTypeOffline) } return options } var _ IDTokenVerifier = new(ProviderGoogle) const issuerURLGoogle = "https://accounts.google.com" func (g *ProviderGoogle) Verify(ctx context.Context, rawIDToken string) (*Claims, error) { keySet := gooidc.NewRemoteKeySet(ctx, g.JWKSUrl) ctx = gooidc.ClientContext(ctx, g.reg.HTTPClient(ctx).HTTPClient) return verifyToken(ctx, keySet, g.config, rawIDToken, issuerURLGoogle) } var _ NonceValidationSkipper = new(ProviderGoogle) func (g *ProviderGoogle) CanSkipNonce(c *Claims) bool { // Not all SDKs support nonce validation, so we skip it if no nonce is present in the claims of the ID Token. return c.Nonce == "" }