Files
tinyauth/internal/providers/providers.go
Stavros a9e8bf89a9 feat: map info from OIDC claims to headers (#122)
* refactor: return all values from body in the providers

* refactor: only accept claims following the OIDC spec

* feat: map info from OIDC claims to headers

* feat: add support for required oauth groups

* fix: bot suggestions

* feat: get claims from github and google

* fix: close body correctly
2025-04-30 19:57:49 +03:00

194 lines
5.1 KiB
Go

package providers
import (
"fmt"
"tinyauth/internal/constants"
"tinyauth/internal/oauth"
"tinyauth/internal/types"
"github.com/rs/zerolog/log"
"golang.org/x/oauth2"
"golang.org/x/oauth2/endpoints"
)
func NewProviders(config types.OAuthConfig) *Providers {
return &Providers{
Config: config,
}
}
type Providers struct {
Config types.OAuthConfig
Github *oauth.OAuth
Google *oauth.OAuth
Generic *oauth.OAuth
}
func (providers *Providers) Init() {
// If we have a client id and secret for github, initialize the oauth provider
if providers.Config.GithubClientId != "" && providers.Config.GithubClientSecret != "" {
log.Info().Msg("Initializing Github OAuth")
// Create a new oauth provider with the github config
providers.Github = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.GithubClientId,
ClientSecret: providers.Config.GithubClientSecret,
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/github", providers.Config.AppURL),
Scopes: GithubScopes(),
Endpoint: endpoints.GitHub,
})
// Initialize the oauth provider
providers.Github.Init()
}
// If we have a client id and secret for google, initialize the oauth provider
if providers.Config.GoogleClientId != "" && providers.Config.GoogleClientSecret != "" {
log.Info().Msg("Initializing Google OAuth")
// Create a new oauth provider with the google config
providers.Google = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.GoogleClientId,
ClientSecret: providers.Config.GoogleClientSecret,
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/google", providers.Config.AppURL),
Scopes: GoogleScopes(),
Endpoint: endpoints.Google,
})
// Initialize the oauth provider
providers.Google.Init()
}
// If we have a client id and secret for generic oauth, initialize the oauth provider
if providers.Config.GenericClientId != "" && providers.Config.GenericClientSecret != "" {
log.Info().Msg("Initializing Generic OAuth")
// Create a new oauth provider with the generic config
providers.Generic = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.GenericClientId,
ClientSecret: providers.Config.GenericClientSecret,
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/generic", providers.Config.AppURL),
Scopes: providers.Config.GenericScopes,
Endpoint: oauth2.Endpoint{
AuthURL: providers.Config.GenericAuthURL,
TokenURL: providers.Config.GenericTokenURL,
},
})
// Initialize the oauth provider
providers.Generic.Init()
}
}
func (providers *Providers) GetProvider(provider string) *oauth.OAuth {
// Return the provider based on the provider string
switch provider {
case "github":
return providers.Github
case "google":
return providers.Google
case "generic":
return providers.Generic
default:
return nil
}
}
func (providers *Providers) GetUser(provider string) (constants.Claims, error) {
// Create user struct
var user constants.Claims
// Get the user from the provider
switch provider {
case "github":
// If the github provider is not configured, return an error
if providers.Github == nil {
log.Debug().Msg("Github provider not configured")
return user, nil
}
// Get the client from the github provider
client := providers.Github.GetClient()
log.Debug().Msg("Got client from github")
// Get the user from the github provider
user, err := GetGithubUser(client)
// Check if there was an error
if err != nil {
return user, err
}
log.Debug().Msg("Got user from github")
// Return the user
return user, nil
case "google":
// If the google provider is not configured, return an error
if providers.Google == nil {
log.Debug().Msg("Google provider not configured")
return user, nil
}
// Get the client from the google provider
client := providers.Google.GetClient()
log.Debug().Msg("Got client from google")
// Get the user from the google provider
user, err := GetGoogleUser(client)
// Check if there was an error
if err != nil {
return user, err
}
log.Debug().Msg("Got user from google")
// Return the user
return user, nil
case "generic":
// If the generic provider is not configured, return an error
if providers.Generic == nil {
log.Debug().Msg("Generic provider not configured")
return user, nil
}
// Get the client from the generic provider
client := providers.Generic.GetClient()
log.Debug().Msg("Got client from generic")
// Get the user from the generic provider
user, err := GetGenericUser(client, providers.Config.GenericUserURL)
// Check if there was an error
if err != nil {
return user, err
}
log.Debug().Msg("Got user from generic")
// Return the email
return user, nil
default:
return user, nil
}
}
func (provider *Providers) GetConfiguredProviders() []string {
// Create a list of the configured providers
providers := []string{}
if provider.Github != nil {
providers = append(providers, "github")
}
if provider.Google != nil {
providers = append(providers, "google")
}
if provider.Generic != nil {
providers = append(providers, "generic")
}
return providers
}