feat: google oauth

This commit is contained in:
Stavros
2025-01-24 16:29:21 +02:00
parent 433e71bd50
commit d4eca52b12
4 changed files with 88 additions and 29 deletions

View File

@@ -61,12 +61,11 @@ var rootCmd = &cobra.Command{
// Create OAuth config // Create OAuth config
oauthConfig := types.OAuthConfig{ oauthConfig := types.OAuthConfig{
GithubClientId: config.GithubClientId, GithubClientId: config.GithubClientId,
GithubClientSecret: config.GithubClientSecret, GithubClientSecret: config.GithubClientSecret,
GoogleClientId: config.GoogleClientId, GoogleClientId: config.GoogleClientId,
GoogleClientSecret: config.GoogleClientSecret, GoogleClientSecret: config.GoogleClientSecret,
MicrosoftClientId: config.MicrosoftClientId, AppURL: config.AppURL,
MicrosoftClientSecret: config.MicrosoftClientSecret,
} }
// Create auth service // Create auth service
@@ -128,8 +127,6 @@ func init() {
rootCmd.Flags().String("github-client-secret", "", "Github OAuth client secret.") rootCmd.Flags().String("github-client-secret", "", "Github OAuth client secret.")
rootCmd.Flags().String("google-client-id", "", "Google OAuth client ID.") rootCmd.Flags().String("google-client-id", "", "Google OAuth client ID.")
rootCmd.Flags().String("google-client-secret", "", "Google OAuth client secret.") rootCmd.Flags().String("google-client-secret", "", "Google OAuth client secret.")
rootCmd.Flags().String("microsoft-client-id", "", "Microsoft OAuth client ID.")
rootCmd.Flags().String("microsoft-client-secret", "", "Microsoft OAuth client secret.")
viper.BindEnv("port", "PORT") viper.BindEnv("port", "PORT")
viper.BindEnv("address", "ADDRESS") viper.BindEnv("address", "ADDRESS")
viper.BindEnv("secret", "SECRET") viper.BindEnv("secret", "SECRET")
@@ -141,7 +138,5 @@ func init() {
viper.BindEnv("github-client-secret", "GITHUB_CLIENT_SECRET") viper.BindEnv("github-client-secret", "GITHUB_CLIENT_SECRET")
viper.BindEnv("google-client-id", "GOOGLE_CLIENT_ID") viper.BindEnv("google-client-id", "GOOGLE_CLIENT_ID")
viper.BindEnv("google-client-secret", "GOOGLE_CLIENT_SECRET") viper.BindEnv("google-client-secret", "GOOGLE_CLIENT_SECRET")
viper.BindEnv("microsoft-client-id", "MICROSOFT_CLIENT_ID")
viper.BindEnv("microsoft-client-secret", "MICROSOFT_CLIENT_SECRET")
viper.BindPFlags(rootCmd.Flags()) viper.BindPFlags(rootCmd.Flags())
} }

View File

@@ -0,0 +1,39 @@
package providers
import (
"encoding/json"
"io"
"net/http"
)
type GoogleUserinfoResponse struct {
Email string `json:"email"`
}
func GoogleScopes() []string {
return []string{"https://www.googleapis.com/auth/userinfo.email"}
}
func GetGoogleEmail(client *http.Client) (string, error) {
res, resErr := client.Get("https://www.googleapis.com/userinfo/v2/me")
if resErr != nil {
return "", resErr
}
body, bodyErr := io.ReadAll(res.Body)
if bodyErr != nil {
return "", bodyErr
}
var user GoogleUserinfoResponse
jsonErr := json.Unmarshal(body, &user)
if jsonErr != nil {
return "", jsonErr
}
return user.Email, nil
}

View File

@@ -1,6 +1,7 @@
package providers package providers
import ( import (
"fmt"
"tinyauth/internal/oauth" "tinyauth/internal/oauth"
"tinyauth/internal/types" "tinyauth/internal/types"
@@ -28,17 +29,31 @@ func (providers *Providers) Init() {
providers.Github = oauth.NewOAuth(oauth2.Config{ providers.Github = oauth.NewOAuth(oauth2.Config{
ClientID: providers.Config.GithubClientId, ClientID: providers.Config.GithubClientId,
ClientSecret: providers.Config.GithubClientSecret, ClientSecret: providers.Config.GithubClientSecret,
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/github", providers.Config.AppURL),
Scopes: GithubScopes(), Scopes: GithubScopes(),
Endpoint: endpoints.GitHub, Endpoint: endpoints.GitHub,
}) })
providers.Github.Init() providers.Github.Init()
} }
if providers.Config.GoogleClientId != "" && providers.Config.GoogleClientSecret != "" {
log.Info().Msg("Initializing Google OAuth")
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,
})
providers.Google.Init()
}
} }
func (providers *Providers) GetProvider(provider string) *oauth.OAuth { func (providers *Providers) GetProvider(provider string) *oauth.OAuth {
switch provider { switch provider {
case "github": case "github":
return providers.Github return providers.Github
case "google":
return providers.Google
default: default:
return nil return nil
} }
@@ -56,6 +71,16 @@ func (providers *Providers) GetUser(provider string) (string, error) {
return "", emailErr return "", emailErr
} }
return email, nil return email, nil
case "google":
if providers.Google == nil {
return "", nil
}
client := providers.Google.GetClient()
email, emailErr := GetGoogleEmail(client)
if emailErr != nil {
return "", emailErr
}
return email, nil
default: default:
return "", nil return "", nil
} }
@@ -66,5 +91,8 @@ func (provider *Providers) GetConfiguredProviders() []string {
if provider.Github != nil { if provider.Github != nil {
providers = append(providers, "github") providers = append(providers, "github")
} }
if provider.Google != nil {
providers = append(providers, "google")
}
return providers return providers
} }

View File

@@ -19,19 +19,17 @@ type User struct {
type Users []User type Users []User
type Config struct { type Config struct {
Port int `validate:"number" mapstructure:"port"` Port int `validate:"number" mapstructure:"port"`
Address string `mapstructure:"address, ip4_addr"` Address string `mapstructure:"address, ip4_addr"`
Secret string `validate:"required,len=32" mapstructure:"secret"` Secret string `validate:"required,len=32" mapstructure:"secret"`
AppURL string `validate:"required,url" mapstructure:"app-url"` AppURL string `validate:"required,url" mapstructure:"app-url"`
Users string `mapstructure:"users"` Users string `mapstructure:"users"`
UsersFile string `mapstructure:"users-file"` UsersFile string `mapstructure:"users-file"`
CookieSecure bool `mapstructure:"cookie-secure"` CookieSecure bool `mapstructure:"cookie-secure"`
GithubClientId string `mapstructure:"github-client-id"` GithubClientId string `mapstructure:"github-client-id"`
GithubClientSecret string `mapstructure:"github-client-secret"` GithubClientSecret string `mapstructure:"github-client-secret"`
GoogleClientId string `mapstructure:"google-client-id"` GoogleClientId string `mapstructure:"google-client-id"`
GoogleClientSecret string `mapstructure:"google-client-secret"` GoogleClientSecret string `mapstructure:"google-client-secret"`
MicrosoftClientId string `mapstructure:"microsoft-client-id"`
MicrosoftClientSecret string `mapstructure:"microsoft-client-secret"`
} }
type UserContext struct { type UserContext struct {
@@ -50,12 +48,11 @@ type APIConfig struct {
} }
type OAuthConfig struct { type OAuthConfig struct {
GithubClientId string GithubClientId string
GithubClientSecret string GithubClientSecret string
GoogleClientId string GoogleClientId string
GoogleClientSecret string GoogleClientSecret string
MicrosoftClientId string AppURL string
MicrosoftClientSecret string
} }
type OAuthRequest struct { type OAuthRequest struct {