2024-09-18 16:21:53 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2025-05-02 15:41:26 +00:00
|
|
|
"fmt"
|
2024-09-19 19:42:17 +00:00
|
|
|
"os"
|
FMA: missing pieces (#22593)
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
<!-- Note that API documentation changes are now addressed by the
product design team. -->
- [ ] 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/Committing-Changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for
new osquery data ingestion features.
- [ ] Added/updated tests
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
- [ ] If database migrations are included, checked table schema to
confirm autoupdate
- For database migrations:
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
- [ ] Manual QA for all new/changed functionality
- For Orbit and Fleet Desktop changes:
- [ ] Orbit runs on macOS, Linux and Windows. Check if the orbit
feature/bugfix should only apply to one platform (`runtime.GOOS`).
- [ ] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [ ] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2024-10-03 17:49:27 +00:00
|
|
|
"path/filepath"
|
2025-03-21 02:21:56 +00:00
|
|
|
"strings"
|
2024-09-19 19:42:17 +00:00
|
|
|
"time"
|
2024-09-18 16:21:53 +00:00
|
|
|
|
FMA: missing pieces (#22593)
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
<!-- Note that API documentation changes are now addressed by the
product design team. -->
- [ ] 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/Committing-Changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for
new osquery data ingestion features.
- [ ] Added/updated tests
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
- [ ] If database migrations are included, checked table schema to
confirm autoupdate
- For database migrations:
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
- [ ] Manual QA for all new/changed functionality
- For Orbit and Fleet Desktop changes:
- [ ] Orbit runs on macOS, Linux and Windows. Check if the orbit
feature/bugfix should only apply to one platform (`runtime.GOOS`).
- [ ] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [ ] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2024-10-03 17:49:27 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/pkg/file"
|
2024-09-19 19:42:17 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
|
2025-05-08 01:12:12 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/server"
|
2025-05-28 21:58:58 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/server/authz"
|
2024-09-18 16:21:53 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
|
|
|
|
|
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
|
|
|
|
|
"github.com/fleetdm/fleet/v4/server/fleet"
|
2025-05-02 15:41:26 +00:00
|
|
|
maintained_apps "github.com/fleetdm/fleet/v4/server/mdm/maintainedapps"
|
2025-05-28 21:58:58 +00:00
|
|
|
"github.com/go-kit/kit/log/level"
|
2024-09-18 16:21:53 +00:00
|
|
|
)
|
|
|
|
|
|
2025-03-21 02:21:56 +00:00
|
|
|
// noCheckHash is used by homebrew to signal that a hash shouldn't be checked, and FMA carries this convention over
|
2024-10-08 15:49:11 +00:00
|
|
|
const noCheckHash = "no_check"
|
|
|
|
|
|
FMA: missing pieces (#22593)
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
<!-- Note that API documentation changes are now addressed by the
product design team. -->
- [ ] 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/Committing-Changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for
new osquery data ingestion features.
- [ ] Added/updated tests
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
- [ ] If database migrations are included, checked table schema to
confirm autoupdate
- For database migrations:
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
- [ ] Manual QA for all new/changed functionality
- For Orbit and Fleet Desktop changes:
- [ ] Orbit runs on macOS, Linux and Windows. Check if the orbit
feature/bugfix should only apply to one platform (`runtime.GOOS`).
- [ ] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [ ] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2024-10-03 17:49:27 +00:00
|
|
|
func (svc *Service) AddFleetMaintainedApp(
|
|
|
|
|
ctx context.Context,
|
|
|
|
|
teamID *uint,
|
|
|
|
|
appID uint,
|
|
|
|
|
installScript, preInstallQuery, postInstallScript, uninstallScript string,
|
2025-02-22 00:08:48 +00:00
|
|
|
selfService bool, automaticInstall bool,
|
2024-12-17 00:17:13 +00:00
|
|
|
labelsIncludeAny, labelsExcludeAny []string,
|
2024-11-26 22:21:00 +00:00
|
|
|
) (titleID uint, err error) {
|
2024-09-18 16:21:53 +00:00
|
|
|
if err := svc.authz.Authorize(ctx, &fleet.SoftwareInstaller{TeamID: teamID}, fleet.ActionWrite); err != nil {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, err
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vc, ok := viewer.FromContext(ctx)
|
|
|
|
|
if !ok {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, fleet.ErrNoContext
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-17 18:12:08 +00:00
|
|
|
// validate labels before we do anything else
|
2024-12-19 21:09:17 +00:00
|
|
|
validatedLabels, err := ValidateSoftwareLabels(ctx, svc, labelsIncludeAny, labelsExcludeAny)
|
2024-12-17 18:12:08 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return 0, ctxerr.Wrap(ctx, err, "validating software labels")
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 22:17:18 +00:00
|
|
|
if err := svc.ds.ValidateEmbeddedSecrets(ctx, []string{installScript, postInstallScript, uninstallScript}); err != nil {
|
2024-12-31 00:46:42 +00:00
|
|
|
// We redo the validation on each script to find out which script has the missing secret.
|
|
|
|
|
// This is done to provide a more informative error message to the UI user.
|
|
|
|
|
var argErr *fleet.InvalidArgumentError
|
|
|
|
|
argErr = svc.validateEmbeddedSecretsOnScript(ctx, "install script", &installScript, argErr)
|
|
|
|
|
argErr = svc.validateEmbeddedSecretsOnScript(ctx, "post-install script", &postInstallScript, argErr)
|
|
|
|
|
argErr = svc.validateEmbeddedSecretsOnScript(ctx, "uninstall script", &uninstallScript, argErr)
|
|
|
|
|
if argErr != nil {
|
|
|
|
|
return 0, argErr
|
|
|
|
|
}
|
|
|
|
|
// We should not get to this point. If we did, it means we have another issue, such as large read replica latency.
|
|
|
|
|
return 0, ctxerr.Wrap(ctx, err, "transient server issue validating embedded secrets")
|
2024-12-20 22:17:18 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-17 15:09:39 +00:00
|
|
|
app, err := svc.ds.GetMaintainedAppByID(ctx, appID, teamID)
|
2024-09-18 16:21:53 +00:00
|
|
|
if err != nil {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, ctxerr.Wrap(ctx, err, "getting maintained app by id")
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-21 02:21:56 +00:00
|
|
|
app, err = maintained_apps.Hydrate(ctx, app)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, ctxerr.Wrap(ctx, err, "hydrating app from manifest")
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-18 16:21:53 +00:00
|
|
|
// Download installer from the URL
|
2025-03-21 02:21:56 +00:00
|
|
|
timeout := maintained_apps.InstallerTimeout
|
2024-09-19 19:42:17 +00:00
|
|
|
if v := os.Getenv("FLEET_DEV_MAINTAINED_APPS_INSTALLER_TIMEOUT"); v != "" {
|
|
|
|
|
timeout, _ = time.ParseDuration(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client := fleethttp.NewClient(fleethttp.WithTimeout(timeout))
|
2025-03-21 02:21:56 +00:00
|
|
|
installerTFR, filename, err := maintained_apps.DownloadInstaller(ctx, app.InstallerURL, client)
|
2024-09-18 16:21:53 +00:00
|
|
|
if err != nil {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, ctxerr.Wrap(ctx, err, "downloading app installer")
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
2024-11-12 14:28:08 +00:00
|
|
|
defer installerTFR.Close()
|
2024-09-18 16:21:53 +00:00
|
|
|
|
2025-09-05 22:31:03 +00:00
|
|
|
gotHash, err := file.SHA256FromTempFileReader(installerTFR)
|
2025-07-07 16:05:19 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return 0, ctxerr.Wrap(ctx, err, "calculating SHA256 hash")
|
|
|
|
|
}
|
2024-09-18 16:21:53 +00:00
|
|
|
|
2025-03-21 02:21:56 +00:00
|
|
|
// Validate the bytes we got are what we expected, if a valid SHA is supplied
|
2024-10-08 15:49:11 +00:00
|
|
|
if app.SHA256 != noCheckHash {
|
|
|
|
|
if gotHash != app.SHA256 {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, ctxerr.New(ctx, "mismatch in maintained app SHA256 hash")
|
2024-10-08 15:49:11 +00:00
|
|
|
}
|
2025-03-21 02:21:56 +00:00
|
|
|
} else { // otherwise set the app hash to what we downloaded so storage writes correctly
|
|
|
|
|
app.SHA256 = gotHash
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-21 02:21:56 +00:00
|
|
|
extension := strings.TrimLeft(filepath.Ext(filename), ".")
|
2024-10-08 15:49:11 +00:00
|
|
|
|
FMA: missing pieces (#22593)
# Checklist for submitter
If some of the following don't apply, delete the relevant line.
<!-- Note that API documentation changes are now addressed by the
product design team. -->
- [ ] 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/Committing-Changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for
new osquery data ingestion features.
- [ ] Added/updated tests
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
- [ ] If database migrations are included, checked table schema to
confirm autoupdate
- For database migrations:
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
- [ ] Manual QA for all new/changed functionality
- For Orbit and Fleet Desktop changes:
- [ ] Orbit runs on macOS, Linux and Windows. Check if the orbit
feature/bugfix should only apply to one platform (`runtime.GOOS`).
- [ ] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [ ] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2024-10-03 17:49:27 +00:00
|
|
|
installScript = file.Dos2UnixNewlines(installScript)
|
|
|
|
|
if installScript == "" {
|
|
|
|
|
installScript = app.InstallScript
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uninstallScript = file.Dos2UnixNewlines(uninstallScript)
|
|
|
|
|
if uninstallScript == "" {
|
|
|
|
|
uninstallScript = app.UninstallScript
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-21 02:21:56 +00:00
|
|
|
maintainedAppID := &app.ID
|
|
|
|
|
if strings.TrimSpace(installScript) != strings.TrimSpace(app.InstallScript) ||
|
|
|
|
|
strings.TrimSpace(uninstallScript) != strings.TrimSpace(app.UninstallScript) {
|
|
|
|
|
maintainedAppID = nil // don't set app as maintained if scripts have been modified
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-27 17:45:23 +00:00
|
|
|
// For platforms other than macOS, installer name has to match what we see in software inventory,
|
|
|
|
|
// so we have the UniqueIdentifier field to indicate what that should be (independent of the name we
|
|
|
|
|
// display when listing the FMA). For macOS, unique identifier is bundle name, and we use bundle
|
|
|
|
|
// identifier to link installers with inventory, so we set the name to the FMA's display name instead.
|
|
|
|
|
appName := app.UniqueIdentifier
|
|
|
|
|
if app.Platform == "darwin" || appName == "" {
|
|
|
|
|
appName = app.Name
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-24 21:14:01 +00:00
|
|
|
version := app.Version
|
|
|
|
|
if version == "latest" { // download URL isn't version-pinned; extract version from installer
|
|
|
|
|
meta, err := file.ExtractInstallerMetadata(installerTFR)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, ctxerr.Wrap(ctx, err, "extracting installer metadata")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reset the reader (it was consumed to extract metadata)
|
|
|
|
|
if err := installerTFR.Rewind(); err != nil {
|
|
|
|
|
return 0, ctxerr.Wrap(ctx, err, "resetting installer file reader")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
version = meta.Version
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-18 16:21:53 +00:00
|
|
|
payload := &fleet.UploadSoftwareInstallerPayload{
|
2025-03-21 02:21:56 +00:00
|
|
|
InstallerFile: installerTFR,
|
2025-03-27 17:45:23 +00:00
|
|
|
Title: appName,
|
2025-03-21 02:21:56 +00:00
|
|
|
UserID: vc.UserID(),
|
|
|
|
|
TeamID: teamID,
|
2025-07-24 21:14:01 +00:00
|
|
|
Version: version,
|
2025-03-21 02:21:56 +00:00
|
|
|
Filename: filename,
|
|
|
|
|
Platform: app.Platform,
|
|
|
|
|
Source: app.Source(),
|
|
|
|
|
Extension: extension,
|
|
|
|
|
BundleIdentifier: app.BundleIdentifier(),
|
|
|
|
|
StorageID: app.SHA256,
|
|
|
|
|
FleetMaintainedAppID: maintainedAppID,
|
|
|
|
|
PreInstallQuery: preInstallQuery,
|
|
|
|
|
PostInstallScript: postInstallScript,
|
|
|
|
|
SelfService: selfService,
|
|
|
|
|
InstallScript: installScript,
|
|
|
|
|
UninstallScript: uninstallScript,
|
|
|
|
|
ValidatedLabels: validatedLabels,
|
|
|
|
|
AutomaticInstall: automaticInstall,
|
|
|
|
|
AutomaticInstallQuery: app.AutomaticInstallQuery,
|
2025-05-02 15:41:26 +00:00
|
|
|
Categories: app.Categories,
|
2025-06-26 19:29:23 +00:00
|
|
|
URL: app.InstallerURL,
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
2025-05-08 01:12:12 +00:00
|
|
|
payload.Categories = server.RemoveDuplicatesFromSlice(payload.Categories)
|
2025-05-02 15:41:26 +00:00
|
|
|
catIDs, err := svc.ds.GetSoftwareCategoryIDs(ctx, payload.Categories)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, ctxerr.Wrap(ctx, err, "getting software category ids")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(catIDs) != len(payload.Categories) {
|
|
|
|
|
return 0, &fleet.BadRequestError{
|
|
|
|
|
Message: "some or all of the categories provided don't exist",
|
|
|
|
|
InternalErr: fmt.Errorf("categories provided: %v", payload.Categories),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
payload.CategoryIDs = catIDs
|
|
|
|
|
|
2024-09-18 16:21:53 +00:00
|
|
|
// Create record in software installers table
|
2024-12-11 14:54:15 +00:00
|
|
|
_, titleID, err = svc.ds.MatchOrCreateSoftwareInstaller(ctx, payload)
|
2024-09-18 16:21:53 +00:00
|
|
|
if err != nil {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, ctxerr.Wrap(ctx, err, "setting downloaded installer")
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save in S3
|
|
|
|
|
if err := svc.storeSoftware(ctx, payload); err != nil {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, ctxerr.Wrap(ctx, err, "upload maintained app installer to S3")
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create activity
|
|
|
|
|
var teamName *string
|
|
|
|
|
if payload.TeamID != nil && *payload.TeamID != 0 {
|
|
|
|
|
t, err := svc.ds.Team(ctx, *payload.TeamID)
|
|
|
|
|
if err != nil {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, ctxerr.Wrap(ctx, err, "getting team")
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
teamName = &t.Name
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-18 13:16:36 +00:00
|
|
|
actLabelsIncl, actLabelsExcl := activitySoftwareLabelsFromValidatedLabels(payload.ValidatedLabels)
|
2024-09-18 16:21:53 +00:00
|
|
|
if err := svc.NewActivity(ctx, vc.User, fleet.ActivityTypeAddedSoftware{
|
2024-12-18 13:16:36 +00:00
|
|
|
SoftwareTitle: payload.Title,
|
|
|
|
|
SoftwarePackage: payload.Filename,
|
|
|
|
|
TeamName: teamName,
|
|
|
|
|
TeamID: payload.TeamID,
|
|
|
|
|
SelfService: payload.SelfService,
|
|
|
|
|
SoftwareTitleID: titleID,
|
|
|
|
|
LabelsIncludeAny: actLabelsIncl,
|
|
|
|
|
LabelsExcludeAny: actLabelsExcl,
|
2024-09-18 16:21:53 +00:00
|
|
|
}); err != nil {
|
2024-11-26 22:21:00 +00:00
|
|
|
return 0, ctxerr.Wrap(ctx, err, "creating activity for added software")
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
|
2025-05-28 21:58:58 +00:00
|
|
|
if automaticInstall && payload.AddedAutomaticInstallPolicy != nil {
|
|
|
|
|
policyAct := fleet.ActivityTypeCreatedPolicy{
|
|
|
|
|
ID: payload.AddedAutomaticInstallPolicy.ID,
|
|
|
|
|
Name: payload.AddedAutomaticInstallPolicy.Name,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := svc.NewActivity(ctx, authz.UserFromContext(ctx), policyAct); err != nil {
|
|
|
|
|
level.Warn(svc.logger).Log("msg", "failed to create activity for create automatic install policy for FMA", "err", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-11 14:54:15 +00:00
|
|
|
return titleID, nil
|
2024-09-18 16:21:53 +00:00
|
|
|
}
|
2024-09-20 14:42:43 +00:00
|
|
|
|
2024-12-12 03:12:38 +00:00
|
|
|
func (svc *Service) ListFleetMaintainedApps(ctx context.Context, teamID *uint, opts fleet.ListOptions) ([]fleet.MaintainedApp, *fleet.PaginationMetadata, error) {
|
|
|
|
|
var authErr error
|
|
|
|
|
// viewing the maintained app list without showing team-specific info can be done by anyone who can view individual FMAs
|
|
|
|
|
if teamID == nil {
|
|
|
|
|
authErr = svc.authz.Authorize(ctx, &fleet.MaintainedApp{}, fleet.ActionRead)
|
|
|
|
|
} else { // viewing the maintained app list when showing team-specific info requires access to that team
|
|
|
|
|
authErr = svc.authz.Authorize(ctx, &fleet.SoftwareInstaller{TeamID: teamID}, fleet.ActionRead)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if authErr != nil {
|
|
|
|
|
return nil, nil, authErr
|
2024-09-20 14:42:43 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-17 15:09:39 +00:00
|
|
|
opts.IncludeMetadata = true
|
2024-09-20 14:42:43 +00:00
|
|
|
avail, meta, err := svc.ds.ListAvailableFleetMaintainedApps(ctx, teamID, opts)
|
|
|
|
|
if err != nil {
|
2025-03-21 02:21:56 +00:00
|
|
|
return nil, nil, ctxerr.Wrap(ctx, err, "listing available fleet maintained apps")
|
2024-09-20 14:42:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return avail, meta, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-17 15:09:39 +00:00
|
|
|
func (svc *Service) GetFleetMaintainedApp(ctx context.Context, appID uint, teamID *uint) (*fleet.MaintainedApp, error) {
|
|
|
|
|
var authErr error
|
|
|
|
|
// viewing the maintained app without showing team-specific info can be done by anyone who can view individual FMAs
|
|
|
|
|
if teamID == nil {
|
|
|
|
|
authErr = svc.authz.Authorize(ctx, &fleet.MaintainedApp{}, fleet.ActionRead)
|
|
|
|
|
} else { // viewing the maintained app when showing team-specific info requires access to that team
|
|
|
|
|
authErr = svc.authz.Authorize(ctx, &fleet.SoftwareInstaller{TeamID: teamID}, fleet.ActionRead)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if authErr != nil {
|
|
|
|
|
return nil, authErr
|
2024-09-20 14:42:43 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-17 15:09:39 +00:00
|
|
|
app, err := svc.ds.GetMaintainedAppByID(ctx, appID, teamID)
|
2024-09-20 14:42:43 +00:00
|
|
|
if err != nil {
|
2025-03-21 02:21:56 +00:00
|
|
|
return nil, err
|
2024-09-20 14:42:43 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-21 02:21:56 +00:00
|
|
|
return maintained_apps.Hydrate(ctx, app)
|
2024-09-20 14:42:43 +00:00
|
|
|
}
|