2
0
Files
logikonline d1f20f6b46
All checks were successful
Build and Release / Create Release (push) Successful in 0s
Build and Release / Unit Tests (push) Successful in 3m10s
Build and Release / Integration Tests (PostgreSQL) (push) Successful in 5m13s
Build and Release / Lint (push) Successful in 5m25s
Build and Release / Build Binaries (amd64, linux, linux-latest) (push) Successful in 3m13s
Build and Release / Build Binaries (amd64, windows, windows-latest) (push) Successful in 8h5m42s
Build and Release / Build Binaries (amd64, darwin, macos) (push) Successful in 7m30s
Build and Release / Build Binaries (arm64, darwin, macos) (push) Successful in 7m55s
Build and Release / Build Binary (linux/arm64) (push) Successful in 7m36s
feat(ci): add repository subscription monetization system
Implement complete subscription monetization system for repositories with Stripe and PayPal integration. Includes:
- Database models and migrations for monetization settings, subscription products, and user subscriptions
- Payment provider abstraction layer with Stripe and PayPal implementations
- Admin UI for configuring payment providers and viewing subscriptions
- Repository settings UI for managing subscription products and tiers
- Subscription checkout flow and webhook handlers for payment events
- Access control to gate repository code behind active subscriptions
2026-01-31 13:37:07 -05:00

87 lines
2.5 KiB
Go

// Copyright 2026 MarketAlly. All rights reserved.
// SPDX-License-Identifier: MIT
package context
import (
"net/http"
monetize_model "code.gitcaddy.com/server/v3/models/monetize"
perm_model "code.gitcaddy.com/server/v3/models/perm"
"code.gitcaddy.com/server/v3/modules/setting"
"code.gitcaddy.com/server/v3/modules/templates"
)
const tplSubscribe templates.TplName = "repo/subscribe"
// RequireSubscriptionForCode returns middleware that gates code access behind a paid subscription.
// It checks:
// 1. Is monetization enabled globally?
// 2. Does this repo have subscriptions enabled?
// 3. Is the user the owner, admin, or collaborator with write access? (bypass)
// 4. Is the user a site admin? (bypass)
// 5. Does the user have an active subscription? If not, show the subscribe page.
func RequireSubscriptionForCode() func(ctx *Context) {
return func(ctx *Context) {
if !setting.Monetize.Enabled {
return
}
if ctx.Repo.Repository == nil || !ctx.Repo.Repository.SubscriptionsEnabled {
return
}
// Bypass for owner, admin, and collaborators with write+ access
if ctx.Repo.IsOwner() || ctx.Repo.IsAdmin() {
return
}
if ctx.Repo.Permission.AccessMode >= perm_model.AccessModeWrite {
return
}
// Bypass for site admins
if ctx.Doer != nil && ctx.Doer.IsAdmin {
return
}
// Bypass for unauthenticated users on public repos — they see the subscribe prompt
if ctx.Doer == nil {
ctx.Redirect(ctx.Repo.RepoLink + "/subscribe")
return
}
// Check if user has an active subscription
hasAccess, err := monetize_model.HasActiveSubscription(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("HasActiveSubscription", err)
return
}
if hasAccess {
return
}
// Show subscribe page with HTTP 402
ctx.Data["Title"] = ctx.Tr("repo.subscribe.title")
products, err := monetize_model.GetActiveProductsByRepoID(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("GetActiveProductsByRepoID", err)
return
}
ctx.Data["Products"] = products
settings, err := monetize_model.GetSetting(ctx)
if err != nil {
ctx.ServerError("GetSetting", err)
return
}
ctx.Data["StripeEnabled"] = settings.StripeEnabled
ctx.Data["StripePublishableKey"] = settings.StripePublishableKey
ctx.Data["PayPalEnabled"] = settings.PayPalEnabled
ctx.Data["PayPalClientID"] = settings.PayPalClientID
ctx.Data["PayPalSandbox"] = settings.PayPalSandbox
ctx.HTML(http.StatusPaymentRequired, tplSubscribe)
}
}