social

package
v0.0.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2026 License: Apache-2.0 Imports: 36 Imported by: 0

README

Social OAuth Plugin

Enterprise-grade social authentication plugin for AuthSome, providing OAuth 2.0 integration with popular identity providers.

Features

Multi-Provider Support

  • Google, GitHub, Facebook, Microsoft, Apple, and more
  • Extensible provider system
  • Dynamic provider configuration per app

Account Management

  • OAuth sign-in and sign-up
  • Account linking (multiple providers per user)
  • Account unlinking
  • Provider discovery

Enterprise Features

  • Redis-backed OAuth state storage
  • Distributed rate limiting
  • Comprehensive audit logging
  • Multi-tenancy support (apps & orgs)
  • CSRF protection via state tokens
  • Email verification checks

Production Ready

  • Type-safe request/response handling
  • Graceful error handling
  • Connection pooling
  • Horizontal scaling support
  • Zero-downtime configuration updates

Quick Start

1. Configure Providers
auth:
  social:
    baseUrl: "https://your-domain.com"
    allowAccountLinking: true
    autoCreateUser: true
    requireEmailVerified: false
    trustEmailVerified: true
    
    # State storage configuration
    stateStorage:
      useRedis: true
      redisAddr: "localhost:6379"
      redisPassword: ""
      redisDb: 0
      stateTtl: "15m"
    
    # Provider configurations
    providers:
      google:
        clientId: "${GOOGLE_CLIENT_ID}"
        clientSecret: "${GOOGLE_CLIENT_SECRET}"
        redirectUrl: "https://your-domain.com/api/auth/callback/google"
        scopes: ["email", "profile"]
        enabled: true
        
      github:
        clientId: "${GITHUB_CLIENT_ID}"
        clientSecret: "${GITHUB_CLIENT_SECRET}"
        redirectUrl: "https://your-domain.com/api/auth/callback/github"
        scopes: ["user:email"]
        enabled: true
2. Register Plugin
import (
    "github.com/xraph/authsome"
    "github.com/xraph/authsome/plugins/social"
    "github.com/xraph/authsome/plugins/social/providers"
)

// Create AuthSome instance
auth := authsome.New(db, config)

// Create and register social plugin
socialPlugin := social.NewPlugin(
    social.WithProvider("google", 
        os.Getenv("GOOGLE_CLIENT_ID"),
        os.Getenv("GOOGLE_CLIENT_SECRET"),
        "https://your-domain.com/api/auth/callback/google",
        []string{"email", "profile"},
    ),
    social.WithAutoCreateUser(true),
    social.WithAllowLinking(true),
    social.WithTrustEmailVerified(true),
)

auth.RegisterPlugin(socialPlugin)
3. Use in Application
Sign In with Google
POST /api/auth/signin/social
Content-Type: application/json

{
  "provider": "google",
  "scopes": ["email", "profile"],
  "redirectUrl": "https://app.example.com/auth/callback"
}

# Response
{
  "url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=..."
}
OAuth Callback
GET /api/auth/callback/google?code=xxx&state=yyy

# Response
{
  "user": {
    "id": "c9h7b3j2k1m4n5p6",
    "email": "user@example.com",
    "emailVerified": true,
    "name": "John Doe"
  },
  "isNewUser": true,
  "action": "signup"
}
POST /api/auth/account/link
Content-Type: application/json
X-User-ID: c9h7b3j2k1m4n5p6

{
  "provider": "github",
  "scopes": ["user:email"]
}

# Response
{
  "url": "https://github.com/login/oauth/authorize?..."
}
DELETE /api/auth/account/unlink/github
X-User-ID: c9h7b3j2k1m4n5p6

# Response
{
  "message": "Account unlinked successfully"
}
List Providers
GET /api/auth/providers

# Response
{
  "providers": ["google", "github", "facebook"]
}

Architecture

State Management

OAuth state tokens are stored for CSRF protection and callback validation:

  • Development: In-memory storage (single instance)
  • Production: Redis-backed storage (distributed)
  • TTL: 15 minutes (configurable)
  • One-time use: State deleted after verification
type StateStore interface {
    Set(ctx context.Context, key string, state *OAuthState, ttl time.Duration) error
    Get(ctx context.Context, key string) (*OAuthState, error)
    Delete(ctx context.Context, key string) error
}
Rate Limiting

Distributed rate limiting via Redis:

Action Limit Window
oauth_signin 10 requests 1 minute
oauth_callback 20 requests 1 minute
oauth_link 5 requests 1 minute
oauth_unlink 5 requests 1 minute

Rate limits are customizable:

rateLimiter.SetLimit("oauth_signin", 20, 2*time.Minute)
Audit Logging

Comprehensive audit events:

  • social_signin_initiated - OAuth flow started
  • social_callback_received - Callback received
  • social_state_invalid - Invalid/expired state
  • social_token_exchange_success - Token exchanged
  • social_userinfo_fetched - User info retrieved
  • social_link_initiated - Account linking started
  • social_provider_not_found - Provider not configured

Supported Providers

Built-in Providers
  • ✅ Google
  • ✅ GitHub
  • ✅ Facebook
  • ✅ Microsoft
  • ✅ Apple
  • ✅ Twitter/X
  • ✅ LinkedIn
  • ✅ Discord
Adding Custom Providers
package providers

import (
    "context"
    "golang.org/x/oauth2"
)

type CustomProvider struct {
    config *oauth2.Config
}

func NewCustomProvider(config *ProviderConfig) Provider {
    return &CustomProvider{
        config: &oauth2.Config{
            ClientID:     config.ClientID,
            ClientSecret: config.ClientSecret,
            RedirectURL:  config.RedirectURL,
            Scopes:       config.Scopes,
            Endpoint: oauth2.Endpoint{
                AuthURL:  "https://provider.com/oauth/authorize",
                TokenURL: "https://provider.com/oauth/token",
            },
        },
    }
}

func (p *CustomProvider) GetOAuth2Config() *oauth2.Config {
    return p.config
}

func (p *CustomProvider) GetUserInfo(ctx context.Context, token *oauth2.Token) (*UserInfo, error) {
    // Fetch user info from provider API
    // ...
    return &UserInfo{
        ProviderUserID: "...",
        Email:          "...",
        EmailVerified:  true,
        Name:           "...",
        Picture:        "...",
    }, nil
}

Configuration Options

Plugin Configuration
Option Type Default Description
baseUrl string http://localhost:3000 Base URL for OAuth callbacks
allowAccountLinking bool true Allow users to link multiple providers
autoCreateUser bool true Auto-create user on OAuth sign-in
requireEmailVerified bool false Require email verification from provider
trustEmailVerified bool true Trust email verification from provider
State Storage Configuration
Option Type Default Description
useRedis bool false Use Redis for state storage
redisAddr string localhost:6379 Redis server address
redisPassword string "" Redis password
redisDb int 0 Redis database number
stateTtl duration 15m State expiration time
Provider Configuration
Option Type Required Description
clientId string OAuth client ID
clientSecret string OAuth client secret
redirectUrl string OAuth callback URL
scopes []string OAuth scopes (default: provider-specific)
enabled bool Enable/disable provider (default: true)

Security

CSRF Protection
  • Crypto-secure random state tokens (32 bytes)
  • One-time use state tokens
  • State expiration (15 minutes)
  • State-provider binding validation
Rate Limiting
  • Distributed via Redis
  • Per-IP rate limiting
  • Configurable limits per action
  • Graceful degradation
Email Verification
  • Configurable email verification checks
  • Trust provider email verification
  • Optional manual verification flow
Audit Logging
  • All OAuth events logged
  • User attribution
  • Error tracking
  • Compliance support

Testing

# Run all tests
go test ./plugins/social/... -v

# Run with coverage
go test ./plugins/social/... -cover

# Run specific test
go test ./plugins/social/... -run TestService_ListProviders -v

# Run rate limiter tests
go test ./plugins/social/... -run TestRateLimiter -v
Test Coverage
  • ✅ Request/response serialization
  • ✅ State store operations (memory & Redis)
  • ✅ State expiration
  • ✅ Rate limiting
  • ✅ Configuration validation
  • ✅ Handler logic
  • ✅ Mock implementations

Performance

Benchmarks
go test ./plugins/social/... -bench=. -benchmem
Optimization Tips
  1. Use Redis for state storage in production
  2. Enable rate limiting to prevent abuse
  3. Configure connection pooling for Redis
  4. Use async audit logging for high-volume scenarios
  5. Cache provider configurations per app

Troubleshooting

Common Issues
"state not found or expired"
  • Check Redis connectivity
  • Verify stateTtl configuration
  • Check clock synchronization across servers
"rate limit exceeded"
  • Increase rate limits in configuration
  • Check Redis for stuck keys
  • Verify client IP extraction
"provider not configured"
  • Verify provider credentials
  • Check provider enabled flag
  • Verify app-specific configuration
Debug Mode

Enable debug logging:

socialPlugin.SetLogLevel("debug")

Migration from v1

See MIGRATION_SUMMARY.md for detailed migration guide.

License

See LICENSE file in the root directory.

Support

Contributing

Contributions welcome! Please see CONTRIBUTING.md for guidelines.

Changelog

See CHANGELOG.md for version history.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AdminAddProviderRequest

type AdminAddProviderRequest struct {
	AppID        xid.ID   `json:"appId" validate:"required"`
	Provider     string   `json:"provider" validate:"required" example:"google"`
	ClientID     string   `json:"clientId" validate:"required"`
	ClientSecret string   `json:"clientSecret" validate:"required"`
	Scopes       []string `json:"scopes,omitempty"`
	Enabled      bool     `json:"enabled"`
}

type AdminUpdateProviderRequest

type AdminUpdateProviderRequest struct {
	ClientID     *string  `json:"clientId,omitempty"`
	ClientSecret *string  `json:"clientSecret,omitempty"`
	Scopes       []string `json:"scopes,omitempty"`
	Enabled      *bool    `json:"enabled,omitempty"`
}

type AuthURLResponse

type AuthURLResponse struct {
	URL string `json:"url" example:"https://accounts.google.com/o/oauth2/v2/auth?..."`
}

Response types - properly typed

type CallbackDataResponse

type CallbackDataResponse struct {
	User      *user.User `json:"user"`
	IsNewUser bool       `json:"isNewUser" example:"false"`
	Action    string     `json:"action" example:"signin"` // "signin", "signup", "linked"
}

type CallbackRequest added in v0.0.7

type CallbackRequest struct {
	Provider         string `path:"provider" validate:"required" json:"-"`
	State            string `query:"state" validate:"required" json:"state"`
	Code             string `query:"code" json:"code"`
	Error            string `query:"error" json:"error,omitempty"`
	ErrorDescription string `query:"error_description" json:"errorDescription,omitempty"`
}

CallbackRequest represents OAuth callback parameters

type CallbackResponse

type CallbackResponse struct {
	User    *user.User       `json:"user"`
	Session *session.Session `json:"session"`
	Token   string           `json:"token" example:"session_token_abc123"`
}

type CallbackResult

type CallbackResult struct {
	User          *user.User          // Nil for new users, populated for existing users
	OAuthUserInfo *providers.UserInfo // OAuth provider user info (always populated)
	OAuthToken    *oauth2.Token       // OAuth token for linking social account
	Provider      string              // OAuth provider name (e.g., "github", "google")
	SocialAccount *schema.SocialAccount
	IsNewUser     bool
	Action        string  // "signin", "signup", "linked"
	AppID         xid.ID  // App ID from state
	UserOrgID     *xid.ID // Optional user organization ID from state
}

CallbackResult holds the result of OAuth callback processing

type Config

type Config struct {
	// Base URL for OAuth callbacks (e.g., "https://example.com")
	BaseURL string `json:"baseUrl" yaml:"baseUrl"`

	// Providers configuration
	Providers ProvidersConfig `json:"providers" yaml:"providers"`

	// Advanced options
	AllowAccountLinking  bool `json:"allowAccountLinking" yaml:"allowAccountLinking"`   // Allow linking multiple providers to one user
	AutoCreateUser       bool `json:"autoCreateUser" yaml:"autoCreateUser"`             // Auto-create user on OAuth sign-in
	RequireEmailVerified bool `json:"requireEmailVerified" yaml:"requireEmailVerified"` // Require email verification from provider
	TrustEmailVerified   bool `json:"trustEmailVerified" yaml:"trustEmailVerified"`     // Trust email verification from provider

	// State storage configuration
	StateStorage StateStorageConfig `json:"stateStorage" yaml:"stateStorage"`
}

Config holds the configuration for social auth providers

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns default configuration

type ConnectionResponse

type ConnectionResponse struct {
	Connection *base.SocialAccount `json:"connection"`
}

type ConnectionsResponse

type ConnectionsResponse struct {
	Connections []*base.SocialAccount `json:"connections"`
}

type DashboardExtension added in v0.0.3

type DashboardExtension struct {
	// contains filtered or unexported fields
}

DashboardExtension implements ui.DashboardExtension for the social plugin

func NewDashboardExtension added in v0.0.3

func NewDashboardExtension(plugin *Plugin, configRepo repository.SocialProviderConfigRepository) *DashboardExtension

NewDashboardExtension creates a new dashboard extension

func (*DashboardExtension) DashboardWidgets added in v0.0.3

func (e *DashboardExtension) DashboardWidgets() []ui.DashboardWidget

DashboardWidgets returns dashboard widgets

func (*DashboardExtension) ExtensionID added in v0.0.3

func (e *DashboardExtension) ExtensionID() string

ExtensionID returns the unique identifier for this extension

func (*DashboardExtension) HandleCreateProvider added in v0.0.3

func (e *DashboardExtension) HandleCreateProvider(c forge.Context) error

HandleCreateProvider creates a new social provider configuration

func (*DashboardExtension) HandleDeleteProvider added in v0.0.3

func (e *DashboardExtension) HandleDeleteProvider(c forge.Context) error

HandleDeleteProvider deletes a social provider configuration

func (*DashboardExtension) HandleToggleProvider added in v0.0.3

func (e *DashboardExtension) HandleToggleProvider(c forge.Context) error

HandleToggleProvider toggles a social provider's enabled status

func (*DashboardExtension) HandleUpdateProvider added in v0.0.3

func (e *DashboardExtension) HandleUpdateProvider(c forge.Context) error

HandleUpdateProvider updates an existing social provider configuration

func (*DashboardExtension) NavigationItems added in v0.0.3

func (e *DashboardExtension) NavigationItems() []ui.NavigationItem

NavigationItems returns the navigation items for the dashboard

func (*DashboardExtension) Routes added in v0.0.3

func (e *DashboardExtension) Routes() []ui.Route

Routes returns the dashboard routes

func (*DashboardExtension) ServeProviderAddPage added in v0.0.3

func (e *DashboardExtension) ServeProviderAddPage(c forge.Context) error

ServeProviderAddPage renders the add provider form

func (*DashboardExtension) ServeProviderEditPage added in v0.0.3

func (e *DashboardExtension) ServeProviderEditPage(c forge.Context) error

ServeProviderEditPage renders the edit provider form

func (*DashboardExtension) ServeProvidersListPage added in v0.0.3

func (e *DashboardExtension) ServeProvidersListPage(c forge.Context) error

ServeProvidersListPage renders the social providers list page

func (*DashboardExtension) SetRegistry added in v0.0.3

func (e *DashboardExtension) SetRegistry(registry *dashboard.ExtensionRegistry)

SetRegistry sets the extension registry reference (called by dashboard after registration)

func (*DashboardExtension) SettingsPages added in v0.0.3

func (e *DashboardExtension) SettingsPages() []ui.SettingsPage

SettingsPages returns settings pages for the plugin

func (*DashboardExtension) SettingsSections added in v0.0.3

func (e *DashboardExtension) SettingsSections() []ui.SettingsSection

SettingsSections returns settings sections (deprecated, using SettingsPages instead)

type ErrorResponse

type ErrorResponse = errs.AuthsomeError

Type alias for error responses

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler handles HTTP requests for social OAuth

func NewHandler

func NewHandler(
	service *Service,
	rateLimiter *RateLimiter,
	authCompletion *authflow.CompletionService,
) *Handler

NewHandler creates a new social OAuth handler

func (*Handler) AdminAddProvider

func (h *Handler) AdminAddProvider(c forge.Context) error

AdminAddProvider handles POST /social/admin/providers Adds/configures an OAuth provider for an app

func (*Handler) AdminDeleteProvider

func (h *Handler) AdminDeleteProvider(c forge.Context) error

AdminDeleteProvider handles DELETE /social/admin/providers/:provider Removes OAuth provider configuration for an app

func (*Handler) AdminListProviders

func (h *Handler) AdminListProviders(c forge.Context) error

AdminListProviders handles GET /social/admin/providers Lists configured OAuth providers for an app

func (*Handler) AdminUpdateProvider

func (h *Handler) AdminUpdateProvider(c forge.Context) error

AdminUpdateProvider handles PUT /social/admin/providers/:provider Updates OAuth provider configuration for an app

func (*Handler) Callback

func (h *Handler) Callback(c forge.Context) error

Callback handles OAuth provider callback GET /api/auth/callback/:provider

func (*Handler) LinkAccount

func (h *Handler) LinkAccount(c forge.Context) error

LinkAccount links a social provider to the current user POST /api/auth/account/link

func (*Handler) ListProviders

func (h *Handler) ListProviders(c forge.Context) error

ListProviders returns available OAuth providers GET /api/auth/providers

func (*Handler) SignIn

func (h *Handler) SignIn(c forge.Context) error

SignIn initiates OAuth flow for sign-in POST /api/auth/signin/social

func (*Handler) UnlinkAccount

func (h *Handler) UnlinkAccount(c forge.Context) error

UnlinkAccount unlinks a social provider from the current user DELETE /api/auth/account/unlink/:provider

type LinkAccountRequest

type LinkAccountRequest struct {
	Provider string   `json:"provider" validate:"required" example:"github"`
	Scopes   []string `json:"scopes,omitempty" example:"[\"user:email\"]"`
}

type MemoryStateStore

type MemoryStateStore struct {
	// contains filtered or unexported fields
}

MemoryStateStore is an in-memory implementation of StateStore

func NewMemoryStateStore

func NewMemoryStateStore() *MemoryStateStore

NewMemoryStateStore creates a new in-memory state store

func (*MemoryStateStore) Delete

func (s *MemoryStateStore) Delete(ctx context.Context, key string) error

Delete removes a state

func (*MemoryStateStore) Get

func (s *MemoryStateStore) Get(ctx context.Context, key string) (*OAuthState, error)

Get retrieves a state

func (*MemoryStateStore) Set

func (s *MemoryStateStore) Set(ctx context.Context, key string, state *OAuthState, ttl time.Duration) error

Set stores a state with TTL

type MessageResponse

type MessageResponse = responses.MessageResponse

Use shared response type

type OAuthState

type OAuthState struct {
	Provider           string    `json:"provider"`
	AppID              xid.ID    `json:"app_id"`
	UserOrganizationID *xid.ID   `json:"user_organization_id,omitempty"`
	RedirectURL        string    `json:"redirect_url,omitempty"`
	CreatedAt          time.Time `json:"created_at"`
	ExtraScopes        []string  `json:"extra_scopes,omitempty"`
	LinkUserID         *xid.ID   `json:"link_user_id,omitempty"`
}

OAuthState stores temporary OAuth state data

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin implements the social OAuth plugin

func NewPlugin

func NewPlugin(opts ...PluginOption) *Plugin

NewPlugin creates a new social OAuth plugin with optional configuration

func (*Plugin) DashboardExtension added in v0.0.3

func (p *Plugin) DashboardExtension() ui.DashboardExtension

DashboardExtension returns the dashboard extension for the social plugin

func (*Plugin) GetConfigRepository added in v0.0.3

func (p *Plugin) GetConfigRepository() repository.SocialProviderConfigRepository

GetConfigRepository returns the config repository (for testing/internal use)

func (*Plugin) GetService

func (p *Plugin) GetService() *Service

GetService returns the social service (for testing/internal use)

func (*Plugin) ID

func (p *Plugin) ID() string

ID returns the plugin identifier

func (*Plugin) Init

func (p *Plugin) Init(authInst core.Authsome) error

Init initializes the plugin with dependencies

func (*Plugin) Migrate

func (p *Plugin) Migrate() error

Migrate creates database tables

func (*Plugin) RegisterHooks

func (p *Plugin) RegisterHooks(_ *hooks.HookRegistry) error

RegisterHooks registers plugin hooks

func (*Plugin) RegisterRoutes

func (p *Plugin) RegisterRoutes(router forge.Router) error

RegisterRoutes registers the plugin's HTTP routes

func (*Plugin) RegisterServiceDecorators

func (p *Plugin) RegisterServiceDecorators(_ *registry.ServiceRegistry) error

RegisterServiceDecorators registers service decorators

func (*Plugin) SetConfig

func (p *Plugin) SetConfig(config Config)

SetConfig allows setting configuration after plugin creation

type PluginOption

type PluginOption func(*Plugin)

PluginOption is a functional option for configuring the social plugin

func WithAllowLinking

func WithAllowLinking(allow bool) PluginOption

WithAllowLinking sets whether to allow account linking

func WithAutoCreateUser

func WithAutoCreateUser(auto bool) PluginOption

WithAutoCreateUser sets whether to auto-create users

func WithDefaultConfig

func WithDefaultConfig(cfg Config) PluginOption

WithDefaultConfig sets the default configuration for the plugin

func WithProvider

func WithProvider(name string, clientID, clientSecret, callbackURL string, scopes []string) PluginOption

WithProvider adds a provider configuration

func WithTrustEmailVerified

func WithTrustEmailVerified(trust bool) PluginOption

WithTrustEmailVerified sets whether to trust provider email verification

type ProviderConfigResponse

type ProviderConfigResponse struct {
	Message  string `json:"message" example:"Provider configured successfully"`
	Provider string `json:"provider" example:"google"`
	AppID    string `json:"appId" example:"c9h7b3j2k1m4n5p6"`
}

type ProvidersAppResponse

type ProvidersAppResponse struct {
	Providers []string `json:"providers"`
	AppID     string   `json:"appId"`
}

type ProvidersConfig

type ProvidersConfig struct {
	Google    *providers.ProviderConfig `json:"google,omitempty" yaml:"google,omitempty"`
	GitHub    *providers.ProviderConfig `json:"github,omitempty" yaml:"github,omitempty"`
	Microsoft *providers.ProviderConfig `json:"microsoft,omitempty" yaml:"microsoft,omitempty"`
	Apple     *providers.ProviderConfig `json:"apple,omitempty" yaml:"apple,omitempty"`
	Facebook  *providers.ProviderConfig `json:"facebook,omitempty" yaml:"facebook,omitempty"`
	Discord   *providers.ProviderConfig `json:"discord,omitempty" yaml:"discord,omitempty"`
	Twitter   *providers.ProviderConfig `json:"twitter,omitempty" yaml:"twitter,omitempty"`
	LinkedIn  *providers.ProviderConfig `json:"linkedin,omitempty" yaml:"linkedin,omitempty"`
	Spotify   *providers.ProviderConfig `json:"spotify,omitempty" yaml:"spotify,omitempty"`
	Twitch    *providers.ProviderConfig `json:"twitch,omitempty" yaml:"twitch,omitempty"`
	Dropbox   *providers.ProviderConfig `json:"dropbox,omitempty" yaml:"dropbox,omitempty"`
	GitLab    *providers.ProviderConfig `json:"gitlab,omitempty" yaml:"gitlab,omitempty"`
	LINE      *providers.ProviderConfig `json:"line,omitempty" yaml:"line,omitempty"`
	Reddit    *providers.ProviderConfig `json:"reddit,omitempty" yaml:"reddit,omitempty"`
	Slack     *providers.ProviderConfig `json:"slack,omitempty" yaml:"slack,omitempty"`
	Bitbucket *providers.ProviderConfig `json:"bitbucket,omitempty" yaml:"bitbucket,omitempty"`
	Notion    *providers.ProviderConfig `json:"notion,omitempty" yaml:"notion,omitempty"`
}

ProvidersConfig holds configuration for each provider

type ProvidersResponse

type ProvidersResponse struct {
	Providers []string `json:"providers" example:"[\"google\",\"github\",\"facebook\"]"`
}

type RateLimit

type RateLimit struct {
	Requests int
	Window   time.Duration
}

RateLimit defines rate limiting parameters

type RateLimiter

type RateLimiter struct {
	// contains filtered or unexported fields
}

RateLimiter provides rate limiting for OAuth endpoints

func NewRateLimiter

func NewRateLimiter(redisClient *redis.Client) *RateLimiter

NewRateLimiter creates a new rate limiter

func (*RateLimiter) Allow

func (r *RateLimiter) Allow(ctx context.Context, action, key string) error

Allow checks if a request is allowed under rate limits

func (*RateLimiter) SetLimit

func (r *RateLimiter) SetLimit(action string, requests int, window time.Duration)

SetLimit allows customizing rate limits

type RedisStateStore

type RedisStateStore struct {
	// contains filtered or unexported fields
}

RedisStateStore is a Redis-backed implementation of StateStore

func NewRedisStateStore

func NewRedisStateStore(client *redis.Client) *RedisStateStore

NewRedisStateStore creates a new Redis state store

func (*RedisStateStore) Delete

func (s *RedisStateStore) Delete(ctx context.Context, key string) error

Delete removes a state from Redis

func (*RedisStateStore) Get

func (s *RedisStateStore) Get(ctx context.Context, key string) (*OAuthState, error)

Get retrieves a state from Redis

func (*RedisStateStore) Set

func (s *RedisStateStore) Set(ctx context.Context, key string, state *OAuthState, ttl time.Duration) error

Set stores a state with TTL in Redis

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service handles social OAuth flows

func NewService

func NewService(config Config, socialRepo repository.SocialAccountRepository, userSvc *user.Service, stateStore StateStore, auditSvc *audit.Service) *Service

NewService creates a new social auth service

func (*Service) CreateSocialAccount added in v0.0.7

func (s *Service) CreateSocialAccount(ctx context.Context, userID, appID xid.ID, userOrganizationID *xid.ID, provider string, userInfo *providers.UserInfo, token *oauth2.Token) error

CreateSocialAccount creates a new social account record This is called after user creation to link the OAuth provider

func (*Service) GetAuthorizationURL

func (s *Service) GetAuthorizationURL(ctx context.Context, providerName string, appID xid.ID, userOrganizationID *xid.ID, extraScopes []string) (string, error)

GetAuthorizationURL generates an OAuth authorization URL

func (*Service) GetLinkAccountURL

func (s *Service) GetLinkAccountURL(ctx context.Context, providerName string, userID xid.ID, appID xid.ID, userOrganizationID *xid.ID, extraScopes []string) (string, error)

GetLinkAccountURL generates a URL to link an additional provider to an existing user

func (*Service) GetProviderConfig added in v0.0.3

func (s *Service) GetProviderConfig(providerName string) *providers.ProviderConfig

GetProviderConfig returns the current provider configuration for a specific provider This can be used to inspect what's currently configured

func (*Service) HandleCallback

func (s *Service) HandleCallback(ctx context.Context, providerName, stateToken, code string) (*CallbackResult, error)

HandleCallback processes the OAuth callback

func (*Service) InvalidateEnvironmentCache added in v0.0.7

func (s *Service) InvalidateEnvironmentCache(appID, envID xid.ID)

InvalidateEnvironmentCache clears the cache for a specific environment This should be called when provider configurations are updated

func (*Service) IsProviderEnabled added in v0.0.3

func (s *Service) IsProviderEnabled(providerName string) bool

IsProviderEnabled checks if a provider is currently enabled and configured

func (*Service) ListProviders

func (s *Service) ListProviders(ctx context.Context, appID, envID xid.ID) []string

ListProviders returns available providers for a specific environment

func (*Service) LoadConfigForEnvironment added in v0.0.3

func (s *Service) LoadConfigForEnvironment(ctx context.Context, appID, envID xid.ID) error

LoadConfigForEnvironment loads provider configurations from the database for a specific environment and merges them with the current configuration. DB configs take precedence over code-based configs.

func (*Service) SetConfigRepository added in v0.0.3

func (s *Service) SetConfigRepository(repo repository.SocialProviderConfigRepository)

SetConfigRepository sets the config repository for DB-backed configuration

func (*Service) UnlinkAccount

func (s *Service) UnlinkAccount(ctx context.Context, userID xid.ID, provider string) error

UnlinkAccount removes a social account link

type SignInRequest

type SignInRequest struct {
	Provider    string   `json:"provider" validate:"required" example:"google"`
	Scopes      []string `json:"scopes,omitempty" example:"[\"email\",\"profile\"]"`
	RedirectURL string   `json:"redirectUrl,omitempty" example:"https://example.com/auth/callback"`
}

Request types

type StateStorageConfig

type StateStorageConfig struct {
	// UseRedis enables Redis-backed state storage (recommended for production)
	UseRedis bool `json:"useRedis" yaml:"useRedis"`
	// RedisAddr is the Redis server address
	RedisAddr string `json:"redisAddr" yaml:"redisAddr"`
	// RedisPassword is the Redis password (optional)
	RedisPassword string `json:"redisPassword" yaml:"redisPassword"`
	// RedisDB is the Redis database number
	RedisDB int `json:"redisDb" yaml:"redisDb"`
	// StateTTL is the state expiration time
	StateTTL time.Duration `json:"stateTtl" yaml:"stateTtl"`
}

StateStorageConfig holds configuration for OAuth state storage

type StateStore

type StateStore interface {
	Set(ctx context.Context, key string, state *OAuthState, ttl time.Duration) error
	Get(ctx context.Context, key string) (*OAuthState, error)
	Delete(ctx context.Context, key string) error
}

StateStore defines the interface for OAuth state storage

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL