Add auth-required to config.json for Cargo http registry (#26729)

Cargo registry-auth feature requires config.json to have a property
auth-required set to true in order to send token to all registry
requests.
This is ok for git index because you can manually edit the config.json
file to add the auth-required, but when using sparse
(setting index url to
"sparse+https://git.example.com/api/packages/{owner}/cargo/"), the
config.json is dynamically rendered, and does not reflect changes to the
config.json file in the repo.

I see two approaches:
- Serve the real config.json file when fetching the config.json on the
cargo service.
- Automatically detect if the registry requires authorization. (This is
what I implemented in this PR).

What the PR does:
- When a cargo index repository is created, on the config.json, set
auth-required to wether or not the repository is private.
- When the cargo/config.json endpoint is called, set auth-required to
wether or not the request was authorized using an API token.
This commit is contained in:
merlleu 2023-08-28 09:05:39 +02:00 committed by GitHub
parent 8cd46024fd
commit a587d25261
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 7 deletions

View file

@ -16,6 +16,8 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
packages_module "code.gitea.io/gitea/modules/packages" packages_module "code.gitea.io/gitea/modules/packages"
cargo_module "code.gitea.io/gitea/modules/packages/cargo" cargo_module "code.gitea.io/gitea/modules/packages/cargo"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/api/packages/helper" "code.gitea.io/gitea/routers/api/packages/helper"
"code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/convert"
@ -48,7 +50,7 @@ func apiError(ctx *context.Context, status int, obj any) {
// https://rust-lang.github.io/rfcs/2789-sparse-index.html // https://rust-lang.github.io/rfcs/2789-sparse-index.html
func RepositoryConfig(ctx *context.Context) { func RepositoryConfig(ctx *context.Context) {
ctx.JSON(http.StatusOK, cargo_service.BuildConfig(ctx.Package.Owner)) ctx.JSON(http.StatusOK, cargo_service.BuildConfig(ctx.Package.Owner, setting.Service.RequireSignInView || ctx.Package.Owner.Visibility != structs.VisibleTypePublic))
} }
func EnumeratePackageVersions(ctx *context.Context) { func EnumeratePackageVersions(ctx *context.Context) {

View file

@ -21,6 +21,7 @@ import (
cargo_module "code.gitea.io/gitea/modules/packages/cargo" cargo_module "code.gitea.io/gitea/modules/packages/cargo"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
files_service "code.gitea.io/gitea/services/repository/files" files_service "code.gitea.io/gitea/services/repository/files"
) )
@ -222,12 +223,14 @@ func getOrCreateIndexRepository(ctx context.Context, doer, owner *user_model.Use
type Config struct { type Config struct {
DownloadURL string `json:"dl"` DownloadURL string `json:"dl"`
APIURL string `json:"api"` APIURL string `json:"api"`
AuthRequired bool `json:"auth-required"`
} }
func BuildConfig(owner *user_model.User) *Config { func BuildConfig(owner *user_model.User, isPrivate bool) *Config {
return &Config{ return &Config{
DownloadURL: setting.AppURL + "api/packages/" + owner.Name + "/cargo/api/v1/crates", DownloadURL: setting.AppURL + "api/packages/" + owner.Name + "/cargo/api/v1/crates",
APIURL: setting.AppURL + "api/packages/" + owner.Name + "/cargo", APIURL: setting.AppURL + "api/packages/" + owner.Name + "/cargo",
AuthRequired: isPrivate,
} }
} }
@ -239,7 +242,7 @@ func createOrUpdateConfigFile(ctx context.Context, repo *repo_model.Repository,
"Initialize Cargo Config", "Initialize Cargo Config",
func(t *files_service.TemporaryUploadRepository) error { func(t *files_service.TemporaryUploadRepository) error {
var b bytes.Buffer var b bytes.Buffer
err := json.NewEncoder(&b).Encode(BuildConfig(owner)) err := json.NewEncoder(&b).Encode(BuildConfig(owner, setting.Service.RequireSignInView || owner.Visibility != structs.VisibleTypePublic || repo.IsPrivate))
if err != nil { if err != nil {
return err return err
} }