Implement external assets

This commit is contained in:
Malte Jürgens 2023-09-15 18:20:16 +02:00
parent 2e234300a2
commit a61e7c7a39
No known key found for this signature in database
22 changed files with 826 additions and 119 deletions

View file

@ -74,6 +74,8 @@ var migrations = []*Migration{
NewMigration("Add `normalized_federated_uri` column to `user` table", AddNormalizedFederatedURIToUser),
// v18 -> v19
NewMigration("Create the `following_repo` table", CreateFollowingRepoTable),
// v19 -> v20
NewMigration("Add external_url to attachment table", AddExternalURLColumnToAttachmentTable),
}
// GetCurrentDBVersion returns the current Forgejo database version.

View file

@ -0,0 +1,14 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forgejo_migrations //nolint:revive
import "xorm.io/xorm"
func AddExternalURLColumnToAttachmentTable(x *xorm.Engine) error {
type Attachment struct {
ID int64 `xorm:"pk autoincr"`
ExternalURL string
}
return x.Sync(new(Attachment))
}

View file

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/validation"
)
// Attachment represent a attachment of issue/comment/release.
@ -31,6 +32,7 @@ type Attachment struct {
NoAutoTime bool `xorm:"-"`
CreatedUnix timeutil.TimeStamp `xorm:"created"`
CustomDownloadURL string `xorm:"-"`
ExternalURL string
}
func init() {
@ -59,6 +61,10 @@ func (a *Attachment) RelativePath() string {
// DownloadURL returns the download url of the attached file
func (a *Attachment) DownloadURL() string {
if a.ExternalURL != "" {
return a.ExternalURL
}
if a.CustomDownloadURL != "" {
return a.CustomDownloadURL
}
@ -86,6 +92,23 @@ func (err ErrAttachmentNotExist) Unwrap() error {
return util.ErrNotExist
}
type ErrInvalidExternalURL struct {
ExternalURL string
}
func IsErrInvalidExternalURL(err error) bool {
_, ok := err.(ErrInvalidExternalURL)
return ok
}
func (err ErrInvalidExternalURL) Error() string {
return fmt.Sprintf("invalid external URL: '%s'", err.ExternalURL)
}
func (err ErrInvalidExternalURL) Unwrap() error {
return util.ErrPermissionDenied
}
// GetAttachmentByID returns attachment by given id
func GetAttachmentByID(ctx context.Context, id int64) (*Attachment, error) {
attach := &Attachment{}
@ -221,12 +244,18 @@ func UpdateAttachmentByUUID(ctx context.Context, attach *Attachment, cols ...str
if attach.UUID == "" {
return fmt.Errorf("attachment uuid should be not blank")
}
if attach.ExternalURL != "" && !validation.IsValidExternalURL(attach.ExternalURL) {
return ErrInvalidExternalURL{ExternalURL: attach.ExternalURL}
}
_, err := db.GetEngine(ctx).Where("uuid=?", attach.UUID).Cols(cols...).Update(attach)
return err
}
// UpdateAttachment updates the given attachment in database
func UpdateAttachment(ctx context.Context, atta *Attachment) error {
if atta.ExternalURL != "" && !validation.IsValidExternalURL(atta.ExternalURL) {
return ErrInvalidExternalURL{ExternalURL: atta.ExternalURL}
}
sess := db.GetEngine(ctx).Cols("name", "issue_id", "release_id", "comment_id", "download_count")
if atta.ID != 0 && atta.UUID == "" {
sess = sess.ID(atta.ID)