Some checks failed
Build and Release / Build Binaries (arm64, darwin, macos) (push) Has been cancelled
Build and Release / Build Binaries (amd64, windows, windows-latest) (push) Has been cancelled
Build and Release / Build Binary (linux/arm64) (push) Has been cancelled
Build and Release / Lint (push) Has been cancelled
Build and Release / Unit Tests (push) Has been cancelled
Build and Release / Build Binaries (amd64, linux, linux-latest) (push) Has been cancelled
Build and Release / Build Binaries (amd64, darwin, macos) (push) Has been cancelled
Build and Release / Create Release (push) Has been cancelled
Build and Release / Integration Tests (PostgreSQL) (push) Has been cancelled
Introduce PluginRouter interface to standardize plugin route registration and replace the previous 'any' type approach. Add WebRouterAdapter to wrap web.Router and handle path prefixes correctly. This provides a cleaner, type-safe API for plugins to register routes without needing to know about the underlying router implementation.
185 lines
5.4 KiB
Go
185 lines
5.4 KiB
Go
// Copyright 2026 MarketAlly. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package plugins
|
|
|
|
import (
|
|
"context"
|
|
|
|
"xorm.io/xorm"
|
|
)
|
|
|
|
// Plugin defines the interface that all GitCaddy plugins must implement
|
|
type Plugin interface {
|
|
// Name returns the unique identifier for this plugin
|
|
Name() string
|
|
|
|
// Version returns the plugin version
|
|
Version() string
|
|
|
|
// Description returns a human-readable description
|
|
Description() string
|
|
|
|
// Init is called when the plugin is loaded
|
|
Init(ctx context.Context) error
|
|
|
|
// Shutdown is called when the server is shutting down
|
|
Shutdown(ctx context.Context) error
|
|
}
|
|
|
|
// DatabasePlugin is implemented by plugins that need database tables
|
|
type DatabasePlugin interface {
|
|
Plugin
|
|
|
|
// RegisterModels returns the models to be registered with the database
|
|
RegisterModels() []any
|
|
|
|
// Migrate runs any database migrations for this plugin
|
|
Migrate(ctx context.Context, x *xorm.Engine) error
|
|
}
|
|
|
|
// WebRoutesPlugin is implemented by plugins that add web UI routes
|
|
type WebRoutesPlugin interface {
|
|
Plugin
|
|
|
|
// RegisterWebRoutes adds routes to the web UI router
|
|
// The router is a *web.Router from the gitcaddy server
|
|
RegisterWebRoutes(m any)
|
|
}
|
|
|
|
// APIRoutesPlugin is implemented by plugins that add API routes
|
|
type APIRoutesPlugin interface {
|
|
Plugin
|
|
|
|
// RegisterAPIRoutes adds routes to the API router
|
|
// The router is a *web.Router from the gitcaddy server
|
|
RegisterAPIRoutes(m any)
|
|
}
|
|
|
|
// RepoRoutesPlugin is implemented by plugins that add per-repository routes
|
|
type RepoRoutesPlugin interface {
|
|
Plugin
|
|
|
|
// RegisterRepoWebRoutes adds routes under /{owner}/{repo}/
|
|
// The router is a PluginRouter that handles path prefixes correctly
|
|
RegisterRepoWebRoutes(r PluginRouter)
|
|
|
|
// RegisterRepoAPIRoutes adds routes under /api/v1/repos/{owner}/{repo}/
|
|
// The router is a PluginRouter that handles path prefixes correctly
|
|
RegisterRepoAPIRoutes(r PluginRouter)
|
|
}
|
|
|
|
// LicensedPlugin is implemented by plugins that require a license
|
|
type LicensedPlugin interface {
|
|
Plugin
|
|
|
|
// ValidateLicense checks if the plugin is properly licensed
|
|
ValidateLicense(ctx context.Context) error
|
|
|
|
// LicenseInfo returns information about the current license
|
|
LicenseInfo() *LicenseInfo
|
|
}
|
|
|
|
// License tier constants
|
|
const (
|
|
TierSolo = "solo"
|
|
TierPro = "pro"
|
|
TierTeam = "team"
|
|
TierEnterprise = "enterprise"
|
|
)
|
|
|
|
// LicenseInfo contains license details
|
|
type LicenseInfo struct {
|
|
Valid bool
|
|
Tier string // e.g., "solo", "pro", "team", "enterprise"
|
|
CustomerID string
|
|
ExpiresAt int64
|
|
GracePeriod bool // true if in grace period after expiry
|
|
}
|
|
|
|
// LicenseLimits defines the limits for each tier
|
|
type LicenseLimits struct {
|
|
Users int // Max users with vault access (-1 = unlimited)
|
|
SecretsPerRepo int // Max secrets per repo (-1 = unlimited)
|
|
AuditRetentionDays int // Days to keep audit logs
|
|
VersioningEnabled bool // Can use secret versioning/rollback
|
|
MaxVersions int // Max versions to keep per secret (-1 = unlimited, 0 = disabled)
|
|
CICDTokensEnabled bool // Can create CI/CD tokens
|
|
MaxTokens int // Max CI/CD tokens per repo (-1 = unlimited, 0 = disabled)
|
|
MaxTokenTTLHours int // Max token TTL in hours (-1 = unlimited)
|
|
TokensReadOnly bool // If true, tokens can only read secrets (not write)
|
|
SSOEnabled bool // Can use SSO/SAML
|
|
}
|
|
|
|
// DefaultSoloLicense returns the default Solo tier license (free, no registration required)
|
|
func DefaultSoloLicense() *LicenseInfo {
|
|
return &LicenseInfo{
|
|
Valid: true,
|
|
Tier: TierSolo,
|
|
CustomerID: "",
|
|
ExpiresAt: 0, // Never expires
|
|
GracePeriod: false,
|
|
}
|
|
}
|
|
|
|
// GetLimitsForTier returns the limits for a given license tier
|
|
func GetLimitsForTier(tier string) *LicenseLimits {
|
|
switch tier {
|
|
case TierSolo:
|
|
return &LicenseLimits{
|
|
Users: 1,
|
|
SecretsPerRepo: 5,
|
|
AuditRetentionDays: 7,
|
|
VersioningEnabled: true, // Limited versioning
|
|
MaxVersions: 2, // Keep last 2 versions only
|
|
CICDTokensEnabled: true, // Limited CI/CD
|
|
MaxTokens: 1, // 1 token only
|
|
MaxTokenTTLHours: 24, // Max 24h TTL
|
|
TokensReadOnly: true, // Read-only access
|
|
SSOEnabled: false,
|
|
}
|
|
case TierPro:
|
|
return &LicenseLimits{
|
|
Users: 5,
|
|
SecretsPerRepo: -1, // Unlimited
|
|
AuditRetentionDays: 90,
|
|
VersioningEnabled: true,
|
|
MaxVersions: -1, // Unlimited
|
|
CICDTokensEnabled: true,
|
|
MaxTokens: -1, // Unlimited
|
|
MaxTokenTTLHours: -1, // Unlimited
|
|
TokensReadOnly: false,
|
|
SSOEnabled: false,
|
|
}
|
|
case TierTeam:
|
|
return &LicenseLimits{
|
|
Users: 25,
|
|
SecretsPerRepo: -1, // Unlimited
|
|
AuditRetentionDays: 365,
|
|
VersioningEnabled: true,
|
|
MaxVersions: -1, // Unlimited
|
|
CICDTokensEnabled: true,
|
|
MaxTokens: -1, // Unlimited
|
|
MaxTokenTTLHours: -1, // Unlimited
|
|
TokensReadOnly: false,
|
|
SSOEnabled: true,
|
|
}
|
|
case TierEnterprise:
|
|
return &LicenseLimits{
|
|
Users: -1, // Unlimited
|
|
SecretsPerRepo: -1, // Unlimited
|
|
AuditRetentionDays: -1, // Custom/unlimited
|
|
VersioningEnabled: true,
|
|
MaxVersions: -1, // Unlimited
|
|
CICDTokensEnabled: true,
|
|
MaxTokens: -1, // Unlimited
|
|
MaxTokenTTLHours: -1, // Unlimited
|
|
TokensReadOnly: false,
|
|
SSOEnabled: true,
|
|
}
|
|
default:
|
|
// Unknown tier defaults to Solo limits
|
|
return GetLimitsForTier(TierSolo)
|
|
}
|
|
}
|