feat(filters): validate existence of external exec cmd (#1501)

* feat(filters): check external cmd exists

* fix: imports

* Update internal/domain/filter.go

---------

Co-authored-by: s0up4200 <soup@r4tio.dev>
This commit is contained in:
ze0s 2024-04-12 13:56:57 +02:00 committed by GitHub
parent b44d55ea55
commit da53230077
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 84 additions and 8 deletions

View file

@ -6,12 +6,14 @@ package domain
import ( import (
"context" "context"
"fmt" "fmt"
"os/exec"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/autobrr/autobrr/pkg/errors" "github.com/autobrr/autobrr/pkg/errors"
"github.com/autobrr/autobrr/pkg/sanitize"
"github.com/autobrr/autobrr/pkg/wildcard" "github.com/autobrr/autobrr/pkg/wildcard"
"github.com/dustin/go-humanize" "github.com/dustin/go-humanize"
@ -254,6 +256,63 @@ func (f *Filter) Validate() error {
return fmt.Errorf("error validating filter size limits: %w", err) return fmt.Errorf("error validating filter size limits: %w", err)
} }
for _, external := range f.External {
if external.Type == ExternalFilterTypeExec {
if external.ExecCmd != "" && external.Enabled {
// check if program exists
_, err := exec.LookPath(external.ExecCmd)
if err != nil {
return errors.Wrap(err, "could not find external exec command: %s", external.ExecCmd)
}
}
}
}
for _, action := range f.Actions {
if action.Type == ActionTypeExec {
if action.ExecCmd != "" && action.Enabled {
// check if program exists
_, err := exec.LookPath(action.ExecCmd)
if err != nil {
return errors.Wrap(err, "could not find action exec command: %s", action.ExecCmd)
}
}
}
}
return nil
}
func (f *Filter) Sanitize() error {
f.Shows = sanitize.FilterString(f.Shows)
if !f.UseRegex {
f.MatchReleases = sanitize.FilterString(f.MatchReleases)
f.ExceptReleases = sanitize.FilterString(f.ExceptReleases)
}
f.MatchReleaseGroups = sanitize.FilterString(f.MatchReleaseGroups)
f.ExceptReleaseGroups = sanitize.FilterString(f.ExceptReleaseGroups)
f.MatchCategories = sanitize.FilterString(f.MatchCategories)
f.ExceptCategories = sanitize.FilterString(f.ExceptCategories)
f.MatchUploaders = sanitize.FilterString(f.MatchUploaders)
f.ExceptUploaders = sanitize.FilterString(f.ExceptUploaders)
f.TagsAny = sanitize.FilterString(f.TagsAny)
f.ExceptTags = sanitize.FilterString(f.ExceptTags)
if !f.UseRegexReleaseTags {
f.MatchReleaseTags = sanitize.FilterString(f.MatchReleaseTags)
f.ExceptReleaseTags = sanitize.FilterString(f.ExceptReleaseTags)
}
f.Years = sanitize.FilterString(f.Years)
f.Artists = sanitize.FilterString(f.Artists)
f.Albums = sanitize.FilterString(f.Albums)
return nil return nil
} }

View file

@ -188,29 +188,35 @@ func (s *service) Store(ctx context.Context, filter *domain.Filter) error {
} }
func (s *service) Update(ctx context.Context, filter *domain.Filter) error { func (s *service) Update(ctx context.Context, filter *domain.Filter) error {
if err := filter.Validate(); err != nil { err := filter.Validate()
s.log.Error().Err(err).Msgf("invalid filter: %v", filter) if err != nil {
s.log.Error().Err(err).Msgf("validation error filter: %+v", filter)
return err return err
} }
// replace newline with comma err = filter.Sanitize()
filter.Shows = strings.ReplaceAll(filter.Shows, "\n", ",") if err != nil {
filter.Shows = strings.ReplaceAll(filter.Shows, ",,", ",") s.log.Error().Err(err).Msgf("could not sanitize filter: %v", filter)
return err
}
// update // update
if err := s.repo.Update(ctx, filter); err != nil { err = s.repo.Update(ctx, filter)
if err != nil {
s.log.Error().Err(err).Msgf("could not update filter: %s", filter.Name) s.log.Error().Err(err).Msgf("could not update filter: %s", filter.Name)
return err return err
} }
// take care of connected indexers // take care of connected indexers
if err := s.repo.StoreIndexerConnections(ctx, filter.ID, filter.Indexers); err != nil { err = s.repo.StoreIndexerConnections(ctx, filter.ID, filter.Indexers)
if err != nil {
s.log.Error().Err(err).Msgf("could not store filter indexer connections: %s", filter.Name) s.log.Error().Err(err).Msgf("could not store filter indexer connections: %s", filter.Name)
return err return err
} }
// take care of connected external filters // take care of connected external filters
if err := s.repo.StoreFilterExternal(ctx, filter.ID, filter.External); err != nil { err = s.repo.StoreFilterExternal(ctx, filter.ID, filter.External)
if err != nil {
s.log.Error().Err(err).Msgf("could not store external filters: %s", filter.Name) s.log.Error().Err(err).Msgf("could not store external filters: %s", filter.Name)
return err return err
} }

View file

@ -6,3 +6,14 @@ func String(str string) string {
str = strings.TrimSpace(str) str = strings.TrimSpace(str)
return str return str
} }
func FilterString(str string) string {
str = strings.TrimSpace(str)
str = strings.Trim(str, ",")
// replace newline with comma
str = strings.ReplaceAll(str, "\n", ",")
str = strings.ReplaceAll(str, ",,", ",")
return str
}