Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changes/fix-get-policy-id-endpoint-and-unify-access-in-ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* Fixed `GET /api/v1/fleet/policies/:id` endpoint to return (and properly populate) team policies.

* Fixed `GET /api/v1/fleet/policies/:id` to perform authz check on team policies before returning.

* Unify access to policies in UI by using the now generic `GET /api/v1/fleet/policies/:id` endpoint.
Comment thread
lucasmrod marked this conversation as resolved.
Outdated
4 changes: 2 additions & 2 deletions frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import enrollSecretsAPI from "services/entities/enroll_secret";
import usersAPI from "services/entities/users";
import labelsAPI, { ILabelsResponse } from "services/entities/labels";
import teamsAPI, { ILoadTeamsResponse } from "services/entities/teams";
import globalPoliciesAPI from "services/entities/global_policies";
import policiesAPI from "services/entities/policies";
import hostsAPI, {
HOSTS_QUERY_PARAMS as PARAMS,
ILoadHostsQueryKey,
Expand Down Expand Up @@ -479,7 +479,7 @@ const ManageHostsPage = ({
error: errorPolicy,
} = useQuery<IStoredPolicyResponse, Error, IPolicy>(
["policy", policyId],
() => globalPoliciesAPI.load(policyId),
() => policiesAPI.load(policyId),
{
enabled: isRouteOk && !!policyId,
select: (data) => data.policy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ const generateTableHeaders = (
</>
}
path={getPathWithQueryParams(PATHS.POLICY_DETAILS(id), {
fleet_id: team_id,
// Inherited policies show team_id === null; preserve the
// current team context so back nav returns to the same list
// instead of "All teams".
fleet_id:
team_id ?? (selectedTeamId !== -1 ? selectedTeamId : null),
})}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ import { AppContext } from "context/app";
import { PolicyContext } from "context/policy";
import { IPolicy, IStoredPolicyResponse } from "interfaces/policy";
import { ILabelPolicy } from "interfaces/label";
import { API_ALL_TEAMS_ID, APP_CONTEXT_ALL_TEAMS_ID } from "interfaces/team";
import {
API_ALL_TEAMS_ID,
APP_CONTEXT_ALL_TEAMS_ID,
APP_CONTEXT_ALL_TEAMS_SUMMARY,
APP_CONTEXT_NO_TEAM_SUMMARY,
} from "interfaces/team";
import { PLATFORM_DISPLAY_NAMES, Platform } from "interfaces/platform";
import globalPoliciesAPI from "services/entities/global_policies";
import teamPoliciesAPI from "services/entities/team_policies";
import policiesAPI from "services/entities/policies";
import teamsAPI, { ILoadTeamResponse } from "services/entities/teams";
import { addGravatarUrlToResource } from "utilities/helpers";
import { DOCUMENT_TITLE_SUFFIX } from "utilities/constants";
Expand Down Expand Up @@ -57,7 +61,6 @@ const PolicyDetailsPage = ({
isGlobalTechnician,
isOnGlobalTeam,
config,
currentTeam,
} = useContext(AppContext);

const {
Expand Down Expand Up @@ -111,10 +114,7 @@ const PolicyDetailsPage = ({
IPolicy
>(
["policy", policyId, teamIdForApi],
Comment thread
lucasmrod marked this conversation as resolved.
Outdated
() =>
teamIdForApi && teamIdForApi > 0
? teamPoliciesAPI.load(teamIdForApi, policyId as number)
: globalPoliciesAPI.load(policyId as number),
() => policiesAPI.load(policyId as number),
{
enabled: isRouteOk && !!policyId,
refetchOnWindowFocus: false,
Expand Down Expand Up @@ -148,11 +148,17 @@ const PolicyDetailsPage = ({
}
);

// Drive the team display from the policy's own team_id rather than the URL's
// fleet_id: a user can land here from another team's list (e.g. clicking an
// inherited policy from team 42's view), and the displayed Fleet must reflect
// the policy's owner, not the navigation context.
const policyTeamId = storedPolicy?.team_id ?? undefined;
Comment thread
lucasmrod marked this conversation as resolved.
Outdated

const { data: teamData } = useQuery<ILoadTeamResponse>(
["team", teamIdForApi],
() => teamsAPI.load(teamIdForApi as number),
["team", policyTeamId],
() => teamsAPI.load(policyTeamId as number),
{
enabled: !!teamIdForApi && teamIdForApi > 0,
enabled: policyTeamId !== undefined && policyTeamId > 0,
refetchOnWindowFocus: false,
}
);
Expand Down Expand Up @@ -385,13 +391,36 @@ const PolicyDetailsPage = ({
/>
)}
{renderAuthor()}
{currentTeam && (
<DataSet
className={`${baseClass}__fleet`}
title="Fleet"
value={currentTeam.name}
/>
)}
{storedPolicy &&
(() => {
if (storedPolicy.team_id === null) {
return (
<DataSet
Comment thread
lucasmrod marked this conversation as resolved.
Outdated
className={`${baseClass}__fleet`}
title="Fleet"
value={APP_CONTEXT_ALL_TEAMS_SUMMARY.name}
/>
);
}
if (storedPolicy.team_id === 0) {
return (
<DataSet
className={`${baseClass}__fleet`}
title="Fleet"
value={APP_CONTEXT_NO_TEAM_SUMMARY.name}
/>
);
}
return (
teamData?.team && (
<DataSet
className={`${baseClass}__fleet`}
title="Fleet"
value={teamData.team.name}
/>
)
);
})()}
{renderPlatforms()}
{renderLabels()}
{storedPolicy && (
Expand Down
8 changes: 2 additions & 6 deletions frontend/pages/policies/edit/EditPolicyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { API_ALL_TEAMS_ID, APP_CONTEXT_ALL_TEAMS_ID } from "interfaces/team";
import globalPoliciesAPI from "services/entities/global_policies";
import teamPoliciesAPI from "services/entities/team_policies";
import policiesAPI from "services/entities/policies";
import teamsAPI, { ILoadTeamResponse } from "services/entities/teams";
import statusAPI from "services/entities/status";
import PATHS from "router/paths";
Expand Down Expand Up @@ -141,18 +142,13 @@ const PolicyPage = ({
false
);

// TODO: Remove team endpoint workaround once global policy endpoint populates patch_software.
// The global endpoint does not return patch_software for patch policies, but the team endpoint does.
const {
isLoading: isStoredPolicyLoading,
data: storedPolicy,
error: storedPolicyError,
} = useQuery<IStoredPolicyResponse, Error, IPolicy>(
["policy", policyId, teamIdForApi],
() =>
teamIdForApi && teamIdForApi > 0
? teamPoliciesAPI.load(teamIdForApi, policyId as number)
: globalPoliciesAPI.load(policyId as number),
() => policiesAPI.load(policyId as number),
{
enabled: isRouteOk && !!policyId,
refetchOnWindowFocus: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { AppContext } from "context/app";
import { PolicyContext } from "context/policy";
import { LIVE_QUERY_STEPS, DOCUMENT_TITLE_SUFFIX } from "utilities/constants";
import { getPathWithQueryParams } from "utilities/url";
import globalPoliciesAPI from "services/entities/global_policies";
import teamPoliciesAPI from "services/entities/team_policies";
import policiesAPI from "services/entities/policies";
import hostAPI from "services/entities/hosts";
import { IHost, IHostResponse } from "interfaces/host";
import { ILabel } from "interfaces/label";
Expand Down Expand Up @@ -93,10 +92,7 @@ const LivePolicyPage = ({
IPolicy
>(
["policy", policyId, teamIdForApi],
() =>
teamIdForApi && teamIdForApi > 0
? teamPoliciesAPI.load(teamIdForApi, policyId as number)
: globalPoliciesAPI.load(policyId as number),
() => policiesAPI.load(policyId as number),
{
enabled: !!policyId,
refetchOnWindowFocus: false,
Expand Down
14 changes: 14 additions & 0 deletions frontend/services/entities/policies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */

import sendRequest from "services";
import endpoints from "utilities/endpoints";
import { IStoredPolicyResponse } from "interfaces/policy";

export default {
load: (id: number): Promise<IStoredPolicyResponse> => {
const { GLOBAL_POLICIES } = endpoints;
const path = `${GLOBAL_POLICIES}/${id}`;

return sendRequest("GET", path);
},
};
4 changes: 2 additions & 2 deletions server/fleet/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ type Service interface {
ListGlobalPolicies(ctx context.Context, opts ListOptions) ([]*Policy, error)
DeleteGlobalPolicies(ctx context.Context, ids []uint) ([]uint, error)
ModifyGlobalPolicy(ctx context.Context, id uint, p ModifyPolicyPayload) (*Policy, error)
GetPolicyByIDQueries(ctx context.Context, policyID uint) (*Policy, error)
GetPolicyByID(ctx context.Context, policyID uint) (*Policy, error)
ApplyPolicySpecs(ctx context.Context, policies []*PolicySpec) error
CountGlobalPolicies(ctx context.Context, matchQuery string) (int, error)
AutofillPolicySql(ctx context.Context, sql string) (description string, resolution string, err error)
Expand Down Expand Up @@ -851,7 +851,7 @@ type Service interface {
ListTeamPolicies(ctx context.Context, teamID uint, opts ListOptions, iopts ListOptions, mergeInherited bool, automationType string) (teamPolicies, inheritedPolicies []*Policy, err error)
DeleteTeamPolicies(ctx context.Context, teamID uint, ids []uint) ([]uint, error)
ModifyTeamPolicy(ctx context.Context, teamID uint, id uint, p ModifyPolicyPayload) (*Policy, error)
GetTeamPolicyByIDQueries(ctx context.Context, teamID uint, policyID uint) (*Policy, error)
GetTeamPolicyByID(ctx context.Context, teamID uint, policyID uint) (*Policy, error)
CountTeamPolicies(ctx context.Context, teamID uint, matchQuery string, mergeInherited bool, automationType string) (int, int, error)

// /////////////////////////////////////////////////////////////////////////////
Expand Down
24 changes: 12 additions & 12 deletions server/mock/service/service_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ type DeleteGlobalPoliciesFunc func(ctx context.Context, ids []uint) ([]uint, err

type ModifyGlobalPolicyFunc func(ctx context.Context, id uint, p fleet.ModifyPolicyPayload) (*fleet.Policy, error)

type GetPolicyByIDQueriesFunc func(ctx context.Context, policyID uint) (*fleet.Policy, error)
type GetPolicyByIDFunc func(ctx context.Context, policyID uint) (*fleet.Policy, error)

type ApplyPolicySpecsFunc func(ctx context.Context, policies []*fleet.PolicySpec) error

Expand Down Expand Up @@ -532,7 +532,7 @@ type DeleteTeamPoliciesFunc func(ctx context.Context, teamID uint, ids []uint) (

type ModifyTeamPolicyFunc func(ctx context.Context, teamID uint, id uint, p fleet.ModifyPolicyPayload) (*fleet.Policy, error)

type GetTeamPolicyByIDQueriesFunc func(ctx context.Context, teamID uint, policyID uint) (*fleet.Policy, error)
type GetTeamPolicyByIDFunc func(ctx context.Context, teamID uint, policyID uint) (*fleet.Policy, error)

type CountTeamPoliciesFunc func(ctx context.Context, teamID uint, matchQuery string, mergeInherited bool, automationType string) (int, int, error)

Expand Down Expand Up @@ -1584,8 +1584,8 @@ type Service struct {
ModifyGlobalPolicyFunc ModifyGlobalPolicyFunc
ModifyGlobalPolicyFuncInvoked bool

GetPolicyByIDQueriesFunc GetPolicyByIDQueriesFunc
GetPolicyByIDQueriesFuncInvoked bool
GetPolicyByIDFunc GetPolicyByIDFunc
GetPolicyByIDFuncInvoked bool

ApplyPolicySpecsFunc ApplyPolicySpecsFunc
ApplyPolicySpecsFuncInvoked bool
Expand Down Expand Up @@ -1695,8 +1695,8 @@ type Service struct {
ModifyTeamPolicyFunc ModifyTeamPolicyFunc
ModifyTeamPolicyFuncInvoked bool

GetTeamPolicyByIDQueriesFunc GetTeamPolicyByIDQueriesFunc
GetTeamPolicyByIDQueriesFuncInvoked bool
GetTeamPolicyByIDFunc GetTeamPolicyByIDFunc
GetTeamPolicyByIDFuncInvoked bool

CountTeamPoliciesFunc CountTeamPoliciesFunc
CountTeamPoliciesFuncInvoked bool
Expand Down Expand Up @@ -3822,11 +3822,11 @@ func (s *Service) ModifyGlobalPolicy(ctx context.Context, id uint, p fleet.Modif
return s.ModifyGlobalPolicyFunc(ctx, id, p)
}

func (s *Service) GetPolicyByIDQueries(ctx context.Context, policyID uint) (*fleet.Policy, error) {
func (s *Service) GetPolicyByID(ctx context.Context, policyID uint) (*fleet.Policy, error) {
s.mu.Lock()
s.GetPolicyByIDQueriesFuncInvoked = true
s.GetPolicyByIDFuncInvoked = true
s.mu.Unlock()
return s.GetPolicyByIDQueriesFunc(ctx, policyID)
return s.GetPolicyByIDFunc(ctx, policyID)
}

func (s *Service) ApplyPolicySpecs(ctx context.Context, policies []*fleet.PolicySpec) error {
Expand Down Expand Up @@ -4081,11 +4081,11 @@ func (s *Service) ModifyTeamPolicy(ctx context.Context, teamID uint, id uint, p
return s.ModifyTeamPolicyFunc(ctx, teamID, id, p)
}

func (s *Service) GetTeamPolicyByIDQueries(ctx context.Context, teamID uint, policyID uint) (*fleet.Policy, error) {
func (s *Service) GetTeamPolicyByID(ctx context.Context, teamID uint, policyID uint) (*fleet.Policy, error) {
s.mu.Lock()
s.GetTeamPolicyByIDQueriesFuncInvoked = true
s.GetTeamPolicyByIDFuncInvoked = true
s.mu.Unlock()
return s.GetTeamPolicyByIDQueriesFunc(ctx, teamID, policyID)
return s.GetTeamPolicyByIDFunc(ctx, teamID, policyID)
}

func (s *Service) CountTeamPolicies(ctx context.Context, teamID uint, matchQuery string, mergeInherited bool, automationType string) (int, int, error) {
Expand Down
32 changes: 0 additions & 32 deletions server/service/global_policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,38 +112,6 @@ func (svc Service) ListGlobalPolicies(ctx context.Context, opts fleet.ListOption
return svc.ds.ListGlobalPolicies(ctx, opts)
}

/////////////////////////////////////////////////////////////////////////////////
// Get by id
/////////////////////////////////////////////////////////////////////////////////

func getPolicyByIDEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (fleet.Errorer, error) {
req := request.(*fleet.GetPolicyByIDRequest)
policy, err := svc.GetPolicyByIDQueries(ctx, req.PolicyID)
if err != nil {
return fleet.GetPolicyByIDResponse{Err: err}, nil
}
return fleet.GetPolicyByIDResponse{Policy: policy}, nil
}

func (svc Service) GetPolicyByIDQueries(ctx context.Context, policyID uint) (*fleet.Policy, error) {
if err := svc.authz.Authorize(ctx, &fleet.Policy{}, fleet.ActionRead); err != nil {
return nil, err
}

policy, err := svc.ds.Policy(ctx, policyID)
if err != nil {
return nil, err
}
if err := svc.populatePolicyInstallSoftware(ctx, policy); err != nil {
return nil, ctxerr.Wrap(ctx, err, "populate install_software")
}
if err := svc.populatePolicyRunScript(ctx, policy); err != nil {
return nil, ctxerr.Wrap(ctx, err, "populate run_script")
}

return policy, nil
}

// ///////////////////////////////////////////////////////////////////////////////
// Count
// ///////////////////////////////////////////////////////////////////////////////
Expand Down
Loading
Loading