diff --git a/internal/processing/status/create.go b/internal/processing/status/create.go index fef857c7c..0fc21f94b 100644 --- a/internal/processing/status/create.go +++ b/internal/processing/status/create.go @@ -64,8 +64,8 @@ func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, appli return nil, errWithCode } - if err := p.ProcessMediaIDs(ctx, form, account.ID, newStatus); err != nil { - return nil, gtserror.NewErrorInternalError(err) + if errWithCode := p.ProcessMediaIDs(ctx, form, account.ID, newStatus); errWithCode != nil { + return nil, errWithCode } if err := p.ProcessVisibility(ctx, form, account.Privacy, newStatus); err != nil { diff --git a/internal/processing/status/create_test.go b/internal/processing/status/create_test.go index 98d6c9ffe..1573dd9ae 100644 --- a/internal/processing/status/create_test.go +++ b/internal/processing/status/create_test.go @@ -24,6 +24,7 @@ "github.com/stretchr/testify/suite" "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" ) @@ -174,6 +175,40 @@ func (suite *StatusCreateTestSuite) TestProcessStatusMarkdownWithSpoilerTextEmoj suite.NotEmpty(apiStatus.Emojis) } +func (suite *StatusCreateTestSuite) TestProcessMediaDescriptionTooShort() { + ctx := context.Background() + + config.SetMediaDescriptionMinChars(100) + + creatingAccount := suite.testAccounts["local_account_1"] + creatingApplication := suite.testApplications["application_1"] + + statusCreateForm := &model.AdvancedStatusCreateForm{ + StatusCreateRequest: model.StatusCreateRequest{ + Status: "poopoo peepee", + MediaIDs: []string{suite.testAttachments["local_account_1_unattached_1"].ID}, + Poll: nil, + InReplyToID: "", + Sensitive: false, + SpoilerText: "", + Visibility: model.VisibilityPublic, + ScheduledAt: "", + Language: "en", + Format: model.StatusFormatPlain, + }, + AdvancedVisibilityFlagsForm: model.AdvancedVisibilityFlagsForm{ + Federated: nil, + Boostable: nil, + Replyable: nil, + Likeable: nil, + }, + } + + apiStatus, err := suite.status.Create(ctx, creatingAccount, creatingApplication, statusCreateForm) + suite.EqualError(err, "ProcessMediaIDs: description too short! media description of at least 100 chararacters is required but 15 was provided for media with id 01F8MH8RMYQ6MSNY3JM2XT1CQ5") + suite.Nil(apiStatus) +} + func TestStatusCreateTestSuite(t *testing.T) { suite.Run(t, new(StatusCreateTestSuite)) } diff --git a/internal/processing/status/status.go b/internal/processing/status/status.go index acd588461..c63769c76 100644 --- a/internal/processing/status/status.go +++ b/internal/processing/status/status.go @@ -61,7 +61,7 @@ type Processor interface { ProcessVisibility(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountDefaultVis gtsmodel.Visibility, status *gtsmodel.Status) error ProcessReplyToID(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, thisAccountID string, status *gtsmodel.Status) gtserror.WithCode - ProcessMediaIDs(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, thisAccountID string, status *gtsmodel.Status) error + ProcessMediaIDs(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, thisAccountID string, status *gtsmodel.Status) gtserror.WithCode ProcessLanguage(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountDefaultLanguage string, status *gtsmodel.Status) error ProcessMentions(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error ProcessTags(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error diff --git a/internal/processing/status/util.go b/internal/processing/status/util.go index c8b30e2ca..ca6e5063b 100644 --- a/internal/processing/status/util.go +++ b/internal/processing/status/util.go @@ -25,6 +25,7 @@ "github.com/superseriousbusiness/gotosocial/internal/api/model" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" @@ -157,7 +158,7 @@ func (p *processor) ProcessReplyToID(ctx context.Context, form *apimodel.Advance return nil } -func (p *processor) ProcessMediaIDs(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, thisAccountID string, status *gtsmodel.Status) error { +func (p *processor) ProcessMediaIDs(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, thisAccountID string, status *gtsmodel.Status) gtserror.WithCode { if form.MediaIDs == nil { return nil } @@ -167,15 +168,28 @@ func (p *processor) ProcessMediaIDs(ctx context.Context, form *apimodel.Advanced for _, mediaID := range form.MediaIDs { attachment, err := p.db.GetAttachmentByID(ctx, mediaID) if err != nil { - return fmt.Errorf("ProcessMediaIDs: invalid media type or media not found for media id %s", mediaID) + if errors.Is(err, db.ErrNoEntries) { + err = fmt.Errorf("ProcessMediaIDs: media not found for media id %s", mediaID) + return gtserror.NewErrorBadRequest(err, err.Error()) + } + err = fmt.Errorf("ProcessMediaIDs: db error for media id %s", mediaID) + return gtserror.NewErrorInternalError(err) } if attachment.AccountID != thisAccountID { - return fmt.Errorf("ProcessMediaIDs: media with id %s does not belong to account %s", mediaID, thisAccountID) + err = fmt.Errorf("ProcessMediaIDs: media with id %s does not belong to account %s", mediaID, thisAccountID) + return gtserror.NewErrorBadRequest(err, err.Error()) } if attachment.StatusID != "" || attachment.ScheduledStatusID != "" { - return fmt.Errorf("ProcessMediaIDs: media with id %s is already attached to a status", mediaID) + err = fmt.Errorf("ProcessMediaIDs: media with id %s is already attached to a status", mediaID) + return gtserror.NewErrorBadRequest(err, err.Error()) + } + + minDescriptionChars := config.GetMediaDescriptionMinChars() + if descriptionLength := len([]rune(attachment.Description)); descriptionLength < minDescriptionChars { + err = fmt.Errorf("ProcessMediaIDs: description too short! media description of at least %d chararacters is required but %d was provided for media with id %s", minDescriptionChars, descriptionLength, mediaID) + return gtserror.NewErrorBadRequest(err, err.Error()) } attachments = append(attachments, attachment)