gotrust

package module
v0.0.0-...-159dada Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2025 License: MIT Imports: 15 Imported by: 0

README

GoTrust 🔐

Framework-agnostic authentication library for Go. Works with Echo, Gin, Fiber, or standard net/http. One auth library, any framework.

Why GoTrust?

After building authentication for multiple production applications, I found myself writing the same auth code over and over. GoTrust extracts those battle-tested patterns into a reusable library that just works.

Features ✨

  • 🔑 Email/password authentication with bcrypt
  • 🌐 OAuth providers (Google, GitHub) with easy extensibility
  • 🎫 JWT tokens with refresh token rotation
  • 💾 Session management via Redis or in-memory storage
  • 🗄️ Database-agnostic through interfaces
  • Framework-agnostic - works with any Go web framework
  • 🛡️ Production-ready security defaults
  • 📦 Modular adapters - only import what you need

Installation

# Core library (required)
go get github.com/mayurrawte/gotrust

# Then install ONLY the adapter for your framework:
go get github.com/mayurrawte/gotrust/adapters/echo   # For Echo
go get github.com/mayurrawte/gotrust/adapters/gin    # For Gin  
go get github.com/mayurrawte/gotrust/adapters/fiber  # For Fiber
go get github.com/mayurrawte/gotrust/adapters/stdlib # For net/http

No bloat! If you use Echo, you won't get Gin dependencies. Each adapter is isolated.

Basic Usage

With Echo Framework
import (
    "github.com/labstack/echo/v4"
    "github.com/mayurrawte/gotrust"
    echoAdapter "github.com/mayurrawte/gotrust/adapters/echo"
)

// Setup
config := gotrust.NewConfig()
userStore := NewPostgresUserStore(db)  
authService := gotrust.NewAuthService(config, userStore, gotrust.NewMemorySessionStore())
handlers := gotrust.NewGenericAuthHandlers(authService, config)

// Register routes
e := echo.New()
echoAdapter.RegisterRoutes(e, "/auth", handlers)

// Protect routes
api := e.Group("/api")
api.Use(echoAdapter.WrapMiddleware(handlers.AuthMiddleware()))
With Gin Framework
import (
    "github.com/gin-gonic/gin"
    "github.com/mayurrawte/gotrust"
    ginAdapter "github.com/mayurrawte/gotrust/adapters/gin"
)

// Setup
config := gotrust.NewConfig()
userStore := NewPostgresUserStore(db)  
authService := gotrust.NewAuthService(config, userStore, gotrust.NewMemorySessionStore())
handlers := gotrust.NewGenericAuthHandlers(authService, config)

// Register routes
router := gin.Default()
ginAdapter.RegisterRoutes(router, "/auth", handlers)

// Protect routes
api := router.Group("/api")
api.Use(ginAdapter.WrapMiddleware(handlers.AuthMiddleware()))
With Standard net/http
import (
    "net/http"
    "github.com/mayurrawte/gotrust"
    stdAdapter "github.com/mayurrawte/gotrust/adapters/stdlib"
)

// Setup
config := gotrust.NewConfig()
userStore := NewPostgresUserStore(db)  
authService := gotrust.NewAuthService(config, userStore, gotrust.NewMemorySessionStore())
handlers := gotrust.NewGenericAuthHandlers(authService, config)

// Register routes
mux := http.NewServeMux()
stdAdapter.RegisterRoutes(mux, "/auth", handlers)

// Protect routes with middleware
protectedHandler := stdAdapter.AuthMiddleware(handlers)(yourHandler)
mux.HandleFunc("/api/protected", protectedHandler)

That's it! 🎉 Your app now has production-ready authentication with YOUR preferred framework.

Full Setup Guide

1. Set Environment Variables 🔧
# JWT Configuration (Required)
export JWT_SECRET="your-secret-key-min-32-chars"
export JWT_ISSUER="your-app-name"

# Google OAuth (Optional)
export GOOGLE_CLIENT_ID="your-google-client-id"
export GOOGLE_CLIENT_SECRET="your-google-client-secret"
export GOOGLE_REDIRECT_URI="http://localhost:4000/auth/google/callback"

# GitHub OAuth (Optional)
export GITHUB_CLIENT_ID="your-github-client-id"
export GITHUB_CLIENT_SECRET="your-github-client-secret"
export GITHUB_REDIRECT_URI="http://localhost:4000/auth/github/callback"

# Redis (Optional - for session storage)
export REDIS_URL="redis://localhost:6379"

# Frontend URLs
export FRONTEND_SUCCESS_URL="http://localhost:3000/auth/success"
export FRONTEND_ERROR_URL="http://localhost:3000/auth/error"
2. Implement UserStore Interface

GoTrust works with any database. Just implement the UserStore interface:

type UserStore interface {
    CreateUser(ctx context.Context, user *gotrust.User, hashedPassword string) error
    GetUserByEmail(ctx context.Context, email string) (*gotrust.User, string, error)
    GetUserByID(ctx context.Context, userID string) (*gotrust.User, error)
    UpdateUser(ctx context.Context, user *gotrust.User) error
    UserExists(ctx context.Context, email string) (bool, error)
}
Example: PostgreSQL Implementation 🐘
package main

import (
    "context"
    "database/sql"
    "github.com/mayurrawte/gotrust"
    _ "github.com/lib/pq"
)

type PostgresUserStore struct {
    db *sql.DB
}

func NewPostgresUserStore(db *sql.DB) *PostgresUserStore {
    return &PostgresUserStore{db: db}
}

func (s *PostgresUserStore) CreateUser(ctx context.Context, user *gotrust.User, hashedPassword string) error {
    query := `
        INSERT INTO users (id, email, name, avatar_url, provider, password, created_at, updated_at)
        VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
    `
    _, err := s.db.ExecContext(ctx, query,
        user.ID, user.Email, user.Name, user.AvatarURL, 
        user.Provider, hashedPassword, user.CreatedAt, user.UpdatedAt,
    )
    return err
}

func (s *PostgresUserStore) GetUserByEmail(ctx context.Context, email string) (*gotrust.User, string, error) {
    var user gotrust.User
    var hashedPassword string
    
    query := `
        SELECT id, email, name, avatar_url, provider, password, created_at, updated_at
        FROM users WHERE email = $1
    `
    err := s.db.QueryRowContext(ctx, query, email).Scan(
        &user.ID, &user.Email, &user.Name, &user.AvatarURL,
        &user.Provider, &hashedPassword, &user.CreatedAt, &user.UpdatedAt,
    )
    if err != nil {
        return nil, "", err
    }
    
    return &user, hashedPassword, nil
}

func (s *PostgresUserStore) GetUserByID(ctx context.Context, userID string) (*gotrust.User, error) {
    var user gotrust.User
    
    query := `
        SELECT id, email, name, avatar_url, provider, created_at, updated_at
        FROM users WHERE id = $1
    `
    err := s.db.QueryRowContext(ctx, query, userID).Scan(
        &user.ID, &user.Email, &user.Name, &user.AvatarURL,
        &user.Provider, &user.CreatedAt, &user.UpdatedAt,
    )
    if err != nil {
        return nil, err
    }
    
    return &user, nil
}

func (s *PostgresUserStore) UpdateUser(ctx context.Context, user *gotrust.User) error {
    query := `
        UPDATE users 
        SET name = $2, avatar_url = $3, updated_at = $4
        WHERE id = $1
    `
    _, err := s.db.ExecContext(ctx, query,
        user.ID, user.Name, user.AvatarURL, user.UpdatedAt,
    )
    return err
}

func (s *PostgresUserStore) UserExists(ctx context.Context, email string) (bool, error) {
    var exists bool
    query := `SELECT EXISTS(SELECT 1 FROM users WHERE email = $1)`
    err := s.db.QueryRowContext(ctx, query, email).Scan(&exists)
    return exists, err
}
Example: In-Memory Implementation (for testing)
type InMemoryUserStore struct {
    mu       sync.RWMutex
    users    map[string]*gotrust.User
    passwords map[string]string
}

func NewInMemoryUserStore() *InMemoryUserStore {
    return &InMemoryUserStore{
        users:     make(map[string]*gotrust.User),
        passwords: make(map[string]string),
    }
}

func (s *InMemoryUserStore) CreateUser(ctx context.Context, user *gotrust.User, hashedPassword string) error {
    s.mu.Lock()
    defer s.mu.Unlock()
    
    s.users[user.Email] = user
    if hashedPassword != "" {
        s.passwords[user.Email] = hashedPassword
    }
    return nil
}

func (s *InMemoryUserStore) GetUserByEmail(ctx context.Context, email string) (*gotrust.User, string, error) {
    s.mu.RLock()
    defer s.mu.RUnlock()
    
    user, exists := s.users[email]
    if !exists {
        return nil, "", fmt.Errorf("user not found")
    }
    
    password := s.passwords[email]
    return user, password, nil
}

// ... implement other methods similarly
Example: MongoDB Implementation 🍃
package main

import (
    "context"
    "time"
    
    "github.com/mayurrawte/gotrust"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type MongoUserStore struct {
    collection *mongo.Collection
}

type mongoUser struct {
    ID           primitive.ObjectID `bson:"_id,omitempty"`
    Email        string            `bson:"email"`
    Name         string            `bson:"name"`
    AvatarURL    string            `bson:"avatar_url"`
    Provider     string            `bson:"provider"`
    Password     string            `bson:"password"`
    CreatedAt    time.Time         `bson:"created_at"`
    UpdatedAt    time.Time         `bson:"updated_at"`
}

func NewMongoUserStore(db *mongo.Database) (*MongoUserStore, error) {
    collection := db.Collection("users")
    
    // Create unique index on email
    _, err := collection.Indexes().CreateOne(context.Background(), mongo.IndexModel{
        Keys:    bson.D{{"email", 1}},
        Options: options.Index().SetUnique(true),
    })
    if err != nil {
        return nil, err
    }
    
    return &MongoUserStore{
        collection: collection,
    }, nil
}

func (s *MongoUserStore) CreateUser(ctx context.Context, user *gotrust.User, hashedPassword string) error {
    mongoDoc := mongoUser{
        ID:        primitive.NewObjectID(),
        Email:     user.Email,
        Name:      user.Name,
        AvatarURL: user.AvatarURL,
        Provider:  user.Provider,
        Password:  hashedPassword,
        CreatedAt: user.CreatedAt,
        UpdatedAt: user.UpdatedAt,
    }
    
    result, err := s.collection.InsertOne(ctx, mongoDoc)
    if err != nil {
        return err
    }
    
    // Update user ID with MongoDB ObjectID
    user.ID = result.InsertedID.(primitive.ObjectID).Hex()
    return nil
}

func (s *MongoUserStore) GetUserByEmail(ctx context.Context, email string) (*gotrust.User, string, error) {
    var mongoDoc mongoUser
    
    err := s.collection.FindOne(ctx, bson.M{"email": email}).Decode(&mongoDoc)
    if err != nil {
        if err == mongo.ErrNoDocuments {
            return nil, "", fmt.Errorf("user not found")
        }
        return nil, "", err
    }
    
    user := &gotrust.User{
        ID:        mongoDoc.ID.Hex(),
        Email:     mongoDoc.Email,
        Name:      mongoDoc.Name,
        AvatarURL: mongoDoc.AvatarURL,
        Provider:  mongoDoc.Provider,
        CreatedAt: mongoDoc.CreatedAt,
        UpdatedAt: mongoDoc.UpdatedAt,
    }
    
    return user, mongoDoc.Password, nil
}

func (s *MongoUserStore) GetUserByID(ctx context.Context, userID string) (*gotrust.User, error) {
    objectID, err := primitive.ObjectIDFromHex(userID)
    if err != nil {
        return nil, fmt.Errorf("invalid user ID")
    }
    
    var mongoDoc mongoUser
    err = s.collection.FindOne(ctx, bson.M{"_id": objectID}).Decode(&mongoDoc)
    if err != nil {
        return nil, err
    }
    
    return &gotrust.User{
        ID:        mongoDoc.ID.Hex(),
        Email:     mongoDoc.Email,
        Name:      mongoDoc.Name,
        AvatarURL: mongoDoc.AvatarURL,
        Provider:  mongoDoc.Provider,
        CreatedAt: mongoDoc.CreatedAt,
        UpdatedAt: mongoDoc.UpdatedAt,
    }, nil
}

func (s *MongoUserStore) UpdateUser(ctx context.Context, user *gotrust.User) error {
    objectID, err := primitive.ObjectIDFromHex(user.ID)
    if err != nil {
        return err
    }
    
    update := bson.M{
        "$set": bson.M{
            "name":       user.Name,
            "avatar_url": user.AvatarURL,
            "updated_at": time.Now(),
        },
    }
    
    _, err = s.collection.UpdateByID(ctx, objectID, update)
    return err
}

func (s *MongoUserStore) UserExists(ctx context.Context, email string) (bool, error) {
    count, err := s.collection.CountDocuments(ctx, bson.M{"email": email})
    if err != nil {
        return false, err
    }
    return count > 0, nil
}

// Usage with MongoDB
func main() {
    // Connect to MongoDB
    client, err := mongo.Connect(context.Background(), 
        options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        log.Fatal(err)
    }
    
    db := client.Database("myapp")
    userStore, err := NewMongoUserStore(db)
    if err != nil {
        log.Fatal(err)
    }
    
    // Rest of the setup is the same
    config := gotrust.NewConfig()
    sessionStore := gotrust.NewMemorySessionStore()
    authService := gotrust.NewAuthService(config, userStore, sessionStore)
    // ...
}
3. Initialize and Use GoTrust 🚀
package main

import (
    "database/sql"
    "log"
    
    "github.com/labstack/echo/v4"
    "github.com/mayurrawte/gotrust"
    _ "github.com/lib/pq"
)

func main() {
    // 1. Setup database connection
    db, err := sql.Open("postgres", "postgresql://user:pass@localhost/dbname?sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    // Create users table if not exists
    createTableSQL := `
    CREATE TABLE IF NOT EXISTS users (
        id VARCHAR(255) PRIMARY KEY,
        email VARCHAR(255) UNIQUE NOT NULL,
        name VARCHAR(255),
        avatar_url TEXT,
        provider VARCHAR(50),
        password TEXT,
        created_at TIMESTAMP,
        updated_at TIMESTAMP
    );`
    db.Exec(createTableSQL)
    
    // 2. Create configuration
    config := gotrust.NewConfig()
    
    // 3. Create user store
    userStore := NewPostgresUserStore(db)
    
    // 4. Create session store (Redis or Memory)
    var sessionStore gotrust.SessionStore
    if config.RedisURL != "" {
        sessionStore, err = gotrust.NewRedisSessionStore(config.RedisURL)
        if err != nil {
            log.Printf("Redis not available, using memory store: %v", err)
            sessionStore = gotrust.NewMemorySessionStore()
        }
    } else {
        sessionStore = gotrust.NewMemorySessionStore()
    }
    
    // 5. Create auth service
    authService := gotrust.NewAuthService(config, userStore, sessionStore)
    
    // 6. Setup Echo server
    e := echo.New()
    
    // 7. Register auth routes
    handlers := gotrust.NewAuthHandlers(authService, config)
    handlers.RegisterRoutes(e, "/auth")
    
    // 8. Setup protected routes
    protected := e.Group("/api")
    protected.Use(authService.AuthMiddleware())
    
    protected.GET("/profile", func(c echo.Context) error {
        userID, _ := gotrust.GetUserFromContext(c)
        return c.JSON(200, map[string]string{
            "user_id": userID,
            "message": "This is a protected route",
        })
    })
    
    // 9. Setup optional auth routes (public + authenticated)
    public := e.Group("/public")
    public.Use(authService.OptionalAuthMiddleware())
    
    public.GET("/info", func(c echo.Context) error {
        userID, _ := c.Get("user_id").(string)
        if userID != "" {
            return c.JSON(200, map[string]string{
                "message": "Hello authenticated user",
                "user_id": userID,
            })
        }
        return c.JSON(200, map[string]string{
            "message": "Hello anonymous user",
        })
    })
    
    // 10. Start server
    log.Println("Server starting on :4000")
    e.Start(":4000")
}

API Reference

Authentication Endpoints
Method Endpoint Description Request Body
POST /auth/signup Register new user {"email": "...", "password": "...", "name": "..."}
POST /auth/signin Login with email/password {"email": "...", "password": "..."}
POST /auth/refresh Refresh access token {"refresh_token": "..."}
POST /auth/logout Logout (invalidate session) -
GET /auth/user Get current user info -
OAuth Endpoints
Method Endpoint Description
GET /auth/google Initiate Google OAuth
GET /auth/google/callback Google OAuth callback
GET /auth/github Initiate GitHub OAuth
GET /auth/github/callback GitHub OAuth callback
Response Format
Successful Authentication
{
    "user": {
        "id": "user_123",
        "email": "user@example.com",
        "name": "John Doe",
        "avatar_url": "https://...",
        "provider": "local"
    },
    "access_token": "eyJhbGciOiJ...",
    "refresh_token": "eyJhbGciOiJ...",
    "expires_in": 86400
}
Error Response
{
    "error": "Invalid credentials"
}

Middleware Options

1. Required Authentication
// All routes in this group require authentication
protected := e.Group("/api")
protected.Use(authService.AuthMiddleware())

protected.GET("/secret", handler)
2. Optional Authentication
// Routes work for both authenticated and anonymous users
public := e.Group("/public")
public.Use(authService.OptionalAuthMiddleware())

public.GET("/content", func(c echo.Context) error {
    userID, _ := c.Get("user_id").(string)
    if userID != "" {
        // User is authenticated
    } else {
        // User is anonymous
    }
})
3. Session-based Authentication
// Use sessions instead of JWT tokens
sessionRoutes := e.Group("/session")
sessionRoutes.Use(authService.SessionMiddleware())

Common Use Cases

Custom User Data
// Extend the User struct in your application
type AppUser struct {
    gotrust.User
    Role        string    `json:"role"`
    Permissions []string  `json:"permissions"`
    LastLoginAt time.Time `json:"last_login_at"`
}
Rate Limiting
// Add rate limiting to auth endpoints
import "github.com/labstack/echo/v4/middleware"

authGroup := e.Group("/auth")
authGroup.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(10)))
handlers.RegisterRoutes(authGroup, "")
Custom Claims in JWT
// After successful authentication, add custom claims
func customAuthHandler(c echo.Context) error {
    // ... authenticate user
    
    // Add custom claims to context
    c.Set("user_role", "admin")
    c.Set("tenant_id", "tenant_123")
    
    // ... return response
}

Security Best Practices 🔒

  1. Use strong JWT secrets: At least 32 characters
  2. Enable HTTPS: Always use TLS in production
  3. Set secure cookies: Use HttpOnly and Secure flags
  4. Implement rate limiting: Prevent brute force attacks
  5. Validate email addresses: Implement email verification
  6. Use CSRF protection: For web applications
  7. Regular token rotation: Use refresh tokens
  8. Audit logging: Log authentication events

Configuration Options

Environment Variable Description Default Required
JWT_SECRET Secret key for JWT signing (min 32 chars) -
JWT_ISSUER JWT issuer claim gotrust
GOOGLE_CLIENT_ID Google OAuth client ID -
GOOGLE_CLIENT_SECRET Google OAuth client secret -
GITHUB_CLIENT_ID GitHub OAuth client ID -
GITHUB_CLIENT_SECRET GitHub OAuth client secret -
REDIS_URL Redis connection URL -
ALLOW_SIGNUP Enable user registration true
REQUIRE_EMAIL_VERIFICATION Require email verification false
FRONTEND_SUCCESS_URL OAuth success redirect URL http://localhost:3000/auth/success
FRONTEND_ERROR_URL OAuth error redirect URL http://localhost:3000/auth/error

Testing 🧪

func TestAuthentication(t *testing.T) {
    // Use in-memory store for testing
    userStore := NewInMemoryUserStore()
    sessionStore := gotrust.NewMemorySessionStore()
    config := gotrust.NewConfig()
    
    authService := gotrust.NewAuthService(config, userStore, sessionStore)
    
    // Test signup
    ctx := context.Background()
    response, err := authService.SignUp(ctx, &gotrust.SignUpRequest{
        Email:    "test@example.com",
        Password: "password123",
        Name:     "Test User",
    })
    
    assert.NoError(t, err)
    assert.NotEmpty(t, response.AccessToken)
    
    // Test signin
    signInResp, err := authService.SignIn(ctx, &gotrust.SignInRequest{
        Email:    "test@example.com",
        Password: "password123",
    })
    
    assert.NoError(t, err)
    assert.Equal(t, "test@example.com", signInResp.User.Email)
}

Contributing

Found a bug? Have a feature request? PRs are welcome. Check out CONTRIBUTING.md for guidelines.

License

MIT - see LICENSE

Roadmap 🚀

  • Email verification
  • Password reset functionality
  • Two-factor authentication (2FA)
  • Additional OAuth providers (Microsoft, Twitter, etc.)
  • WebAuthn support
  • Account linking
  • Audit logging
  • Admin dashboard

Built for the Go community. Feel free to use, modify, and contribute.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetUserFromContext

func GetUserFromContext(ctx HTTPContext) (string, error)

GetUserFromContext extracts user ID from context

Types

type AuthResponse

type AuthResponse struct {
	User         *User  `json:"user"`
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token,omitempty"`
	ExpiresIn    int64  `json:"expires_in"`
}

AuthResponse is returned after successful authentication

type AuthService

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

AuthService handles authentication operations

func NewAuthService

func NewAuthService(config *Config, userStore UserStore, sessionStore SessionStore) *AuthService

NewAuthService creates a new authentication service

func (*AuthService) GetOAuthURL

func (a *AuthService) GetOAuthURL(provider OAuthProvider, redirectURI string) (string, error)

GetOAuthURL generates OAuth authorization URL

func (*AuthService) GetSession

func (a *AuthService) GetSession(ctx context.Context, sessionID string) (*SessionData, error)

GetSession retrieves session data

func (*AuthService) Logout

func (a *AuthService) Logout(ctx context.Context, sessionID string) error

Logout invalidates a session

func (*AuthService) LogoutAllSessions

func (a *AuthService) LogoutAllSessions(ctx context.Context, userID string) error

LogoutAllSessions invalidates all sessions for a user

func (*AuthService) OAuthSignIn

func (a *AuthService) OAuthSignIn(ctx context.Context, provider OAuthProvider, state, code string) (*AuthResponse, error)

OAuthSignIn handles OAuth authentication

func (*AuthService) RefreshToken

func (a *AuthService) RefreshToken(ctx context.Context, refreshToken string) (*AuthResponse, error)

RefreshToken generates new access token from refresh token

func (*AuthService) SignIn

func (a *AuthService) SignIn(ctx context.Context, req *SignInRequest) (*AuthResponse, error)

SignIn authenticates a user with email and password

func (*AuthService) SignUp

func (a *AuthService) SignUp(ctx context.Context, req *SignUpRequest) (*AuthResponse, error)

SignUp registers a new user with email and password

func (*AuthService) ValidateToken

func (a *AuthService) ValidateToken(token string) (*TokenClaims, error)

ValidateToken validates an access token and returns claims

type Config

type Config struct {
	// JWT Configuration
	JWTSecret     string
	JWTExpiration time.Duration
	JWTIssuer     string

	// OAuth Google Configuration
	GoogleClientID     string
	GoogleClientSecret string
	GoogleRedirectURI  string
	GoogleScopes       []string

	// OAuth GitHub Configuration
	GitHubClientID     string
	GitHubClientSecret string
	GitHubRedirectURI  string
	GitHubScopes       []string

	// General OAuth Configuration
	OAuthStateExpiration time.Duration
	FrontendSuccessURL   string
	FrontendErrorURL     string

	// Redis Configuration (optional)
	RedisURL         string
	EnableRedisCache bool

	// Security Settings
	BCryptCost               int
	AllowSignup              bool
	RequireEmailVerification bool
}

func NewConfig

func NewConfig() *Config

type GenericAuthHandlers

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

GenericAuthHandlers provides framework-agnostic HTTP handlers for authentication

func NewGenericAuthHandlers

func NewGenericAuthHandlers(authService *AuthService, config *Config) *GenericAuthHandlers

NewGenericAuthHandlers creates new framework-agnostic authentication handlers

func (*GenericAuthHandlers) AuthMiddleware

func (h *GenericAuthHandlers) AuthMiddleware() HTTPMiddleware

AuthMiddleware validates JWT tokens and sets user context

func (*GenericAuthHandlers) GetUserHandler

func (h *GenericAuthHandlers) GetUserHandler(ctx HTTPContext) error

GetUserHandler returns current user info

func (*GenericAuthHandlers) LogoutHandler

func (h *GenericAuthHandlers) LogoutHandler(ctx HTTPContext) error

LogoutHandler handles user logout

func (*GenericAuthHandlers) OAuthCallbackHandler

func (h *GenericAuthHandlers) OAuthCallbackHandler(provider string) HTTPHandler

OAuthCallbackHandler handles OAuth callback

func (*GenericAuthHandlers) OAuthHandler

func (h *GenericAuthHandlers) OAuthHandler(provider string) HTTPHandler

OAuthHandler initiates OAuth flow

func (*GenericAuthHandlers) OptionalAuthMiddleware

func (h *GenericAuthHandlers) OptionalAuthMiddleware() HTTPMiddleware

OptionalAuthMiddleware allows both authenticated and unauthenticated requests

func (*GenericAuthHandlers) RefreshTokenHandler

func (h *GenericAuthHandlers) RefreshTokenHandler(ctx HTTPContext) error

RefreshTokenHandler handles token refresh

func (*GenericAuthHandlers) SignInHandler

func (h *GenericAuthHandlers) SignInHandler(ctx HTTPContext) error

SignInHandler handles user login

func (*GenericAuthHandlers) SignUpHandler

func (h *GenericAuthHandlers) SignUpHandler(ctx HTTPContext) error

SignUpHandler handles user registration

type HTTPContext

type HTTPContext interface {
	// Request operations
	Context() context.Context
	Request() *http.Request
	GetHeader(key string) string
	GetQueryParam(key string) string
	GetFormValue(key string) string
	Bind(dest interface{}) error

	// Response operations
	SetHeader(key, value string)
	SetStatus(code int)
	JSON(code int, data interface{}) error
	Redirect(code int, url string) error
	String(code int, text string) error

	// Cookie operations
	GetCookie(name string) (*http.Cookie, error)
	SetCookie(cookie *http.Cookie)

	// Context values (for middleware)
	Set(key string, value interface{})
	Get(key string) interface{}
}

HTTPContext is a framework-agnostic interface for handling HTTP requests

type HTTPHandler

type HTTPHandler func(HTTPContext) error

HTTPHandler is a generic handler function

type HTTPMiddleware

type HTTPMiddleware func(HTTPHandler) HTTPHandler

HTTPMiddleware is a generic middleware function

type JWTManager

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

func NewJWTManager

func NewJWTManager(secret string, issuer string, expiresIn time.Duration) *JWTManager

func (*JWTManager) GenerateRefreshToken

func (j *JWTManager) GenerateRefreshToken(userID string) (string, error)

func (*JWTManager) GenerateToken

func (j *JWTManager) GenerateToken(claims TokenClaims) (string, error)

func (*JWTManager) ValidateRefreshToken

func (j *JWTManager) ValidateRefreshToken(tokenString string) (string, error)

func (*JWTManager) ValidateToken

func (j *JWTManager) ValidateToken(tokenString string) (*TokenClaims, error)

type MemorySessionStore

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

MemorySessionStore uses in-memory storage (for development/testing)

func NewMemorySessionStore

func NewMemorySessionStore() *MemorySessionStore

func (*MemorySessionStore) Delete

func (m *MemorySessionStore) Delete(ctx context.Context, keys ...string) error

func (*MemorySessionStore) Exists

func (m *MemorySessionStore) Exists(ctx context.Context, keys ...string) (bool, error)

func (*MemorySessionStore) Get

func (m *MemorySessionStore) Get(ctx context.Context, key string, dest interface{}) error

func (*MemorySessionStore) Set

func (m *MemorySessionStore) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error

type OAuthManager

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

func NewOAuthManager

func NewOAuthManager(config *Config, sessionStore SessionStore) *OAuthManager

func (*OAuthManager) GetAuthURL

func (o *OAuthManager) GetAuthURL(provider OAuthProvider, redirectURI string) (string, error)

GetAuthURL generates the OAuth authorization URL

func (*OAuthManager) ValidateCallback

func (o *OAuthManager) ValidateCallback(provider OAuthProvider, state, code string) (*OAuthUserInfo, string, error)

ValidateCallback validates OAuth callback and returns user info

type OAuthProvider

type OAuthProvider string

OAuthProvider represents an OAuth provider

const (
	ProviderGoogle OAuthProvider = "google"
	ProviderGitHub OAuthProvider = "github"
	ProviderLocal  OAuthProvider = "local"
)

type OAuthState

type OAuthState struct {
	State       string    `json:"state"`
	RedirectURI string    `json:"redirect_uri"`
	ExpiresAt   time.Time `json:"expires_at"`
}

OAuthState represents OAuth state data

type OAuthUserInfo

type OAuthUserInfo struct {
	ID        string `json:"id"`
	Email     string `json:"email"`
	Name      string `json:"name"`
	AvatarURL string `json:"avatar_url"`
	Provider  string `json:"provider"`
}

OAuthUserInfo contains user information from OAuth providers

type RedisSessionStore

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

RedisSessionStore uses Redis for session storage

func NewRedisSessionStore

func NewRedisSessionStore(redisURL string) (*RedisSessionStore, error)

func (*RedisSessionStore) Close

func (r *RedisSessionStore) Close() error

func (*RedisSessionStore) Delete

func (r *RedisSessionStore) Delete(ctx context.Context, keys ...string) error

func (*RedisSessionStore) Exists

func (r *RedisSessionStore) Exists(ctx context.Context, keys ...string) (bool, error)

func (*RedisSessionStore) Get

func (r *RedisSessionStore) Get(ctx context.Context, key string, dest interface{}) error

func (*RedisSessionStore) Set

func (r *RedisSessionStore) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error

type Router

type Router interface {
	GET(path string, handler HTTPHandler, middleware ...HTTPMiddleware)
	POST(path string, handler HTTPHandler, middleware ...HTTPMiddleware)
	PUT(path string, handler HTTPHandler, middleware ...HTTPMiddleware)
	DELETE(path string, handler HTTPHandler, middleware ...HTTPMiddleware)
	Group(prefix string, middleware ...HTTPMiddleware) Router
}

Router interface for registering routes

type SessionData

type SessionData struct {
	UserID    string    `json:"user_id"`
	Email     string    `json:"email"`
	CreatedAt time.Time `json:"created_at"`
	ExpiresAt time.Time `json:"expires_at"`
}

SessionData represents session information

type SessionManager

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

SessionManager handles session operations

func NewSessionManager

func NewSessionManager(store SessionStore, prefix string) *SessionManager

func (*SessionManager) CreateSession

func (s *SessionManager) CreateSession(ctx context.Context, userID, email string, duration time.Duration) (string, error)

func (*SessionManager) GetSession

func (s *SessionManager) GetSession(ctx context.Context, sessionID string) (*SessionData, error)

func (*SessionManager) InvalidateSession

func (s *SessionManager) InvalidateSession(ctx context.Context, sessionID string) error

func (*SessionManager) InvalidateUserSessions

func (s *SessionManager) InvalidateUserSessions(ctx context.Context, userID string) error

type SessionStore

type SessionStore interface {
	Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error
	Get(ctx context.Context, key string, dest interface{}) error
	Delete(ctx context.Context, keys ...string) error
	Exists(ctx context.Context, keys ...string) (bool, error)
}

type SignInRequest

type SignInRequest struct {
	Email    string `json:"email" validate:"required,email"`
	Password string `json:"password" validate:"required"`
}

SignInRequest for email/password login

type SignUpRequest

type SignUpRequest struct {
	Email    string `json:"email" validate:"required,email"`
	Password string `json:"password" validate:"required,min=6"`
	Name     string `json:"name,omitempty"`
}

SignUpRequest for email/password registration

type TokenClaims

type TokenClaims struct {
	UserID   string `json:"user_id"`
	Email    string `json:"email"`
	Name     string `json:"name,omitempty"`
	Provider string `json:"provider,omitempty"`
}

TokenClaims represents JWT token claims

type User

type User struct {
	ID        string    `json:"id"`
	Email     string    `json:"email"`
	Name      string    `json:"name,omitempty"`
	AvatarURL string    `json:"avatar_url,omitempty"`
	Provider  string    `json:"provider,omitempty"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

User represents a user in the system

type UserStore

type UserStore interface {
	CreateUser(ctx context.Context, user *User, hashedPassword string) error
	GetUserByEmail(ctx context.Context, email string) (*User, string, error) // returns user and hashed password
	GetUserByID(ctx context.Context, userID string) (*User, error)
	UpdateUser(ctx context.Context, user *User) error
	UserExists(ctx context.Context, email string) (bool, error)
}

UserStore interface for user persistence

type Validator

type Validator interface {
	Validate(interface{}) error
}

Validator interface for request validation

Directories

Path Synopsis
adapters
echo module
gin module
stdlib module
examples
basic command
gin command
mongodb command

Jump to

Keyboard shortcuts

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