initial commit
This commit is contained in:
119
internal/pkg/oauth/oauth.go
Normal file
119
internal/pkg/oauth/oauth.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"base/config"
|
||||
|
||||
"base/internal/pkg/oauth/github"
|
||||
"base/internal/pkg/oauth/google"
|
||||
"base/internal/pkg/oauth/linkedin"
|
||||
"base/internal/pkg/oauth/mock"
|
||||
"base/internal/pkg/oauth/types"
|
||||
)
|
||||
|
||||
// Token is an alias for types.Token for backward compatibility
|
||||
type Token = types.Token
|
||||
|
||||
type OAuth struct {
|
||||
google types.Oauth
|
||||
linkedin types.Oauth
|
||||
github types.Oauth
|
||||
mock types.Oauth
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
GoogleConfig oauth2.Config
|
||||
GitHubConfig oauth2.Config
|
||||
LinkedinConfig oauth2.Config
|
||||
}
|
||||
|
||||
func New(cfg *config.AppConfig) OAuth {
|
||||
oauthConfig := Config{
|
||||
GoogleConfig: oauth2.Config{
|
||||
ClientID: cfg.OAuth.Google.ClientID,
|
||||
ClientSecret: cfg.OAuth.Google.ClientSecret,
|
||||
RedirectURL: cfg.OAuth.Google.RedirectURL,
|
||||
Scopes: cfg.OAuth.Google.Scopes,
|
||||
},
|
||||
GitHubConfig: oauth2.Config{
|
||||
ClientID: cfg.OAuth.GitHub.ClientID,
|
||||
ClientSecret: cfg.OAuth.GitHub.ClientSecret,
|
||||
RedirectURL: cfg.OAuth.GitHub.RedirectURL,
|
||||
Scopes: cfg.OAuth.GitHub.Scopes,
|
||||
},
|
||||
LinkedinConfig: oauth2.Config{
|
||||
ClientID: cfg.OAuth.LinkedIn.ClientID,
|
||||
ClientSecret: cfg.OAuth.LinkedIn.ClientSecret,
|
||||
RedirectURL: cfg.OAuth.LinkedIn.RedirectURL,
|
||||
Scopes: cfg.OAuth.LinkedIn.Scopes,
|
||||
},
|
||||
}
|
||||
|
||||
o := OAuth{
|
||||
google: google.New(oauthConfig.GoogleConfig),
|
||||
linkedin: linkedin.New(oauthConfig.LinkedinConfig),
|
||||
github: github.New(oauthConfig.GitHubConfig),
|
||||
}
|
||||
|
||||
if cfg.OAuth.Mock.Enabled && strings.TrimSpace(cfg.OAuth.Mock.BaseURL) != "" {
|
||||
baseURL := strings.TrimSuffix(strings.TrimSpace(cfg.OAuth.Mock.BaseURL), "/")
|
||||
mockConfig := oauth2.Config{
|
||||
ClientID: cfg.OAuth.Mock.ClientID,
|
||||
ClientSecret: cfg.OAuth.Mock.ClientSecret,
|
||||
RedirectURL: cfg.OAuth.Mock.RedirectURL,
|
||||
Scopes: cfg.OAuth.Mock.Scopes,
|
||||
}
|
||||
if mockConfig.ClientID == "" {
|
||||
mockConfig.ClientID = "mock-client"
|
||||
}
|
||||
if mockConfig.ClientSecret == "" {
|
||||
mockConfig.ClientSecret = "mock-secret"
|
||||
}
|
||||
if mockConfig.RedirectURL == "" {
|
||||
mockConfig.RedirectURL = "http://localhost:3000/auth/callback"
|
||||
}
|
||||
o.mock = mock.New(mockConfig, baseURL)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (a OAuth) Client(provider Provider) types.Oauth {
|
||||
switch provider {
|
||||
case Google:
|
||||
return a.google
|
||||
case Linkedin:
|
||||
return a.linkedin
|
||||
case GitHub:
|
||||
return a.github
|
||||
case Mock:
|
||||
if a.mock != nil {
|
||||
return a.mock
|
||||
}
|
||||
return disabledMockClient{}
|
||||
default:
|
||||
return a.google
|
||||
}
|
||||
}
|
||||
|
||||
// ErrMockNotEnabled is returned when mock provider is used but not configured
|
||||
var ErrMockNotEnabled = errors.New("oauth mock is not enabled - set oauth.mock.enabled=true and oauth.mock.base_url")
|
||||
|
||||
// disabledMockClient is used when mock is requested but not configured
|
||||
type disabledMockClient struct{}
|
||||
|
||||
func (disabledMockClient) GetConsentAuthUrl(_ context.Context, _ string) string {
|
||||
panic("oauth mock is not enabled - set oauth.mock.enabled=true and oauth.mock.base_url")
|
||||
}
|
||||
|
||||
func (disabledMockClient) ExchangeCodeWithToken(context.Context, string) (*types.Token, error) {
|
||||
return nil, ErrMockNotEnabled
|
||||
}
|
||||
|
||||
func (disabledMockClient) GetUserInfo(context.Context, string, string) (types.UserInfo, error) {
|
||||
return nil, ErrMockNotEnabled
|
||||
}
|
||||
Reference in New Issue
Block a user