diff --git a/models/licenses/update_stream_config.go b/models/licenses/update_stream_config.go index c8dc1e6e55..32d2e67601 100644 --- a/models/licenses/update_stream_config.go +++ b/models/licenses/update_stream_config.go @@ -24,6 +24,8 @@ type UpdateStreamConfig struct { OwnerID int64 `xorm:"INDEX NOT NULL"` // org or user RepoID int64 `xorm:"INDEX NOT NULL DEFAULT 0"` // 0 = org-level default StreamMode string `xorm:"NOT NULL DEFAULT 'joomla'"` // joomla, custom + Platform string `xorm:"NOT NULL DEFAULT 'joomla'"` // joomla, dolibarr, both + RequireKey bool `xorm:"NOT NULL DEFAULT false"` // require license key for update feed // CustomStreams is a JSON array of stream definitions. // Each entry: {"name":"lts","suffix":"-lts","description":"Long-term support"} CustomStreams string `xorm:"TEXT"` diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index aa7fb2b103..d022bc82f3 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -414,6 +414,8 @@ func prepareMigrationTasks() []*migration { newMigration(334, "Add actions user whitelist to protected branches", v1_27.AddActionsUserWhitelistToProtectedBranch), newMigration(335, "Add license key tables for update server", v1_27.AddLicenseKeyTables), newMigration(336, "Add update stream config table", v1_27.AddUpdateStreamConfigTable), + newMigration(337, "Add key_plain column to license_key", v1_27.AddKeyPlainToLicenseKey), + newMigration(338, "Add platform and require_key to update_stream_config", v1_27.AddPlatformAndRequireKeyToStreamConfig), } return preparedMigrations } diff --git a/models/migrations/v1_27/v337.go b/models/migrations/v1_27/v337.go new file mode 100644 index 0000000000..35495cf580 --- /dev/null +++ b/models/migrations/v1_27/v337.go @@ -0,0 +1,20 @@ +// Copyright 2026 Moko Consulting +// SPDX-License-Identifier: GPL-3.0-or-later + +package v1_27 + +import "xorm.io/xorm" + +type licenseKey337 struct { + ID int64 `xorm:"pk autoincr"` + KeyPlain string `xorm:""` +} + +func (licenseKey337) TableName() string { + return "license_key" +} + +// AddKeyPlainToLicenseKey adds the key_plain column to license_key table. +func AddKeyPlainToLicenseKey(x *xorm.Engine) error { + return x.Sync(new(licenseKey337)) +} diff --git a/models/migrations/v1_27/v338.go b/models/migrations/v1_27/v338.go new file mode 100644 index 0000000000..fe31e21e01 --- /dev/null +++ b/models/migrations/v1_27/v338.go @@ -0,0 +1,22 @@ +// Copyright 2026 Moko Consulting +// SPDX-License-Identifier: GPL-3.0-or-later + +package v1_27 + +import "xorm.io/xorm" + +type updateStreamConfig338 struct { + ID int64 `xorm:"pk autoincr"` + Platform string `xorm:"NOT NULL DEFAULT 'joomla'"` + RequireKey bool `xorm:"NOT NULL DEFAULT false"` +} + +func (updateStreamConfig338) TableName() string { + return "update_stream_config" +} + +// AddPlatformAndRequireKeyToStreamConfig adds platform and require_key +// columns to update_stream_config. +func AddPlatformAndRequireKeyToStreamConfig(x *xorm.Engine) error { + return x.Sync(new(updateStreamConfig338)) +} diff --git a/options/locale/locale_en-US.json b/options/locale/locale_en-US.json index 6658233bf1..eb8eee22d6 100644 --- a/options/locale/locale_en-US.json +++ b/options/locale/locale_en-US.json @@ -2147,7 +2147,10 @@ "repo.settings.unit_visibility": "Visibility", "repo.settings.unit_visibility_private": "Private (follow repo visibility)", "repo.settings.unit_visibility_public": "Public (anyone can read)", - "repo.settings.unit_visibility_releases_help": "Update feeds (updates.xml, dolibarr.json) are always accessible regardless of this setting. Set to Public to also show the releases page to anonymous visitors.", + "repo.settings.unit_visibility_releases_help": "Controls whether the releases page is visible to anonymous visitors.", + "repo.settings.update_platform": "Update Server Platform", + "repo.settings.update_platform_both": "Both (Joomla + Dolibarr)", + "repo.settings.require_update_key": "Require license key for update feed access", "repo.settings.packages_desc": "Enable Repository Packages Registry", "repo.settings.projects_desc": "Enable Projects", "repo.settings.projects_mode_desc": "Projects Mode (which kinds of projects to show)", diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 58e0322726..408eb5960a 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -12,6 +12,7 @@ import ( "git.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db" "git.mokoconsulting.tech/MokoConsulting/MokoGitea/models/organization" + licenses_model "git.mokoconsulting.tech/MokoConsulting/MokoGitea/models/licenses" "git.mokoconsulting.tech/MokoConsulting/MokoGitea/models/perm" repo_model "git.mokoconsulting.tech/MokoConsulting/MokoGitea/models/repo" unit_model "git.mokoconsulting.tech/MokoConsulting/MokoGitea/models/unit" @@ -100,6 +101,8 @@ func SettingsCtxData(ctx *context.Context) { // Settings show a repository's settings page func Settings(ctx *context.Context) { + repoCfg, _ := licenses_model.GetRepoConfig(ctx, ctx.Repo.Repository.ID) + ctx.Data["RepoUpdateConfig"] = repoCfg ctx.HTML(http.StatusOK, tplSettingsOptions) } @@ -672,6 +675,22 @@ func handleSettingsPostAdvanced(ctx *context.Context) { return } } + // Save update server platform and require-key settings. + updatePlatform := form.UpdatePlatform + if updatePlatform == "" { + updatePlatform = "joomla" + } + updateCfg := &licenses_model.UpdateStreamConfig{ + OwnerID: repo.OwnerID, + RepoID: repo.ID, + Platform: updatePlatform, + RequireKey: form.RequireUpdateKey, + StreamMode: "joomla", // inherit org default + } + if err := licenses_model.SaveConfig(ctx, updateCfg); err != nil { + log.Error("SaveConfig: %v", err) + } + log.Trace("Repository advanced settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name) ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success")) diff --git a/routers/web/repo/updateserver.go b/routers/web/repo/updateserver.go index 957ecd60de..121112ddc5 100644 --- a/routers/web/repo/updateserver.go +++ b/routers/web/repo/updateserver.go @@ -23,7 +23,13 @@ func validateUpdateKey(ctx *context.Context) (allowedChannels []string, ok bool) } if rawKey == "" { - // No key provided — allow public access (all channels). + // Check if this repo requires a key for update feed access. + repoCfg, _ := licenses.GetRepoConfig(ctx, ctx.Repo.Repository.ID) + if repoCfg != nil && repoCfg.RequireKey { + // Key required but not provided — return empty. + return nil, false + } + // No key required — allow public access (all channels). return nil, true } diff --git a/services/context/repo.go b/services/context/repo.go index 88a0d7d61b..46c587e696 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -614,6 +614,14 @@ func repoAssignmentPrepareTemplateData(ctx *Context, data *repoAssignmentPrepare ctx.Data["EnableLicenses"] = numLicensePackages > 0 ctx.Data["IsRepoAdmin"] = ctx.Repo.Permission.IsAdmin() + // Load repo update config for platform-aware UI. + repoUpdateCfg, _ := licenses_model.GetRepoConfig(ctx, repo.ID) + if repoUpdateCfg != nil { + ctx.Data["RepoUpdatePlatform"] = repoUpdateCfg.Platform + } else { + ctx.Data["RepoUpdatePlatform"] = "joomla" + } + ctx.Data["Title"] = repo.Owner.Name + "/" + repo.Name ctx.Data["PageTitleCommon"] = repo.Name + " - " + setting.AppName ctx.Data["Repository"] = repo diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index f6312c1348..651718a473 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -133,6 +133,8 @@ type RepoSettingForm struct { EnableReleases bool ReleasesVisibility string + UpdatePlatform string + RequireUpdateKey bool EnablePackages bool diff --git a/templates/repo/release_tag_header.tmpl b/templates/repo/release_tag_header.tmpl index 3b675e79ae..3e83f132d5 100644 --- a/templates/repo/release_tag_header.tmpl +++ b/templates/repo/release_tag_header.tmpl @@ -17,9 +17,16 @@ {{end}} {{if not .PageIsTagList}} - - {{svg "octicon-download" 16}} {{ctx.Locale.Tr "repo.release.update_feed"}} - + {{if or (eq .RepoUpdatePlatform "joomla") (eq .RepoUpdatePlatform "both") (eq .RepoUpdatePlatform "")}} + + {{svg "octicon-download" 16}} Joomla XML + + {{end}} + {{if or (eq .RepoUpdatePlatform "dolibarr") (eq .RepoUpdatePlatform "both")}} + + {{svg "octicon-download" 16}} Dolibarr JSON + + {{end}} {{end}} {{if and (not .PageIsTagList) .CanCreateRelease}} diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 9dfaa8407d..b9c79de630 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -514,6 +514,20 @@

{{ctx.Locale.Tr "repo.settings.unit_visibility_releases_help"}}

+
+ + +
+
+
+ + +
+
{{$isPackagesEnabled := .Repository.UnitEnabled ctx ctx.Consts.RepoUnitTypePackages}}