feat: [AH-1261]: fix auth issue in gitness (#3732)

* feat: [AH-1261]: fix auth issue in gitness
This commit is contained in:
Tudor Macari 2025-04-29 20:05:51 +00:00 committed by Harness
parent 6aa9e3cfbc
commit 57f613cac1
15 changed files with 128 additions and 89 deletions

View File

@ -527,7 +527,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
}
registryHelper := rpm.LocalRegistryHelperProvider(fileManager, artifactRepository)
indexService := index.ProvideService(registryHelper)
apiHandler := router.APIHandlerProvider(registryRepository, upstreamProxyConfigRepository, fileManager, tagRepository, manifestRepository, cleanupPolicyRepository, imageRepository, storageDriver, spaceFinder, transactor, authenticator, provider, authorizer, auditService, artifactRepository, webhooksRepository, webhooksExecutionRepository, service2, spacePathStore, reporter10, downloadStatRepository, indexService)
apiHandler := router.APIHandlerProvider(registryRepository, upstreamProxyConfigRepository, fileManager, tagRepository, manifestRepository, cleanupPolicyRepository, imageRepository, storageDriver, spaceFinder, transactor, authenticator, provider, authorizer, auditService, artifactRepository, webhooksRepository, webhooksExecutionRepository, service2, spacePathStore, reporter10, downloadStatRepository, indexService, config)
mavenDBStore := maven.DBStoreProvider(registryRepository, imageRepository, artifactRepository, spaceStore, bandwidthStatRepository, downloadStatRepository, nodesRepository, upstreamProxyConfigRepository)
mavenLocalRegistry := maven.LocalRegistryProvider(mavenDBStore, transactor, fileManager)
mavenController := maven.ProvideProxyController(mavenLocalRegistry, secretService, spaceFinder)

View File

@ -37,6 +37,7 @@ func GetArtifactMetadata(
artifacts []types.ArtifactMetadata,
rootIdentifier string,
urlProvider url.Provider,
setupDetailsAuthHeaderPrefix string,
) []artifactapi.ArtifactMetadata {
artifactMetadataList := make([]artifactapi.ArtifactMetadata, 0, len(artifacts))
for _, artifact := range artifacts {
@ -44,7 +45,7 @@ func GetArtifactMetadata(
if artifact.PackageType == artifactapi.PackageTypeGENERIC {
registryURL = urlProvider.RegistryURL(ctx, rootIdentifier, "generic", artifact.RepoName)
}
artifactMetadata := mapToArtifactMetadata(artifact, registryURL)
artifactMetadata := mapToArtifactMetadata(artifact, registryURL, setupDetailsAuthHeaderPrefix)
artifactMetadataList = append(artifactMetadataList, *artifactMetadata)
}
return artifactMetadataList
@ -83,11 +84,12 @@ func GetMavenArtifactDetail(
func mapToArtifactMetadata(
artifact types.ArtifactMetadata,
registryURL string,
setupDetailsAuthHeaderPrefix string,
) *artifactapi.ArtifactMetadata {
lastModified := GetTimeInMs(artifact.ModifiedAt)
packageType := artifact.PackageType
pullCommand := GetPullCommand(artifact.Name, artifact.Version,
string(packageType), registryURL)
string(packageType), registryURL, setupDetailsAuthHeaderPrefix)
return &artifactapi.ArtifactMetadata{
RegistryIdentifier: artifact.RepoName,
Name: artifact.Name,
@ -140,13 +142,14 @@ func GetTagMetadata(
tags *[]types.TagMetadata,
image string,
registryURL string,
setupDetailsAuthHeaderPrefix string,
) []artifactapi.ArtifactVersionMetadata {
artifactVersionMetadataList := []artifactapi.ArtifactVersionMetadata{}
for _, tag := range *tags {
modifiedAt := GetTimeInMs(tag.ModifiedAt)
size := GetImageSize(tag.Size)
digestCount := tag.DigestCount
command := GetPullCommand(image, tag.Name, string(tag.PackageType), registryURL)
command := GetPullCommand(image, tag.Name, string(tag.PackageType), registryURL, setupDetailsAuthHeaderPrefix)
packageType, err := toPackageType(string(tag.PackageType))
downloadCount := tag.DownloadCount
if err != nil {
@ -175,12 +178,13 @@ func GetAllArtifactResponse(
pageSize int,
rootIdentifier string,
urlProvider url.Provider,
setupDetailsAuthHeaderPrefix string,
) *artifactapi.ListArtifactResponseJSONResponse {
var artifactMetadataList []artifactapi.ArtifactMetadata
if artifacts == nil {
artifactMetadataList = make([]artifactapi.ArtifactMetadata, 0)
} else {
artifactMetadataList = GetArtifactMetadata(ctx, *artifacts, rootIdentifier, urlProvider)
artifactMetadataList = GetArtifactMetadata(ctx, *artifacts, rootIdentifier, urlProvider, setupDetailsAuthHeaderPrefix)
}
pageCount := GetPageCount(count, pageSize)
listArtifact := &artifactapi.ListArtifact{
@ -206,12 +210,14 @@ func GetAllArtifactFilesResponse(
artifactName string,
version string,
packageType artifactapi.PackageType,
setupDetailsAuthHeaderPrefix string,
) *artifactapi.FileDetailResponseJSONResponse {
var fileMetadataList []artifactapi.FileDetail
if files == nil {
fileMetadataList = make([]artifactapi.FileDetail, 0)
} else {
fileMetadataList = GetArtifactFilesMetadata(files, registryURL, artifactName, version, packageType)
fileMetadataList = GetArtifactFilesMetadata(files, registryURL, artifactName,
version, packageType, setupDetailsAuthHeaderPrefix)
}
pageCount := GetPageCount(count, pageSize)
return &artifactapi.FileDetailResponseJSONResponse{
@ -230,6 +236,7 @@ func GetArtifactFilesMetadata(
artifactName string,
version string,
packageType artifactapi.PackageType,
setupDetailsAuthHeaderPrefix string,
) []artifactapi.FileDetail {
var files []artifactapi.FileDetail
for _, file := range *metadata {
@ -239,15 +246,17 @@ func GetArtifactFilesMetadata(
//nolint:exhaustive
switch packageType {
case artifactapi.PackageTypeGENERIC, artifactapi.PackageTypePYTHON, artifactapi.PackageTypeNPM:
downloadCommand = GetGenericArtifactFileDownloadCommand(registryURL, artifactName, version, filename)
downloadCommand = GetGenericArtifactFileDownloadCommand(registryURL, artifactName,
version, filename, setupDetailsAuthHeaderPrefix)
case artifactapi.PackageTypeMAVEN:
artifactName = strings.ReplaceAll(artifactName, ".", "/")
artifactName = strings.ReplaceAll(artifactName, ":", "/")
filePathPrefix = "/" + artifactName + "/" + version + "/"
filename = strings.Replace(file.Path, filePathPrefix, "", 1)
downloadCommand = GetMavenArtifactFileDownloadCommand(registryURL, artifactName, version, filename)
downloadCommand = GetMavenArtifactFileDownloadCommand(registryURL, artifactName,
version, filename, setupDetailsAuthHeaderPrefix)
case artifactapi.PackageTypeRPM:
downloadCommand = GetRPMArtifactFileDownloadCommand(registryURL, filename)
downloadCommand = GetRPMArtifactFileDownloadCommand(registryURL, filename, setupDetailsAuthHeaderPrefix)
}
files = append(files, artifactapi.FileDetail{
Checksums: getCheckSums(file),
@ -325,9 +334,10 @@ func GetAllArtifactVersionResponse(
pageNumber int64,
pageSize int,
registryURL string,
setupDetailsAuthHeaderPrefix string,
) *artifactapi.ListArtifactVersionResponseJSONResponse {
artifactVersionMetadataList := GetTagMetadata(
ctx, tags, image, registryURL,
ctx, tags, image, registryURL, setupDetailsAuthHeaderPrefix,
)
pageCount := GetPageCount(count, pageSize)
listArtifactVersions := &artifactapi.ListArtifactVersion{
@ -352,10 +362,10 @@ func GetNonOCIAllArtifactVersionResponse(
pageNumber int64,
pageSize int,
registryURL string,
setupDetailsAuthHeaderPrefix string,
) *artifactapi.ListArtifactVersionResponseJSONResponse {
artifactVersionMetadataList := GetNonOCIArtifactMetadata(
ctx, artifacts, image, registryURL,
)
ctx, artifacts, image, registryURL, setupDetailsAuthHeaderPrefix)
pageCount := GetPageCount(count, pageSize)
listArtifactVersions := &artifactapi.ListArtifactVersion{
ItemCount: &count,
@ -376,12 +386,13 @@ func GetNonOCIArtifactMetadata(
tags *[]types.NonOCIArtifactMetadata,
image string,
registryURL string,
setupDetailsAuthHeaderPrefix string,
) []artifactapi.ArtifactVersionMetadata {
artifactVersionMetadataList := []artifactapi.ArtifactVersionMetadata{}
for _, tag := range *tags {
modifiedAt := GetTimeInMs(tag.ModifiedAt)
size := GetImageSize(tag.Size)
command := GetPullCommand(image, tag.Name, string(tag.PackageType), registryURL)
command := GetPullCommand(image, tag.Name, string(tag.PackageType), registryURL, setupDetailsAuthHeaderPrefix)
packageType, err := toPackageType(string(tag.PackageType))
downloadCount := tag.DownloadCount
if err != nil {

View File

@ -53,6 +53,7 @@ type APIController struct {
ArtifactEventReporter registryevents.Reporter
DownloadStatRepository store.DownloadStatRepository
RegistryIndexService index.Service
SetupDetailsAuthHeaderPrefix string
}
func NewAPIController(
@ -79,6 +80,7 @@ func NewAPIController(
artifactEventReporter registryevents.Reporter,
downloadStatRepository store.DownloadStatRepository,
registryIndexService index.Service,
setupDetailsAuthHeaderPrefix string,
) *APIController {
return &APIController{
fileManager: fileManager,
@ -104,5 +106,6 @@ func NewAPIController(
ArtifactEventReporter: artifactEventReporter,
DownloadStatRepository: downloadStatRepository,
RegistryIndexService: registryIndexService,
SetupDetailsAuthHeaderPrefix: setupDetailsAuthHeaderPrefix,
}
}

View File

@ -264,6 +264,7 @@ func TestCreateRegistry(t *testing.T) {
eventReporter,
nil, // downloadStatRepository.
nil, // registryIndexService - not needed for this test.
"",
)
},
},
@ -335,6 +336,7 @@ func TestCreateRegistry(t *testing.T) {
eventReporter,
nil, //
nil, // downloadStatRepository.
"",
)
},
},

View File

@ -131,7 +131,7 @@ func (c *APIController) GetArtifactFiles(
return artifact.GetArtifactFiles200JSONResponse{
FileDetailResponseJSONResponse: *GetAllArtifactFilesResponse(
fileMetadataList, count, reqInfo.pageNumber, reqInfo.limit, registryURL, img.Name, art.Version,
registry.PackageType),
registry.PackageType, c.SetupDetailsAuthHeaderPrefix),
}, nil
default:
return artifact.GetArtifactFiles400JSONResponse{

View File

@ -91,7 +91,7 @@ func (c *APIController) GetAllArtifacts(
}
return artifact.GetAllArtifacts200JSONResponse{
ListArtifactResponseJSONResponse: *GetAllArtifactResponse(ctx, artifacts, count, regInfo.pageNumber, regInfo.limit,
regInfo.RootIdentifier, c.URLProvider),
regInfo.RootIdentifier, c.URLProvider, c.SetupDetailsAuthHeaderPrefix),
}, nil
}

View File

@ -130,6 +130,7 @@ func (c *APIController) GetAllArtifactVersions(
ListArtifactVersionResponseJSONResponse: *GetAllArtifactVersionResponse(
ctx, tags, image, count, regInfo.pageNumber, regInfo.limit,
c.URLProvider.RegistryURL(ctx, regInfo.RootIdentifier, regInfo.RegistryIdentifier),
c.SetupDetailsAuthHeaderPrefix,
),
}, nil
}
@ -150,6 +151,7 @@ func (c *APIController) GetAllArtifactVersions(
ListArtifactVersionResponseJSONResponse: *GetNonOCIAllArtifactVersionResponse(
ctx, metadata, image, cnt, regInfo.pageNumber, regInfo.limit,
c.URLProvider.RegistryURL(ctx, regInfo.RootIdentifier, regInfo.RegistryIdentifier),
c.SetupDetailsAuthHeaderPrefix,
),
}, nil
}

View File

@ -278,7 +278,7 @@ func (c *APIController) generateGenericClientSetupDetail(
header2 := "Upload Artifact"
section2step1Header := "Run this curl command in your terminal to push the artifact."
//nolint:lll
pushValue := "curl --location --request PUT '<HOSTNAME>/<ARTIFACT_NAME>/<VERSION>' \\\n--form 'filename=\"<FILENAME>\"' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--form 'description=\"<DESC>\"' \\\n--header 'x-api-key: <API_KEY>'"
pushValue := "curl --location --request PUT '<HOSTNAME>/<ARTIFACT_NAME>/<VERSION>' \\\n--form 'filename=\"<FILENAME>\"' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--form 'description=\"<DESC>\"' \\\n--header '<AUTH_HEADER_PREFIX> <API_KEY>'"
section2step1Commands := []artifact.ClientSetupStepCommand{
{Label: &blankString, Value: &pushValue},
}
@ -299,7 +299,7 @@ func (c *APIController) generateGenericClientSetupDetail(
header3 := "Download Artifact"
section3step1Header := "Run this command in your terminal to download the artifact."
//nolint:lll
pullValue := "curl --location '<HOSTNAME>/<ARTIFACT_NAME>/<VERSION>' \\\n--form 'filename=\"<FILENAME>\"' --header 'x-api-key: <API_KEY>' " +
pullValue := "curl --location '<HOSTNAME>/<ARTIFACT_NAME>/<VERSION>' \\\n--form 'filename=\"<FILENAME>\"' --header '<AUTH_HEADER_PREFIX> <API_KEY>' " +
"-o <FILENAME>"
section3step1Commands := []artifact.ClientSetupStepCommand{
{Label: &blankString, Value: &pullValue},
@ -869,7 +869,7 @@ func (c *APIController) generateRpmClientSetupDetail(
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: utils.StringPtr("curl --location --request PUT '<REGISTRY_URL>/' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--header 'x-api-key: <API_KEY>'"),
Value: utils.StringPtr("curl --location --request PUT '<REGISTRY_URL>/' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--header '<AUTH_HEADER_PREFIX> <API_KEY>'"),
},
},
},
@ -936,7 +936,7 @@ func (c *APIController) generateRpmClientSetupDetail(
Commands: &[]artifact.ClientSetupStepCommand{
{
//nolint:lll
Value: utils.StringPtr("curl --location --request PUT '<REGISTRY_URL>/' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--header 'x-api-key: <API_KEY>'"),
Value: utils.StringPtr("curl --location --request PUT '<REGISTRY_URL>/' \\\n--form 'file=@\"<FILE_PATH>\"' \\\n--header '<AUTH_HEADER_PREFIX> <API_KEY>'"),
},
},
},
@ -1264,13 +1264,13 @@ func (c *APIController) replacePlaceholdersInSection(
continue
}
for j := range *st.Commands {
replaceText(username, st, j, hostname, registryName, image, tag, registryURL, groupID, uploadURL)
c.replaceText(username, st, j, hostname, registryName, image, tag, registryURL, groupID, uploadURL)
}
}
_ = clientSetupSection.FromClientSetupStepConfig(sec)
}
func replaceText(
func (c *APIController) replaceText(
username string,
st artifact.ClientSetupStep,
i int,
@ -1282,6 +1282,10 @@ func replaceText(
groupID string,
uploadURL string,
) {
if c.SetupDetailsAuthHeaderPrefix != "" {
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value,
"<AUTH_HEADER_PREFIX>", c.SetupDetailsAuthHeaderPrefix))
}
if username != "" {
(*st.Commands)[i].Value = utils.StringPtr(strings.ReplaceAll(*(*st.Commands)[i].Value, "<USERNAME>", username))
if (*st.Commands)[i].Label != nil {

View File

@ -364,7 +364,7 @@ func GetTagURL(artifact string, version string, registryURL string) string {
func GetPullCommand(
image string, tag string,
packageType string, registryURL string,
packageType string, registryURL string, setupDetailsAuthHeaderPrefix string,
) string {
switch packageType {
case string(a.PackageTypeDOCKER):
@ -372,7 +372,7 @@ func GetPullCommand(
case string(a.PackageTypeHELM):
return GetHelmPullCommand(image, tag, registryURL)
case string(a.PackageTypeGENERIC):
return GetGenericArtifactFileDownloadCommand(registryURL, image, tag, "<FILENAME>")
return GetGenericArtifactFileDownloadCommand(registryURL, image, tag, "<FILENAME>", setupDetailsAuthHeaderPrefix)
case string(a.PackageTypePYTHON):
return GetPythonDownloadCommand(image, tag)
case string(a.PackageTypeNPM):
@ -443,8 +443,12 @@ func GetPythonDownloadCommand(artifact, version string) string {
return downloadCommand
}
func GetGenericArtifactFileDownloadCommand(regURL, artifact, version, filename string) string {
downloadCommand := "curl --location '<HOSTNAME>/<ARTIFACT>:<VERSION>:<FILENAME>' --header 'x-api-key: <API_KEY>'" +
func GetGenericArtifactFileDownloadCommand(
regURL, artifact, version, filename string,
setupDetailsAuthHeaderPrefix string,
) string {
downloadCommand := "curl --location '<HOSTNAME>/<ARTIFACT>:<VERSION>:<FILENAME>'" +
" --header '<AUTH_HEADER_PREFIX> <API_KEY>'" +
" -J -O"
// Replace the placeholders with the actual values
@ -453,6 +457,7 @@ func GetGenericArtifactFileDownloadCommand(regURL, artifact, version, filename s
"<ARTIFACT>": artifact,
"<VERSION>": version,
"<FILENAME>": filename,
"<AUTH_HEADER_PREFIX>": setupDetailsAuthHeaderPrefix,
}
for placeholder, value := range replacements {
@ -462,12 +467,13 @@ func GetGenericArtifactFileDownloadCommand(regURL, artifact, version, filename s
return downloadCommand
}
func GetRPMArtifactFileDownloadCommand(regURL, filename string) string {
downloadCommand := "curl --location '<HOSTNAME>/package<FILENAME>' --header 'x-api-key: <API_KEY>'" +
func GetRPMArtifactFileDownloadCommand(regURL, filename string, setupDetailsAuthHeaderPrefix string) string {
downloadCommand := "curl --location '<HOSTNAME>/package<FILENAME>' --header '<AUTH_HEADER_PREFIX> <API_KEY>'" +
" -J -O"
replacements := map[string]string{
"<HOSTNAME>": regURL,
"<FILENAME>": filename,
"<AUTH_HEADER_PREFIX>": setupDetailsAuthHeaderPrefix,
}
for placeholder, value := range replacements {
@ -477,9 +483,12 @@ func GetRPMArtifactFileDownloadCommand(regURL, filename string) string {
return downloadCommand
}
func GetMavenArtifactFileDownloadCommand(regURL, artifact, version, filename string) string {
func GetMavenArtifactFileDownloadCommand(
regURL, artifact, version, filename string,
setupDetailsAuthHeaderPrefix string,
) string {
downloadCommand := "curl --location '<HOSTNAME>/<ARTIFACT>/<VERSION>/<FILENAME>'" +
" --header 'x-api-key: <IDENTITY_TOKEN>' -O"
" --header '<AUTH_HEADER_PREFIX> <IDENTITY_TOKEN>' -O"
// Replace the placeholders with the actual values
replacements := map[string]string{
@ -487,6 +496,7 @@ func GetMavenArtifactFileDownloadCommand(regURL, artifact, version, filename str
"<ARTIFACT>": artifact,
"<VERSION>": version,
"<FILENAME>": filename,
"<AUTH_HEADER_PREFIX>": setupDetailsAuthHeaderPrefix,
}
for placeholder, value := range replacements {

View File

@ -208,7 +208,7 @@ func TestGetPullCommand(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := metadata.GetPullCommand(tt.image, tt.tag, tt.pkgType, tt.baseURL)
result := metadata.GetPullCommand(tt.image, tt.tag, tt.pkgType, tt.baseURL, "Authorization: Bearer")
assert.Equal(t, tt.expected, result)
})
}

View File

@ -35,6 +35,7 @@ import (
"github.com/harness/gitness/registry/services/index"
registrywebhook "github.com/harness/gitness/registry/services/webhook"
"github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types"
"github.com/go-chi/chi/v5"
)
@ -79,6 +80,7 @@ func NewAPIHandler(
artifactEventReporter registryevents.Reporter,
downloadStatRepository store.DownloadStatRepository,
registryIndexService index.Service,
gitnessConfig *types.Config,
) APIHandler {
r := chi.NewRouter()
r.Use(audit.Middleware())
@ -109,6 +111,7 @@ func NewAPIHandler(
artifactEventReporter,
downloadStatRepository,
registryIndexService,
gitnessConfig.Registry.SetupDetailsAuthHeaderPrefix,
)
handler := artifact.NewStrictHandler(apiController, []artifact.StrictMiddlewareFunc{})

View File

@ -42,6 +42,7 @@ import (
"github.com/harness/gitness/registry/services/index"
registrywebhook "github.com/harness/gitness/registry/services/webhook"
"github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types"
"github.com/google/wire"
)
@ -79,6 +80,7 @@ func APIHandlerProvider(
artifactEventReporter *registryevents.Reporter,
downloadStatRepository store.DownloadStatRepository,
registryIndexService index.Service,
gitnessConfig *types.Config,
) harness.APIHandler {
return harness.NewAPIHandler(
repoDao,
@ -104,6 +106,7 @@ func APIHandlerProvider(
*artifactEventReporter,
downloadStatRepository,
registryIndexService,
gitnessConfig,
)
}

View File

@ -542,6 +542,7 @@ type Config struct {
TransactionTimeoutDuration time.Duration `envconfig:"GITNESS_REGISTRY_GARBAGE_COLLECTION_TRANSACTION_TIMEOUT_DURATION" default:"10s"` //nolint:lll
BlobsStorageTimeoutDuration time.Duration `envconfig:"GITNESS_REGISTRY_GARBAGE_COLLECTION_BLOB_STORAGE_TIMEOUT_DURATION" default:"5s"` //nolint:lll
}
SetupDetailsAuthHeaderPrefix string `envconfig:"SETUP_DETAILS_AUTH_PREFIX" default:"Authorization: Bearer"`
}
Instrumentation struct {

View File

@ -84,7 +84,7 @@ export const MockGetGenericSetupClientOnRegistryConfigPageResponse = {
{
label: '',
value:
"curl --location --request PUT 'http://host.docker.internal:3000/generic/artifact-registry/generic-repo/\u003cARTIFACT_NAME\u003e/\u003cVERSION\u003e' \\\n--form 'filename=\"\u003cFILENAME\u003e\"' \\\n--form 'file=@\"\u003cFILE_PATH\u003e\"' \\\n--form 'description=\"\u003cDESC\u003e\"' \\\n--header 'x-api-key: \u003cAPI_KEY\u003e'"
"curl --location --request PUT 'http://host.docker.internal:3000/generic/artifact-registry/generic-repo/\u003cARTIFACT_NAME\u003e/\u003cVERSION\u003e' \\\n--form 'filename=\"\u003cFILENAME\u003e\"' \\\n--form 'file=@\"\u003cFILE_PATH\u003e\"' \\\n--form 'description=\"\u003cDESC\u003e\"' \\\n--header 'Authorization: Bearer \u003cAPI_KEY\u003e'"
}
],
header: 'Run this curl command in your terminal to push the artifact.',
@ -101,7 +101,7 @@ export const MockGetGenericSetupClientOnRegistryConfigPageResponse = {
{
label: '',
value:
"curl --location 'http://host.docker.internal:3000/generic/artifact-registry/generic-repo/\u003cARTIFACT_NAME\u003e:\u003cVERSION\u003e:\u003cFILENAME\u003e' --header 'x-api-key: \u003cAPI_KEY\u003e' -J -O"
"curl --location 'http://host.docker.internal:3000/generic/artifact-registry/generic-repo/\u003cARTIFACT_NAME\u003e:\u003cVERSION\u003e:\u003cFILENAME\u003e' --header 'Authorization: Bearer \u003cAPI_KEY\u003e' -J -O"
}
],
header: 'Run this command in your terminal to download the artifact.',

View File

@ -130,7 +130,7 @@ export const mockGenericArtifactFiles: FileDetailResponseResponse = {
],
createdAt: '1738258177381',
downloadCommand:
"curl --location 'https://pkg.qa.harness.io/generic/iWnhltqOT7GFt7R-F_zP7Q/generic-registry/artifact:v1:image.png' --header 'x-api-key: \u003cAPI_KEY\u003e' -J -O",
"curl --location 'https://pkg.qa.harness.io/generic/iWnhltqOT7GFt7R-F_zP7Q/generic-registry/artifact:v1:image.png' --header 'Authorization: Bearer \u003cAPI_KEY\u003e' -J -O",
name: 'image.png',
size: '170.18KB'
},