diff --git a/changes/24166-script-line-endings b/changes/24166-script-line-endings new file mode 100644 index 0000000000..3beeb8d9dd --- /dev/null +++ b/changes/24166-script-line-endings @@ -0,0 +1 @@ +* Changed script upload endpoint (`POST /api/v1/fleet/scripts`) to automatically switch CRLF line endings to LF diff --git a/server/service/scripts.go b/server/service/scripts.go index 2a4a3938e1..71ed203d32 100644 --- a/server/service/scripts.go +++ b/server/service/scripts.go @@ -12,6 +12,7 @@ import ( "time" "github.com/docker/go-units" + "github.com/fleetdm/fleet/v4/pkg/file" "github.com/fleetdm/fleet/v4/pkg/scripts" "github.com/fleetdm/fleet/v4/server/authz" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" @@ -507,7 +508,7 @@ func (svc *Service) NewScript(ctx context.Context, teamID *uint, name string, r script := &fleet.Script{ TeamID: teamID, Name: name, - ScriptContents: string(b), + ScriptContents: file.Dos2UnixNewlines(string(b)), } if err := script.ValidateNewScript(); err != nil { return nil, fleet.NewInvalidArgumentError("script", err.Error()) diff --git a/server/service/scripts_test.go b/server/service/scripts_test.go index 404f345704..d1957ea0e7 100644 --- a/server/service/scripts_test.go +++ b/server/service/scripts_test.go @@ -498,10 +498,14 @@ func TestSavedScripts(t *testing.T) { license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)} svc, ctx := newTestService(t, ds, nil, nil, &TestServerOpts{License: license, SkipCreateTestUsers: true}) + withLFContents := "echo\necho" + withCRLFContents := "echo\r\necho" + ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) { return &fleet.AppConfig{}, nil } ds.NewScriptFunc = func(ctx context.Context, script *fleet.Script) (*fleet.Script, error) { + require.Equal(t, withLFContents, script.ScriptContents) newScript := *script newScript.ID = 1 return &newScript, nil @@ -669,7 +673,7 @@ func TestSavedScripts(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx = viewer.NewContext(ctx, viewer.Viewer{User: tt.user}) - _, err := svc.NewScript(ctx, nil, "test.sh", strings.NewReader("echo")) + _, err := svc.NewScript(ctx, nil, "test.ps1", strings.NewReader(withCRLFContents)) checkAuthErr(t, tt.shouldFailGlobalWrite, err) err = svc.DeleteScript(ctx, noTeamScriptID) checkAuthErr(t, tt.shouldFailGlobalWrite, err) @@ -680,7 +684,7 @@ func TestSavedScripts(t *testing.T) { _, _, err = svc.GetScript(ctx, noTeamScriptID, true) checkAuthErr(t, tt.shouldFailGlobalRead, err) - _, err = svc.NewScript(ctx, ptr.Uint(1), "test.sh", strings.NewReader("echo")) + _, err = svc.NewScript(ctx, ptr.Uint(1), "test.sh", strings.NewReader(withLFContents)) checkAuthErr(t, tt.shouldFailTeamWrite, err) err = svc.DeleteScript(ctx, team1ScriptID) checkAuthErr(t, tt.shouldFailTeamWrite, err)