diff --git a/models/repo/attachment.go b/models/repo/attachment.go index 4a09ef14f2..6d903be5f8 100644 --- a/models/repo/attachment.go +++ b/models/repo/attachment.go @@ -235,7 +235,7 @@ func UpdateAttachmentByUUID(ctx context.Context, attach *Attachment, cols ...str if attach.UUID == "" { return errors.New("attachment uuid should be not blank") } - if attach.ExternalURL != "" && !validation.IsValidExternalURL(attach.ExternalURL) { + if attach.ExternalURL != "" && !validation.IsValidReleaseAssetURL(attach.ExternalURL) { return ErrInvalidExternalURL{ExternalURL: attach.ExternalURL} } _, err := db.GetEngine(ctx).Where("uuid=?", attach.UUID).Cols(cols...).Update(attach) @@ -244,7 +244,7 @@ func UpdateAttachmentByUUID(ctx context.Context, attach *Attachment, cols ...str // UpdateAttachment updates the given attachment in database func UpdateAttachment(ctx context.Context, atta *Attachment) error { - if atta.ExternalURL != "" && !validation.IsValidExternalURL(atta.ExternalURL) { + if atta.ExternalURL != "" && !validation.IsValidReleaseAssetURL(atta.ExternalURL) { return ErrInvalidExternalURL{ExternalURL: atta.ExternalURL} } sess := db.GetEngine(ctx).Cols("name", "issue_id", "release_id", "comment_id", "download_count") diff --git a/modules/validation/helpers.go b/modules/validation/helpers.go index 1f573564e6..4b28dead03 100644 --- a/modules/validation/helpers.go +++ b/modules/validation/helpers.go @@ -75,6 +75,11 @@ func IsValidExternalURL(uri string) bool { return true } +// IsValidReleaseAssetURL checks if the URL is valid for external release assets +func IsValidReleaseAssetURL(uri string) bool { + return IsValidURL(uri) +} + // IsValidExternalTrackerURLFormat checks if URL matches required syntax for external trackers func IsValidExternalTrackerURLFormat(uri string) bool { if !IsValidExternalURL(uri) { diff --git a/services/attachment/attachment.go b/services/attachment/attachment.go index 365bd7faf6..b6f763842b 100644 --- a/services/attachment/attachment.go +++ b/services/attachment/attachment.go @@ -51,7 +51,7 @@ func NewExternalAttachment(ctx context.Context, attach *repo_model.Attachment) ( if attach.ExternalURL == "" { return nil, fmt.Errorf("attachment %s should have a external url", attach.Name) } - if !validation.IsValidExternalURL(attach.ExternalURL) { + if !validation.IsValidReleaseAssetURL(attach.ExternalURL) { return nil, repo_model.ErrInvalidExternalURL{ExternalURL: attach.ExternalURL} } diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index d5f7960ab1..f25948989a 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -430,6 +430,30 @@ func TestAPIExternalAssetRelease(t *testing.T) { assert.Equal(t, "external", attachment.Type) } +func TestAPIAllowedAPIURLInRelease(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + session := loginUser(t, owner.LowerName) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + r := createNewReleaseUsingAPI(t, token, owner, repo, "release-tag", "", "Release Tag", "test") + internalURL := "https://localhost:3003/api/packages/owner/generic/test/1.0.0/test.txt" + + req := NewRequest(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets?name=test-asset&external_url=%s", owner.Name, repo.Name, r.ID, url.QueryEscape(internalURL))). + AddTokenAuth(token) + resp := MakeRequest(t, req, http.StatusCreated) + + var attachment *api.Attachment + DecodeJSON(t, resp, &attachment) + + assert.Equal(t, "test-asset", attachment.Name) + assert.EqualValues(t, 0, attachment.Size) + assert.Equal(t, internalURL, attachment.DownloadURL) + assert.Equal(t, "external", attachment.Type) +} + func TestAPIDuplicateAssetRelease(t *testing.T) { defer tests.PrepareTestEnv(t)()