2
0
Files
gitcaddy-vault/plugin.go
logikonline 1443be11bc fix: handle web.Router compatibility for compiled-in mode
When compiled into the server, the router passed is *web.Router not chi.Router.
Added ChiRouterProvider interface to extract the underlying chi router.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 00:33:21 -05:00

166 lines
4.1 KiB
Go

// Copyright 2026 MarketAlly. All rights reserved.
// Business Source License 1.1 - See LICENSE file for details.
package vault
import (
"context"
"git.marketally.com/gitcaddy/gitcaddy-vault/license"
"git.marketally.com/gitcaddy/gitcaddy-vault/models"
"git.marketally.com/gitcaddy/gitcaddy-vault/routes"
"code.gitcaddy.com/server/v3/modules/log"
"code.gitcaddy.com/server/v3/modules/plugins"
"github.com/go-chi/chi/v5"
"xorm.io/xorm"
)
const (
PluginName = "vault"
PluginVersion = "1.0.0"
)
// PluginVersion can be set at build time
var Version = PluginVersion
// init automatically registers the vault when this package is imported
func init() {
Register()
}
// VaultPlugin is the main entry point for the GitCaddy Vault plugin
type VaultPlugin struct {
license *license.Manager
}
// New creates a new VaultPlugin instance
func New() *VaultPlugin {
return &VaultPlugin{
license: license.NewManager(),
}
}
// Name returns the plugin name
func (p *VaultPlugin) Name() string {
return PluginName
}
// Version returns the plugin version
func (p *VaultPlugin) Version() string {
return PluginVersion
}
// Description returns the plugin description
func (p *VaultPlugin) Description() string {
return "Secure secrets management for GitCaddy repositories"
}
// Init initializes the plugin
func (p *VaultPlugin) Init(ctx context.Context) error {
log.Info("Initializing GitCaddy Vault plugin v%s", PluginVersion)
// Load and validate license
if err := p.license.Load(); err != nil {
log.Warn("Vault license not found or invalid: %v", err)
log.Warn("Vault features will be disabled. Visit https://gitcaddy.com/vault to purchase a license.")
} else {
info := p.license.Info()
log.Info("Vault licensed: tier=%s, expires=%v", info.Tier, info.ExpiresAt)
}
return nil
}
// Shutdown cleans up the plugin
func (p *VaultPlugin) Shutdown(ctx context.Context) error {
log.Info("Shutting down GitCaddy Vault plugin")
return nil
}
// RegisterModels returns the database models for this plugin
func (p *VaultPlugin) RegisterModels() []any {
return []any{
new(models.VaultSecret),
new(models.VaultSecretVersion),
new(models.VaultAuditEntry),
new(models.VaultToken),
new(models.VaultRepoKey),
}
}
// Migrate runs database migrations for this plugin
func (p *VaultPlugin) Migrate(ctx context.Context, x *xorm.Engine) error {
return x.Sync(p.RegisterModels()...)
}
// ChiRouterProvider is an interface for objects that can provide a chi.Router
type ChiRouterProvider interface {
ChiRouter() chi.Router
}
// getChiRouter extracts a chi.Router from various types
func getChiRouter(m any) chi.Router {
// Try direct chi.Router first
if r, ok := m.(chi.Router); ok {
return r
}
// Try ChiRouter() method (for *web.Router)
if provider, ok := m.(ChiRouterProvider); ok {
return provider.ChiRouter()
}
return nil
}
// RegisterRepoWebRoutes adds vault routes under /{owner}/{repo}/vault
func (p *VaultPlugin) RegisterRepoWebRoutes(m any) {
r := getChiRouter(m)
if r == nil {
return
}
routes.RegisterRepoWebRoutes(r, p.license)
}
// RegisterRepoAPIRoutes adds vault API routes under /api/v1/repos/{owner}/{repo}/vault
func (p *VaultPlugin) RegisterRepoAPIRoutes(m any) {
r := getChiRouter(m)
if r == nil {
return
}
routes.RegisterRepoAPIRoutes(r, p.license)
}
// ValidateLicense validates the plugin license
func (p *VaultPlugin) ValidateLicense(ctx context.Context) error {
return p.license.Validate()
}
// LicenseInfo returns current license information
func (p *VaultPlugin) LicenseInfo() *plugins.LicenseInfo {
info := p.license.Info()
if info == nil {
return nil
}
return &plugins.LicenseInfo{
Valid: info.Valid,
Tier: info.Tier,
CustomerID: info.CustomerEmail,
ExpiresAt: info.ExpiresAt,
GracePeriod: info.GracePeriod,
}
}
// Ensure VaultPlugin implements all required interfaces
var (
_ plugins.Plugin = (*VaultPlugin)(nil)
_ plugins.DatabasePlugin = (*VaultPlugin)(nil)
_ plugins.RepoRoutesPlugin = (*VaultPlugin)(nil)
_ plugins.LicensedPlugin = (*VaultPlugin)(nil)
)
// Register registers the vault plugin with GitCaddy
func Register() {
plugins.Register(New())
}