fleet/server/mdm/maintainedapps/installers_test.go
Konstantin Sykulev b643b326ee
Generate SHA from file if FMA sha is no_check (#30558)
fixes: #30325

Related to incorrect behavior introduced at
https://github.com/fleetdm/fleet/pull/28945

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [x] Added/updated automated tests
- [x] Manual QA for all new/changed functionality


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* When uploading software batches, if the installer SHA is set to
"no_check," the system will now automatically generate and use the
SHA256 checksum of the installer file.
* **Bug Fixes**
* Fixed an issue ensuring the latest Google Chrome version is pulled
during Fleet-maintained app updates.
* Corrected the display of the SHA256 hash in the UI and API to show
valid values.
* Improved handling of installer uploads to ensure a valid SHA256
checksum is always applied, even when "no_check" is specified.
* **Tests**
* Added a test to verify correct SHA256 hash calculation for installer
files.
* Extended integration tests to validate batch software installer
operations for maintained apps with SHA256 hash checks.
* Added tests covering behavior when SHA256 checksum is marked as
"no_check" for maintained apps.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ian Littman <iansltx@gmail.com>
2025-07-07 11:05:19 -05:00

63 lines
2.2 KiB
Go

package maintained_apps
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/stretchr/testify/require"
)
func TestInstallerFilenameExtraction(t *testing.T) {
// Mock server to serve the "installers"
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/redirect":
w.Header().Set("Location", "/redirected%20package.exe")
w.WriteHeader(302)
_, _ = w.Write([]byte("redirecting"))
case "/redirected%20package.exe":
_, _ = w.Write([]byte("redirected fallback"))
case "/compliant":
w.Header().Set("Content-Disposition", `attachment; filename="compliant.msi"`)
_, _ = w.Write([]byte("compliant"))
case "/not_compliant":
w.Header().Set("Content-Disposition", `attachment; filename=not_compliant.pkg`)
_, _ = w.Write([]byte("not_compliant"))
}
}))
defer srv.Close()
// follow redirect and fall back to URL, after sanitization, when we don't have a content-disposition header
client := fleethttp.NewClient(fleethttp.WithTimeout(time.Second))
_, filename, err := DownloadInstaller(context.Background(), srv.URL+"/redirect", client)
require.NoError(t, err)
require.Equal(t, "redirected package.exe", filename)
// handle properly formatted content-disposition header
_, filename, err = DownloadInstaller(context.Background(), srv.URL+"/compliant", client)
require.NoError(t, err)
require.Equal(t, "compliant.msi", filename)
// handle non-compliant content-disposition header
_, filename, err = DownloadInstaller(context.Background(), srv.URL+"/not_compliant", client)
require.NoError(t, err)
require.Equal(t, "not_compliant.pkg", filename)
}
func TestSHA256FromInstallerFile(t *testing.T) {
tmpFileReader := func(ident string) *fleet.TempFileReader {
tfr, err := fleet.NewTempFileReader(strings.NewReader(ident), t.TempDir)
require.NoError(t, err)
return tfr
}
sha256, err := SHA256FromInstallerFile(tmpFileReader("installer1"))
require.NoError(t, err)
require.Equal(t, "026ac8ee705035f2422eeba7fdea15df563e4f4687ce3abc9a306d2de261f8de", sha256)
}