Added view_pin param. (#19788)
#19545 `/api/latest/fleet/hosts/:id/lock` returns `unlock_pin` for Apple hosts when query parameter `view_pin=true` is set The lock host activity now has a `view_pin` parameter. Frontend change is needed to reflect this in the UI. # Checklist for submitter <!-- Note that API documentation changes are now addressed by the product design team. --> - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
* /api/latest/fleet/hosts/:id/lock returns `unlock_pin` for Apple hosts
|
||||
* /api/latest/fleet/hosts/:id/lock returns `unlock_pin` for Apple hosts when query parameter `view_pin=true` is set
|
||||
* UI no longer uses unlock pending state for Apple hosts
|
||||
|
||||
@@ -38,7 +38,7 @@ func (svc *Service) OSVersion(ctx context.Context, osID uint, teamID *uint, incl
|
||||
return svc.Service.OSVersion(ctx, osID, teamID, true)
|
||||
}
|
||||
|
||||
func (svc *Service) LockHost(ctx context.Context, hostID uint) (unlockPIN string, err error) {
|
||||
func (svc *Service) LockHost(ctx context.Context, hostID uint, viewPIN bool) (unlockPIN string, err error) {
|
||||
// First ensure the user has access to list hosts, then check the specific
|
||||
// host once team_id is loaded.
|
||||
if err := svc.authz.Authorize(ctx, &fleet.Host{}, fleet.ActionList); err != nil {
|
||||
@@ -152,7 +152,7 @@ func (svc *Service) LockHost(ctx context.Context, hostID uint) (unlockPIN string
|
||||
}
|
||||
|
||||
// all good, go ahead with queuing the lock request.
|
||||
return svc.enqueueLockHostRequest(ctx, host, lockWipe)
|
||||
return svc.enqueueLockHostRequest(ctx, host, lockWipe, viewPIN)
|
||||
}
|
||||
|
||||
func (svc *Service) UnlockHost(ctx context.Context, hostID uint) (string, error) {
|
||||
@@ -345,7 +345,7 @@ func (svc *Service) WipeHost(ctx context.Context, hostID uint) error {
|
||||
return svc.enqueueWipeHostRequest(ctx, host, lockWipe)
|
||||
}
|
||||
|
||||
func (svc *Service) enqueueLockHostRequest(ctx context.Context, host *fleet.Host, lockStatus *fleet.HostLockWipeStatus) (
|
||||
func (svc *Service) enqueueLockHostRequest(ctx context.Context, host *fleet.Host, lockStatus *fleet.HostLockWipeStatus, viewPIN bool) (
|
||||
unlockPIN string, err error,
|
||||
) {
|
||||
vc, ok := viewer.FromContext(ctx)
|
||||
@@ -365,6 +365,7 @@ func (svc *Service) enqueueLockHostRequest(ctx context.Context, host *fleet.Host
|
||||
fleet.ActivityTypeLockedHost{
|
||||
HostID: host.ID,
|
||||
HostDisplayName: host.DisplayName(),
|
||||
ViewPIN: viewPIN,
|
||||
},
|
||||
); err != nil {
|
||||
return "", ctxerr.Wrap(ctx, err, "create activity for darwin lock host request")
|
||||
|
||||
@@ -1267,6 +1267,7 @@ func (a ActivityTypeEditedWindowsProfile) Documentation() (activity, details, de
|
||||
type ActivityTypeLockedHost struct {
|
||||
HostID uint `json:"host_id"`
|
||||
HostDisplayName string `json:"host_display_name"`
|
||||
ViewPIN bool `json:"view_pin"`
|
||||
}
|
||||
|
||||
func (a ActivityTypeLockedHost) ActivityName() string {
|
||||
|
||||
@@ -1042,7 +1042,7 @@ type Service interface {
|
||||
BatchSetScripts(ctx context.Context, maybeTmID *uint, maybeTmName *string, payloads []ScriptPayload, dryRun bool) error
|
||||
|
||||
// Script-based methods (at least for some platforms, MDM-based for others)
|
||||
LockHost(ctx context.Context, hostID uint) (unlockPIN string, err error)
|
||||
LockHost(ctx context.Context, hostID uint, viewPIN bool) (unlockPIN string, err error)
|
||||
UnlockHost(ctx context.Context, hostID uint) (unlockPIN string, err error)
|
||||
WipeHost(ctx context.Context, hostID uint) error
|
||||
|
||||
|
||||
@@ -598,6 +598,8 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
||||
mdmAppleMW.PATCH("/api/_version_/fleet/mdm/hosts/{id:[0-9]+}/unenroll", mdmAppleCommandRemoveEnrollmentProfileEndpoint, mdmAppleCommandRemoveEnrollmentProfileRequest{})
|
||||
mdmAppleMW.DELETE("/api/_version_/fleet/hosts/{id:[0-9]+}/mdm", mdmAppleCommandRemoveEnrollmentProfileEndpoint, mdmAppleCommandRemoveEnrollmentProfileRequest{})
|
||||
|
||||
// Deprecated: POST /mdm/hosts/:id/lock is now deprecated, replaced by
|
||||
// POST /hosts/:id/lock.
|
||||
mdmAppleMW.POST("/api/_version_/fleet/mdm/hosts/{id:[0-9]+}/lock", deviceLockEndpoint, deviceLockRequest{})
|
||||
mdmAppleMW.POST("/api/_version_/fleet/mdm/hosts/{id:[0-9]+}/wipe", deviceWipeEndpoint, deviceWipeRequest{})
|
||||
|
||||
|
||||
@@ -1651,9 +1651,9 @@ func TestLockUnlockWipeHostAuth(t *testing.T) {
|
||||
}
|
||||
ctx := viewer.NewContext(ctx, viewer.Viewer{User: tt.user})
|
||||
|
||||
_, err := svc.LockHost(ctx, globalHostID)
|
||||
_, err := svc.LockHost(ctx, globalHostID, false)
|
||||
checkAuthErr(t, tt.shouldFailGlobalWrite, err)
|
||||
_, err = svc.LockHost(ctx, teamHostID)
|
||||
_, err = svc.LockHost(ctx, teamHostID, false)
|
||||
checkAuthErr(t, tt.shouldFailTeamWrite, err)
|
||||
|
||||
// Pretend we locked the host
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -74,15 +73,12 @@ func (s *integrationMDMTestSuite) TestTurnOnLifecycleEventsApple() {
|
||||
{
|
||||
"locked host turns on MDM",
|
||||
func(t *testing.T, host *fleet.Host, device *mdmtest.TestAppleMDMClient) {
|
||||
var resp lockHostResponse
|
||||
s.DoJSON(
|
||||
s.Do(
|
||||
"POST",
|
||||
fmt.Sprintf("/api/latest/fleet/hosts/%d/lock", host.ID),
|
||||
nil,
|
||||
http.StatusOK,
|
||||
&resp,
|
||||
http.StatusNoContent,
|
||||
)
|
||||
assert.Len(t, resp.UnlockPIN, 6)
|
||||
|
||||
cmd, err := device.Idle()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -8024,7 +8024,7 @@ func (s *integrationMDMTestSuite) TestLockUnlockWipeMacOS() {
|
||||
|
||||
// lock the host
|
||||
var lockResp lockHostResponse
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/lock", host.ID), nil, http.StatusOK, &lockResp)
|
||||
s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/lock", host.ID), nil, http.StatusOK, &lockResp, "view_pin", "true")
|
||||
assert.Len(t, lockResp.UnlockPIN, 6)
|
||||
|
||||
// refresh the host's status, it is now pending lock
|
||||
@@ -8155,6 +8155,10 @@ func (s *integrationMDMTestSuite) TestLockUnlockWipeMacOS() {
|
||||
require.Equal(t, "unlocked", *getHostResp.Host.MDM.DeviceStatus)
|
||||
require.NotNil(t, getHostResp.Host.MDM.PendingAction)
|
||||
require.Equal(t, "", *getHostResp.Host.MDM.PendingAction)
|
||||
|
||||
// lock the host without viewing the PIN
|
||||
s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/lock", host.ID), nil, http.StatusNoContent)
|
||||
|
||||
}
|
||||
|
||||
func (s *integrationMDMTestSuite) TestZCustomConfigurationWebURL() {
|
||||
|
||||
@@ -911,7 +911,8 @@ func (svc *Service) authorizeScriptByID(ctx context.Context, scriptID uint, auth
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type lockHostRequest struct {
|
||||
HostID uint `url:"id"`
|
||||
HostID uint `url:"id"`
|
||||
ViewPin bool `query:"view_pin,optional"`
|
||||
}
|
||||
|
||||
type lockHostResponse struct {
|
||||
@@ -930,17 +931,17 @@ func (r lockHostResponse) error() error { return r.Err }
|
||||
|
||||
func lockHostEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (errorer, error) {
|
||||
req := request.(*lockHostRequest)
|
||||
unlockPIN, err := svc.LockHost(ctx, req.HostID)
|
||||
unlockPIN, err := svc.LockHost(ctx, req.HostID, req.ViewPin)
|
||||
if err != nil {
|
||||
return lockHostResponse{Err: err}, nil
|
||||
}
|
||||
if unlockPIN != "" {
|
||||
if req.ViewPin && unlockPIN != "" {
|
||||
return lockHostResponse{UnlockPIN: unlockPIN, StatusCode: http.StatusOK}, nil
|
||||
}
|
||||
return lockHostResponse{}, nil
|
||||
}
|
||||
|
||||
func (svc *Service) LockHost(ctx context.Context, hostID uint) (string, error) {
|
||||
func (svc *Service) LockHost(ctx context.Context, _ uint, _ bool) (string, error) {
|
||||
// skipauth: No authorization check needed due to implementation returning
|
||||
// only license error.
|
||||
svc.authz.SkipAuthorization(ctx)
|
||||
|
||||
Reference in New Issue
Block a user