initial commit

This commit is contained in:
m.zare
2026-04-10 18:25:21 +03:30
commit 77ca6c34a3
263 changed files with 34470 additions and 0 deletions

119
internal/pkg/oauth/oauth.go Normal file
View 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
}