Detailed changes
@@ -7,12 +7,14 @@ import (
"github.com/charmbracelet/soft-serve/pkg/db"
"github.com/charmbracelet/soft-serve/pkg/proto"
+ "github.com/charmbracelet/soft-serve/pkg/utils"
)
// CreateAccessToken creates an access token for user.
func (b *Backend) CreateAccessToken(ctx context.Context, user proto.User, name string, expiresAt time.Time) (string, error) {
token := GenerateToken()
tokenHash := HashToken(token)
+ name = utils.Sanitize(name)
if err := b.db.TransactionContext(ctx, func(tx *db.Tx) error {
_, err := b.store.CreateAccessToken(ctx, tx, name, user.ID(), tokenHash, expiresAt)
@@ -544,6 +544,7 @@ func (d *Backend) SetHidden(ctx context.Context, name string, hidden bool) error
// It implements backend.Backend.
func (d *Backend) SetDescription(ctx context.Context, name string, desc string) error {
name = utils.SanitizeRepo(name)
+ desc = utils.Sanitize(desc)
rp := filepath.Join(d.repoPath(name))
// Delete cache
@@ -617,6 +618,7 @@ func (d *Backend) SetPrivate(ctx context.Context, name string, private bool) err
// It implements backend.Backend.
func (d *Backend) SetProjectName(ctx context.Context, repo string, name string) error {
repo = utils.SanitizeRepo(repo)
+ name = utils.Sanitize(name)
// Delete cache
d.cache.Delete(repo)
@@ -279,6 +279,7 @@ func (d *Backend) AddPublicKey(ctx context.Context, username string, pk ssh.Publ
//
// It implements backend.Backend.
func (d *Backend) CreateUser(ctx context.Context, username string, opts proto.UserOptions) (proto.User, error) {
+ username = utils.Sanitize(username)
username = strings.ToLower(username)
if err := utils.ValidateUsername(username); err != nil {
return nil, err
@@ -9,6 +9,7 @@ import (
"github.com/charmbracelet/soft-serve/pkg/db/models"
"github.com/charmbracelet/soft-serve/pkg/proto"
"github.com/charmbracelet/soft-serve/pkg/store"
+ "github.com/charmbracelet/soft-serve/pkg/utils"
"github.com/charmbracelet/soft-serve/pkg/webhook"
"github.com/google/uuid"
)
@@ -17,6 +18,7 @@ import (
func (b *Backend) CreateWebhook(ctx context.Context, repo proto.Repository, url string, contentType webhook.ContentType, secret string, events []webhook.Event, active bool) error {
dbx := db.FromContext(ctx)
datastore := store.FromContext(ctx)
+ url = utils.Sanitize(url)
return dbx.TransactionContext(ctx, func(tx *db.Tx) error {
lastID, err := datastore.CreateWebhook(ctx, tx, repo.ID(), url, secret, int(contentType), active)
@@ -10,6 +10,7 @@ import (
"github.com/charmbracelet/soft-serve/pkg/backend"
"github.com/charmbracelet/soft-serve/pkg/ui/common"
"github.com/charmbracelet/soft-serve/pkg/ui/styles"
+ "github.com/charmbracelet/soft-serve/pkg/utils"
"github.com/spf13/cobra"
)
@@ -59,9 +60,9 @@ func commitCommand() *cobra.Command {
s := strings.Builder{}
commitLine := "commit " + commitSHA
- authorLine := "Author: " + commit.Author.Name
+ authorLine := "Author: " + utils.Sanitize(commit.Author.Name)
dateLine := "Date: " + commit.Committer.When.UTC().Format(time.UnixDate)
- msgLine := strings.ReplaceAll(commit.Message, "\r\n", "\n")
+ msgLine := strings.ReplaceAll(utils.Sanitize(commit.Message), "\r\n", "\n")
statsLine := renderStats(diff, commonStyle, color)
diffLine := renderDiff(patch, color)
@@ -7,6 +7,7 @@ import (
"github.com/charmbracelet/lipgloss/v2/table"
"github.com/charmbracelet/soft-serve/pkg/backend"
+ "github.com/charmbracelet/soft-serve/pkg/utils"
"github.com/charmbracelet/soft-serve/pkg/webhook"
"github.com/dustin/go-humanize"
"github.com/google/uuid"
@@ -69,7 +70,7 @@ func webhookListCommand() *cobra.Command {
table = table.Row(
strconv.FormatInt(h.ID, 10),
- h.URL,
+ utils.Sanitize(h.URL),
strings.Join(events, ","),
strconv.FormatBool(h.Active),
humanize.Time(h.CreatedAt),
@@ -122,7 +123,8 @@ func webhookCreateCommand() *cobra.Command {
return webhook.ErrInvalidContentType
}
- return be.CreateWebhook(ctx, repo, strings.TrimSpace(args[1]), ct, secret, evs, active)
+ url := utils.Sanitize(args[1])
+ return be.CreateWebhook(ctx, repo, strings.TrimSpace(url), ct, secret, evs, active)
},
}
@@ -5,10 +5,13 @@ import (
"path"
"strings"
"unicode"
+
+ "github.com/charmbracelet/x/ansi"
)
// SanitizeRepo returns a sanitized version of the given repository name.
func SanitizeRepo(repo string) string {
+ repo = Sanitize(repo)
// We need to use an absolute path for the path to be cleaned correctly.
repo = strings.TrimPrefix(repo, "/")
repo = "/" + repo
@@ -20,6 +23,11 @@ func SanitizeRepo(repo string) string {
return repo[1:]
}
+// Sanitize strips ANSI escape codes from the given string.
+func Sanitize(s string) string {
+ return ansi.Strip(s)
+}
+
// ValidateUsername returns an error if any of the given usernames are invalid.
func ValidateUsername(username string) error {
if username == "" {