From ead620daf9262b5d28763c2067d90d10605e171f Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 2 Jun 2026 09:36:06 -0500 Subject: [PATCH] fix(updates): allow update feeds on private repos via lightweight repo loader Update feed endpoints (updates.xml, dolibarr.json, wordpress.json, packages.json, prestashop.xml, drupal.xml, whmcs.json, changelog.xml) now use RepoAssignmentPublicFeed instead of the full RepoAssignment. The lightweight loader fetches the repo by owner/name without checking user permissions. Feed handlers gate access via license keys, not repo membership. This allows private repos to serve update feeds to anonymous Joomla/WordPress/Composer clients with valid license keys. Co-Authored-By: Claude Opus 4.6 (1M context) --- routers/web/web.go | 2 +- services/context/repo_public_feed.go | 55 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 services/context/repo_public_feed.go diff --git a/routers/web/web.go b/routers/web/web.go index bf111c87f6..67b4be89ec 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1524,7 +1524,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) { m.Get("/updates/drupal.xml", repo.ServeDrupalXML) m.Get("/updates/whmcs.json", repo.ServeWHMCSJSON) m.Get("/changelog.xml", repo.ServeChangelogXML) - }, optSignIn, context.RepoAssignment) + }, context.RepoAssignmentPublicFeed()) // end "/{username}/{reponame}": update server // "/{username}/{reponame}": licenses page diff --git a/services/context/repo_public_feed.go b/services/context/repo_public_feed.go new file mode 100644 index 0000000000..a66f992b75 --- /dev/null +++ b/services/context/repo_public_feed.go @@ -0,0 +1,55 @@ +// Copyright 2026 Moko Consulting +// SPDX-License-Identifier: GPL-3.0-or-later + +package context + +import ( + licenses_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/licenses" + repo_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/repo" + user_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/user" + "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log" +) + +// RepoAssignmentPublicFeed is a lightweight repo loader for update feed endpoints. +// It loads the repo and owner without checking user permissions — the feed +// handlers gate access via license keys instead of repo membership. +// This allows private repos to serve update feeds to anonymous clients. +func RepoAssignmentPublicFeed() func(ctx *Context) { + return func(ctx *Context) { + ownerName := ctx.PathParam("username") + repoName := ctx.PathParam("reponame") + + owner, err := user_model.GetUserByName(ctx, ownerName) + if err != nil { + if user_model.IsErrUserNotExist(err) { + ctx.NotFound(err) + } else { + ctx.ServerError("GetUserByName", err) + } + return + } + + repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, ownerName, repoName) + if err != nil { + if repo_model.IsErrRepoNotExist(err) { + ctx.NotFound(err) + } else { + ctx.ServerError("GetRepositoryByOwnerAndName", err) + } + return + } + + repo.Owner = owner + ctx.Repo.Repository = repo + + // Load update config for platform-aware routing. + repoUpdateCfg, _ := licenses_model.GetRepoConfig(ctx, repo.ID) + if repoUpdateCfg != nil { + ctx.Data["RepoUpdatePlatform"] = repoUpdateCfg.Platform + } else { + ctx.Data["RepoUpdatePlatform"] = "joomla" + } + + log.Trace("Public feed access: %s/%s", ownerName, repoName) + } +} -- 2.52.0