mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
add a dedicated endpoint that redirects to fleet_desktop.transparency_url (#6204)
As part of https://github.com/fleetdm/fleet/issues/5947, and in order to have a simplified workflow in Fleet Desktop, we defined https://github.com/fleetdm/fleet/issues/6200 to add a new endpoint that redirects to the transparency url as defined in the config (for premium users only) ``` ~/projects/fleet $ curl -v -s https://localhost:8080/api/latest/fleet/device/bf34ab98-23b0-48bc-8e82-8c0143cba11c/transparency * Connection state changed (MAX_CONCURRENT_STREAMS == 250)! < HTTP/2 307 < content-type: application/json; charset=utf-8 < location: https://fleetdm.com/transparency < content-length: 0 < date: Mon, 13 Jun 2022 18:09:29 GMT < * Connection #0 to host localhost left intact ```
This commit is contained in:
parent
ef6ae42d86
commit
19c5e3545b
5 changed files with 71 additions and 33 deletions
|
|
@ -1,4 +1,3 @@
|
|||
- Add `fleet_desktop.transparency_url` to `app_config_json`
|
||||
- Set default `transparency_url="https://fleetdm.com/transparency`
|
||||
- Enable Fleet Premium licensees to set custom `transparency_url` via REST API and `fleetctl apply`
|
||||
- Add `transparency_url` to `GET /device/{token}` endpoint response
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
|
||||
hostctx "github.com/fleetdm/fleet/v4/server/contexts/host"
|
||||
|
|
@ -21,11 +22,10 @@ func (r *getDeviceHostRequest) deviceAuthToken() string {
|
|||
}
|
||||
|
||||
type getDeviceHostResponse struct {
|
||||
Host *HostDetailResponse `json:"host"`
|
||||
OrgLogoURL string `json:"org_logo_url"`
|
||||
TransparencyURL string `json:"transparency_url"`
|
||||
Err error `json:"error,omitempty"`
|
||||
License fleet.LicenseInfo `json:"license"`
|
||||
Host *HostDetailResponse `json:"host"`
|
||||
OrgLogoURL string `json:"org_logo_url"`
|
||||
Err error `json:"error,omitempty"`
|
||||
License fleet.LicenseInfo `json:"license"`
|
||||
}
|
||||
|
||||
func (r getDeviceHostResponse) error() error { return r.Err }
|
||||
|
|
@ -65,16 +65,10 @@ func getDeviceHostEndpoint(ctx context.Context, request interface{}, svc fleet.S
|
|||
return getDeviceHostResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
transparencyURL := fleet.DefaultTransparencyURL
|
||||
if license.Tier == "premium" && ac.FleetDesktop.TransparencyURL != "" {
|
||||
transparencyURL = ac.FleetDesktop.TransparencyURL
|
||||
}
|
||||
|
||||
return getDeviceHostResponse{
|
||||
Host: resp,
|
||||
OrgLogoURL: ac.OrgInfo.OrgLogoURL,
|
||||
TransparencyURL: transparencyURL,
|
||||
License: *license,
|
||||
Host: resp,
|
||||
OrgLogoURL: ac.OrgInfo.OrgLogoURL,
|
||||
License: *license,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -244,3 +238,47 @@ func (r deviceAPIFeaturesResponse) error() error { return r.Err }
|
|||
func deviceAPIFeaturesEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
return deviceAPIFeaturesResponse{Features: fleet.DeviceAPIFeatures{}}, nil
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Transparency URL Redirect
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type transparencyURLRequest struct {
|
||||
Token string `url:"token"`
|
||||
}
|
||||
|
||||
func (r *transparencyURLRequest) deviceAuthToken() string {
|
||||
return r.Token
|
||||
}
|
||||
|
||||
type transparencyURLResponse struct {
|
||||
RedirectURL string `json:"-"` // used to control the redirect, see hijackRender method
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (r transparencyURLResponse) hijackRender(ctx context.Context, w http.ResponseWriter) {
|
||||
w.Header().Set("Location", r.RedirectURL)
|
||||
w.WriteHeader(http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func (r transparencyURLResponse) error() error { return r.Err }
|
||||
|
||||
func transparencyURL(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
config, err := svc.AppConfig(ctx)
|
||||
if err != nil {
|
||||
return transparencyURLResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
license, err := svc.License(ctx)
|
||||
if err != nil {
|
||||
return transparencyURLResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
transparencyURL := fleet.DefaultTransparencyURL
|
||||
// Fleet Premium license is required for custom transparency url
|
||||
if license.Tier == "premium" && config.FleetDesktop.TransparencyURL != "" {
|
||||
transparencyURL = config.FleetDesktop.TransparencyURL
|
||||
}
|
||||
|
||||
return transparencyURLResponse{RedirectURL: transparencyURL}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -401,6 +401,7 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
|||
de.GET("/api/_version_/fleet/device/{token}/macadmins", getDeviceMacadminsDataEndpoint, getDeviceMacadminsDataRequest{})
|
||||
de.GET("/api/_version_/fleet/device/{token}/policies", listDevicePoliciesEndpoint, listDevicePoliciesRequest{})
|
||||
de.GET("/api/_version_/fleet/device/{token}/api_features", deviceAPIFeaturesEndpoint, deviceAPIFeaturesRequest{})
|
||||
de.GET("/api/_version_/fleet/device/{token}/transparency", transparencyURL, transparencyURLRequest{})
|
||||
|
||||
// host-authenticated endpoints
|
||||
he := newHostAuthenticatedEndpointer(svc, logger, opts, r, apiVersions...)
|
||||
|
|
|
|||
|
|
@ -4766,12 +4766,12 @@ func (s *integrationTestSuite) TestDefaultTransparencyURL() {
|
|||
require.Equal(t, fleet.DefaultTransparencyURL, acResp.FleetDesktop.TransparencyURL)
|
||||
|
||||
// confirm device endpoint returns initial default url
|
||||
deviceResp := &getDeviceHostResponse{}
|
||||
rawResp := s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token, nil, http.StatusOK)
|
||||
deviceResp := &transparencyURLResponse{}
|
||||
rawResp := s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/transparency", nil, http.StatusTemporaryRedirect)
|
||||
json.NewDecoder(rawResp.Body).Decode(deviceResp)
|
||||
rawResp.Body.Close()
|
||||
require.NoError(t, deviceResp.Err)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, deviceResp.TransparencyURL)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, rawResp.Header.Get("Location"))
|
||||
|
||||
// empty string applies default url
|
||||
acResp = appConfigResponse{}
|
||||
|
|
@ -4780,24 +4780,24 @@ func (s *integrationTestSuite) TestDefaultTransparencyURL() {
|
|||
require.Equal(t, fleet.DefaultTransparencyURL, acResp.FleetDesktop.TransparencyURL)
|
||||
|
||||
// device endpoint returns default url
|
||||
deviceResp = &getDeviceHostResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token, nil, http.StatusOK)
|
||||
deviceResp = &transparencyURLResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/transparency", nil, http.StatusTemporaryRedirect)
|
||||
json.NewDecoder(rawResp.Body).Decode(deviceResp)
|
||||
rawResp.Body.Close()
|
||||
require.NoError(t, deviceResp.Err)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, deviceResp.TransparencyURL)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, rawResp.Header.Get("Location"))
|
||||
|
||||
// modify transparency url with custom url fails
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", fleet.AppConfig{FleetDesktop: fleet.FleetDesktopSettings{TransparencyURL: "customURL"}}, http.StatusUnprocessableEntity, &acResp)
|
||||
|
||||
// device endpoint still returns default url
|
||||
deviceResp = &getDeviceHostResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token, nil, http.StatusOK)
|
||||
deviceResp = &transparencyURLResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/transparency", nil, http.StatusTemporaryRedirect)
|
||||
json.NewDecoder(rawResp.Body).Decode(deviceResp)
|
||||
rawResp.Body.Close()
|
||||
require.NoError(t, deviceResp.Err)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, deviceResp.TransparencyURL)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, rawResp.Header.Get("Location"))
|
||||
}
|
||||
|
||||
func (s *integrationTestSuite) TestModifyUser() {
|
||||
|
|
|
|||
|
|
@ -1136,12 +1136,12 @@ func (s *integrationEnterpriseTestSuite) TestCustomTransparencyURL() {
|
|||
require.Equal(t, fleet.DefaultTransparencyURL, acResp.FleetDesktop.TransparencyURL)
|
||||
|
||||
// confirm device endpoint returns initial default url
|
||||
deviceResp := &getDeviceHostResponse{}
|
||||
rawResp := s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token, nil, http.StatusOK)
|
||||
deviceResp := &transparencyURLResponse{}
|
||||
rawResp := s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/transparency", nil, http.StatusTemporaryRedirect)
|
||||
json.NewDecoder(rawResp.Body).Decode(deviceResp)
|
||||
rawResp.Body.Close()
|
||||
require.NoError(t, deviceResp.Err)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, deviceResp.TransparencyURL)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, rawResp.Header.Get("Location"))
|
||||
|
||||
// set custom url
|
||||
acResp = appConfigResponse{}
|
||||
|
|
@ -1150,12 +1150,12 @@ func (s *integrationEnterpriseTestSuite) TestCustomTransparencyURL() {
|
|||
require.Equal(t, "customURL", acResp.FleetDesktop.TransparencyURL)
|
||||
|
||||
// device endpoint returns custom url
|
||||
deviceResp = &getDeviceHostResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token, nil, http.StatusOK)
|
||||
deviceResp = &transparencyURLResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/transparency", nil, http.StatusTemporaryRedirect)
|
||||
json.NewDecoder(rawResp.Body).Decode(deviceResp)
|
||||
rawResp.Body.Close()
|
||||
require.NoError(t, deviceResp.Err)
|
||||
require.Equal(t, "customURL", deviceResp.TransparencyURL)
|
||||
require.Equal(t, "customURL", rawResp.Header.Get("Location"))
|
||||
|
||||
// empty string applies default url
|
||||
acResp = appConfigResponse{}
|
||||
|
|
@ -1164,10 +1164,10 @@ func (s *integrationEnterpriseTestSuite) TestCustomTransparencyURL() {
|
|||
require.Equal(t, fleet.DefaultTransparencyURL, acResp.FleetDesktop.TransparencyURL)
|
||||
|
||||
// device endpoint returns default url
|
||||
deviceResp = &getDeviceHostResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token, nil, http.StatusOK)
|
||||
deviceResp = &transparencyURLResponse{}
|
||||
rawResp = s.DoRawNoAuth("GET", "/api/latest/fleet/device/"+token+"/transparency", nil, http.StatusTemporaryRedirect)
|
||||
json.NewDecoder(rawResp.Body).Decode(deviceResp)
|
||||
rawResp.Body.Close()
|
||||
require.NoError(t, deviceResp.Err)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, deviceResp.TransparencyURL)
|
||||
require.Equal(t, fleet.DefaultTransparencyURL, rawResp.Header.Get("Location"))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue